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() )
29 BranchObj::~BranchObj ()
31 // cout << "Destr BranchObj of "<<this<<" ("<<treeItem->getHeading().toStdString()<<")"<<endl;
33 // If I'm animated, I need to un-animate myself first
34 if (anim.isAnimated() )
36 anim.setAnimated (false);
37 VymModel *model=treeItem->getModel();
38 model->stopAnimation (this);
41 // Check, if this branch was the last child to be deleted
42 // If so, unset the scrolled flags in parent // FIXME-2 better do this in model?
45 BranchObj *po=(BranchObj*)parObj;
49 bo=((BranchObj*)parObj)->getLastBranch();
50 if (bo) po->unScroll();
56 void BranchObj::init ()
61 absPos+=parObj->getChildPos();
65 void BranchObj::copy (BranchObj* other)
67 OrnamentedObj::copy(other);
69 setVisibility (other->visible);
74 void BranchObj::clear()
76 //setVisibility (true); //FIXME-4 needed?
78 while (!xlink.isEmpty())
79 delete xlink.takeFirst();
82 void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off)
84 // Temporary link to dst
85 // m is position of mouse pointer
86 // offset 0: default 1: below dst -1 above dst (if possible)
88 BranchItem *dsti=(BranchItem*)(dst->getTreeItem());
90 BranchItem *pi=(BranchItem*)(dsti->parent());
91 int pi_depth=pi->depth();
92 BranchObj* bodst=(BranchObj*)dst;
100 if (pi_depth<2) off=0;
107 setLinkStyle (dst->getDefLinkStyle (dsti));
109 // Move temporary to new position at destination
110 // Usually the positioning would be done by reposition(),
111 // but then also the destination branch would "Jump" around...
112 // Better just do it approximately
113 if (dsti->depth()==0)
114 { // new parent is a mapcenter
115 Vector v= ( m - bodst->getChildPos());
116 if (v.x()<0) v.setX( v.x()-bbox.width() );
119 move2RelPos (v.toQPointF());
125 // new parent is just a branch, link to it
126 QRectF t=bodst->getBBoxSizeWithChildren();
127 if (dsti->getLastBranch())
128 y=t.y() + t.height() ;
137 // we want to link above dst
138 y=bodst->y() - height() + 5;
140 // we want to link below dst
141 // Bottom of sel should be 5 pixels above
142 // the bottom of the branch _below_ the target:
143 // Don't try to find that branch, guess 12 pixels
144 y=bodst->getChildPos().y() -height() + 12;
146 if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
147 move ( bodst->getChildPos().x() - linkwidth, y );
149 move (bodst->getChildPos().x() + linkwidth, y );
152 // updateLinkGeometry is called implicitly in move
156 void BranchObj::unsetParObjTmp()
164 setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
165 updateLinkGeometry();
169 void BranchObj::setVisibility(bool v, int toDepth)
171 BranchItem *bi=(BranchItem*)treeItem;
172 if (bi->depth() <= toDepth)
174 frame->setVisibility(v);
175 heading->setVisibility(v);
176 systemFlags->setVisibility(v);
177 standardFlags->setVisibility(v);
178 LinkableMapObj::setVisibility (v);
180 for (i=0; i<treeItem->imageCount(); ++i)
181 treeItem->getImageObjNum(i)->setVisibility (v);
182 for (i=0; i<treeItem->xlinkCount(); ++i)
183 treeItem->getXLinkObjNum(i)->setVisibility ();
185 // Only change children, if I am not scrolled
186 if (! bi->isScrolled() && (bi->depth() < toDepth))
188 // Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
189 for (i=0; i<treeItem->branchCount(); ++i)
190 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
192 } // depth <= toDepth
196 void BranchObj::setVisibility(bool v)
198 setVisibility (v,MAX_DEPTH);
202 void BranchObj::setLinkColor ()
204 // Overloaded from LinkableMapObj
205 // BranchObj can use color of heading
207 VymModel *model=treeItem->getModel();
210 if (model->getMapLinkColorHint()==HeadingColor)
211 LinkableMapObj::setLinkColor (heading->getColor() );
213 LinkableMapObj::setLinkColor ();
217 void BranchObj::updateContentSize()
224 void BranchObj::positionContents()
226 for (int i=0; i<treeItem->imageCount(); ++i)
227 treeItem->getImageObjNum(i)->reposition();
228 OrnamentedObj::positionContents();
231 void BranchObj::move (double x, double y)
233 OrnamentedObj::move (x,y);
237 void BranchObj::move (QPointF p)
242 void BranchObj::moveBy (double x, double y)
244 OrnamentedObj::moveBy (x,y);
245 for (int i=0; i<treeItem->branchCount(); ++i)
246 treeItem->getBranchObjNum(i)->moveBy (x,y);
250 void BranchObj::moveBy (QPointF p)
252 moveBy (p.x(), p.y());
256 void BranchObj::positionBBox()
258 QPointF ap=getAbsPos();
259 bbox.moveTopLeft (ap);
263 frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
265 //Update links to other branches
267 for (int i=0; i<treeItem->xlinkCount(); ++i)
269 xlo=treeItem->getXLinkObjNum(i);
270 if (xlo) xlo->updateXLink();
274 void BranchObj::calcBBoxSize()
276 QSizeF heading_r=heading->getSize();
277 qreal heading_w=(qreal) heading_r.width() ;
278 qreal heading_h=(qreal) heading_r.height() ;
279 QSizeF sysflags_r=systemFlags->getSize();
280 qreal sysflags_h=sysflags_r.height();
281 qreal sysflags_w=sysflags_r.width();
282 QSizeF stanflags_r=standardFlags->getSize();
283 qreal stanflags_h=stanflags_r.height();
284 qreal stanflags_w=stanflags_r.width();
288 // set width to sum of all widths
289 w=heading_w + sysflags_w + stanflags_w;
290 // set height to maximum needed height
291 h=max (sysflags_h,stanflags_h);
294 // Save the dimension of flags and heading
295 ornamentsBBox.setSize ( QSizeF(w,h));
297 // clickBox includes Flags and Heading
298 clickBox.setSize (ornamentsBBox.size() );
303 topPad=botPad=leftPad=rightPad=0;
304 bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
305 bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
309 for (int i=0; i<treeItem->imageCount(); ++i )
311 fio=treeItem->getImageObjNum(i);
316 topPad=max (topPad,-rp.y()-h);
317 if (rp.y()+fio->height() > 0)
318 botPad=max (botPad,rp.y()+fio->height());
322 if (orientation==LinkableMapObj::RightOfCenter)
325 leftPad=max (leftPad,-rp.x()-w);
326 if (rp.x()+fio->width() > 0)
327 rightPad=max (rightPad,rp.x()+fio->width());
331 leftPad=max (leftPad,-rp.x());
332 if (rp.x()+fio->width() > w)
333 rightPad=max (rightPad,rp.x()+fio->width()-w);
342 w+=frame->getPadding();
343 h+=frame->getPadding();
346 bbox.setSize (QSizeF (w,h));
349 void BranchObj::setDockPos()
351 if (treeItem->getType()==TreeItem::MapCenter)
353 // set childPos to middle of MapCenterObj
354 childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
355 childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
357 for (int i=0; i<treeItem->branchCount(); ++i)
358 treeItem->getBranchObjNum(i)->updateLinkGeometry();
362 // Sets childpos and parpos depending on orientation
363 if (getOrientation()==LinkableMapObj::LeftOfCenter )
366 ornamentsBBox.bottomLeft().x(),
369 ornamentsBBox.bottomRight().x(),
374 ornamentsBBox.bottomRight().x(),
377 ornamentsBBox.bottomLeft().x(),
383 void BranchObj::updateData()
388 qWarning ("BranchObj::udpateHeading treeItem==NULL");
391 QString s=treeItem->getHeading();
392 if (s!=heading->text())
394 heading->setText (s);
397 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
399 // Add missing standard flags active in TreeItem
400 for (int i=0;i<=TIactiveFlags.size()-1;i++)
402 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
404 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
405 if (f) standardFlags->activate (f);
409 // Remove standard flags no longer active in TreeItem
410 QStringList BOactiveFlags=standardFlags->activeFlagNames();
411 for (int i=0;i<BOactiveFlags.size();++i)
412 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
414 standardFlags->deactivate (BOactiveFlags.at(i));
418 // Add missing system flags active in TreeItem
419 TIactiveFlags=treeItem->activeSystemFlagNames();
420 for (int i=0;i<TIactiveFlags.size();++i)
422 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
424 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
425 if (f) systemFlags->activate (f);
429 // Remove system flags no longer active in TreeItem
430 BOactiveFlags=systemFlags->activeFlagNames();
431 for (int i=0;i<BOactiveFlags.size();++i)
433 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
435 systemFlags->deactivate (BOactiveFlags.at(i));
439 if (changed) updateContentSize();
442 void BranchObj::setDefAttr (BranchModification mod)
445 switch (treeItem->depth())
449 setFrameType (FrameObj::Rectangle);
453 setFrameType (FrameObj::NoFrame);
457 setFrameType (FrameObj::NoFrame);
461 setFrameType (FrameObj::NoFrame);
464 setLinkStyle(getDefLinkStyle(treeItem->parent() ));
466 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
467 font.setPointSize(fontsize);
468 heading->setFont(font );
471 setColor (treeItem->getHeadingColor() );
473 // Also set styles for children
474 for (int i=0; i<treeItem->branchCount(); ++i)
475 treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch);
479 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
481 qreal th = bboxTotal.height();
483 if (parObj) depth=1 + parObj->getTreeItem()->depth();
486 QString h=QString (depth+1,' ');
487 h+=treeItem->getHeading();
491 if (parObj) pp=parObj->getChildPos();
492 cout << "BO::alignRelTo ";
493 cout<<h.toStdString();
494 cout << " d="<<depth;
495 cout <<" parO="<<parObj;
496 //cout<< " ref="<<ref<<
497 //cout << " bbox.tL="<<bboxTotal.topLeft();
498 cout<< " absPos="<<absPos<<
501 // " w="<<bbox.width()<<
502 // " h="<<bbox.height()<<
503 // " orient="<<orientation<<
504 // " alignSelf="<<alignSelf<<
505 // " scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
506 // " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
507 // " hidden="<<hidden<<
513 //updateLinkGeometry();
517 move2RelPos (getRelPos() );
521 // Align myself depending on orientation and parent, but
522 // only if I am not a mainbranch or mapcenter itself
524 if (anim.isAnimated())
529 LinkableMapObj::Orientation o;
530 o=parObj->getOrientation();
534 case LinkableMapObj::LeftOfCenter:
535 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
536 //move (ref.x() , ref.y() + (th-bbox.height())/2 );
538 case LinkableMapObj::RightOfCenter:
539 move (ref.x() , ref.y() + (th-bbox.height())/2 );
542 qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
548 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
550 // Set reference point for alignment of children
552 if (orientation==LinkableMapObj::LeftOfCenter)
553 ref2.setX(bbox.topLeft().x() - linkwidth);
555 ref2.setX(bbox.topRight().x() + linkwidth);
558 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
562 // Align the children depending on reference point
563 for (int i=0; i<treeItem->branchCount(); ++i)
565 if (!treeItem->getBranchNum(i)->isHidden())
567 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
569 // append next branch below current one
570 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
576 void BranchObj::reposition()
579 if (!treeItem->getHeading().isEmpty())
580 cout << "BO::reposition "<<qPrintable(treeItem->getHeading())<<endl;
582 cout << "BO::reposition ???"<<endl;
583 // cout << " orient="<<orientation<<endl;
586 if (treeItem->depth()==0)
588 // only calculate the sizes once. If the deepest LMO
589 // changes its height,
590 // all upper LMOs have to change, too.
591 calcBBoxSizeWithChildren();
592 updateLinkGeometry(); // This update is needed if the scene is resized
593 // due to excessive moving of a FIO
595 alignRelativeTo ( QPointF (absPos.x(),
596 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
597 positionBBox(); // Reposition bbox and contents
600 // This is only important for moving branches:
601 // For editing a branch it isn't called...
602 alignRelativeTo ( QPointF (absPos.x(),
603 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
607 void BranchObj::unsetAllRepositionRequests()
609 repositionRequest=false;
610 for (int i=0; i<treeItem->branchCount(); ++i)
611 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
615 QRectF BranchObj::getTotalBBox() // FIXME-2 not really needed, get rid of this
619 if ( ((BranchItem*)treeItem)->isScrolled() ) return r;
621 /* FIXME-2 really include children _here_ ? likely not needed anymore, but done in TreeItem */
622 for (int i=0; i<treeItem->branchCount(); ++i)
623 if (!treeItem->getBranchNum(i)->isHidden())
624 r=addBBox(treeItem->getBranchObjNum(i)->getTotalBBox(),r);
626 /* FIXME-3 lots of occurences of treeItem->getBranchObjNum(i) in branchobj.cpp
627 better check if they are not NULL and maybe simplify...
628 (have been NULL at least in calcBBoxSizeWithChilds...)
632 for (int i=0; i<treeItem->imageCount(); ++i
633 if (!treeItem->isHidden())
634 r=addBBox(treeItem->getImageObjNum(i)->getTotalBBox(),r);
639 QRectF BranchObj::getBBoxSizeWithChildren()
644 ConvexPolygon BranchObj::getBoundingPolygon()
647 if (!pi) //FIXME-3 Testing only
649 pi=scene->addPolygon(MapObj::getBoundingPolygon() );
650 pi->setPen(Qt::NoPen);
651 pi->setBrush( QColor(qrand()%32*8,qrand()%32*8,qrand()%32*8) );
652 pi->setZValue(Z_BBOX);
656 if (treeItem->branchCount()==0 || treeItem->depth()==0)
658 if (pi) pi->setPolygon (MapObj::getBoundingPolygon() );
659 return MapObj::getBoundingPolygon();
662 calcBBoxSizeWithChildren(); //FIXME-2 really needed?
664 p<<bboxTotal.topLeft();
665 p<<bboxTotal.topRight();
666 p<<bboxTotal.bottomRight();
667 p<<bboxTotal.bottomLeft();
668 //cout << "BO::getBP (total) "<<treeItem->getHeadingStd()<<" tL="<<bboxTotal.topLeft()<<" bR="<<bboxTotal.bottomRight()<<endl;
669 //cout << " "<<" tL="<<bbox.topLeft()<<" bR="<<bbox.bottomRight()<<endl;
670 if (pi) pi->setPolygon (p );
674 void BranchObj::calcBBoxSizeWithChildren()
676 // This is initially called only from reposition and
677 // and only for mapcenter. So it won't be
678 // called more than once for a single user
682 // Calculate size of LMO including all children (to align them later)
683 bboxTotal.setX(bbox.x() );
684 bboxTotal.setY(bbox.y() );
686 // if branch is scrolled, ignore children, but still consider floatimages
687 BranchItem *bi=(BranchItem*)treeItem;
688 if ( bi->isScrolled() )
690 bboxTotal.setWidth (bbox.width());
691 bboxTotal.setHeight(bbox.height());
697 bboxTotal.setWidth (0);
698 bboxTotal.setHeight(0);
701 bboxTotal.setX (parObj->x());
702 bboxTotal.setY (parObj->y());
705 bboxTotal.setX (bbox.x());
706 bboxTotal.setY (bbox.y());
713 // Now calculate recursivly
717 for (int i=0; i<treeItem->branchCount(); i++)
719 if (!bi->getBranchNum(i)->isHidden())
721 bi->getBranchObjNum(i)->calcBBoxSizeWithChildren();
722 br=bi->getBranchObjNum(i)->getBBoxSizeWithChildren();
723 r.setWidth( max (br.width(), r.width() ));
724 r.setHeight(br.height() + r.height() );
725 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
726 if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
729 // Add myself and also
730 // add width of link to sum if necessary
731 if (bi->branchCount()<1)
732 bboxTotal.setWidth (bbox.width() + r.width() );
734 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
736 bboxTotal.setHeight(max (r.height(), bbox.height()));
739 void BranchObj::setAnimation(const AnimPoint &ap)
744 bool BranchObj::animate()
747 if ( anim.isAnimated() )
752 parObj->reposition(); // we might have been relinked meanwhile