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