5 #include "attributeitem.h"
6 #include "branchitem.h"
9 #include "mainwindow.h"
12 extern FlagRow *standardFlagsMaster;
13 extern FlagRow *systemFlagsMaster;
16 /////////////////////////////////////////////////////////////////
18 /////////////////////////////////////////////////////////////////
20 BranchObj::BranchObj (QGraphicsItem *parent,TreeItem *ti):OrnamentedObj (parent,ti)
22 //qDebug ()<< "Const BranchObj (s,ti) ti="<<ti;
24 BranchItem *pi=(BranchItem*)(ti->parent());
25 if (pi && pi!=ti->getModel()->getRootItem() )
32 BranchObj::~BranchObj ()
34 //qDebug()<< "Destr BranchObj of "<<this;
36 // If I'm animated, I need to un-animate myself first
37 if (anim.isAnimated() )
39 anim.setAnimated (false);
40 VymModel *model=treeItem->getModel();
41 model->stopAnimation (this);
47 void BranchObj::init ()
49 if (parObj) absPos=parObj->getChildRefPos();
52 void BranchObj::copy (BranchObj* other)
54 OrnamentedObj::copy(other);
56 setVisibility (other->visible);
61 void BranchObj::clear()
65 void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off)
67 // Temporary link to dst
68 // m is position of mouse pointer
69 // offset 0: default 1: below dst -1 above dst (if possible)
71 BranchItem *dsti=(BranchItem*)(dst->getTreeItem());
73 BranchItem *pi=(BranchItem*)(dsti->parent());
74 int pi_depth=pi->depth();
75 BranchObj* bodst=(BranchObj*)dst;
83 if (pi_depth<1) off=0;
90 setLinkStyle (dst->getDefLinkStyle (dsti));
92 // Move temporary to new position at destination
93 // Usually the positioning would be done by reposition(),
94 // but then also the destination branch would "Jump" around...
95 // Better just do it approximately
97 { // new parent is a mapcenter
98 Vector v= ( m - bodst->getChildRefPos());
101 move2RelPos (v.toQPointF());
107 // Below is needed e.g. in a freshly loaded map,
108 // bboxTotal seems not to be correct yet
109 // relinking positions too far below then
110 calcBBoxSizeWithChildren();
112 // new parent is just a branch, link to it
113 bodst->calcBBoxSizeWithChildren();
114 QRectF t = bodst->getTotalBBox();
115 if (dsti->getLastBranch())
116 // Move below children of destination
117 y = t.y() + t.height() ;
119 // Move left or right to destination
124 // we want to link above dst
125 y = bodst->y() - height() + 12;
127 // we want to link below dst
128 // Bottom of sel should be 5 pixels above
129 // the bottom of the branch _below_ the target:
130 // Don't try to find that branch, guess 12 pixels
131 y = bodst->getChildRefPos().y() -height() + 12;
133 if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
134 move ( bodst->getChildRefPos().x() - linkwidth - bboxTotal.width(), y );
136 move ( bodst->getChildRefPos().x() + linkwidth, y );
139 // updateLinkGeometry is called implicitly in move
143 void BranchObj::unsetParObjTmp()
151 setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
152 updateLinkGeometry();
156 void BranchObj::setVisibility(bool v, int toDepth)
158 BranchItem *bi=(BranchItem*)treeItem;
159 if (bi->depth() <= toDepth)
161 frame->setVisibility(v);
162 heading->setVisibility(v);
163 systemFlags->setVisibility(v);
164 standardFlags->setVisibility(v);
165 LinkableMapObj::setVisibility (v);
167 for (i=0; i<treeItem->imageCount(); ++i)
168 treeItem->getImageObjNum(i)->setVisibility (v);
169 for (i=0; i<treeItem->xlinkCount(); ++i)
170 treeItem->getXLinkObjNum(i)->setVisibility ();
172 // Only change children, if I am not scrolled
173 if (! bi->isScrolled() && (bi->depth() < toDepth))
175 // Now go recursivly through all children
176 for (i=0; i<treeItem->branchCount(); ++i)
177 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
182 void BranchObj::setVisibility(bool v)
184 setVisibility (v,MAX_DEPTH);
188 void BranchObj::setLinkColor ()
190 // Overloaded from LinkableMapObj
191 // BranchObj can use color of heading
193 VymModel *model=treeItem->getModel();
196 if (model->getMapLinkColorHint()==HeadingColor)
197 LinkableMapObj::setLinkColor (heading->getColor() );
199 LinkableMapObj::setLinkColor ();
203 void BranchObj::positionContents()
205 OrnamentedObj::positionContents();
206 updateLinkGeometry();// required before positioning images
207 for (int i=0; i<treeItem->imageCount(); ++i)
208 treeItem->getImageObjNum(i)->reposition();
211 void BranchObj::move (double x, double y)
213 OrnamentedObj::move (x,y);
216 void BranchObj::move (QPointF p)
221 void BranchObj::moveBy (double x, double y)
223 OrnamentedObj::moveBy (x,y);
224 for (int i=0; i<treeItem->branchCount(); ++i)
225 treeItem->getBranchObjNum(i)->moveBy (x,y);
229 void BranchObj::moveBy (QPointF p)
231 moveBy (p.x(), p.y());
234 void BranchObj::positionBBox() // FIXME-3 consider dimensions of frame (thickness, geometry, padding...
236 QPointF ap=getAbsPos();
237 bbox.moveTopLeft (ap);
238 positionContents(); // this positions FIOs
240 //Update links to other branches
242 for (int i=0; i<treeItem->xlinkCount(); ++i)
244 xlo=treeItem->getXLinkObjNum(i);
245 if (xlo) xlo->updateXLink();
249 void BranchObj::calcBBoxSize()
251 QSizeF heading_r=heading->getSize();
252 qreal heading_w=(qreal) heading_r.width() ;
253 qreal heading_h=(qreal) heading_r.height() ;
254 QSizeF sysflags_r=systemFlags->getSize();
255 qreal sysflags_h=sysflags_r.height();
256 qreal sysflags_w=sysflags_r.width();
257 QSizeF stanflags_r=standardFlags->getSize();
258 qreal stanflags_h=stanflags_r.height();
259 qreal stanflags_w=stanflags_r.width();
263 // set width to sum of all widths
264 w=heading_w + sysflags_w + stanflags_w;
266 // set height to maximum needed height
267 h=max (sysflags_h,stanflags_h);
270 // Save the dimension of flags and heading
271 ornamentsBBox.setSize ( QSizeF(w,h));
273 // clickBox includes Flags and Heading
274 clickPoly=QPolygonF (ornamentsBBox);
279 topPad = botPad = leftPad = rightPad = 0;
280 bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
281 bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
285 for (int i=0; i<treeItem->imageCount(); ++i )
287 fio=treeItem->getImageObjNum(i);
294 y = rp.y() + fio->height()/2 - ornamentsBBox.height()/2;
295 botPad = max(botPad, y);
298 y=-rp.y() + fio->height()/2 - ornamentsBBox.height()/2;
299 topPad=max(topPad, y);
307 x=rp.x() + fio->width()/2 - ornamentsBBox.width()/2;
308 rightPad=max(rightPad, x);
311 x=-rp.x() + fio->width()/2 - ornamentsBBox.width()/2;
312 leftPad=max(leftPad, x);
316 h += topPad + botPad;
317 w += leftPad + rightPad;
321 w += frame->getTotalPadding() * 2;
322 h += frame->getTotalPadding() * 2;
325 bbox.setSize (QSizeF (w,h));
326 //if (debug) qDebug()<<"BO: calcBBox "<<treeItem->getHeading()<<" bbox="<<bbox;
329 void BranchObj::setDockPos()
331 floatRefPos=ornamentsBBox.center();
333 if (treeItem->getType() == TreeItem::MapCenter)
335 // set childRefPos to middle of MapCenterObj
336 QRectF r=clickPoly.boundingRect();
337 childRefPos.setX( r.topLeft().x() + r.width()/2 );
338 childRefPos.setY( r.topLeft().y() + r.height()/2 );
340 for (int i=0; i<treeItem->branchCount(); ++i)
341 treeItem->getBranchObjNum(i)->updateLinkGeometry();
344 if (orientation == LinkableMapObj::LeftOfCenter )
347 if ( ((BranchItem*)treeItem)->getFrameIncludeChildren() )
349 childRefPos=QPointF (ornamentsBBox.bottomLeft().x() - leftPad, bottomlineY);
350 parPos=QPointF (bboxTotal.bottomRight().x()-frame->getPadding()/2, bottomlineY);
353 childRefPos=QPointF (ornamentsBBox.bottomLeft().x() - frame->getPadding(), bottomlineY);
354 parPos=QPointF (ornamentsBBox.bottomRight().x(), bottomlineY);
359 if ( ((BranchItem*)treeItem)->getFrameIncludeChildren() )
361 childRefPos=QPointF(ornamentsBBox.bottomRight().x() + rightPad , bottomlineY);
362 parPos=QPointF ( bboxTotal.bottomLeft().x()+frame->getPadding()/2, bottomlineY);
365 childRefPos=QPointF(ornamentsBBox.bottomRight().x() + frame->getPadding(), bottomlineY);
366 parPos=QPointF ( ornamentsBBox.bottomLeft().x(), bottomlineY);
372 void BranchObj::updateData()
376 qWarning ("BranchObj::udpateHeading treeItem==NULL");
379 QString s = treeItem->getHeadingText();
380 if ( s!=heading->text()) heading->setText (s);
382 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
384 // Add missing standard flags active in TreeItem
385 for (int i=0;i<=TIactiveFlags.size()-1;i++)
387 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
389 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
390 if (f) standardFlags->activate (f);
393 // Remove standard flags no longer active in TreeItem
394 QStringList BOactiveFlags=standardFlags->activeFlagNames();
395 for (int i=0;i<BOactiveFlags.size();++i)
396 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
397 standardFlags->deactivate (BOactiveFlags.at(i));
399 // Add missing system flags active in TreeItem
400 TIactiveFlags=treeItem->activeSystemFlagNames();
401 for (int i=0;i<TIactiveFlags.size();++i)
403 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
405 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
406 if (f) systemFlags->activate (f);
409 // Remove system flags no longer active in TreeItem
410 BOactiveFlags=systemFlags->activeFlagNames();
411 for (int i=0;i<BOactiveFlags.size();++i)
413 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
414 systemFlags->deactivate (BOactiveFlags.at(i));
419 void BranchObj::setDefAttr (BranchModification mod, bool keepFrame)
421 QFont font=treeItem->getModel()->getMapDefaultFont();
422 qreal fontsize=font.pointSizeF();
423 switch (treeItem->depth())
437 setLinkStyle(getDefLinkStyle(treeItem->parent() ));
439 font.setPointSizeF (fontsize);
440 heading->setFont(font );
442 if (mod==NewBranch && !keepFrame)
444 if (treeItem->depth()==0)
445 setFrameType (FrameObj::Rectangle);
447 setFrameType (FrameObj::NoFrame);
450 setColor (treeItem->getHeadingColor() );
453 // Relinked mapcenters
454 if (!keepFrame && getFrameType()!=FrameObj::NoFrame)
455 setFrameType (FrameObj::NoFrame);
457 // Also set styles for children
458 for (int i=0; i<treeItem->branchCount(); ++i)
459 treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch, keepFrame);
464 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
466 // Define some heights
467 qreal th = bboxTotal.height();
468 qreal ch=0; // Sum of childrens heights
469 for (int i=0; i<treeItem->branchCount(); ++i)
470 ch+=treeItem->getBranchObjNum(i)->getTotalBBox().height();
473 BranchItem::LayoutHint layoutHint = BranchItem::AutoPositioning;
476 TreeItem *pi = parObj->getTreeItem();
477 depth = 1 + pi->depth();
478 layoutHint = ((BranchItem*)treeItem)->parentBranch()->getChildrenLayout();
481 // set useRelPos, depending on layout
484 if (layoutHint == BranchItem::FreePositioning)
489 // if we used relPos before, set known positions
490 // "known" means any position != (0,0)
491 if (relPos == QPointF(0,0) )
492 // use current position to get relPos()
507 case UndefinedOrientation: o = "UndefOrientation"; break;
508 case LeftOfCenter: o = "LeftOfCenter"; break;
509 case RightOfCenter: o = "RightOfCenter"; break;
512 QString h=QString (depth+1,' ');
513 h += treeItem->getHeadingPlain();
514 h += QString (25,' ');
517 if (parObj) pp = parObj->getChildRefPos();
518 qDebug() << "BO::alignRelTo for "<<h
519 // qDebug() << " d="<<depth;
520 // qDebug() <<" ref="<<ref;
521 // qDebug() <<" th="<<th;
522 // qDebug() <<" ch="<<ch;
523 // if (ch < th) qDebug()<<" ch<th !";
524 // qDebug() <<" parO="<<parObj;
525 //qDebug() << " bbox.tL="<<bboxTotal.topLeft();
526 << " useRelPos=" << useRelPos
527 << " layoutHint= " << layoutHint
528 // qDebug() <<"absPos="<<absPos
529 << " relPos="<<relPos
532 << " orient="<<o<<" "<<orientation;
533 // << " alignSelf="<<alignSelf
534 // << " scrolled="<<((BranchItem*)treeItem)->isScrolled()
535 // << " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad
536 // << " hidden="<<hidden
546 move (getAbsPos()); // Trigger update of frames etc.
548 move2RelPos (getRelPos() );
551 if (layoutHint == BranchItem::FreePositioning)
552 move2RelPos (getRelPos() );
555 if (anim.isAnimated())
562 case LinkableMapObj::LeftOfCenter:
563 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
565 case LinkableMapObj::RightOfCenter:
566 move (ref.x() , ref.y() + (th - bbox.height())/2 );
569 qWarning ("LMO::alignRelativeTo: oops, no orientation given for BO...");
576 // Without ancestors I am done
577 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
579 // Set reference point for alignment of children
581 if (orientation==LinkableMapObj::LeftOfCenter)
582 ref2.setX(childRefPos.x() - linkwidth);
584 ref2.setX(childRefPos.x() + linkwidth);
587 ref2.setY (absPos.y() + (bbox.height() - ch)/2);
591 ref2.setY (ref.y() + frame->getPadding());
593 // Parent is bigger than all of childs, center childs vertically
594 ref2.setY (ref.y() + (th - ch)/2 );
597 // Align the branch children depending on reference point
598 for (int i=0; i<treeItem->branchCount(); ++i)
600 if (!treeItem->getBranchNum(i)->isHidden())
602 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
604 // append next branch below current one
605 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getTotalBBox().height() );
610 void BranchObj::reposition()
615 if (!treeItem->getHeading().isEmpty())
616 qDebug()<< " BO::reposition a) d="<<treeItem->depth()<<" "<<treeItem->getHeading();
618 qDebug()<< " BO::reposition a) d="<<treeItem->depth()<<" ???";
622 if (treeItem->depth()==0)
623 // only calculate the sizes once. If the deepest LMO
624 // changes its height,
625 // all upper LMOs have to change, too.
626 calcBBoxSizeWithChildren();
628 alignRelativeTo ( QPointF (absPos.x(),
629 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
632 void BranchObj::unsetAllRepositionRequests()
634 repositionRequest=false;
635 for (int i=0; i<treeItem->branchCount(); ++i)
636 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
639 QRectF BranchObj::getTotalBBox()
644 ConvexPolygon BranchObj::getBoundingPolygon()
646 if (treeItem->branchCount()==0 || treeItem->depth()==0)
649 boundingPolygon->setPolygon (MapObj::getBoundingPolygon() );
650 return MapObj::getBoundingPolygon();
654 p<<bboxTotal.topLeft();
655 p<<bboxTotal.topRight();
656 p<<bboxTotal.bottomRight();
657 p<<bboxTotal.bottomLeft();
658 if (boundingPolygon) boundingPolygon->setPolygon (p );
662 void BranchObj::calcBBoxSizeWithChildren()
664 // if branch is scrolled, ignore children, but still consider floatimages
665 BranchItem *bi=(BranchItem*)treeItem;
666 if ( bi->isScrolled() )
668 bboxTotal.setWidth (bbox.width());
669 bboxTotal.setHeight(bbox.height());
675 bboxTotal.setWidth (0);
676 bboxTotal.setHeight(0);
687 for (int i=0; i<treeItem->branchCount(); i++)
689 if (!bi->getBranchNum(i)->isHidden())
691 BranchObj *bo=bi->getBranchObjNum(i);
692 bo->calcBBoxSizeWithChildren();
693 br=bo->getTotalBBox();
694 r.setWidth( max (br.width(), r.width() ));
695 r.setHeight(br.height() + r.height() );
699 // Add myself and also
700 // add width of link to sum if necessary
701 if (bi->branchCount()<1)
702 bboxTotal.setWidth (bbox.width() + r.width() );
704 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth );
706 // bbox already contains frame->padding()*2
707 bboxTotal.setHeight(max (r.height() + frame->getPadding()*2, bbox.height()) );
710 void BranchObj::setAnimation(const AnimPoint &ap)
715 void BranchObj::stopAnimation()
724 bool BranchObj::animate()
727 if ( anim.isAnimated() )