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