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