3 #include "branchitem.h"
6 #include "mainwindow.h"
9 extern FlagRow *standardFlagsMaster;
10 extern FlagRow *systemFlagsMaster;
12 /////////////////////////////////////////////////////////////////
14 /////////////////////////////////////////////////////////////////
16 BranchObj::BranchObj (QGraphicsScene* s,TreeItem *ti):OrnamentedObj (s)
18 // cout << "Const BranchObj (s) \n";
26 BranchObj::BranchObj (QGraphicsScene* s, LinkableMapObj* p):OrnamentedObj (s)// FIXME-3 needed at all?
28 // cout << "Const BranchObj (s,p)\n";
31 if (treeItem->depth()==1) // FIXME-3 needed to recursively calc depth?
32 // Calc angle to mapCenter if I am a mainbranch
33 // needed for reordering the mainbranches clockwise
35 angle=getAngle (QPointF (x() - parObj->getChildPos().x() ,
36 (y() - parObj->getChildPos().y() ) ) );
41 BranchObj::~BranchObj ()
43 // cout << "Destr BranchObj of "<<this<<" ("<<treeItem->getHeading().toStdString()<<")"<<endl;
45 // If I'm animated, I need to un-animate myself first
46 if (anim.isAnimated() )
48 anim.setAnimated (false);
49 VymModel *model=treeItem->getModel();
50 model->stopAnimation (this);
53 // Check, if this branch was the last child to be deleted
54 // If so, unset the scrolled flags in parent // FIXME-2 better do this in model?
57 BranchObj *po=(BranchObj*)parObj;
61 bo=((BranchObj*)parObj)->getLastBranch();
62 if (bo) po->unScroll();
68 bool BranchObj::operator< ( const BranchObj & other )
70 return angle < other.angle;
73 bool BranchObj::operator== ( const BranchObj & other )
75 return angle == other.angle;
78 void BranchObj::init ()
83 absPos+=parObj->getChildPos();
87 void BranchObj::copy (BranchObj* other)
89 OrnamentedObj::copy(other);
91 setVisibility (other->visible);
98 void BranchObj::clear()
100 //setVisibility (true); //FIXME-4 needed?
102 while (!xlink.isEmpty())
103 delete xlink.takeFirst();
106 bool isAbove (BranchObj* a, BranchObj *b)
108 if (a->angle < b->angle)
114 void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPointF m, int off)
116 // Temporary link to lmo
117 // m is position of mouse pointer
118 // offset 0: default 1: below lmo -1 above lmo (if possible)
120 BranchItem *pi=(BranchItem*)(lmo->getTreeItem()->parent());
121 int pi_depth=pi->depth();
122 BranchObj* o=(BranchObj*)(lmo);
126 // ignore mapcenter and mainbranch //FIXME-3 MCO meanwhile also could be relinked
127 if (pi_depth<2) off=0;
134 // setLinkStyle calls updateLinkGeometry, only set it once
135 //LinkableMapObj::Style ls=getDefLinkStyle (lmo->getTreeItem() );
136 //if (style!=ls ) setLinkStyle (ls);
137 setLinkStyle (lmo->getDefLinkStyle (lmo->getTreeItem()));
139 // Move temporary to new position at destination
140 // Usually the positioning would be done by reposition(),
141 // but then also the destination branch would "Jump" around...
142 // Better just do it approximately
143 if (parObj->getTreeItem()->depth()==0)
144 { // new parent is a mapcenter
146 //FIXME-2 rewrite to us new normalize QPointF p= normalize ( QPointF (m.x() - o->getChildPos().x(),
147 // m.y() - o->getChildPos().y() ));
148 QPointF p= ( QPointF (m.x() - o->getChildPos().x(),
149 m.y() - o->getChildPos().y() ));
150 if (p.x()<0) p.setX( p.x()-bbox.width() );
157 // new parent is just a branch, link to it
158 QRectF t=o->getBBoxSizeWithChildren();
159 if (o->getTreeItem()->getLastBranch())
160 y=t.y() + t.height() ;
167 // we want to link above lmo
168 y=o->y() - height() + 5;
170 // we want to link below lmo
171 // Bottom of sel should be 5 pixels above
172 // the bottom of the branch _below_ the target:
173 // Don't try to find that branch, guess 12 pixels
174 y=o->getChildPos().y() -height() + 12;
176 if (o->getOrientation()==LinkableMapObj::LeftOfCenter)
177 move ( o->getChildPos().x() - linkwidth, y );
179 move (o->getChildPos().x() + linkwidth, y );
182 // updateLinkGeometry is called implicitly in move
186 void BranchObj::unsetParObjTmp()
193 setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
194 updateLinkGeometry();
198 void BranchObj::setVisibility(bool v, int toDepth)
200 BranchItem *bi=(BranchItem*)treeItem;
201 if (bi->depth() <= toDepth)
203 frame->setVisibility(v);
204 heading->setVisibility(v);
205 systemFlags->setVisibility(v);
206 standardFlags->setVisibility(v);
207 LinkableMapObj::setVisibility (v);
209 for (i=0; i<treeItem->imageCount(); ++i)
210 treeItem->getImageObjNum(i)->setVisibility (v);
211 for (i=0; i<treeItem->xlinkCount(); ++i)
212 treeItem->getXLinkObjNum(i)->setVisibility ();
214 // Only change children, if I am not scrolled
215 if (! bi->isScrolled() && (bi->depth() < toDepth))
217 // Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
218 for (i=0; i<treeItem->branchCount(); ++i)
219 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
221 } // depth <= toDepth
225 void BranchObj::setVisibility(bool v)
227 setVisibility (v,MAX_DEPTH);
231 void BranchObj::setLinkColor ()
233 // Overloaded from LinkableMapObj
234 // BranchObj can use color of heading
236 VymModel *model=treeItem->getModel();
239 if (model->getMapLinkColorHint()==HeadingColor)
240 LinkableMapObj::setLinkColor (heading->getColor() );
242 LinkableMapObj::setLinkColor ();
246 void BranchObj::updateContentSize()
253 void BranchObj::positionContents()
255 for (int i=0; i<treeItem->imageCount(); ++i)
256 treeItem->getImageObjNum(i)->reposition();
257 OrnamentedObj::positionContents();
260 void BranchObj::move (double x, double y)
262 OrnamentedObj::move (x,y);
264 for (int i=0; i<treeItem->imageCount(); ++i )
266 fio=treeItem->getImageObjNum(i);
267 if (fio) fio->reposition();
272 void BranchObj::move (QPointF p)
277 void BranchObj::moveBy (double x, double y)
279 OrnamentedObj::moveBy (x,y);
280 for (int i=0; i<treeItem->branchCount(); ++i)
281 treeItem->getBranchObjNum(i)->moveBy (x,y);
285 void BranchObj::moveBy (QPointF p)
287 moveBy (p.x(), p.y());
291 void BranchObj::positionBBox()
293 QPointF ap=getAbsPos();
294 bbox.moveTopLeft (ap);
298 frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
300 //Update links to other branches
302 for (int i=0; i<treeItem->xlinkCount(); ++i)
304 xlo=treeItem->getXLinkObjNum(i);
305 if (xlo) xlo->updateXLink();
309 void BranchObj::calcBBoxSize()
311 QSizeF heading_r=heading->getSize();
312 qreal heading_w=(qreal) heading_r.width() ;
313 qreal heading_h=(qreal) heading_r.height() ;
314 QSizeF sysflags_r=systemFlags->getSize();
315 qreal sysflags_h=sysflags_r.height();
316 qreal sysflags_w=sysflags_r.width();
317 QSizeF stanflags_r=standardFlags->getSize();
318 qreal stanflags_h=stanflags_r.height();
319 qreal stanflags_w=stanflags_r.width();
323 // set width to sum of all widths
324 w=heading_w + sysflags_w + stanflags_w;
325 // set height to maximum needed height
326 h=max (sysflags_h,stanflags_h);
329 // Save the dimension of flags and heading
330 ornamentsBBox.setSize ( QSizeF(w,h));
332 // clickBox includes Flags and Heading
333 clickBox.setSize (ornamentsBBox.size() );
338 topPad=botPad=leftPad=rightPad=0;
339 bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
340 bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
344 for (int i=0; i<treeItem->imageCount(); ++i )
346 fio=treeItem->getImageObjNum(i);
351 topPad=max (topPad,-rp.y()-h);
352 if (rp.y()+fio->height() > 0)
353 botPad=max (botPad,rp.y()+fio->height());
357 if (orientation==LinkableMapObj::RightOfCenter)
360 leftPad=max (leftPad,-rp.x()-w);
361 if (rp.x()+fio->width() > 0)
362 rightPad=max (rightPad,rp.x()+fio->width());
366 leftPad=max (leftPad,-rp.x());
367 if (rp.x()+fio->width() > w)
368 rightPad=max (rightPad,rp.x()+fio->width()-w);
377 w+=frame->getPadding();
378 h+=frame->getPadding();
381 bbox.setSize (QSizeF (w,h));
384 void BranchObj::setDockPos()
386 if (treeItem->getType()==TreeItem::MapCenter)
388 // set childPos to middle of MapCenterObj
389 childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
390 childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
392 for (int i=0; i<treeItem->branchCount(); ++i)
393 treeItem->getBranchObjNum(i)->updateLinkGeometry();
397 // Sets childpos and parpos depending on orientation
398 if (getOrientation()==LinkableMapObj::LeftOfCenter )
401 ornamentsBBox.bottomLeft().x(),
404 ornamentsBBox.bottomRight().x(),
409 ornamentsBBox.bottomRight().x(),
412 ornamentsBBox.bottomLeft().x(),
418 void BranchObj::updateData()
423 qWarning ("BranchObj::udpateHeading treeItem==NULL");
426 QString s=treeItem->getHeading();
427 if (s!=heading->text())
429 heading->setText (s);
432 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
434 // Add missing standard flags active in TreeItem
435 for (int i=0;i<=TIactiveFlags.size()-1;i++)
437 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
439 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
440 if (f) standardFlags->activate (f);
444 // Remove standard flags no longer active in TreeItem
445 QStringList BOactiveFlags=standardFlags->activeFlagNames();
446 for (int i=0;i<BOactiveFlags.size();++i)
447 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
449 standardFlags->deactivate (BOactiveFlags.at(i));
453 // Add missing system flags active in TreeItem
454 TIactiveFlags=treeItem->activeSystemFlagNames();
455 for (int i=0;i<TIactiveFlags.size();++i)
457 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
459 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
460 if (f) systemFlags->activate (f);
464 // Remove system flags no longer active in TreeItem
465 BOactiveFlags=systemFlags->activeFlagNames();
466 for (int i=0;i<BOactiveFlags.size();++i)
468 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
470 systemFlags->deactivate (BOactiveFlags.at(i));
477 void BranchObj::savePosInAngle ()
479 // Save position in angle
480 for (int i=0; i<treeItem->branchCount(); ++i)
481 treeItem->getBranchObjNum(i)->angle=i;
484 void BranchObj::setDefAttr (BranchModification mod)
487 switch (treeItem->depth())
489 case 0: fontsize=16; break;
490 case 1: fontsize=12; break;
491 default: fontsize=10; break;
493 setLinkStyle(getDefLinkStyle(treeItem->parent() ));
495 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
496 font.setPointSize(fontsize);
497 heading->setFont(font );
500 setColor (treeItem->getHeadingColor() );
504 void BranchObj::sortChildren() //FIXME-3 not moved to model yet
507 int childCount=branch.count();
509 bool madeChanges=false;
513 for(curChildIndex=1;curChildIndex<childCount;curChildIndex++){
514 BranchObj* curChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex);
515 BranchObj* prevChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex-1);
516 if(prevChild->heading->text().compare(curChild->heading->text())>0)
518 this->moveBranchUp(curChild);
526 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
528 qreal th = bboxTotal.height();
529 int depth=treeItem->depth(); // FIXME-3 needed to recursively calc depth?
533 QString h=QString (depth,' ');
534 h+=treeItem->getHeading();
537 QPointF pp; if (parObj) pp=parObj->getChildPos();
538 cout << "BO::alignRelTo ";
539 cout<<h.toStdString();
540 cout << " d="<<depth<<
541 //cout<< " ref="<<ref<<
542 " bbox.tL="<<bboxTotal.topLeft()<<
544 // " relPos="<<relPos<<
546 " w="<<bbox.width()<<
547 " h="<<bbox.height()<<
548 // " orient="<<orientation<<
549 // " alignSelf="<<alignSelf<<
550 // " scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
551 // " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
552 // " hidden="<<hidden<<
558 //updateLinkGeometry();
560 if (depth==1 && parObj)
562 // Position relatively, if needed
563 //if (useRelPos) move2RelPos (relPos.x(), relPos.y());
565 // Calc angle to mapCenter if I am a mainbranch
566 // needed for reordering the mainbranches clockwise
568 angle=getAngle (QPointF ((int)(x() - parObj->getChildPos().x() ),
569 (int)(y() - parObj->getChildPos().y() ) ) );
573 // Align myself depending on orientation and parent, but
574 // only if I am not a mainbranch or mapcenter itself
576 if (anim.isAnimated())
581 LinkableMapObj::Orientation o;
582 o=parObj->getOrientation();
586 case LinkableMapObj::LeftOfCenter:
587 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
588 //move (ref.x() , ref.y() + (th-bbox.height())/2 );
590 case LinkableMapObj::RightOfCenter:
591 move (ref.x() , ref.y() + (th-bbox.height())/2 );
594 qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
600 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
602 // Set reference point for alignment of children
604 if (orientation==LinkableMapObj::LeftOfCenter)
605 ref2.setX(bbox.topLeft().x() - linkwidth);
607 ref2.setX(bbox.topRight().x() + linkwidth);
610 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
614 // Align the children depending on reference point
615 for (int i=0; i<treeItem->branchCount(); ++i)
617 if (!treeItem->getBranchNum(i)->isHidden())
619 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
621 // append next branch below current one
622 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
628 void BranchObj::reposition()
631 if (!treeItem->getHeading().isEmpty())
632 cout << "BO::reposition "<<qPrintable(treeItem->getHeading())<<endl;
634 cout << "BO::reposition ???"<<endl;
635 // cout << " orient="<<orientation<<endl;
638 if (treeItem->depth()==0)
640 // only calculate the sizes once. If the deepest LMO
641 // changes its height,
642 // all upper LMOs have to change, too.
643 calcBBoxSizeWithChildren();
644 updateLinkGeometry(); // This update is needed if the scene is resized
645 // due to excessive moving of a FIO
647 alignRelativeTo ( QPointF (absPos.x(),
648 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
649 //FIXME-2 qSort (branch.begin(),branch.end(), isAbove);
650 positionBBox(); // Reposition bbox and contents
653 // This is only important for moving branches:
654 // For editing a branch it isn't called...
655 alignRelativeTo ( QPointF (absPos.x(),
656 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
660 void BranchObj::unsetAllRepositionRequests()
662 repositionRequest=false;
663 for (int i=0; i<treeItem->branchCount(); ++i)
664 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
668 QPolygonF BranchObj::shape()
672 QRectF r=getTotalBBox();
673 if (orientation==LinkableMapObj::LeftOfCenter)
676 <<QPointF (bbox.topLeft().x(), r.topLeft().y() )
679 <<QPointF (bbox.bottomLeft().x(), r.bottomLeft().y() ) ;
683 <<QPointF (bbox.topRight().x(), r.topRight().y() )
686 <<QPointF (bbox.bottomRight().x(), r.bottomRight().y() ) ;
690 QRectF BranchObj::getTotalBBox()
694 if ( ((BranchItem*)treeItem)->isScrolled() ) return r;
696 for (int i=0; i<treeItem->branchCount(); ++i)
697 if (!treeItem->getBranchNum(i)->isHidden())
698 r=addBBox(treeItem->getBranchObjNum(i)->getTotalBBox(),r);
700 /* FIXME-3 lots of occurences of treeItem->getBranchObjNum(i) in branchobj.cpp
701 better check if they are not NULL and maybe simplify...
702 (have been NULL at least in calcBBoxSizeWithChilds...)
705 for (int i=0; i<treeItem->imageCount(); ++i)
706 if (!treeItem->isHidden())
707 r=addBBox(treeItem->getImageObjNum(i)->getTotalBBox(),r);
711 QRectF BranchObj::getBBoxSizeWithChildren()
716 ConvexPolygon BranchObj::getBoundingPolygon()
718 if (treeItem->branchCount()==0)
719 return MapObj::getBoundingPolygon();
722 p<<bboxTotal.topLeft();
723 p<<bboxTotal.topRight();
724 p<<bboxTotal.bottomRight();
725 p<<bboxTotal.bottomLeft();
729 void BranchObj::calcBBoxSizeWithChildren()
731 // This is initially called only from reposition and
732 // and only for mapcenter. So it won't be
733 // called more than once for a single user
737 // Calculate size of LMO including all children (to align them later)
738 bboxTotal.setX(bbox.x() );
739 bboxTotal.setY(bbox.y() );
741 // if branch is scrolled, ignore children, but still consider floatimages
742 BranchItem *bi=(BranchItem*)treeItem;
743 if ( bi->isScrolled() )
745 bboxTotal.setWidth (bbox.width());
746 bboxTotal.setHeight(bbox.height());
752 bboxTotal.setWidth (0);
753 bboxTotal.setHeight(0);
756 bboxTotal.setX (parObj->x());
757 bboxTotal.setY (parObj->y());
760 bboxTotal.setX (bbox.x());
761 bboxTotal.setY (bbox.y());
768 // Now calculate recursivly
772 for (int i=0; i<treeItem->branchCount(); i++)
774 if (!bi->getBranchNum(i)->isHidden())
776 bi->getBranchObjNum(i)->calcBBoxSizeWithChildren();
777 br=bi->getBranchObjNum(i)->getBBoxSizeWithChildren();
778 r.setWidth( max (br.width(), r.width() ));
779 r.setHeight(br.height() + r.height() );
780 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
783 // Add myself and also
784 // add width of link to sum if necessary
785 if (bi->branchCount()<1)
786 bboxTotal.setWidth (bbox.width() + r.width() );
788 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
790 bboxTotal.setHeight(max (r.height(), bbox.height()));
793 QString BranchObj::getSelectString()
795 VymModel *model=treeItem->getModel();
797 return model->getSelectString (this);
802 void BranchObj::setAnimation(const AnimPoint &ap)
807 bool BranchObj::animate()
810 if ( anim.isAnimated() )
815 parObj->reposition(); // we might have been relinked meanwhile