branchobj.cpp
author convert-repo
Fri, 23 Jul 2010 16:43:49 +0000
changeset 849 988f1908a7c4
parent 848 e265f07f2173
permissions -rw-r--r--
update tags
     1 #include "branchobj.h"
     2 
     3 #include "attributeitem.h"
     4 #include "branchitem.h"
     5 #include "geometry.h"
     6 #include "mapeditor.h"
     7 #include "mainwindow.h"   
     8 #include "misc.h"
     9 
    10 extern FlagRow *standardFlagsMaster;
    11 extern FlagRow *systemFlagsMaster;
    12 
    13 /////////////////////////////////////////////////////////////////
    14 // BranchObj
    15 /////////////////////////////////////////////////////////////////
    16 
    17 BranchObj::BranchObj (QGraphicsScene* s,TreeItem *ti):OrnamentedObj (s)
    18 {
    19 //    cout << "Const BranchObj (s)  \n";
    20     scene=s;
    21 	treeItem=ti;
    22 	BranchItem *pi=(BranchItem*)(ti->parent());
    23 	if (pi && pi!=ti->getModel()->getRootItem() )
    24 		parObj=pi->getLMO();
    25 	else
    26 		parObj=NULL;
    27 	init();
    28 }
    29 
    30 BranchObj::~BranchObj ()
    31 {
    32 	//qDebug()<< "Destr BranchObj of "<<this<<" ("<<treeItem->getHeading()<<")";
    33 
    34 	// If I'm animated, I need to un-animate myself first
    35 	if (anim.isAnimated() )
    36 	{
    37 		anim.setAnimated (false);
    38 		VymModel *model=treeItem->getModel();
    39 		model->stopAnimation (this);
    40 	}
    41 
    42 	clear();
    43 }
    44 
    45 void BranchObj::init () 
    46 {
    47 	if (parObj)
    48 	{
    49 		absPos=getRandPos();
    50 		absPos+=parObj->getChildPos();
    51 	}
    52 }
    53 
    54 void BranchObj::copy (BranchObj* other)
    55 {
    56     OrnamentedObj::copy(other);
    57 
    58 	setVisibility (other->visible);
    59 
    60     positionBBox();
    61 }
    62 
    63 void BranchObj::clear() 
    64 {
    65 	//setVisibility (true); //FIXME-4 needed?
    66 }
    67 
    68 void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off)	
    69 {
    70 	// Temporary link to dst
    71 	// m is position of mouse pointer 
    72 	// offset 0: default 1: below dst   -1 above dst  (if possible)
    73 
    74 	BranchItem *dsti=(BranchItem*)(dst->getTreeItem());
    75 
    76 	BranchItem *pi=(BranchItem*)(dsti->parent());
    77 	int pi_depth=pi->depth();
    78 	BranchObj* bodst=(BranchObj*)dst;
    79 
    80 	if (!tmpParent) 
    81 	{
    82 		tmpParent=true;
    83 		parObjTmpBuf=parObj;
    84 	}
    85 
    86 	if (pi_depth<2) off=0;
    87 	if (off==0)
    88 		link2ParPos=false;
    89 	else
    90 		link2ParPos=true;
    91 	parObj=bodst;
    92 
    93 	setLinkStyle (dst->getDefLinkStyle (dsti));
    94  
    95 	// Move temporary to new position at destination
    96 	// Usually the positioning would be done by reposition(),
    97 	// but then also the destination branch would "Jump" around...
    98 	// Better just do it approximately
    99 	if (dsti->depth()==0)	
   100 	{	// new parent is a mapcenter
   101 		Vector v= ( m - bodst->getChildPos());
   102 		if (v.x()<0) v.setX( v.x()-bbox.width() );
   103 		v.normalize();
   104 		v.scale (100);
   105 		move2RelPos (v.toQPointF());
   106 	} else
   107 	{	
   108 		qreal y;
   109 		if (off==0)
   110 		{
   111 				// Below is needed e.g. in a freshly loaded map, 
   112 				// bboxTotal seems not to be correct yet
   113 				// relinking positions too far below then
   114 				calcBBoxSizeWithChildren();	
   115 
   116 			// new parent is just a branch, link to it
   117 			bodst->calcBBoxSizeWithChildren();
   118 			QRectF t=bodst->getBBoxSizeWithChildren();
   119 			if (dsti->getLastBranch())
   120 				y=t.y() + t.height() ;
   121 			else
   122 				y=t.y();
   123 
   124 			y=t.bottom();
   125 
   126 		} else
   127 		{
   128 			if (off<0)
   129 				// we want to link above dst
   130 				y=bodst->y() - height() + 5;
   131 			else	
   132 				// we want to link below dst
   133 				// Bottom of sel should be 5 pixels above
   134 				// the bottom of the branch _below_ the target:
   135 				// Don't try to find that branch, guess 12 pixels
   136 				y=bodst->getChildPos().y()  -height() + 12; 
   137 		}	
   138 		if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
   139 			move ( bodst->getChildPos().x() - linkwidth, y );
   140 		else	
   141 			move (bodst->getChildPos().x() + linkwidth, y );
   142 	}	
   143 
   144 	// updateLinkGeometry is called implicitly in move
   145 	requestReposition();	
   146 }
   147 
   148 void BranchObj::unsetParObjTmp()
   149 {
   150 	if (tmpParent) 
   151 	{
   152 		tmpParent=false;
   153 		link2ParPos=false;
   154 		parObj=parObjTmpBuf;
   155 		parObjTmpBuf=NULL;
   156 		setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
   157 		updateLinkGeometry();
   158 	}		
   159 }
   160 
   161 void BranchObj::setVisibility(bool v, int toDepth)
   162 {
   163 	BranchItem *bi=(BranchItem*)treeItem;
   164     if (bi->depth() <= toDepth)
   165     {
   166 		frame->setVisibility(v);
   167 		heading->setVisibility(v);
   168 		systemFlags->setVisibility(v);
   169 		standardFlags->setVisibility(v);
   170 		LinkableMapObj::setVisibility (v);
   171 		int i;
   172 		for (i=0; i<treeItem->imageCount(); ++i)
   173 			treeItem->getImageObjNum(i)->setVisibility (v);
   174 		for (i=0; i<treeItem->xlinkCount(); ++i)	
   175 			treeItem->getXLinkObjNum(i)->setVisibility ();	
   176 
   177 		// Only change children, if I am not scrolled
   178 		if (! bi->isScrolled() && (bi->depth() < toDepth))
   179 		{
   180 			// Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
   181 			for (i=0; i<treeItem->branchCount(); ++i)
   182 				treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);	
   183 		}
   184     } // depth <= toDepth	
   185 	requestReposition();
   186 }	
   187 
   188 void BranchObj::setVisibility(bool v)
   189 {
   190     setVisibility (v,MAX_DEPTH);
   191 }
   192 
   193 
   194 void BranchObj::setLinkColor ()
   195 {
   196 	// Overloaded from LinkableMapObj
   197 	// BranchObj can use color of heading
   198 
   199 	VymModel *model=treeItem->getModel();
   200 	if (model)
   201 	{
   202 		if (model->getMapLinkColorHint()==HeadingColor)
   203 			LinkableMapObj::setLinkColor (heading->getColor() );
   204 		else	
   205 			LinkableMapObj::setLinkColor ();
   206 	}		
   207 }
   208 
   209 void BranchObj::updateContentSize()
   210 {
   211 	calcBBoxSize();
   212 	positionBBox();
   213 	requestReposition();
   214 }
   215 
   216 void BranchObj::positionContents()
   217 {
   218 	for (int i=0; i<treeItem->imageCount(); ++i)
   219 		treeItem->getImageObjNum(i)->reposition();
   220 	OrnamentedObj::positionContents();
   221 }
   222 
   223 void BranchObj::move (double x, double y)
   224 {
   225 	OrnamentedObj::move (x,y);
   226     positionBBox();
   227 }
   228 
   229 void BranchObj::move (QPointF p)
   230 {
   231 	move (p.x(), p.y());
   232 }
   233 
   234 void BranchObj::moveBy (double x, double y)
   235 {
   236 	OrnamentedObj::moveBy (x,y);
   237 	for (int i=0; i<treeItem->branchCount(); ++i)
   238 		treeItem->getBranchObjNum(i)->moveBy (x,y);
   239     positionBBox();
   240 }
   241 	
   242 void BranchObj::moveBy (QPointF p)
   243 {
   244 	moveBy (p.x(), p.y());
   245 }
   246 
   247 
   248 void BranchObj::positionBBox()
   249 {
   250 	QPointF ap=getAbsPos();
   251 	bbox.moveTopLeft (ap);
   252 	positionContents();
   253 
   254 	// set the frame
   255 	frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
   256 
   257 	//Update links to other branches	
   258 	XLinkObj *xlo;
   259 	for (int i=0; i<treeItem->xlinkCount(); ++i)	
   260 	{
   261 		xlo=treeItem->getXLinkObjNum(i);
   262 		if (xlo) xlo->updateXLink();
   263 	}	
   264 }
   265 
   266 void BranchObj::calcBBoxSize()
   267 {
   268     QSizeF heading_r=heading->getSize();
   269     qreal heading_w=(qreal) heading_r.width() ;
   270     qreal heading_h=(qreal) heading_r.height() ;
   271     QSizeF sysflags_r=systemFlags->getSize();
   272 	qreal sysflags_h=sysflags_r.height();
   273 	qreal sysflags_w=sysflags_r.width();
   274     QSizeF stanflags_r=standardFlags->getSize();
   275 	qreal stanflags_h=stanflags_r.height();
   276 	qreal stanflags_w=stanflags_r.width();
   277     qreal w;
   278     qreal h;
   279 
   280 	// set width to sum of all widths
   281 	w=heading_w + sysflags_w + stanflags_w;
   282 	// set height to maximum needed height
   283 	h=max (sysflags_h,stanflags_h);
   284 	h=max (h,heading_h);
   285 
   286 	// Save the dimension of flags and heading
   287 	ornamentsBBox.setSize ( QSizeF(w,h));
   288 
   289 	// clickBox includes Flags and Heading
   290     clickBox.setSize (ornamentsBBox.size() );
   291 
   292 	// Floatimages 
   293 	QPointF rp;
   294 
   295 	topPad=botPad=leftPad=rightPad=0;
   296 	bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
   297 	bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
   298 	if (incH || incV)
   299 	{
   300 		FloatImageObj *fio;
   301 		for (int i=0; i<treeItem->imageCount(); ++i )	
   302 		{
   303 			fio=treeItem->getImageObjNum(i);
   304 			rp=fio->getRelPos();
   305 			if (incV)
   306 			{
   307 				if (rp.y() < 0) 
   308 					topPad=max (topPad,-rp.y()-h);
   309 				if (rp.y()+fio->height() > 0)
   310 					botPad=max (botPad,rp.y()+fio->height());
   311 			}		
   312 			if (incH)
   313 			{
   314 				if (orientation==LinkableMapObj::RightOfCenter)
   315 				{
   316 					if (-rp.x()-w > 0) 
   317 						leftPad=max (leftPad,-rp.x()-w);
   318 					if (rp.x()+fio->width() > 0)
   319 						rightPad=max (rightPad,rp.x()+fio->width());
   320 				} else
   321 				{
   322 					if (rp.x()< 0) 
   323 						leftPad=max (leftPad,-rp.x());
   324 					if (rp.x()+fio->width() > w)
   325 						rightPad=max (rightPad,rp.x()+fio->width()-w);
   326 				}
   327 			}		
   328 		}	
   329 		h+=topPad+botPad;
   330 		w+=leftPad+rightPad;
   331 	}
   332 
   333 	// Frame thickness
   334     w+=frame->getPadding();
   335     h+=frame->getPadding();
   336 	
   337 	// Finally set size
   338     bbox.setSize (QSizeF (w,h));
   339 }
   340 
   341 void BranchObj::setDockPos()
   342 {
   343 	if (treeItem->getType()==TreeItem::MapCenter)
   344 	{
   345 		// set childPos to middle of MapCenterObj
   346 		childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
   347 		childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
   348 		parPos=childPos;		
   349 		for (int i=0; i<treeItem->branchCount(); ++i)
   350 			treeItem->getBranchObjNum(i)->updateLinkGeometry();
   351 
   352 	} else
   353 	{
   354 		// Sets childpos and parpos depending on orientation
   355 		if (getOrientation()==LinkableMapObj::LeftOfCenter )
   356 		{
   357 			childPos=QPointF (
   358 				ornamentsBBox.bottomLeft().x(), 
   359 				bottomlineY);
   360 			parPos=QPointF (
   361 				ornamentsBBox.bottomRight().x(),
   362 				bottomlineY);
   363 		} else
   364 		{
   365 			childPos=QPointF (
   366 				ornamentsBBox.bottomRight().x(), 
   367 				bottomlineY);
   368 			parPos=QPointF (
   369 				ornamentsBBox.bottomLeft().x(),
   370 				bottomlineY);
   371 		}
   372 	}
   373 }
   374 
   375 void BranchObj::updateData()
   376 {
   377 	bool changed=false;
   378 	if (!treeItem)
   379 	{
   380 		qWarning ("BranchObj::udpateHeading treeItem==NULL");
   381 		return;
   382 	}
   383 	QString s=treeItem->getHeading();
   384 	if (s!=heading->text())
   385 	{
   386 		heading->setText (s);
   387 		changed=true;
   388 	}
   389 	QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
   390 
   391 	// Add missing standard flags active in TreeItem
   392 	for (int i=0;i<=TIactiveFlags.size()-1;i++)
   393 	{	
   394 		if (!standardFlags->isActive (TIactiveFlags.at(i) ))
   395 		{
   396 			Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
   397 			if (f) standardFlags->activate (f);
   398 			changed=true;
   399 		}
   400 	}
   401 	// Remove standard flags no longer active in TreeItem
   402 	QStringList BOactiveFlags=standardFlags->activeFlagNames();
   403 	for (int i=0;i<BOactiveFlags.size();++i)
   404 		if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
   405 		{
   406 			standardFlags->deactivate (BOactiveFlags.at(i));
   407 			changed=true;
   408 		}	
   409 
   410 	// Add missing system flags active in TreeItem
   411 	TIactiveFlags=treeItem->activeSystemFlagNames();
   412 	for (int i=0;i<TIactiveFlags.size();++i)
   413 	{	
   414 		if (!systemFlags->isActive (TIactiveFlags.at(i) ))
   415 		{
   416 			Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
   417 			if (f) systemFlags->activate (f);
   418 			changed=true;
   419 		}
   420 	}
   421 	// Remove system flags no longer active in TreeItem
   422 	BOactiveFlags=systemFlags->activeFlagNames();
   423 	for (int i=0;i<BOactiveFlags.size();++i)
   424 	{
   425 		if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
   426 		{
   427 			systemFlags->deactivate (BOactiveFlags.at(i));
   428 			changed=true;
   429 		}	
   430 	}
   431 	if (changed) updateContentSize(); 
   432 }
   433 
   434 void BranchObj::setDefAttr (BranchModification mod, bool keepFrame)
   435 {
   436 	int fontsize;
   437 	switch (treeItem->depth())
   438 	{
   439 		case 0: 
   440 			fontsize=16; 
   441 			break;
   442 		case 1: 
   443 			fontsize=14; 
   444 			break;
   445 		case 2: 
   446 			fontsize=12; 
   447 			break;
   448 		default: 
   449 			fontsize=10; 
   450 			break;
   451 	}	
   452 	setLinkStyle(getDefLinkStyle(treeItem->parent() ));
   453 	setLinkColor ();
   454 	QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
   455 	font.setPointSize(fontsize);
   456 	heading->setFont(font );
   457 
   458 	if (mod==NewBranch && !keepFrame)
   459 	{
   460 		if (treeItem->depth()==0)
   461 			setFrameType (FrameObj::Rectangle);
   462 		else	
   463 			setFrameType (FrameObj::NoFrame);
   464 	}
   465 	if (mod==NewBranch)
   466 		setColor (treeItem->getHeadingColor() );
   467 	else
   468 	{
   469 		// Also set styles for children
   470 		for (int i=0; i<treeItem->branchCount(); ++i)
   471 			treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch);
   472 	}		
   473 	calcBBoxSize();
   474 }
   475 
   476 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
   477 {
   478 	qreal th = bboxTotal.height();	
   479 	int depth=0;
   480 	if (parObj)	depth=1 + parObj->getTreeItem()->depth();
   481 // TODO testing
   482 /*
   483 	QString h=QString (depth+1,' ');
   484 	h+=treeItem->getHeading();
   485 	h+=QString (15,' ');
   486 	h.truncate (15);
   487 	QPointF pp; 
   488 	if (parObj) pp=parObj->getChildPos();
   489 	cout << "BO::alignRelTo ";
   490 	cout<<h.toStdString();
   491 	cout << "    d="<<depth;
   492 	cout <<"  parO="<<parObj;
   493 //cout<<  "  ref="<<ref<<
   494 //cout <<	"  bbox.tL="<<bboxTotal.topLeft();
   495 cout<<	"  absPos="<<absPos<<
   496 		"  relPos="<<relPos<<
   497 //		"  parPos="<<pp<<
   498 //		"  w="<<bbox.width()<<
   499 //		"  h="<<bbox.height()<<
   500 //		"  orient="<<orientation<<
   501 //		"  alignSelf="<<alignSelf<<
   502 //		"  scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
   503 //		"  pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
   504 //		"  hidden="<<hidden<<
   505 //		"  th="<<th<<
   506 		endl;
   507 */
   508 
   509 	setOrientation();
   510 	//updateLinkGeometry();
   511 
   512 	if (depth==1)
   513 	{
   514 		move2RelPos (getRelPos() );
   515 	}
   516 	if (depth>1)
   517     {
   518 		// Align myself depending on orientation and parent, but
   519 		// only if I am not a mainbranch or mapcenter itself
   520 
   521 		if (anim.isAnimated())
   522 		{
   523 			move2RelPos(anim);
   524 		} else
   525 		{
   526 			LinkableMapObj::Orientation o;
   527 			o=parObj->getOrientation();
   528 			if (alignSelf)
   529 				switch (orientation) 
   530 				{
   531 					case LinkableMapObj::LeftOfCenter:
   532 						move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
   533 						//move (ref.x() , ref.y() + (th-bbox.height())/2 );
   534 					break;
   535 					case LinkableMapObj::RightOfCenter:	
   536 						move (ref.x() , ref.y() + (th-bbox.height())/2  );
   537 					break;
   538 					default:
   539 						qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
   540 					break;
   541 			}
   542 		}
   543     }		
   544 
   545 	if ( ((BranchItem*)treeItem)->isScrolled() ) return;
   546 
   547     // Set reference point for alignment of children
   548     QPointF ref2;
   549     if (orientation==LinkableMapObj::LeftOfCenter)
   550 		ref2.setX(bbox.topLeft().x() - linkwidth);
   551     else	
   552 		ref2.setX(bbox.topRight().x() + linkwidth);
   553 
   554 	if (depth==1)
   555 		ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
   556 	else	
   557 		ref2.setY(ref.y() );	
   558 
   559     // Align the attribute children depending on reference point 
   560 	// on top like in TreeEditor
   561 	for (int i=0; i<treeItem->attributeCount(); ++i)
   562     {	
   563 		if (!treeItem->getAttributeNum(i)->isHidden())
   564 		{
   565 			BranchObj *bo=(BranchObj*)(treeItem->getAttributeNum(i)->getBranchObj());
   566 			if (!bo) break;
   567 			bo->alignRelativeTo (ref2,true);
   568 
   569 			// append next branch below current one
   570 			ref2.setY(ref2.y() + bo->getBBoxSizeWithChildren().height() );
   571 		}
   572     }
   573     // Align the branch children depending on reference point 
   574 	for (int i=0; i<treeItem->branchCount(); ++i)
   575     {	
   576 		if (!treeItem->getBranchNum(i)->isHidden())
   577 		{
   578 			treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
   579 
   580 			// append next branch below current one
   581 			ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
   582 		}
   583     }
   584 }
   585 
   586 
   587 void BranchObj::reposition()
   588 {	
   589 /* TODO testing only
   590 	if (!treeItem->getHeading().isEmpty())
   591 		cout << "BO::reposition  "<<qPrintable(treeItem->getHeading())<<endl;
   592 	else	
   593 		cout << "BO::reposition  ???"<<endl;
   594 //	cout << "  orient="<<orientation<<endl;
   595 */		
   596 
   597 	if (treeItem->depth()==0)
   598 	{
   599 		// only calculate the sizes once. If the deepest LMO 
   600 		// changes its height,
   601 		// all upper LMOs have to change, too.
   602 		calcBBoxSizeWithChildren();
   603 		updateLinkGeometry();	// This update is needed if the scene is resized 
   604 						// due to excessive moving of a FIO
   605 
   606 	    alignRelativeTo ( QPointF (absPos.x(),
   607 			absPos.y()-(bboxTotal.height()-bbox.height())/2) );
   608 		positionBBox();	// Reposition bbox and contents
   609 	} else
   610 	{
   611 		// This is only important for moving branches:
   612 		// For editing a branch it isn't called...
   613 	    alignRelativeTo ( QPointF (absPos.x(),
   614 							absPos.y()-(bboxTotal.height()-bbox.height())/2) );
   615 	}
   616 }
   617 
   618 void BranchObj::unsetAllRepositionRequests()
   619 {
   620 	repositionRequest=false;
   621 	for (int i=0; i<treeItem->branchCount(); ++i)
   622 		treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
   623 }
   624 
   625 QRectF BranchObj::getBBoxSizeWithChildren()
   626 {
   627 	return bboxTotal;
   628 }
   629 
   630 ConvexPolygon BranchObj::getBoundingPolygon()	
   631 {
   632 /*
   633 	if (!pi)	//FIXME-3 Testing only
   634 	{
   635 		pi=scene->addPolygon(MapObj::getBoundingPolygon() );
   636 		pi->setPen(Qt::NoPen);
   637 		pi->setBrush( QColor(qrand()%32*8,qrand()%32*8,qrand()%32*8) );
   638 		pi->setZValue(Z_BBOX);
   639 	}
   640 	*/
   641 
   642 	if (treeItem->branchCount()==0 || treeItem->depth()==0)
   643 	{
   644 		if (pi) pi->setPolygon (MapObj::getBoundingPolygon() );
   645 		return MapObj::getBoundingPolygon();
   646 	}
   647 
   648 	calcBBoxSizeWithChildren();	//FIXME-3 really needed?
   649 	QPolygonF p;
   650 	p<<bboxTotal.topLeft();
   651 	p<<bboxTotal.topRight();
   652 	p<<bboxTotal.bottomRight();
   653 	p<<bboxTotal.bottomLeft();
   654 	//cout << "BO::getBP (total)  "<<treeItem->getHeadingStd()<<"  tL="<<bboxTotal.topLeft()<<"  bR="<<bboxTotal.bottomRight()<<endl;
   655 	//cout << "                   "<<"  tL="<<bbox.topLeft()<<"  bR="<<bbox.bottomRight()<<endl;
   656 	if (pi) pi->setPolygon (p );
   657 	return p;
   658 }
   659 
   660 void BranchObj::calcBBoxSizeWithChildren()
   661 {	
   662 	// This is initially called only from reposition and
   663 	// and only for mapcenter. So it won't be
   664 	// called more than once for a single user 
   665 	// action
   666 	
   667 
   668 	// Calculate size of LMO including all children (to align them later)
   669 	bboxTotal.setX(bbox.x() );
   670 	bboxTotal.setY(bbox.y() );
   671 
   672 	// if branch is scrolled, ignore children, but still consider floatimages
   673 	BranchItem *bi=(BranchItem*)treeItem;
   674 	if ( bi->isScrolled() ) 
   675 	{
   676 		bboxTotal.setWidth (bbox.width());
   677 		bboxTotal.setHeight(bbox.height());
   678 		return;
   679 	}
   680 	
   681 	if (bi->isHidden())
   682 	{
   683 		bboxTotal.setWidth (0);
   684 		bboxTotal.setHeight(0);
   685 		if (parObj)
   686 		{
   687 			bboxTotal.setX (parObj->x());
   688 			bboxTotal.setY (parObj->y());
   689 		} else
   690 		{
   691 			bboxTotal.setX (bbox.x());
   692 			bboxTotal.setY (bbox.y());
   693 		}
   694 		return;
   695 	}
   696 	
   697 	QRectF r(0,0,0,0);
   698 	QRectF br;
   699 	// Now calculate recursivly
   700 	// sum of heights 
   701 	// maximum of widths 
   702 	// minimum of y
   703 	for (int i=0; i<treeItem->branchCount(); i++)
   704 	{
   705 		if (!bi->getBranchNum(i)->isHidden())
   706 		{
   707 			BranchObj *bo=bi->getBranchObjNum(i);
   708 			bo->calcBBoxSizeWithChildren();
   709 			br=bo->getBBoxSizeWithChildren();
   710 			r.setWidth( max (br.width(), r.width() ));
   711 			r.setHeight(br.height() + r.height() );
   712 			if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
   713 			if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
   714 		}
   715 	}
   716 	for (int i=0; i<treeItem->attributeCount(); i++)
   717 	{
   718 		if (!bi->getAttributeNum(i)->isHidden())
   719 		{
   720 			BranchObj *bo=bi->getAttributeNum(i)->getBranchObj();
   721 			bo->calcBBoxSizeWithChildren();
   722 			br=bo->getBBoxSizeWithChildren();
   723 			r.setWidth( max (br.width(), r.width() ));
   724 			r.setHeight(br.height() + r.height() );
   725 			if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
   726 			if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
   727 		}
   728 	}
   729 	// Add myself and also
   730 	// add width of link to sum if necessary
   731 	if (bi->branchCount()<1)
   732 		bboxTotal.setWidth (bbox.width() + r.width() );
   733 	else	
   734 		bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
   735 	
   736 	bboxTotal.setHeight(max (r.height(),  bbox.height()));
   737 }
   738 
   739 void BranchObj::setAnimation(const AnimPoint &ap)
   740 {
   741 	anim=ap;
   742 }
   743 
   744 void BranchObj::stopAnimation()
   745 {
   746 	anim.stop();
   747 	if (useRelPos)
   748 		setRelPos (anim);
   749 	else
   750 		move (anim);
   751 }
   752 
   753 bool BranchObj::animate()
   754 {
   755 	anim.animate ();
   756 	if ( anim.isAnimated() )
   757 	{
   758 		if (useRelPos)
   759 			setRelPos (anim);
   760 		else
   761 			move (anim);
   762 		return true;
   763 	}
   764 	/*FIXME-3 reposition in BO:animate nearly never reached? needed?	
   765 	if (((MapItem*)treeItem)->getPositionMode()==MapItem::Relative)
   766 		parObj->reposition();	// we might have been relinked meanwhile
   767 	*/	
   768 	return false;
   769 }
   770