3 #include "branchitem.h"
6 #include "mainwindow.h"
9 extern FlagRow *standardFlagsMaster;
10 extern FlagRow *systemFlagsMaster;
12 /////////////////////////////////////////////////////////////////
14 /////////////////////////////////////////////////////////////////
16 BranchObj::BranchObj () :OrnamentedObj() // FIXME-3 needed at all?
18 // cout << "Const BranchObj ()\n";
23 BranchObj::BranchObj (QGraphicsScene* s):OrnamentedObj (s)// FIXME-3 needed at all?
25 // cout << "Const BranchObj (s) \n";
31 BranchObj::BranchObj (QGraphicsScene* s, LinkableMapObj* p):OrnamentedObj (s)// FIXME-3 needed at all?
33 // cout << "Const BranchObj (s,p)\n";
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
40 angle=getAngle (QPointF (x() - parObj->getChildPos().x() ,
41 (y() - parObj->getChildPos().y() ) ) );
45 BranchObj::~BranchObj ()
47 // cout << "Destr BranchObj of "<<this<<" ("<<treeItem->getHeading().toStdString()<<")"<<endl;
49 // If I'm animated, I need to un-animate myself first
50 if (anim.isAnimated() )
52 anim.setAnimated (false);
53 VymModel *model=treeItem->getModel();
54 model->stopAnimation (this);
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?
61 BranchObj *po=(BranchObj*)parObj;
65 bo=((BranchObj*)parObj)->getLastBranch();
66 if (bo) po->unScroll();
72 bool BranchObj::operator< ( const BranchObj & other )
74 return angle < other.angle;
77 bool BranchObj::operator== ( const BranchObj & other )
79 return angle == other.angle;
82 void BranchObj::init ()
87 absPos+=parObj->getChildPos();
90 includeImagesVer=false;
91 includeImagesHor=false;
94 void BranchObj::copy (BranchObj* other)
96 OrnamentedObj::copy(other);
98 for (int i=0; i<other->floatimage.size(); ++i)
99 addFloatImage (other->floatimage.at(i));
101 setVisibility (other->visible);
108 void BranchObj::clear()
110 //setVisibility (true); //FIXME-4 needed?
112 while (!floatimage.isEmpty())
113 delete floatimage.takeFirst();
115 while (!xlink.isEmpty())
116 delete xlink.takeFirst();
119 bool isAbove (BranchObj* a, BranchObj *b)
121 if (a->angle < b->angle)
127 void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPointF m, int off)
129 // Temporary link to lmo
130 // m is position of mouse pointer
131 // offset 0: default 1: below lmo -1 above lmo (if possible)
134 BranchObj* o=(BranchObj*)(lmo);
138 // ignore mapcenter and mainbranch
139 if (treeItem->depth()<2) off=0;
146 // FIXME-2 depth=parObj->getDepth()+1;
148 // setLinkStyle calls updateLink, only set it once
149 if (style!=getDefLinkStyle() ) setLinkStyle (getDefLinkStyle());
151 // Move temporary to new position at destination
152 // Usually the positioning would be done by reposition(),
153 // but then also the destination branch would "Jump" around...
154 // Better just do it approximately
155 if (treeItem->depth()==1) // FIXME-3 needed to recursively calc depth?
156 { // new parent is the mapcenter itself
158 QPointF p= normalise ( QPointF (m.x() - o->getChildPos().x(),
159 m.y() - o->getChildPos().y() ));
160 if (p.x()<0) p.setX( p.x()-bbox.width() );
167 // new parent is just a branch, link to it
168 QRectF t=o->getBBoxSizeWithChildren();
169 if (o->getTreeItem()->getLastBranch())
170 y=t.y() + t.height() ;
177 // we want to link above lmo
178 y=o->y() - height() + 5;
180 // we want to link below lmo
181 // Bottom of sel should be 5 pixels above
182 // the bottom of the branch _below_ the target:
183 // Don't try to find that branch, guess 12 pixels
184 y=o->getChildPos().y() -height() + 12;
186 if (o->getOrientation()==LinkableMapObj::LeftOfCenter)
187 move ( o->getChildPos().x() - linkwidth, y );
189 move (o->getChildPos().x() + linkwidth, y );
192 // updateLink is called implicitly in move
196 void BranchObj::unsetParObjTmp()
203 //FIXME-2 depth=parObj->getDepth()+1;
204 setLinkStyle (getDefLinkStyle() );
209 void BranchObj::setVisibility(bool v, int toDepth)
211 BranchItem *bi=(BranchItem*)treeItem;
212 if (bi->depth() <= toDepth)
214 frame->setVisibility(v);
215 heading->setVisibility(v);
216 systemFlags->setVisibility(v);
217 standardFlags->setVisibility(v);
218 LinkableMapObj::setVisibility (v);
220 for (i=0; i<floatimage.size(); ++i)
221 floatimage.at(i)->setVisibility (v);
222 for (i=0; i<xlink.size(); ++i)
223 xlink.at(i)->setVisibility ();
225 // Only change children, if I am not scrolled
226 if (! bi->isScrolled() && (bi->depth() < toDepth))
228 // Now go recursivly through all children
229 for (i=0; i<treeItem->branchCount(); ++i)
230 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
232 } // depth <= toDepth
236 void BranchObj::setVisibility(bool v)
238 setVisibility (v,MAX_DEPTH);
242 void BranchObj::setLinkColor ()
244 // Overloaded from LinkableMapObj
245 // BranchObj can use color of heading
247 VymModel *model=treeItem->getModel();
250 if (model->getMapLinkColorHint()==HeadingColor)
251 LinkableMapObj::setLinkColor (heading->getColor() );
253 LinkableMapObj::setLinkColor ();
257 void BranchObj::updateContentSize()
264 void BranchObj::positionContents()
266 for (int i=0; i<floatimage.size(); ++i )
267 floatimage.at(i)->reposition();
268 OrnamentedObj::positionContents();
271 void BranchObj::move (double x, double y)
273 OrnamentedObj::move (x,y);
274 for (int i=0; i<floatimage.size(); ++i )
275 floatimage.at(i)->reposition();
279 void BranchObj::move (QPointF p)
284 void BranchObj::moveBy (double x, double y)
286 OrnamentedObj::moveBy (x,y);
287 for (int i=0; i<treeItem->branchCount(); ++i)
288 treeItem->getBranchObjNum(i)->moveBy (x,y);
292 void BranchObj::moveBy (QPointF p)
294 moveBy (p.x(), p.y());
298 void BranchObj::positionBBox()
300 QPointF ap=getAbsPos();
301 bbox.moveTopLeft (ap);
305 frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
307 // Update links to other branches
308 for (int i=0; i<xlink.size(); ++i)
309 xlink.at(i)->updateXLink();
312 void BranchObj::calcBBoxSize()
314 QSizeF heading_r=heading->getSize();
315 qreal heading_w=(qreal) heading_r.width() ;
316 qreal heading_h=(qreal) heading_r.height() ;
317 QSizeF sysflags_r=systemFlags->getSize();
318 qreal sysflags_h=sysflags_r.height();
319 qreal sysflags_w=sysflags_r.width();
320 QSizeF stanflags_r=standardFlags->getSize();
321 qreal stanflags_h=stanflags_r.height();
322 qreal stanflags_w=stanflags_r.width();
326 // set width to sum of all widths
327 w=heading_w + sysflags_w + stanflags_w;
328 // set height to maximum needed height
329 h=max (sysflags_h,stanflags_h);
332 // Save the dimension of flags and heading
333 ornamentsBBox.setSize ( QSizeF(w,h));
335 // clickBox includes Flags and Heading
336 clickBox.setSize (ornamentsBBox.size() );
341 topPad=botPad=leftPad=rightPad=0;
342 if (includeImagesVer || includeImagesHor)
344 if (treeItem->imageCount()>0)
346 for (int i=0; i<floatimage.size(); ++i )
348 rp=floatimage.at(i)->getRelPos();
349 if (includeImagesVer)
352 topPad=max (topPad,-rp.y()-h);
353 if (rp.y()+floatimage.at(i)->height() > 0)
354 botPad=max (botPad,rp.y()+floatimage.at(i)->height());
356 if (includeImagesHor)
358 if (orientation==LinkableMapObj::RightOfCenter)
361 leftPad=max (leftPad,-rp.x()-w);
362 if (rp.x()+floatimage.at(i)->width() > 0)
363 rightPad=max (rightPad,rp.x()+floatimage.at(i)->width());
367 leftPad=max (leftPad,-rp.x());
368 if (rp.x()+floatimage.at(i)->width() > w)
369 rightPad=max (rightPad,rp.x()+floatimage.at(i)->width()-w);
379 w+=frame->getPadding();
380 h+=frame->getPadding();
383 bbox.setSize (QSizeF (w,h));
386 void BranchObj::setDockPos()
388 // Sets childpos and parpos depending on orientation
389 if (getOrientation()==LinkableMapObj::LeftOfCenter )
392 ornamentsBBox.bottomLeft().x(),
395 ornamentsBBox.bottomRight().x(),
400 ornamentsBBox.bottomRight().x(),
403 ornamentsBBox.bottomLeft().x(),
408 void BranchObj::updateData()
413 qWarning ("BranchObj::udpateHeading treeItem==NULL");
416 QString s=treeItem->getHeading();
417 if (s!=heading->text())
419 heading->setText (s);
422 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
424 // Add missing standard flags active in TreeItem
425 for (int i=0;i<=TIactiveFlags.size()-1;i++)
427 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
429 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
430 if (f) standardFlags->activate (f);
434 // Remove standard flags no longer active in TreeItem
435 QStringList BOactiveFlags=standardFlags->activeFlagNames();
436 for (int i=0;i<BOactiveFlags.size();++i)
437 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
439 standardFlags->deactivate (BOactiveFlags.at(i));
443 // Add missing system flags active in TreeItem
444 TIactiveFlags=treeItem->activeSystemFlagNames();
445 for (int i=0;i<TIactiveFlags.size();++i)
447 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
449 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
450 if (f) systemFlags->activate (f);
454 // Remove system flags no longer active in TreeItem
455 BOactiveFlags=systemFlags->activeFlagNames();
456 for (int i=0;i<BOactiveFlags.size();++i)
458 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
460 systemFlags->deactivate (BOactiveFlags.at(i));
470 void BranchObj::addXLink (XLinkObj *xlo)
476 void BranchObj::removeXLinkRef (XLinkObj *xlo)
478 xlink.removeAt (xlink.indexOf(xlo));
481 void BranchObj::deleteXLink(XLinkObj *xlo)
484 if (!xlo->isUsed()) delete (xlo);
487 void BranchObj::deleteXLinkAt (int i)
489 XLinkObj *xlo=xlink.at(i);
491 if (!xlo->isUsed()) delete(xlo);
494 XLinkObj* BranchObj::XLinkAt (int i)
499 BranchObj* BranchObj::XLinkTargetAt (int i)
501 if (i>=0 && i<xlink.size())
504 return xlink.at(i)->otherBranch (this);
509 void BranchObj::setIncludeImagesVer(bool b)
517 bool BranchObj::getIncludeImagesVer()
519 return includeImagesVer;
522 void BranchObj::setIncludeImagesHor(bool b)
530 bool BranchObj::getIncludeImagesHor()
532 return includeImagesHor;
535 QString BranchObj::getIncludeImageAttr()
538 if (includeImagesVer)
539 a=attribut ("incImgV","true");
541 a=attribut ("incImgV","false");
542 if (includeImagesHor)
543 a+=attribut ("incImgH","true");
545 a+=attribut ("incImgH","false");
549 FloatImageObj* BranchObj::addFloatImage ()
551 FloatImageObj *newfi=new FloatImageObj (scene,this);
552 floatimage.append (newfi);
553 if ( ((BranchItem*)treeItem)->hasScrolledParent((BranchItem*)treeItem) )
554 newfi->setVisibility (false);
556 newfi->setVisibility(visible);
565 FloatImageObj* BranchObj::addFloatImage (FloatImageObj *fio)
567 FloatImageObj *newfi=new FloatImageObj (scene,this);
568 floatimage.append (newfi);
570 if (((BranchItem*)treeItem)->hasScrolledParent((BranchItem*)treeItem) )
571 newfi->setVisibility (false);
573 newfi->setVisibility(visible);
582 FloatImageObj* BranchObj::getFirstFloatImage ()
584 return floatimage.first();
587 FloatImageObj* BranchObj::getLastFloatImage ()
589 return floatimage.last();
592 FloatImageObj* BranchObj::getFloatImageNum (const uint &i)
594 return floatimage.at(i);
597 void BranchObj::removeFloatImage (FloatImageObj *fio)
599 int i=floatimage.indexOf (fio);
600 if (i>-1) delete (floatimage.takeAt (i));
606 void BranchObj::savePosInAngle ()
608 // Save position in angle
609 for (int i=0; i<treeItem->branchCount(); ++i)
610 treeItem->getBranchObjNum(i)->angle=i;
613 void BranchObj::setDefAttr (BranchModification mod)
616 switch (treeItem->depth())
618 case 0: fontsize=16; break;
619 case 1: fontsize=12; break;
620 default: fontsize=10; break;
624 setLinkStyle(getDefLinkStyle());
625 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
626 font.setPointSize(fontsize);
627 heading->setFont(font );
630 setColor (treeItem->getHeadingColor() );
634 void BranchObj::sortChildren() //FIXME-2
637 int childCount=branch.count();
639 bool madeChanges=false;
643 for(curChildIndex=1;curChildIndex<childCount;curChildIndex++){
644 BranchObj* curChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex);
645 BranchObj* prevChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex-1);
646 if(prevChild->heading->text().compare(curChild->heading->text())>0)
648 this->moveBranchUp(curChild);
656 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
658 qreal th = bboxTotal.height();
659 int depth=treeItem->depth(); // FIXME-3 needed to recursively calc depth?
663 QString h=QString (depth,' ');
664 h+=treeItem->getHeading();
667 QPointF pp; if (parObj) pp=parObj->getChildPos();
668 cout << "BO::alignRelTo ";
669 cout<<h.toStdString();
670 cout << " d="<<depth<<
671 //cout<< " ref="<<ref<<
672 " bbox.tL="<<bboxTotal.topLeft()<<
674 // " relPos="<<relPos<<
676 " w="<<bbox.width()<<
677 " h="<<bbox.height()<<
678 // " orient="<<orientation<<
679 // " alignSelf="<<alignSelf<<
680 // " scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
681 // " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
682 // " hidden="<<hidden<<
690 if (depth==1 && parObj)
692 // Position relatively, if needed
693 //if (useRelPos) move2RelPos (relPos.x(), relPos.y());
695 // Calc angle to mapCenter if I am a mainbranch
696 // needed for reordering the mainbranches clockwise
698 angle=getAngle (QPointF ((int)(x() - parObj->getChildPos().x() ),
699 (int)(y() - parObj->getChildPos().y() ) ) );
703 // Align myself depending on orientation and parent, but
704 // only if I am not a mainbranch or mapcenter itself
706 if (anim.isAnimated())
711 LinkableMapObj::Orientation o;
712 o=parObj->getOrientation();
716 case LinkableMapObj::LeftOfCenter:
717 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
718 //move (ref.x() , ref.y() + (th-bbox.height())/2 );
720 case LinkableMapObj::RightOfCenter:
721 move (ref.x() , ref.y() + (th-bbox.height())/2 );
724 qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
730 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
732 // Set reference point for alignment of children
734 if (orientation==LinkableMapObj::LeftOfCenter)
735 ref2.setX(bbox.topLeft().x() - linkwidth);
737 ref2.setX(bbox.topRight().x() + linkwidth);
740 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
744 // Align the children depending on reference point
745 for (int i=0; i<treeItem->branchCount(); ++i)
747 if (!treeItem->getBranchNum(i)->isHidden())
749 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
751 // append next branch below current one
752 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
758 void BranchObj::reposition()
761 if (!treeItem->getHeading().isEmpty())
762 cout << "BO::reposition "<<qPrintable(treeItem->getHeading())<<endl;
764 cout << "BO::reposition ???"<<endl;
765 // cout << " orient="<<orientation<<endl;
768 if (treeItem->depth()==0)
770 // only calculate the sizes once. If the deepest LMO
771 // changes its height,
772 // all upper LMOs have to change, too.
773 calcBBoxSizeWithChildren();
774 updateLink(); // This update is needed if the scene is resized
775 // due to excessive moving of a FIO
777 alignRelativeTo ( QPointF (absPos.x(),
778 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
779 //FIXME-2 qSort (branch.begin(),branch.end(), isAbove);
780 positionBBox(); // Reposition bbox and contents
783 // This is only important for moving branches:
784 // For editing a branch it isn't called...
785 alignRelativeTo ( QPointF (absPos.x(),
786 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
790 void BranchObj::unsetAllRepositionRequests()
792 repositionRequest=false;
793 for (int i=0; i<treeItem->branchCount(); ++i)
794 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
798 QPolygonF BranchObj::shape()
802 QRectF r=getTotalBBox();
803 if (orientation==LinkableMapObj::LeftOfCenter)
806 <<QPointF (bbox.topLeft().x(), r.topLeft().y() )
809 <<QPointF (bbox.bottomLeft().x(), r.bottomLeft().y() ) ;
813 <<QPointF (bbox.topRight().x(), r.topRight().y() )
816 <<QPointF (bbox.bottomRight().x(), r.bottomRight().y() ) ;
820 QRectF BranchObj::getTotalBBox()
824 if ( ((BranchItem*)treeItem)->isScrolled() ) return r;
826 for (int i=0; i<treeItem->branchCount(); ++i)
827 if (!treeItem->getBranchNum(i)->isHidden())
828 r=addBBox(treeItem->getBranchObjNum(i)->getTotalBBox(),r);
830 /* FIXME-3 lots of occurences of treeItem->getBranchObjNum(i) in branchobj.cpp
831 better check if they are not NULL and maybe simplify...
832 (have been NULL at least in calcBBoxSizeWithChilds...)
836 FIXME-3 for (int i=0; i<floatimage.size(); ++i)
837 if (!floatimage.at(i)->isHidden())
838 r=addBBox(floatimage.at(i)->getTotalBBox(),r);
843 QRectF BranchObj::getBBoxSizeWithChildren()
848 void BranchObj::calcBBoxSizeWithChildren()
850 // This is initially called only from reposition and
851 // and only for mapcenter. So it won't be
852 // called more than once for a single user
856 // Calculate size of LMO including all children (to align them later)
857 bboxTotal.setX(bbox.x() );
858 bboxTotal.setY(bbox.y() );
860 // if branch is scrolled, ignore children, but still consider floatimages
861 BranchItem *bi=(BranchItem*)treeItem;
862 if ( bi->isScrolled() )
864 bboxTotal.setWidth (bbox.width());
865 bboxTotal.setHeight(bbox.height());
871 bboxTotal.setWidth (0);
872 bboxTotal.setHeight(0);
875 bboxTotal.setX (parObj->x());
876 bboxTotal.setY (parObj->y());
879 bboxTotal.setX (bbox.x());
880 bboxTotal.setY (bbox.y());
887 // Now calculate recursivly
891 for (int i=0; i<treeItem->branchCount(); i++)
893 if (!bi->getBranchNum(i)->isHidden())
895 bi->getBranchObjNum(i)->calcBBoxSizeWithChildren();
896 br=bi->getBranchObjNum(i)->getBBoxSizeWithChildren();
897 r.setWidth( max (br.width(), r.width() ));
898 r.setHeight(br.height() + r.height() );
899 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
902 // Add myself and also
903 // add width of link to sum if necessary
904 if (bi->branchCount()<1)
905 bboxTotal.setWidth (bbox.width() + r.width() );
907 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
909 bboxTotal.setHeight(max (r.height(), bbox.height()));
912 QString BranchObj::getSelectString()
914 VymModel *model=treeItem->getModel();
916 return model->getSelectString (this);
921 void BranchObj::setAnimation(const AnimPoint &ap)
926 bool BranchObj::animate()
929 if ( anim.isAnimated() )
934 parObj->reposition(); // we might have been relinked meanwhile