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";
21 BranchItem *pi=(BranchItem*)(ti->parent());
22 if (pi && pi!=ti->getModel()->getRootItem() )
30 BranchObj::BranchObj (QGraphicsScene* s, LinkableMapObj* p):OrnamentedObj (s)// FIXME-3 needed at all?
32 // cout << "Const BranchObj (s,p)\n";
35 if (treeItem->depth()==1) // FIXME-3 needed to recursively calc depth?
36 // Calc angle to mapCenter if I am a mainbranch
37 // needed for reordering the mainbranches clockwise
39 angle=getAngle (QPointF (x() - parObj->getChildPos().x() ,
40 (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 void BranchObj::init ()
77 absPos+=parObj->getChildPos();
81 void BranchObj::copy (BranchObj* other)
83 OrnamentedObj::copy(other);
85 setVisibility (other->visible);
90 void BranchObj::clear()
92 //setVisibility (true); //FIXME-4 needed?
94 while (!xlink.isEmpty())
95 delete xlink.takeFirst();
98 void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off) //FIXME-1 when moving a mainbranch to a branch it still has relPos, not moved as child
100 // Temporary link to dst
101 // m is position of mouse pointer
102 // offset 0: default 1: below dst -1 above dst (if possible)
104 BranchItem *dsti=(BranchItem*)(dst->getTreeItem());
106 BranchItem *pi=(BranchItem*)(dsti->parent());
107 int pi_depth=pi->depth();
108 BranchObj* bodst=(BranchObj*)dst;
116 if (pi_depth<2) off=0;
123 setLinkStyle (dst->getDefLinkStyle (dsti));
125 // Move temporary to new position at destination
126 // Usually the positioning would be done by reposition(),
127 // but then also the destination branch would "Jump" around...
128 // Better just do it approximately
129 if (dsti->depth()==0)
130 { // new parent is a mapcenter
131 Vector v= ( m - bodst->getChildPos());
132 if (v.x()<0) v.setX( v.x()-bbox.width() );
135 move2RelPos (v.toQPointF());
141 // new parent is just a branch, link to it
142 QRectF t=bodst->getBBoxSizeWithChildren();
143 if (dsti->getLastBranch())
144 y=t.y() + t.height() ;
153 // we want to link above dst
154 y=bodst->y() - height() + 5;
156 // we want to link below dst
157 // Bottom of sel should be 5 pixels above
158 // the bottom of the branch _below_ the target:
159 // Don't try to find that branch, guess 12 pixels
160 y=bodst->getChildPos().y() -height() + 12;
162 if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
163 move ( bodst->getChildPos().x() - linkwidth, y );
165 move (bodst->getChildPos().x() + linkwidth, y );
168 // updateLinkGeometry is called implicitly in move
172 void BranchObj::unsetParObjTmp()
180 setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
181 updateLinkGeometry();
185 void BranchObj::setVisibility(bool v, int toDepth)
187 BranchItem *bi=(BranchItem*)treeItem;
188 if (bi->depth() <= toDepth)
190 frame->setVisibility(v);
191 heading->setVisibility(v);
192 systemFlags->setVisibility(v);
193 standardFlags->setVisibility(v);
194 LinkableMapObj::setVisibility (v);
196 for (i=0; i<treeItem->imageCount(); ++i)
197 treeItem->getImageObjNum(i)->setVisibility (v);
198 for (i=0; i<treeItem->xlinkCount(); ++i)
199 treeItem->getXLinkObjNum(i)->setVisibility ();
201 // Only change children, if I am not scrolled
202 if (! bi->isScrolled() && (bi->depth() < toDepth))
204 // Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
205 for (i=0; i<treeItem->branchCount(); ++i)
206 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
208 } // depth <= toDepth
212 void BranchObj::setVisibility(bool v)
214 setVisibility (v,MAX_DEPTH);
218 void BranchObj::setLinkColor ()
220 // Overloaded from LinkableMapObj
221 // BranchObj can use color of heading
223 VymModel *model=treeItem->getModel();
226 if (model->getMapLinkColorHint()==HeadingColor)
227 LinkableMapObj::setLinkColor (heading->getColor() );
229 LinkableMapObj::setLinkColor ();
233 void BranchObj::updateContentSize()
240 void BranchObj::positionContents()
242 for (int i=0; i<treeItem->imageCount(); ++i)
243 treeItem->getImageObjNum(i)->reposition();
244 OrnamentedObj::positionContents();
247 void BranchObj::move (double x, double y)
249 OrnamentedObj::move (x,y);
253 void BranchObj::move (QPointF p)
258 void BranchObj::moveBy (double x, double y)
260 OrnamentedObj::moveBy (x,y);
261 for (int i=0; i<treeItem->branchCount(); ++i)
262 treeItem->getBranchObjNum(i)->moveBy (x,y);
266 void BranchObj::moveBy (QPointF p)
268 moveBy (p.x(), p.y());
272 void BranchObj::positionBBox()
274 QPointF ap=getAbsPos();
275 bbox.moveTopLeft (ap);
279 frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
281 //Update links to other branches
283 for (int i=0; i<treeItem->xlinkCount(); ++i)
285 xlo=treeItem->getXLinkObjNum(i);
286 if (xlo) xlo->updateXLink();
290 void BranchObj::calcBBoxSize()
292 QSizeF heading_r=heading->getSize();
293 qreal heading_w=(qreal) heading_r.width() ;
294 qreal heading_h=(qreal) heading_r.height() ;
295 QSizeF sysflags_r=systemFlags->getSize();
296 qreal sysflags_h=sysflags_r.height();
297 qreal sysflags_w=sysflags_r.width();
298 QSizeF stanflags_r=standardFlags->getSize();
299 qreal stanflags_h=stanflags_r.height();
300 qreal stanflags_w=stanflags_r.width();
304 // set width to sum of all widths
305 w=heading_w + sysflags_w + stanflags_w;
306 // set height to maximum needed height
307 h=max (sysflags_h,stanflags_h);
310 // Save the dimension of flags and heading
311 ornamentsBBox.setSize ( QSizeF(w,h));
313 // clickBox includes Flags and Heading
314 clickBox.setSize (ornamentsBBox.size() );
319 topPad=botPad=leftPad=rightPad=0;
320 bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
321 bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
325 for (int i=0; i<treeItem->imageCount(); ++i )
327 fio=treeItem->getImageObjNum(i);
332 topPad=max (topPad,-rp.y()-h);
333 if (rp.y()+fio->height() > 0)
334 botPad=max (botPad,rp.y()+fio->height());
338 if (orientation==LinkableMapObj::RightOfCenter)
341 leftPad=max (leftPad,-rp.x()-w);
342 if (rp.x()+fio->width() > 0)
343 rightPad=max (rightPad,rp.x()+fio->width());
347 leftPad=max (leftPad,-rp.x());
348 if (rp.x()+fio->width() > w)
349 rightPad=max (rightPad,rp.x()+fio->width()-w);
358 w+=frame->getPadding();
359 h+=frame->getPadding();
362 bbox.setSize (QSizeF (w,h));
365 void BranchObj::setDockPos()
367 if (treeItem->getType()==TreeItem::MapCenter)
369 // set childPos to middle of MapCenterObj
370 childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
371 childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
373 for (int i=0; i<treeItem->branchCount(); ++i)
374 treeItem->getBranchObjNum(i)->updateLinkGeometry();
378 // Sets childpos and parpos depending on orientation
379 if (getOrientation()==LinkableMapObj::LeftOfCenter )
382 ornamentsBBox.bottomLeft().x(),
385 ornamentsBBox.bottomRight().x(),
390 ornamentsBBox.bottomRight().x(),
393 ornamentsBBox.bottomLeft().x(),
399 void BranchObj::updateData()
404 qWarning ("BranchObj::udpateHeading treeItem==NULL");
407 QString s=treeItem->getHeading();
408 if (s!=heading->text())
410 heading->setText (s);
413 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
415 // Add missing standard flags active in TreeItem
416 for (int i=0;i<=TIactiveFlags.size()-1;i++)
418 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
420 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
421 if (f) standardFlags->activate (f);
425 // Remove standard flags no longer active in TreeItem
426 QStringList BOactiveFlags=standardFlags->activeFlagNames();
427 for (int i=0;i<BOactiveFlags.size();++i)
428 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
430 standardFlags->deactivate (BOactiveFlags.at(i));
434 // Add missing system flags active in TreeItem
435 TIactiveFlags=treeItem->activeSystemFlagNames();
436 for (int i=0;i<TIactiveFlags.size();++i)
438 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
440 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
441 if (f) systemFlags->activate (f);
445 // Remove system flags no longer active in TreeItem
446 BOactiveFlags=systemFlags->activeFlagNames();
447 for (int i=0;i<BOactiveFlags.size();++i)
449 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
451 systemFlags->deactivate (BOactiveFlags.at(i));
458 void BranchObj::setDefAttr (BranchModification mod)
461 switch (treeItem->depth())
465 setFrameType (FrameObj::Rectangle);
469 setFrameType (FrameObj::NoFrame);
473 setFrameType (FrameObj::NoFrame);
477 setFrameType (FrameObj::NoFrame);
480 setLinkStyle(getDefLinkStyle(treeItem->parent() ));
482 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
483 font.setPointSize(fontsize);
484 heading->setFont(font );
487 setColor (treeItem->getHeadingColor() );
489 // Also set styles for children
490 for (int i=0; i<treeItem->branchCount(); ++i)
491 treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch);
495 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
497 qreal th = bboxTotal.height();
499 if (parObj) depth=1 + parObj->getTreeItem()->depth();
502 QString h=QString (depth+1,' ');
503 h+=treeItem->getHeading();
507 if (parObj) pp=parObj->getChildPos();
508 cout << "BO::alignRelTo ";
509 cout<<h.toStdString();
510 cout << " d="<<depth;
511 cout <<" parO="<<parObj;
512 //cout<< " ref="<<ref<<
513 //cout << " bbox.tL="<<bboxTotal.topLeft();
514 cout<< " absPos="<<absPos<<
517 // " w="<<bbox.width()<<
518 // " h="<<bbox.height()<<
519 // " orient="<<orientation<<
520 // " alignSelf="<<alignSelf<<
521 // " scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
522 // " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
523 // " hidden="<<hidden<<
529 //updateLinkGeometry();
533 move2RelPos (getRelPos() );
537 // Align myself depending on orientation and parent, but
538 // only if I am not a mainbranch or mapcenter itself
540 if (anim.isAnimated())
545 LinkableMapObj::Orientation o;
546 o=parObj->getOrientation();
550 case LinkableMapObj::LeftOfCenter:
551 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
552 //move (ref.x() , ref.y() + (th-bbox.height())/2 );
554 case LinkableMapObj::RightOfCenter:
555 move (ref.x() , ref.y() + (th-bbox.height())/2 );
558 qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
564 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
566 // Set reference point for alignment of children
568 if (orientation==LinkableMapObj::LeftOfCenter)
569 ref2.setX(bbox.topLeft().x() - linkwidth);
571 ref2.setX(bbox.topRight().x() + linkwidth);
574 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
578 // Align the children depending on reference point
579 for (int i=0; i<treeItem->branchCount(); ++i)
581 if (!treeItem->getBranchNum(i)->isHidden())
583 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
585 // append next branch below current one
586 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
592 void BranchObj::reposition()
595 if (!treeItem->getHeading().isEmpty())
596 cout << "BO::reposition "<<qPrintable(treeItem->getHeading())<<endl;
598 cout << "BO::reposition ???"<<endl;
599 // cout << " orient="<<orientation<<endl;
602 if (treeItem->depth()==0)
604 // only calculate the sizes once. If the deepest LMO
605 // changes its height,
606 // all upper LMOs have to change, too.
607 calcBBoxSizeWithChildren();
608 updateLinkGeometry(); // This update is needed if the scene is resized
609 // due to excessive moving of a FIO
611 alignRelativeTo ( QPointF (absPos.x(),
612 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
613 positionBBox(); // Reposition bbox and contents
616 // This is only important for moving branches:
617 // For editing a branch it isn't called...
618 alignRelativeTo ( QPointF (absPos.x(),
619 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
623 void BranchObj::unsetAllRepositionRequests()
625 repositionRequest=false;
626 for (int i=0; i<treeItem->branchCount(); ++i)
627 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
631 QRectF BranchObj::getTotalBBox()
635 if ( ((BranchItem*)treeItem)->isScrolled() ) return r;
637 for (int i=0; i<treeItem->branchCount(); ++i)
638 if (!treeItem->getBranchNum(i)->isHidden())
639 r=addBBox(treeItem->getBranchObjNum(i)->getTotalBBox(),r);
641 /* FIXME-3 lots of occurences of treeItem->getBranchObjNum(i) in branchobj.cpp
642 better check if they are not NULL and maybe simplify...
643 (have been NULL at least in calcBBoxSizeWithChilds...)
646 for (int i=0; i<treeItem->imageCount(); ++i)
647 if (!treeItem->isHidden())
648 r=addBBox(treeItem->getImageObjNum(i)->getTotalBBox(),r);
652 QRectF BranchObj::getBBoxSizeWithChildren()
657 ConvexPolygon BranchObj::getBoundingPolygon()
660 if (!pi) //FIXME-3 Testing only
662 pi=scene->addPolygon(MapObj::getBoundingPolygon() );
663 pi->setPen(Qt::NoPen);
664 pi->setBrush( QColor(qrand()%32*8,qrand()%32*8,qrand()%32*8) );
665 pi->setZValue(Z_BBOX);
669 if (treeItem->branchCount()==0 || treeItem->depth()==0)
671 if (pi) pi->setPolygon (MapObj::getBoundingPolygon() );
672 return MapObj::getBoundingPolygon();
675 calcBBoxSizeWithChildren(); //FIXME-3 really needed?
677 p<<bboxTotal.topLeft();
678 p<<bboxTotal.topRight();
679 p<<bboxTotal.bottomRight();
680 p<<bboxTotal.bottomLeft();
681 //cout << "BO::getBP (total) "<<treeItem->getHeadingStd()<<" tL="<<bboxTotal.topLeft()<<" bR="<<bboxTotal.bottomRight()<<endl;
682 //cout << " "<<" tL="<<bbox.topLeft()<<" bR="<<bbox.bottomRight()<<endl;
683 if (pi) pi->setPolygon (p );
687 void BranchObj::calcBBoxSizeWithChildren()
689 // This is initially called only from reposition and
690 // and only for mapcenter. So it won't be
691 // called more than once for a single user
695 // Calculate size of LMO including all children (to align them later)
696 bboxTotal.setX(bbox.x() );
697 bboxTotal.setY(bbox.y() );
699 // if branch is scrolled, ignore children, but still consider floatimages
700 BranchItem *bi=(BranchItem*)treeItem;
701 if ( bi->isScrolled() )
703 bboxTotal.setWidth (bbox.width());
704 bboxTotal.setHeight(bbox.height());
710 bboxTotal.setWidth (0);
711 bboxTotal.setHeight(0);
714 bboxTotal.setX (parObj->x());
715 bboxTotal.setY (parObj->y());
718 bboxTotal.setX (bbox.x());
719 bboxTotal.setY (bbox.y());
726 // Now calculate recursivly
730 for (int i=0; i<treeItem->branchCount(); i++)
732 if (!bi->getBranchNum(i)->isHidden())
734 bi->getBranchObjNum(i)->calcBBoxSizeWithChildren();
735 br=bi->getBranchObjNum(i)->getBBoxSizeWithChildren();
736 r.setWidth( max (br.width(), r.width() ));
737 r.setHeight(br.height() + r.height() );
738 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
739 if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
742 // Add myself and also
743 // add width of link to sum if necessary
744 if (bi->branchCount()<1)
745 bboxTotal.setWidth (bbox.width() + r.width() );
747 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
749 bboxTotal.setHeight(max (r.height(), bbox.height()));
752 QString BranchObj::getSelectString()
754 VymModel *model=treeItem->getModel();
756 return model->getSelectString (this);
761 void BranchObj::setAnimation(const AnimPoint &ap)
766 bool BranchObj::animate()
769 if ( anim.isAnimated() )
774 parObj->reposition(); // we might have been relinked meanwhile