xlinkobj.cpp
author insilmaril
Thu, 14 Jun 2007 10:21:41 +0000
changeset 503 48ca4c364eab
parent 477 a9ac5dea9561
child 532 50dc461a95e0
permissions -rw-r--r--
Fixed undo/redo of copy/paste
     1 #include "xlinkobj.h"
     2 #include "branchobj.h"
     3 #include "mapeditor.h"
     4 
     5 
     6 /////////////////////////////////////////////////////////////////
     7 // XLinkObj
     8 /////////////////////////////////////////////////////////////////
     9 
    10 int XLinkObj::arrowSize=10;						// make instances 
    11 
    12 XLinkObj::XLinkObj ():MapObj() 
    13 {
    14 	//	cout << "Const XLinkObj ()\n";
    15 	init();
    16 }
    17 
    18 XLinkObj::XLinkObj (QGraphicsScene* s):MapObj(s)
    19 {
    20 	//	cout << "Const XLinkObj (s)  called from MapCenterObj (s)\n";
    21 	init();
    22 }
    23 
    24 
    25 XLinkObj::~XLinkObj ()
    26 {
    27 //	cout << "Destr XLinkObj\n";
    28 	if (xLinkState!=undefinedXLink)
    29 		deactivate();
    30 	delete (line);
    31 	delete (poly);
    32 }
    33 
    34 
    35 void XLinkObj::init () 
    36 {
    37 	beginBranch=NULL;
    38 	endBranch=NULL;
    39 	visBranch=NULL;
    40 	xLinkState=undefinedXLink;
    41 
    42 	color=QColor (180,180,180);
    43 	width=1;
    44 	pen.setColor (color);
    45 	pen.setWidth (width);
    46 	pen.setCapStyle (  Qt::RoundCap );
    47 	line=scene->addLine(QLineF(1,1,1,1),pen);
    48     line->setZValue (Z_XLINK);
    49 	poly=scene->addPolygon(QPolygonF(),pen,color);
    50     poly->setZValue (Z_XLINK);
    51 	setVisibility (false);
    52 }
    53 
    54 void XLinkObj::copy (XLinkObj* other)
    55 {
    56 	// TODO copy not used yet
    57 	MapObj::copy (other);
    58 	setVisibility (other->visible);
    59 	beginBranch=other->beginBranch;
    60 	endBranch=other->endBranch;
    61 	width=other->width;
    62 
    63 }
    64 
    65 void XLinkObj::setBegin (BranchObj *bo)
    66 {
    67 	if (bo) 
    68 	{
    69 		xLinkState=initXLink;
    70 		beginBranch=bo;
    71 		beginPos=beginBranch->getChildPos();
    72 	}	
    73 }
    74 
    75 BranchObj* XLinkObj::getBegin ()
    76 {
    77 	return beginBranch;
    78 }
    79 
    80 void XLinkObj::setEnd (BranchObj *bo)
    81 {
    82 	if (bo) 
    83 	{
    84 		xLinkState=initXLink;
    85 		endBranch=bo;
    86 		endPos=endBranch->getChildPos();
    87 	}		
    88 }
    89 
    90 BranchObj* XLinkObj::getEnd()
    91 {
    92 	return endBranch;
    93 }
    94 
    95 void XLinkObj::setWidth (int w)
    96 {
    97 	width=w;
    98 	pen.setWidth (w);
    99 	setColor (color);
   100 }
   101 
   102 int XLinkObj::getWidth()
   103 {
   104 	return pen.width();
   105 }
   106 
   107 void XLinkObj::setColor(QColor c)
   108 {
   109 	color=c;
   110 	pen.setColor (c);
   111 	line->setPen (pen);
   112 	poly->setBrush( color );
   113 }
   114 
   115 QColor XLinkObj::getColor()
   116 {
   117 	return pen.color();
   118 }
   119 
   120 void XLinkObj::setEnd (QPointF p)
   121 {
   122 	endPos=p;
   123 }
   124 
   125 bool XLinkObj::activate ()
   126 {
   127 	if (beginBranch && endBranch)
   128 	{
   129 		if (beginBranch==endBranch) return false;
   130 		xLinkState=activeXLink;
   131 		beginBranch->addXLink (this);
   132 		endBranch->addXLink (this);
   133 		setVisibility ();
   134 		return true;
   135 	} else
   136 		return false;
   137 }
   138 
   139 void XLinkObj::deactivate ()
   140 {
   141 	if (beginBranch)
   142 		beginBranch->removeXLinkRef (this);
   143 	beginBranch=NULL;	
   144 	if (endBranch)
   145 		endBranch->removeXLinkRef (this);
   146 	endBranch=NULL;	
   147 	visBranch=NULL;
   148 	xLinkState=undefinedXLink;
   149 
   150 	line->hide();
   151 }
   152 
   153 bool XLinkObj::isUsed()
   154 {
   155 	if (beginBranch || endBranch || xLinkState!=undefinedXLink)
   156 		return true;
   157 	else
   158 		return false;
   159 }
   160 
   161 void XLinkObj::updateXLink()
   162 {
   163 	QPointF a,b;
   164 	QPolygonF pa;
   165 	if (visBranch)
   166 	{
   167 		// Only one of the linked branches is visible
   168 		a=b=visBranch->getChildPos();
   169 		if (visBranch->getOrientation()==LinkableMapObj::RightOfCenter)
   170 		{
   171 			b.setX (b.x()+25);
   172 			
   173 			pa.clear();
   174 			pa<< QPointF(b.x(),b.y())<<
   175 				QPointF(b.x()-arrowSize,b.y()-arrowSize)<<
   176 				QPointF(b.x()-arrowSize,b.y()+arrowSize);
   177 			poly->setPolygon(pa);
   178 		} else
   179 		{
   180 			b.setX (b.x()-25);
   181 			pa.clear();
   182 			pa<< QPointF(b.x(),b.y())<<
   183 				QPointF(b.x()+arrowSize,b.y()-arrowSize)<<
   184 				QPointF(b.x()+arrowSize,b.y()+arrowSize);
   185 			poly->setPolygon (pa);
   186 		}	
   187 	} else
   188 	{
   189 		// Both linked branches are visible
   190 		if (beginBranch)
   191 			// If a link is just drawn in the editor,
   192 			// we have already a beginBranch
   193 			a=beginBranch->getChildPos();
   194 		else
   195 			// This shouldn't be reached normally...
   196 			a=beginPos;
   197 		if (xLinkState==activeXLink && endBranch)
   198 			b=endBranch->getChildPos();
   199 		else
   200 			b=endPos;
   201 	}
   202 
   203 
   204 	if (line->line().p1()==a && line->line().p2()==b && !visBranch)
   205 	{
   206 		// update is called from both branches, so only
   207 		// update if something has changed
   208 		return;
   209 	}	
   210 	else
   211 	{
   212 		beginPos=a;
   213 		endPos=b;
   214 		line->setPen (pen);
   215 		line->setLine(a.x(), a.y(), b.x(), b.y());
   216 	}
   217 }
   218 
   219 BranchObj* XLinkObj::otherBranch(BranchObj* thisBranch)
   220 {
   221 	if (!beginBranch && !endBranch)
   222 		return NULL;
   223 	if (thisBranch==beginBranch)
   224 		return endBranch;
   225 	else	
   226 		return beginBranch;
   227 }
   228 
   229 void XLinkObj::positionBBox()
   230 {
   231 }
   232 
   233 void XLinkObj::calcBBoxSize()
   234 {
   235 }
   236 
   237 void XLinkObj::setVisibility (bool b)
   238 {
   239 	MapObj::setVisibility (b);
   240 	if (b)
   241 	{
   242 		line->show();
   243 		if (visBranch) 
   244 			poly->show();
   245 		else	
   246 			poly->hide();
   247 	}	
   248 	else
   249 	{
   250 		line->hide();
   251 		poly->hide();
   252 	}	
   253 }
   254 
   255 void XLinkObj::setVisibility ()
   256 {
   257 	if (beginBranch && endBranch)
   258 	{
   259 		if(beginBranch->isVisibleObj() && endBranch->isVisibleObj())
   260 		{	// Both ends are visible
   261 			visBranch=NULL;
   262 			setVisibility (true);
   263 		} else
   264 		{
   265 			if(!beginBranch->isVisibleObj() && !endBranch->isVisibleObj())
   266 			{	//None of the ends is visible
   267 				visBranch=NULL;
   268 				setVisibility (false);
   269 			} else
   270 			{	// Just one end is visible, draw a symbol that shows
   271 				// that there is a link to a scrolled branch
   272 				if (beginBranch->isVisibleObj())
   273 					visBranch=beginBranch;
   274 				else
   275 					visBranch=endBranch;
   276 				setVisibility (true);
   277 			}
   278 		}
   279 	}
   280 }
   281 
   282 QString XLinkObj::saveToDir ()
   283 {
   284 	QString s="";
   285 	if (beginBranch && endBranch &&xLinkState==activeXLink)
   286 	{
   287 		if (beginBranch==endBranch && xLinkState)
   288 			s="";
   289 		else
   290 		{
   291 			QString colAttr=attribut ("color",color.name());
   292 			QString widAttr=attribut ("width",QString().setNum(width,10));
   293 			QString begSelAttr=attribut ("beginBranch",beginBranch->getSelectString());
   294 			QString endSelAttr=attribut ("endBranch",  endBranch->getSelectString());
   295 			s=beginElement ("xlink", colAttr +widAttr +begSelAttr +endSelAttr);
   296 
   297 			s+=endElement ("xlink");
   298 		}
   299 	}
   300 	return s;
   301 }
   302