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 QPointF p= normalize ( QPointF (m.x() - o->getChildPos().x(),
147 m.y() - o->getChildPos().y() ));
148 if (p.x()<0) p.setX( p.x()-bbox.width() );
155 // new parent is just a branch, link to it
156 QRectF t=o->getBBoxSizeWithChildren();
157 if (o->getTreeItem()->getLastBranch())
158 y=t.y() + t.height() ;
165 // we want to link above lmo
166 y=o->y() - height() + 5;
168 // we want to link below lmo
169 // Bottom of sel should be 5 pixels above
170 // the bottom of the branch _below_ the target:
171 // Don't try to find that branch, guess 12 pixels
172 y=o->getChildPos().y() -height() + 12;
174 if (o->getOrientation()==LinkableMapObj::LeftOfCenter)
175 move ( o->getChildPos().x() - linkwidth, y );
177 move (o->getChildPos().x() + linkwidth, y );
180 // updateLinkGeometry is called implicitly in move
184 void BranchObj::unsetParObjTmp()
191 setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
192 updateLinkGeometry();
196 void BranchObj::setVisibility(bool v, int toDepth)
198 BranchItem *bi=(BranchItem*)treeItem;
199 if (bi->depth() <= toDepth)
201 frame->setVisibility(v);
202 heading->setVisibility(v);
203 systemFlags->setVisibility(v);
204 standardFlags->setVisibility(v);
205 LinkableMapObj::setVisibility (v);
207 for (i=0; i<treeItem->imageCount(); ++i)
208 treeItem->getImageObjNum(i)->setVisibility (v);
209 for (i=0; i<treeItem->xlinkCount(); ++i)
210 treeItem->getXLinkObjNum(i)->setVisibility ();
212 // Only change children, if I am not scrolled
213 if (! bi->isScrolled() && (bi->depth() < toDepth))
215 // Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
216 for (i=0; i<treeItem->branchCount(); ++i)
217 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
219 } // depth <= toDepth
223 void BranchObj::setVisibility(bool v)
225 setVisibility (v,MAX_DEPTH);
229 void BranchObj::setLinkColor ()
231 // Overloaded from LinkableMapObj
232 // BranchObj can use color of heading
234 VymModel *model=treeItem->getModel();
237 if (model->getMapLinkColorHint()==HeadingColor)
238 LinkableMapObj::setLinkColor (heading->getColor() );
240 LinkableMapObj::setLinkColor ();
244 void BranchObj::updateContentSize()
251 void BranchObj::positionContents()
253 for (int i=0; i<treeItem->imageCount(); ++i)
254 treeItem->getImageObjNum(i)->reposition();
255 OrnamentedObj::positionContents();
258 void BranchObj::move (double x, double y)
260 OrnamentedObj::move (x,y);
262 for (int i=0; i<treeItem->imageCount(); ++i )
264 fio=treeItem->getImageObjNum(i);
265 if (fio) fio->reposition();
270 void BranchObj::move (QPointF p)
275 void BranchObj::moveBy (double x, double y)
277 OrnamentedObj::moveBy (x,y);
278 for (int i=0; i<treeItem->branchCount(); ++i)
279 treeItem->getBranchObjNum(i)->moveBy (x,y);
283 void BranchObj::moveBy (QPointF p)
285 moveBy (p.x(), p.y());
289 void BranchObj::positionBBox()
291 QPointF ap=getAbsPos();
292 bbox.moveTopLeft (ap);
296 frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
298 //Update links to other branches
300 for (int i=0; i<treeItem->xlinkCount(); ++i)
302 xlo=treeItem->getXLinkObjNum(i);
303 if (xlo) xlo->updateXLink();
307 void BranchObj::calcBBoxSize()
309 QSizeF heading_r=heading->getSize();
310 qreal heading_w=(qreal) heading_r.width() ;
311 qreal heading_h=(qreal) heading_r.height() ;
312 QSizeF sysflags_r=systemFlags->getSize();
313 qreal sysflags_h=sysflags_r.height();
314 qreal sysflags_w=sysflags_r.width();
315 QSizeF stanflags_r=standardFlags->getSize();
316 qreal stanflags_h=stanflags_r.height();
317 qreal stanflags_w=stanflags_r.width();
321 // set width to sum of all widths
322 w=heading_w + sysflags_w + stanflags_w;
323 // set height to maximum needed height
324 h=max (sysflags_h,stanflags_h);
327 // Save the dimension of flags and heading
328 ornamentsBBox.setSize ( QSizeF(w,h));
330 // clickBox includes Flags and Heading
331 clickBox.setSize (ornamentsBBox.size() );
336 topPad=botPad=leftPad=rightPad=0;
337 bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
338 bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
342 for (int i=0; i<treeItem->imageCount(); ++i )
344 fio=treeItem->getImageObjNum(i);
349 topPad=max (topPad,-rp.y()-h);
350 if (rp.y()+fio->height() > 0)
351 botPad=max (botPad,rp.y()+fio->height());
355 if (orientation==LinkableMapObj::RightOfCenter)
358 leftPad=max (leftPad,-rp.x()-w);
359 if (rp.x()+fio->width() > 0)
360 rightPad=max (rightPad,rp.x()+fio->width());
364 leftPad=max (leftPad,-rp.x());
365 if (rp.x()+fio->width() > w)
366 rightPad=max (rightPad,rp.x()+fio->width()-w);
375 w+=frame->getPadding();
376 h+=frame->getPadding();
379 bbox.setSize (QSizeF (w,h));
382 void BranchObj::setDockPos()
384 if (treeItem->getType()==TreeItem::MapCenter)
386 // set childPos to middle of MapCenterObj
387 childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
388 childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
390 for (int i=0; i<treeItem->branchCount(); ++i)
391 treeItem->getBranchObjNum(i)->updateLinkGeometry();
395 // Sets childpos and parpos depending on orientation
396 if (getOrientation()==LinkableMapObj::LeftOfCenter )
399 ornamentsBBox.bottomLeft().x(),
402 ornamentsBBox.bottomRight().x(),
407 ornamentsBBox.bottomRight().x(),
410 ornamentsBBox.bottomLeft().x(),
416 void BranchObj::updateData()
421 qWarning ("BranchObj::udpateHeading treeItem==NULL");
424 QString s=treeItem->getHeading();
425 if (s!=heading->text())
427 heading->setText (s);
430 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
432 // Add missing standard flags active in TreeItem
433 for (int i=0;i<=TIactiveFlags.size()-1;i++)
435 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
437 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
438 if (f) standardFlags->activate (f);
442 // Remove standard flags no longer active in TreeItem
443 QStringList BOactiveFlags=standardFlags->activeFlagNames();
444 for (int i=0;i<BOactiveFlags.size();++i)
445 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
447 standardFlags->deactivate (BOactiveFlags.at(i));
451 // Add missing system flags active in TreeItem
452 TIactiveFlags=treeItem->activeSystemFlagNames();
453 for (int i=0;i<TIactiveFlags.size();++i)
455 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
457 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
458 if (f) systemFlags->activate (f);
462 // Remove system flags no longer active in TreeItem
463 BOactiveFlags=systemFlags->activeFlagNames();
464 for (int i=0;i<BOactiveFlags.size();++i)
466 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
468 systemFlags->deactivate (BOactiveFlags.at(i));
475 void BranchObj::savePosInAngle ()
477 // Save position in angle
478 for (int i=0; i<treeItem->branchCount(); ++i)
479 treeItem->getBranchObjNum(i)->angle=i;
482 void BranchObj::setDefAttr (BranchModification mod)
485 switch (treeItem->depth())
487 case 0: fontsize=16; break;
488 case 1: fontsize=12; break;
489 default: fontsize=10; break;
491 setLinkStyle(getDefLinkStyle(treeItem->parent() ));
493 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
494 font.setPointSize(fontsize);
495 heading->setFont(font );
498 setColor (treeItem->getHeadingColor() );
502 void BranchObj::sortChildren() //FIXME-3 not moved to model yet
505 int childCount=branch.count();
507 bool madeChanges=false;
511 for(curChildIndex=1;curChildIndex<childCount;curChildIndex++){
512 BranchObj* curChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex);
513 BranchObj* prevChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex-1);
514 if(prevChild->heading->text().compare(curChild->heading->text())>0)
516 this->moveBranchUp(curChild);
524 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
526 qreal th = bboxTotal.height();
527 int depth=treeItem->depth(); // FIXME-3 needed to recursively calc depth?
531 QString h=QString (depth,' ');
532 h+=treeItem->getHeading();
535 QPointF pp; if (parObj) pp=parObj->getChildPos();
536 cout << "BO::alignRelTo ";
537 cout<<h.toStdString();
538 cout << " d="<<depth<<
539 //cout<< " ref="<<ref<<
540 " bbox.tL="<<bboxTotal.topLeft()<<
542 // " relPos="<<relPos<<
544 " w="<<bbox.width()<<
545 " h="<<bbox.height()<<
546 // " orient="<<orientation<<
547 // " alignSelf="<<alignSelf<<
548 // " scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
549 // " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
550 // " hidden="<<hidden<<
556 //updateLinkGeometry();
558 if (depth==1 && parObj)
560 // Position relatively, if needed
561 //if (useRelPos) move2RelPos (relPos.x(), relPos.y());
563 // Calc angle to mapCenter if I am a mainbranch
564 // needed for reordering the mainbranches clockwise
566 angle=getAngle (QPointF ((int)(x() - parObj->getChildPos().x() ),
567 (int)(y() - parObj->getChildPos().y() ) ) );
571 // Align myself depending on orientation and parent, but
572 // only if I am not a mainbranch or mapcenter itself
574 if (anim.isAnimated())
579 LinkableMapObj::Orientation o;
580 o=parObj->getOrientation();
584 case LinkableMapObj::LeftOfCenter:
585 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
586 //move (ref.x() , ref.y() + (th-bbox.height())/2 );
588 case LinkableMapObj::RightOfCenter:
589 move (ref.x() , ref.y() + (th-bbox.height())/2 );
592 qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
598 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
600 // Set reference point for alignment of children
602 if (orientation==LinkableMapObj::LeftOfCenter)
603 ref2.setX(bbox.topLeft().x() - linkwidth);
605 ref2.setX(bbox.topRight().x() + linkwidth);
608 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
612 // Align the children depending on reference point
613 for (int i=0; i<treeItem->branchCount(); ++i)
615 if (!treeItem->getBranchNum(i)->isHidden())
617 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
619 // append next branch below current one
620 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
626 void BranchObj::reposition()
629 if (!treeItem->getHeading().isEmpty())
630 cout << "BO::reposition "<<qPrintable(treeItem->getHeading())<<endl;
632 cout << "BO::reposition ???"<<endl;
633 // cout << " orient="<<orientation<<endl;
636 if (treeItem->depth()==0)
638 // only calculate the sizes once. If the deepest LMO
639 // changes its height,
640 // all upper LMOs have to change, too.
641 calcBBoxSizeWithChildren();
642 updateLinkGeometry(); // This update is needed if the scene is resized
643 // due to excessive moving of a FIO
645 alignRelativeTo ( QPointF (absPos.x(),
646 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
647 //FIXME-2 qSort (branch.begin(),branch.end(), isAbove);
648 positionBBox(); // Reposition bbox and contents
651 // This is only important for moving branches:
652 // For editing a branch it isn't called...
653 alignRelativeTo ( QPointF (absPos.x(),
654 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
658 void BranchObj::unsetAllRepositionRequests()
660 repositionRequest=false;
661 for (int i=0; i<treeItem->branchCount(); ++i)
662 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
666 QPolygonF BranchObj::shape()
670 QRectF r=getTotalBBox();
671 if (orientation==LinkableMapObj::LeftOfCenter)
674 <<QPointF (bbox.topLeft().x(), r.topLeft().y() )
677 <<QPointF (bbox.bottomLeft().x(), r.bottomLeft().y() ) ;
681 <<QPointF (bbox.topRight().x(), r.topRight().y() )
684 <<QPointF (bbox.bottomRight().x(), r.bottomRight().y() ) ;
688 QRectF BranchObj::getTotalBBox()
692 if ( ((BranchItem*)treeItem)->isScrolled() ) return r;
694 for (int i=0; i<treeItem->branchCount(); ++i)
695 if (!treeItem->getBranchNum(i)->isHidden())
696 r=addBBox(treeItem->getBranchObjNum(i)->getTotalBBox(),r);
698 /* FIXME-3 lots of occurences of treeItem->getBranchObjNum(i) in branchobj.cpp
699 better check if they are not NULL and maybe simplify...
700 (have been NULL at least in calcBBoxSizeWithChilds...)
703 for (int i=0; i<treeItem->imageCount(); ++i)
704 if (!treeItem->isHidden())
705 r=addBBox(treeItem->getImageObjNum(i)->getTotalBBox(),r);
709 QRectF BranchObj::getBBoxSizeWithChildren()
714 void BranchObj::calcBBoxSizeWithChildren()
716 // This is initially called only from reposition and
717 // and only for mapcenter. So it won't be
718 // called more than once for a single user
722 // Calculate size of LMO including all children (to align them later)
723 bboxTotal.setX(bbox.x() );
724 bboxTotal.setY(bbox.y() );
726 // if branch is scrolled, ignore children, but still consider floatimages
727 BranchItem *bi=(BranchItem*)treeItem;
728 if ( bi->isScrolled() )
730 bboxTotal.setWidth (bbox.width());
731 bboxTotal.setHeight(bbox.height());
737 bboxTotal.setWidth (0);
738 bboxTotal.setHeight(0);
741 bboxTotal.setX (parObj->x());
742 bboxTotal.setY (parObj->y());
745 bboxTotal.setX (bbox.x());
746 bboxTotal.setY (bbox.y());
753 // Now calculate recursivly
757 for (int i=0; i<treeItem->branchCount(); i++)
759 if (!bi->getBranchNum(i)->isHidden())
761 bi->getBranchObjNum(i)->calcBBoxSizeWithChildren();
762 br=bi->getBranchObjNum(i)->getBBoxSizeWithChildren();
763 r.setWidth( max (br.width(), r.width() ));
764 r.setHeight(br.height() + r.height() );
765 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
768 // Add myself and also
769 // add width of link to sum if necessary
770 if (bi->branchCount()<1)
771 bboxTotal.setWidth (bbox.width() + r.width() );
773 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
775 bboxTotal.setHeight(max (r.height(), bbox.height()));
778 QString BranchObj::getSelectString()
780 VymModel *model=treeItem->getModel();
782 return model->getSelectString (this);
787 void BranchObj::setAnimation(const AnimPoint &ap)
792 bool BranchObj::animate()
795 if ( anim.isAnimated() )
800 parObj->reposition(); // we might have been relinked meanwhile