branchobj.cpp
author insilmaril
Wed, 03 Jun 2009 20:37:17 +0000
changeset 775 6e4b586aa88a
parent 773 340bc29da9a0
child 776 25e634a7e1dc
permissions -rw-r--r--
Unscrolling temporary works again
     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 () :OrnamentedObj()	// FIXME-3 needed at all?
    17 {
    18 //    cout << "Const BranchObj ()\n";
    19     setParObj (this);	
    20     init();
    21 }
    22 
    23 BranchObj::BranchObj (QGraphicsScene* s):OrnamentedObj (s)// FIXME-3 needed at all?
    24 {
    25 //    cout << "Const BranchObj (s)  \n";
    26 	parObj=NULL;
    27     scene=s;
    28 	init();
    29 }
    30 
    31 BranchObj::BranchObj (QGraphicsScene* s, LinkableMapObj* p):OrnamentedObj (s)// FIXME-3 needed at all?
    32 {
    33 //    cout << "Const BranchObj (s,p)\n";
    34     scene=s;
    35     setParObj (p);	
    36 	if (treeItem->depth()==1)	// FIXME-3 needed to recursively calc depth?
    37 		// Calc angle to mapCenter if I am a mainbranch
    38 		// needed for reordering the mainbranches clockwise 
    39 		// around mapcenter 
    40 		angle=getAngle (QPointF (x() - parObj->getChildPos().x() , 
    41 								(y() - parObj->getChildPos().y() ) ) );
    42     init();
    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 bool BranchObj::operator< ( const BranchObj & other )
    73 {
    74     return  angle < other.angle;
    75 }
    76 
    77 bool BranchObj::operator== ( const BranchObj & other )
    78 {
    79     return angle == other.angle;
    80 }
    81 
    82 void BranchObj::init () 
    83 {
    84 	if (parObj)
    85 	{
    86 		absPos=getRandPos();
    87 		absPos+=parObj->getChildPos();
    88 	}
    89 
    90 	includeImagesVer=false;
    91 	includeImagesHor=false;
    92 }
    93 
    94 void BranchObj::copy (BranchObj* other)
    95 {
    96     OrnamentedObj::copy(other);
    97 
    98 	for (int i=0; i<other->floatimage.size(); ++i)
    99 		addFloatImage  (other->floatimage.at(i));
   100 	
   101 	setVisibility (other->visible);
   102 
   103 	angle=other->angle;
   104 
   105     positionBBox();
   106 }
   107 
   108 void BranchObj::clear() 
   109 {
   110 	//setVisibility (true); //FIXME-4 needed?
   111 
   112 	while (!floatimage.isEmpty())
   113 		delete floatimage.takeFirst();
   114 
   115 	while (!xlink.isEmpty())
   116 		delete xlink.takeFirst();
   117 }
   118 
   119 bool isAbove (BranchObj* a, BranchObj *b)
   120 {
   121 	if (a->angle < b->angle)
   122 		return true;
   123 	else	
   124 		return false;
   125 }
   126 
   127 void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPointF m, int off)
   128 {
   129 	// Temporary link to lmo
   130 	// m is position of mouse pointer 
   131 	// offset 0: default 1: below lmo   -1 above lmo  (if possible)
   132 
   133 	BranchItem *pi=(BranchItem*)(lmo->getTreeItem()->parent());
   134 	int pi_depth=pi->depth();
   135 	BranchObj* o=(BranchObj*)(lmo);
   136 	if (!parObjTmpBuf) 
   137 		parObjTmpBuf=parObj;
   138 
   139 	// ignore mapcenter and mainbranch
   140 	if (pi_depth<2) off=0;
   141 	if (off==0)
   142 		link2ParPos=false;
   143 	else
   144 		link2ParPos=true;
   145 	parObj=o;
   146 
   147 	// FIXME-2 depth=parObj->getDepth()+1;
   148 
   149 	// setLinkStyle calls updateLink, only set it once
   150 	if (style!=getDefLinkStyle() ) setLinkStyle (getDefLinkStyle());
   151 
   152 	// Move temporary to new position at destination
   153 	// Usually the positioning would be done by reposition(),
   154 	// but then also the destination branch would "Jump" around...
   155 	// Better just do it approximately
   156 	if (treeItem->depth()==1)	// FIXME-3 needed to recursively calc depth?
   157 	{	// new parent is the mapcenter itself
   158 
   159 		QPointF p= normalise ( QPointF (m.x() - o->getChildPos().x(),
   160 									  m.y() - o->getChildPos().y() ));
   161 		if (p.x()<0) p.setX( p.x()-bbox.width() );
   162 		move2RelPos (p);
   163 	} else
   164 	{	
   165 		qreal y;
   166 		if (off==0)
   167 		{
   168 			// new parent is just a branch, link to it
   169 			QRectF t=o->getBBoxSizeWithChildren();
   170 			if (o->getTreeItem()->getLastBranch())
   171 				y=t.y() + t.height() ;
   172 			else
   173 				y=t.y();
   174 
   175 		} else
   176 		{
   177 			if (off<0)
   178 				// we want to link above lmo
   179 				y=o->y() - height() + 5;
   180 			else	
   181 				// we want to link below lmo
   182 				// Bottom of sel should be 5 pixels above
   183 				// the bottom of the branch _below_ the target:
   184 				// Don't try to find that branch, guess 12 pixels
   185 				y=o->getChildPos().y()  -height() + 12; 
   186 		}	
   187 		if (o->getOrientation()==LinkableMapObj::LeftOfCenter)
   188 			move ( o->getChildPos().x() - linkwidth, y );
   189 		else	
   190 			move (o->getChildPos().x() + linkwidth, y );
   191 	}	
   192 
   193 	// updateLink is called implicitly in move
   194 	requestReposition();	
   195 }
   196 
   197 void BranchObj::unsetParObjTmp()
   198 {
   199 	if (parObjTmpBuf) 
   200 	{
   201 		link2ParPos=false;
   202 		parObj=parObjTmpBuf;
   203 		parObjTmpBuf=NULL;
   204 		//FIXME-2 depth=parObj->getDepth()+1;
   205 		setLinkStyle (getDefLinkStyle() );
   206 		updateLink();
   207 	}		
   208 }
   209 
   210 void BranchObj::setVisibility(bool v, int toDepth)
   211 {
   212 	BranchItem *bi=(BranchItem*)treeItem;
   213     if (bi->depth() <= toDepth)
   214     {
   215 		frame->setVisibility(v);
   216 		heading->setVisibility(v);
   217 		systemFlags->setVisibility(v);
   218 		standardFlags->setVisibility(v);
   219 		LinkableMapObj::setVisibility (v);
   220 		int i;
   221 		for (i=0; i<floatimage.size(); ++i)
   222 			floatimage.at(i)->setVisibility (v);
   223 		for (i=0; i<xlink.size(); ++i)	
   224 			xlink.at(i)->setVisibility ();	
   225 
   226 		// Only change children, if I am not scrolled
   227 		if (! bi->isScrolled() && (bi->depth() < toDepth))
   228 		{
   229 			// Now go recursivly through all children
   230 			for (i=0; i<treeItem->branchCount(); ++i)
   231 				treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);	
   232 		}
   233     } // depth <= toDepth	
   234 	requestReposition();
   235 }	
   236 
   237 void BranchObj::setVisibility(bool v)
   238 {
   239     setVisibility (v,MAX_DEPTH);
   240 }
   241 
   242 
   243 void BranchObj::setLinkColor ()
   244 {
   245 	// Overloaded from LinkableMapObj
   246 	// BranchObj can use color of heading
   247 
   248 	VymModel *model=treeItem->getModel();
   249 	if (model)
   250 	{
   251 		if (model->getMapLinkColorHint()==HeadingColor)
   252 			LinkableMapObj::setLinkColor (heading->getColor() );
   253 		else	
   254 			LinkableMapObj::setLinkColor ();
   255 	}		
   256 }
   257 
   258 void BranchObj::updateContentSize()
   259 {
   260 	calcBBoxSize();
   261 	positionBBox();
   262 	requestReposition();
   263 }
   264 
   265 void BranchObj::positionContents()
   266 {
   267     for (int i=0; i<floatimage.size(); ++i )
   268 		floatimage.at(i)->reposition();
   269 	OrnamentedObj::positionContents();
   270 }
   271 
   272 void BranchObj::move (double x, double y)
   273 {
   274 	OrnamentedObj::move (x,y);
   275     for (int i=0; i<floatimage.size(); ++i )
   276 		floatimage.at(i)->reposition();
   277     positionBBox();
   278 }
   279 
   280 void BranchObj::move (QPointF p)
   281 {
   282 	move (p.x(), p.y());
   283 }
   284 
   285 void BranchObj::moveBy (double x, double y)
   286 {
   287 	OrnamentedObj::moveBy (x,y);
   288 	for (int i=0; i<treeItem->branchCount(); ++i)
   289 		treeItem->getBranchObjNum(i)->moveBy (x,y);
   290     positionBBox();
   291 }
   292 	
   293 void BranchObj::moveBy (QPointF p)
   294 {
   295 	moveBy (p.x(), p.y());
   296 }
   297 
   298 
   299 void BranchObj::positionBBox()
   300 {
   301 	QPointF ap=getAbsPos();
   302 	bbox.moveTopLeft (ap);
   303 	positionContents();
   304 
   305 	// set the frame
   306 	frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
   307 
   308 	// Update links to other branches
   309 	for (int i=0; i<xlink.size(); ++i)
   310 		xlink.at(i)->updateXLink();
   311 }
   312 
   313 void BranchObj::calcBBoxSize()
   314 {
   315     QSizeF heading_r=heading->getSize();
   316     qreal heading_w=(qreal) heading_r.width() ;
   317     qreal heading_h=(qreal) heading_r.height() ;
   318     QSizeF sysflags_r=systemFlags->getSize();
   319 	qreal sysflags_h=sysflags_r.height();
   320 	qreal sysflags_w=sysflags_r.width();
   321     QSizeF stanflags_r=standardFlags->getSize();
   322 	qreal stanflags_h=stanflags_r.height();
   323 	qreal stanflags_w=stanflags_r.width();
   324     qreal w;
   325     qreal h;
   326 
   327 	// set width to sum of all widths
   328 	w=heading_w + sysflags_w + stanflags_w;
   329 	// set height to maximum needed height
   330 	h=max (sysflags_h,stanflags_h);
   331 	h=max (h,heading_h);
   332 
   333 	// Save the dimension of flags and heading
   334 	ornamentsBBox.setSize ( QSizeF(w,h));
   335 
   336 	// clickBox includes Flags and Heading
   337     clickBox.setSize (ornamentsBBox.size() );
   338 
   339 	// Floatimages 
   340 	QPointF rp;
   341 
   342 	topPad=botPad=leftPad=rightPad=0;
   343 	if (includeImagesVer || includeImagesHor)
   344 	{
   345 		if (treeItem->imageCount()>0)
   346 		{
   347 			for (int i=0; i<floatimage.size(); ++i )
   348 			{
   349 				rp=floatimage.at(i)->getRelPos();
   350 				if (includeImagesVer)
   351 				{
   352 					if (rp.y() < 0) 
   353 						topPad=max (topPad,-rp.y()-h);
   354 					if (rp.y()+floatimage.at(i)->height() > 0)
   355 						botPad=max (botPad,rp.y()+floatimage.at(i)->height());
   356 				}		
   357 				if (includeImagesHor)
   358 				{
   359 					if (orientation==LinkableMapObj::RightOfCenter)
   360 					{
   361 						if (-rp.x()-w > 0) 
   362 							leftPad=max (leftPad,-rp.x()-w);
   363 						if (rp.x()+floatimage.at(i)->width() > 0)
   364 							rightPad=max (rightPad,rp.x()+floatimage.at(i)->width());
   365 					} else
   366 					{
   367 						if (rp.x()< 0) 
   368 							leftPad=max (leftPad,-rp.x());
   369 						if (rp.x()+floatimage.at(i)->width() > w)
   370 							rightPad=max (rightPad,rp.x()+floatimage.at(i)->width()-w);
   371 					}
   372 				}		
   373 			}	
   374 		}	
   375 		h+=topPad+botPad;
   376 		w+=leftPad+rightPad;
   377 	}
   378 
   379 	// Frame thickness
   380     w+=frame->getPadding();
   381     h+=frame->getPadding();
   382 	
   383 	// Finally set size
   384     bbox.setSize (QSizeF (w,h));
   385 }
   386 
   387 void BranchObj::setDockPos()
   388 {
   389 	if (treeItem->getType()==TreeItem::MapCenter)
   390 	{
   391 		// set childPos to middle of MapCenterObj
   392 		childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
   393 		childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
   394 		parPos=childPos;		
   395 		for (int i=0; i<treeItem->branchCount(); ++i)
   396 			treeItem->getBranchObjNum(i)->updateLink();
   397 
   398 	} else
   399 	{
   400 		// Sets childpos and parpos depending on orientation
   401 		if (getOrientation()==LinkableMapObj::LeftOfCenter )
   402 		{
   403 			childPos=QPointF (
   404 				ornamentsBBox.bottomLeft().x(), 
   405 				bottomlineY);
   406 			parPos=QPointF (
   407 				ornamentsBBox.bottomRight().x(),
   408 				bottomlineY);
   409 		} else
   410 		{
   411 			childPos=QPointF (
   412 				ornamentsBBox.bottomRight().x(), 
   413 				bottomlineY);
   414 			parPos=QPointF (
   415 				ornamentsBBox.bottomLeft().x(),
   416 				bottomlineY);
   417 		}
   418 	}
   419 }
   420 
   421 void BranchObj::updateData()
   422 {
   423 	bool changed=false;
   424 	if (!treeItem)
   425 	{
   426 		qWarning ("BranchObj::udpateHeading treeItem==NULL");
   427 		return;
   428 	}
   429 	QString s=treeItem->getHeading();
   430 	if (s!=heading->text())
   431 	{
   432 		heading->setText (s);
   433 		changed=true;
   434 	}
   435 	QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
   436 
   437 	// Add missing standard flags active in TreeItem
   438 	for (int i=0;i<=TIactiveFlags.size()-1;i++)
   439 	{	
   440 		if (!standardFlags->isActive (TIactiveFlags.at(i) ))
   441 		{
   442 			Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
   443 			if (f) standardFlags->activate (f);
   444 			changed=true;
   445 		}
   446 	}
   447 	// Remove standard flags no longer active in TreeItem
   448 	QStringList BOactiveFlags=standardFlags->activeFlagNames();
   449 	for (int i=0;i<BOactiveFlags.size();++i)
   450 		if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
   451 		{
   452 			standardFlags->deactivate (BOactiveFlags.at(i));
   453 			changed=true;
   454 		}	
   455 
   456 	// Add missing system flags active in TreeItem
   457 	TIactiveFlags=treeItem->activeSystemFlagNames();
   458 	for (int i=0;i<TIactiveFlags.size();++i)
   459 	{	
   460 		if (!systemFlags->isActive (TIactiveFlags.at(i) ))
   461 		{
   462 			Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
   463 			if (f) systemFlags->activate (f);
   464 			changed=true;
   465 		}
   466 	}
   467 	// Remove system flags no longer active in TreeItem
   468 	BOactiveFlags=systemFlags->activeFlagNames();
   469 	for (int i=0;i<BOactiveFlags.size();++i)
   470 	{
   471 		if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
   472 		{
   473 			systemFlags->deactivate (BOactiveFlags.at(i));
   474 			changed=true;
   475 		}	
   476 	}
   477 
   478 	if (changed)
   479 		updateContentSize();
   480 }
   481 
   482 
   483 void BranchObj::addXLink (XLinkObj *xlo)
   484 {
   485 	xlink.append (xlo);
   486 	
   487 }
   488 
   489 void BranchObj::removeXLinkRef (XLinkObj *xlo)
   490 {
   491 	xlink.removeAt (xlink.indexOf(xlo));
   492 }
   493 
   494 void BranchObj::deleteXLink(XLinkObj *xlo)
   495 {
   496 	xlo->deactivate();
   497 	if (!xlo->isUsed()) delete (xlo);
   498 }
   499 
   500 void BranchObj::deleteXLinkAt (int i)
   501 {
   502 	XLinkObj *xlo=xlink.at(i);
   503 	xlo->deactivate();
   504 	if (!xlo->isUsed()) delete(xlo);
   505 }
   506 
   507 XLinkObj* BranchObj::XLinkAt (int i)
   508 {
   509 	return xlink.at(i);
   510 }
   511 
   512 BranchObj* BranchObj::XLinkTargetAt (int i)
   513 {
   514 	if (i>=0 && i<xlink.size())
   515 	{
   516 		if (xlink.at(i))
   517 			return xlink.at(i)->otherBranch (this);
   518 	}
   519 	return NULL;
   520 }
   521 
   522 void BranchObj::setIncludeImagesVer(bool b)
   523 {
   524 	includeImagesVer=b;
   525 	calcBBoxSize();
   526 	positionBBox();
   527 	requestReposition();
   528 }
   529 
   530 bool BranchObj::getIncludeImagesVer()
   531 {
   532 	return includeImagesVer;
   533 }
   534 
   535 void BranchObj::setIncludeImagesHor(bool b)
   536 {
   537 	includeImagesHor=b;
   538 	calcBBoxSize();
   539 	positionBBox();
   540 	requestReposition();
   541 }
   542 
   543 bool BranchObj::getIncludeImagesHor()
   544 {
   545 	return includeImagesHor;
   546 }
   547 
   548 QString BranchObj::getIncludeImageAttr()
   549 {
   550 	QString a;
   551 	if (includeImagesVer)
   552 		a=attribut ("incImgV","true");
   553 	else
   554 		a=attribut ("incImgV","false");
   555 	if (includeImagesHor)
   556 		a+=attribut ("incImgH","true");
   557 	else
   558 		a+=attribut ("incImgH","false");
   559 	return a;	
   560 }
   561 
   562 FloatImageObj* BranchObj::addFloatImage ()
   563 {
   564 	FloatImageObj *newfi=new FloatImageObj (scene,this);
   565 	floatimage.append (newfi);
   566 	if ( ((BranchItem*)treeItem)->hasScrolledParent((BranchItem*)treeItem) )
   567 		newfi->setVisibility (false);
   568 	else	
   569 		newfi->setVisibility(visible);
   570 		/*
   571 	calcBBoxSize();
   572 	positionBBox();
   573 	*/
   574 	requestReposition();
   575 	return newfi;
   576 }
   577 
   578 FloatImageObj* BranchObj::addFloatImage (FloatImageObj *fio)
   579 {
   580 	FloatImageObj *newfi=new FloatImageObj (scene,this);
   581 	floatimage.append (newfi);
   582 	newfi->copy (fio);
   583 	if (((BranchItem*)treeItem)->hasScrolledParent((BranchItem*)treeItem) )
   584 		newfi->setVisibility (false);
   585 	else	
   586 		newfi->setVisibility(visible);
   587 		/*
   588 	calcBBoxSize();
   589 	positionBBox();
   590 	*/
   591 	requestReposition();
   592 	return newfi;
   593 }
   594 
   595 FloatImageObj* BranchObj::getFirstFloatImage ()
   596 {
   597     return floatimage.first();
   598 }
   599 
   600 FloatImageObj* BranchObj::getLastFloatImage ()
   601 {
   602     return floatimage.last();
   603 }
   604 
   605 FloatImageObj* BranchObj::getFloatImageNum (const uint &i)
   606 {
   607     return floatimage.at(i);
   608 }
   609 
   610 void BranchObj::removeFloatImage (FloatImageObj *fio)
   611 {
   612 	int i=floatimage.indexOf (fio);
   613 	if (i>-1) delete (floatimage.takeAt (i));
   614 	calcBBoxSize();
   615 	positionBBox();
   616 	requestReposition();
   617 }
   618 
   619 void BranchObj::savePosInAngle ()
   620 {
   621 	// Save position in angle
   622 	for (int i=0; i<treeItem->branchCount(); ++i)
   623 		treeItem->getBranchObjNum(i)->angle=i;
   624 }
   625 
   626 void BranchObj::setDefAttr (BranchModification mod)
   627 {
   628 	int fontsize;
   629 	switch (treeItem->depth())
   630 	{
   631 		case 0: fontsize=16; break;
   632 		case 1: fontsize=12; break;
   633 		default: fontsize=10; break;
   634 	}	
   635 
   636 	setLinkColor ();
   637 	setLinkStyle(getDefLinkStyle());
   638 	QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
   639 	font.setPointSize(fontsize);
   640 	heading->setFont(font );
   641 
   642 	if (mod==NewBranch)
   643 		setColor (treeItem->getHeadingColor() );
   644 	calcBBoxSize();
   645 }
   646 
   647 void BranchObj::sortChildren() //FIXME-2  
   648 {
   649 /*
   650 	int childCount=branch.count(); 
   651 	int curChildIndex;
   652 	bool madeChanges=false;
   653 	do
   654 	{
   655 		madeChanges=false;
   656 		for(curChildIndex=1;curChildIndex<childCount;curChildIndex++){
   657 			BranchObj* curChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex);
   658 			BranchObj* prevChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex-1);
   659 			if(prevChild->heading->text().compare(curChild->heading->text())>0)
   660 			{
   661 				this->moveBranchUp(curChild);
   662 				madeChanges=true;
   663 			}
   664 		}
   665 	}while(madeChanges);
   666 */
   667 }
   668 
   669 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
   670 {
   671 	qreal th = bboxTotal.height();	
   672 	int depth=treeItem->depth();	// FIXME-3 needed to recursively calc depth?
   673 // TODO testing
   674 /*
   675 
   676 	QString h=QString (depth,' ');
   677 	h+=treeItem->getHeading();
   678 	h+=QString (15,' ');
   679 	h.truncate (15);
   680 	QPointF pp; if (parObj) pp=parObj->getChildPos();
   681 	cout << "BO::alignRelTo ";
   682 	cout<<h.toStdString();
   683 	cout << "    d="<<depth<<
   684 //cout<<  "  ref="<<ref<<
   685       	"  bbox.tL="<<bboxTotal.topLeft()<<
   686 		"  absPos="<<absPos<<
   687 //		"  relPos="<<relPos<<
   688 //		"  parPos="<<pp<<
   689 		"  w="<<bbox.width()<<
   690 		"  h="<<bbox.height()<<
   691 //		"  orient="<<orientation<<
   692 //		"  alignSelf="<<alignSelf<<
   693 //		"  scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
   694 //		"  pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
   695 //		"  hidden="<<hidden<<
   696 		"  th="<<th<<
   697 		endl;
   698 */
   699 
   700 	setOrientation();
   701 	//updateLink();
   702 
   703 	if (depth==1 && parObj)
   704 	{
   705 		// Position relatively, if needed
   706 		//if (useRelPos) move2RelPos (relPos.x(), relPos.y());
   707 
   708 		// Calc angle to mapCenter if I am a mainbranch
   709 		// needed for reordering the mainbranches clockwise 
   710 		// around mapcenter 
   711 		angle=getAngle (QPointF ((int)(x() - parObj->getChildPos().x() ), 
   712 								(int)(y() - parObj->getChildPos().y() ) ) );
   713 	}							
   714 	if (depth>1)
   715     {
   716 		// Align myself depending on orientation and parent, but
   717 		// only if I am not a mainbranch or mapcenter itself
   718 
   719 		if (anim.isAnimated())
   720 		{
   721 			move2RelPos(anim);
   722 		} else
   723 		{
   724 			LinkableMapObj::Orientation o;
   725 			o=parObj->getOrientation();
   726 			if (alignSelf)
   727 				switch (orientation) 
   728 				{
   729 					case LinkableMapObj::LeftOfCenter:
   730 						move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
   731 						//move (ref.x() , ref.y() + (th-bbox.height())/2 );
   732 					break;
   733 					case LinkableMapObj::RightOfCenter:	
   734 						move (ref.x() , ref.y() + (th-bbox.height())/2  );
   735 					break;
   736 					default:
   737 						qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
   738 					break;
   739 			}
   740 		}
   741     }		
   742 
   743 	if ( ((BranchItem*)treeItem)->isScrolled() ) return;
   744 
   745     // Set reference point for alignment of children
   746     QPointF ref2;
   747     if (orientation==LinkableMapObj::LeftOfCenter)
   748 		ref2.setX(bbox.topLeft().x() - linkwidth);
   749     else	
   750 		ref2.setX(bbox.topRight().x() + linkwidth);
   751 
   752 	if (depth==1)
   753 		ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
   754 	else	
   755 		ref2.setY(ref.y() );	
   756 
   757     // Align the children depending on reference point 
   758 	for (int i=0; i<treeItem->branchCount(); ++i)
   759     {	
   760 		if (!treeItem->getBranchNum(i)->isHidden())
   761 		{
   762 			treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
   763 
   764 			// append next branch below current one
   765 			ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
   766 		}
   767     }
   768 }
   769 
   770 
   771 void BranchObj::reposition()
   772 {	
   773 /* TODO testing only
   774 	if (!treeItem->getHeading().isEmpty())
   775 		cout << "BO::reposition  "<<qPrintable(treeItem->getHeading())<<endl;
   776 	else	
   777 		cout << "BO::reposition  ???"<<endl;
   778 //	cout << "  orient="<<orientation<<endl;
   779 */		
   780 
   781 	if (treeItem->depth()==0)
   782 	{
   783 		// only calculate the sizes once. If the deepest LMO 
   784 		// changes its height,
   785 		// all upper LMOs have to change, too.
   786 		calcBBoxSizeWithChildren();
   787 		updateLink();	// This update is needed if the scene is resized 
   788 						// due to excessive moving of a FIO
   789 
   790 	    alignRelativeTo ( QPointF (absPos.x(),
   791 			absPos.y()-(bboxTotal.height()-bbox.height())/2) );
   792 		//FIXME-2 qSort (branch.begin(),branch.end(), isAbove);
   793 		positionBBox();	// Reposition bbox and contents
   794 	} else
   795 	{
   796 		// This is only important for moving branches:
   797 		// For editing a branch it isn't called...
   798 	    alignRelativeTo ( QPointF (absPos.x(),
   799 							absPos.y()-(bboxTotal.height()-bbox.height())/2) );
   800 	}
   801 }
   802 
   803 void BranchObj::unsetAllRepositionRequests()
   804 {
   805 	repositionRequest=false;
   806 	for (int i=0; i<treeItem->branchCount(); ++i)
   807 		treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
   808 }
   809 
   810 
   811 QPolygonF BranchObj::shape()
   812 {
   813 	QPolygonF p;
   814 
   815 	QRectF r=getTotalBBox();
   816 	if (orientation==LinkableMapObj::LeftOfCenter)
   817 		p   <<r.bottomLeft()
   818 			<<r.topLeft()
   819 			<<QPointF (bbox.topLeft().x(), r.topLeft().y() )
   820 			<<bbox.topRight()
   821 			<<bbox.bottomRight()
   822 			<<QPointF (bbox.bottomLeft().x(), r.bottomLeft().y() ) ;
   823 	else		
   824 		p   <<r.bottomRight()
   825 			<<r.topRight()
   826 			<<QPointF (bbox.topRight().x(), r.topRight().y() )
   827 			<<bbox.topLeft()
   828 			<<bbox.bottomLeft()
   829 			<<QPointF (bbox.bottomRight().x(), r.bottomRight().y() ) ;
   830 	return p;
   831 }
   832 
   833 QRectF BranchObj::getTotalBBox()
   834 {
   835 	QRectF r=bbox;
   836 
   837 	if ( ((BranchItem*)treeItem)->isScrolled() ) return r;
   838 
   839 	for (int i=0; i<treeItem->branchCount(); ++i)
   840 		if (!treeItem->getBranchNum(i)->isHidden())
   841 			r=addBBox(treeItem->getBranchObjNum(i)->getTotalBBox(),r);
   842 
   843 /* FIXME-3 lots of occurences of treeItem->getBranchObjNum(i) in branchobj.cpp
   844             better check if they are not NULL and maybe simplify...
   845 			(have been NULL at least in calcBBoxSizeWithChilds...)
   846 */			
   847 
   848 /*
   849 	FIXME-3 for (int i=0; i<floatimage.size(); ++i)
   850 		if (!floatimage.at(i)->isHidden())
   851 			r=addBBox(floatimage.at(i)->getTotalBBox(),r);
   852 	*/	
   853 	return r;
   854 }
   855 
   856 QRectF BranchObj::getBBoxSizeWithChildren()
   857 {
   858 	return bboxTotal;
   859 }
   860 
   861 void BranchObj::calcBBoxSizeWithChildren()
   862 {	
   863 	// This is initially called only from reposition and
   864 	// and only for mapcenter. So it won't be
   865 	// called more than once for a single user 
   866 	// action
   867 	
   868 
   869 	// Calculate size of LMO including all children (to align them later)
   870 	bboxTotal.setX(bbox.x() );
   871 	bboxTotal.setY(bbox.y() );
   872 
   873 	// if branch is scrolled, ignore children, but still consider floatimages
   874 	BranchItem *bi=(BranchItem*)treeItem;
   875 	if ( bi->isScrolled() ) 
   876 	{
   877 		bboxTotal.setWidth (bbox.width());
   878 		bboxTotal.setHeight(bbox.height());
   879 		return;
   880 	}
   881 	
   882 	if (bi->isHidden())
   883 	{
   884 		bboxTotal.setWidth (0);
   885 		bboxTotal.setHeight(0);
   886 		if (parObj)
   887 		{
   888 			bboxTotal.setX (parObj->x());
   889 			bboxTotal.setY (parObj->y());
   890 		} else
   891 		{
   892 			bboxTotal.setX (bbox.x());
   893 			bboxTotal.setY (bbox.y());
   894 		}
   895 		return;
   896 	}
   897 	
   898 	QRectF r(0,0,0,0);
   899 	QRectF br;
   900 	// Now calculate recursivly
   901 	// sum of heights 
   902 	// maximum of widths 
   903 	// minimum of y
   904 	for (int i=0; i<treeItem->branchCount(); i++)
   905 	{
   906 		if (!bi->getBranchNum(i)->isHidden())
   907 		{
   908 			bi->getBranchObjNum(i)->calcBBoxSizeWithChildren();
   909 			br=bi->getBranchObjNum(i)->getBBoxSizeWithChildren();
   910 			r.setWidth( max (br.width(), r.width() ));
   911 			r.setHeight(br.height() + r.height() );
   912 			if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
   913 		}
   914 	}
   915 	// Add myself and also
   916 	// add width of link to sum if necessary
   917 	if (bi->branchCount()<1)
   918 		bboxTotal.setWidth (bbox.width() + r.width() );
   919 	else	
   920 		bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
   921 	
   922 	bboxTotal.setHeight(max (r.height(),  bbox.height()));
   923 }
   924 
   925 QString BranchObj::getSelectString()
   926 {
   927 	VymModel *model=treeItem->getModel();
   928 	if (model)
   929 		return model->getSelectString (this);
   930 	else
   931 		return QString();
   932 }
   933 
   934 void BranchObj::setAnimation(const AnimPoint &ap)
   935 {
   936 	anim=ap;
   937 }
   938 
   939 bool BranchObj::animate()
   940 {
   941 	anim.animate ();
   942 	if ( anim.isAnimated() )
   943 	{
   944 		setRelPos (anim);
   945 		return true;
   946 	}
   947 	parObj->reposition();	// we might have been relinked meanwhile
   948 	return false;
   949 }
   950