3 #include "attributeitem.h"
4 #include "branchitem.h"
7 #include "mainwindow.h"
10 extern FlagRow *standardFlagsMaster;
11 extern FlagRow *systemFlagsMaster;
13 /////////////////////////////////////////////////////////////////
15 /////////////////////////////////////////////////////////////////
17 BranchObj::BranchObj (QGraphicsScene* s,TreeItem *ti):OrnamentedObj (s)
19 // cout << "Const BranchObj (s) \n";
22 BranchItem *pi=(BranchItem*)(ti->parent());
23 if (pi && pi!=ti->getModel()->getRootItem() )
30 BranchObj::~BranchObj ()
32 // cout << "Destr BranchObj of "<<this<<" ("<<treeItem->getHeading().toStdString()<<")"<<endl;
34 // If I'm animated, I need to un-animate myself first
35 if (anim.isAnimated() )
37 anim.setAnimated (false);
38 VymModel *model=treeItem->getModel();
39 model->stopAnimation (this);
45 void BranchObj::init ()
50 absPos+=parObj->getChildPos();
54 void BranchObj::copy (BranchObj* other)
56 OrnamentedObj::copy(other);
58 setVisibility (other->visible);
63 void BranchObj::clear()
65 //setVisibility (true); //FIXME-4 needed?
67 while (!xlink.isEmpty())
68 delete xlink.takeFirst();
71 void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off)
73 // Temporary link to dst
74 // m is position of mouse pointer
75 // offset 0: default 1: below dst -1 above dst (if possible)
77 BranchItem *dsti=(BranchItem*)(dst->getTreeItem());
79 BranchItem *pi=(BranchItem*)(dsti->parent());
80 int pi_depth=pi->depth();
81 BranchObj* bodst=(BranchObj*)dst;
89 if (pi_depth<2) off=0;
96 setLinkStyle (dst->getDefLinkStyle (dsti));
98 // Move temporary to new position at destination
99 // Usually the positioning would be done by reposition(),
100 // but then also the destination branch would "Jump" around...
101 // Better just do it approximately
102 if (dsti->depth()==0)
103 { // new parent is a mapcenter
104 Vector v= ( m - bodst->getChildPos());
105 if (v.x()<0) v.setX( v.x()-bbox.width() );
108 move2RelPos (v.toQPointF());
114 // new parent is just a branch, link to it
115 QRectF t=bodst->getBBoxSizeWithChildren();
116 if (dsti->getLastBranch())
117 y=t.y() + t.height() ;
126 // we want to link above dst
127 y=bodst->y() - height() + 5;
129 // we want to link below dst
130 // Bottom of sel should be 5 pixels above
131 // the bottom of the branch _below_ the target:
132 // Don't try to find that branch, guess 12 pixels
133 y=bodst->getChildPos().y() -height() + 12;
135 if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
136 move ( bodst->getChildPos().x() - linkwidth, y );
138 move (bodst->getChildPos().x() + linkwidth, y );
141 // updateLinkGeometry is called implicitly in move
145 void BranchObj::unsetParObjTmp()
153 setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
154 updateLinkGeometry();
158 void BranchObj::setVisibility(bool v, int toDepth)
160 BranchItem *bi=(BranchItem*)treeItem;
161 if (bi->depth() <= toDepth)
163 frame->setVisibility(v);
164 heading->setVisibility(v);
165 systemFlags->setVisibility(v);
166 standardFlags->setVisibility(v);
167 LinkableMapObj::setVisibility (v);
169 for (i=0; i<treeItem->imageCount(); ++i)
170 treeItem->getImageObjNum(i)->setVisibility (v);
171 for (i=0; i<treeItem->xlinkCount(); ++i)
172 treeItem->getXLinkObjNum(i)->setVisibility ();
174 // Only change children, if I am not scrolled
175 if (! bi->isScrolled() && (bi->depth() < toDepth))
177 // Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
178 for (i=0; i<treeItem->branchCount(); ++i)
179 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
181 } // depth <= toDepth
185 void BranchObj::setVisibility(bool v)
187 setVisibility (v,MAX_DEPTH);
191 void BranchObj::setLinkColor ()
193 // Overloaded from LinkableMapObj
194 // BranchObj can use color of heading
196 VymModel *model=treeItem->getModel();
199 if (model->getMapLinkColorHint()==HeadingColor)
200 LinkableMapObj::setLinkColor (heading->getColor() );
202 LinkableMapObj::setLinkColor ();
206 void BranchObj::updateContentSize()
213 void BranchObj::positionContents()
215 for (int i=0; i<treeItem->imageCount(); ++i)
216 treeItem->getImageObjNum(i)->reposition();
217 OrnamentedObj::positionContents();
220 void BranchObj::move (double x, double y)
222 OrnamentedObj::move (x,y);
226 void BranchObj::move (QPointF p)
231 void BranchObj::moveBy (double x, double y)
233 OrnamentedObj::moveBy (x,y);
234 for (int i=0; i<treeItem->branchCount(); ++i)
235 treeItem->getBranchObjNum(i)->moveBy (x,y);
239 void BranchObj::moveBy (QPointF p)
241 moveBy (p.x(), p.y());
245 void BranchObj::positionBBox()
247 QPointF ap=getAbsPos();
248 bbox.moveTopLeft (ap);
252 frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
254 //Update links to other branches
256 for (int i=0; i<treeItem->xlinkCount(); ++i)
258 xlo=treeItem->getXLinkObjNum(i);
259 if (xlo) xlo->updateXLink();
263 void BranchObj::calcBBoxSize()
265 QSizeF heading_r=heading->getSize();
266 qreal heading_w=(qreal) heading_r.width() ;
267 qreal heading_h=(qreal) heading_r.height() ;
268 QSizeF sysflags_r=systemFlags->getSize();
269 qreal sysflags_h=sysflags_r.height();
270 qreal sysflags_w=sysflags_r.width();
271 QSizeF stanflags_r=standardFlags->getSize();
272 qreal stanflags_h=stanflags_r.height();
273 qreal stanflags_w=stanflags_r.width();
277 // set width to sum of all widths
278 w=heading_w + sysflags_w + stanflags_w;
279 // set height to maximum needed height
280 h=max (sysflags_h,stanflags_h);
283 // Save the dimension of flags and heading
284 ornamentsBBox.setSize ( QSizeF(w,h));
286 // clickBox includes Flags and Heading
287 clickBox.setSize (ornamentsBBox.size() );
292 topPad=botPad=leftPad=rightPad=0;
293 bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
294 bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
298 for (int i=0; i<treeItem->imageCount(); ++i )
300 fio=treeItem->getImageObjNum(i);
305 topPad=max (topPad,-rp.y()-h);
306 if (rp.y()+fio->height() > 0)
307 botPad=max (botPad,rp.y()+fio->height());
311 if (orientation==LinkableMapObj::RightOfCenter)
314 leftPad=max (leftPad,-rp.x()-w);
315 if (rp.x()+fio->width() > 0)
316 rightPad=max (rightPad,rp.x()+fio->width());
320 leftPad=max (leftPad,-rp.x());
321 if (rp.x()+fio->width() > w)
322 rightPad=max (rightPad,rp.x()+fio->width()-w);
331 w+=frame->getPadding();
332 h+=frame->getPadding();
335 bbox.setSize (QSizeF (w,h));
338 void BranchObj::setDockPos()
340 if (treeItem->getType()==TreeItem::MapCenter)
342 // set childPos to middle of MapCenterObj
343 childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
344 childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
346 for (int i=0; i<treeItem->branchCount(); ++i)
347 treeItem->getBranchObjNum(i)->updateLinkGeometry();
351 // Sets childpos and parpos depending on orientation
352 if (getOrientation()==LinkableMapObj::LeftOfCenter )
355 ornamentsBBox.bottomLeft().x(),
358 ornamentsBBox.bottomRight().x(),
363 ornamentsBBox.bottomRight().x(),
366 ornamentsBBox.bottomLeft().x(),
372 void BranchObj::updateData()
377 qWarning ("BranchObj::udpateHeading treeItem==NULL");
380 QString s=treeItem->getHeading();
381 if (s!=heading->text())
383 heading->setText (s);
386 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
388 // Add missing standard flags active in TreeItem
389 for (int i=0;i<=TIactiveFlags.size()-1;i++)
391 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
393 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
394 if (f) standardFlags->activate (f);
398 // Remove standard flags no longer active in TreeItem
399 QStringList BOactiveFlags=standardFlags->activeFlagNames();
400 for (int i=0;i<BOactiveFlags.size();++i)
401 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
403 standardFlags->deactivate (BOactiveFlags.at(i));
407 // Add missing system flags active in TreeItem
408 TIactiveFlags=treeItem->activeSystemFlagNames();
409 for (int i=0;i<TIactiveFlags.size();++i)
411 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
413 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
414 if (f) systemFlags->activate (f);
418 // Remove system flags no longer active in TreeItem
419 BOactiveFlags=systemFlags->activeFlagNames();
420 for (int i=0;i<BOactiveFlags.size();++i)
422 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
424 systemFlags->deactivate (BOactiveFlags.at(i));
428 if (changed) updateContentSize();
431 void BranchObj::setDefAttr (BranchModification mod, bool keepFrame)
434 switch (treeItem->depth())
449 setLinkStyle(getDefLinkStyle(treeItem->parent() ));
451 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
452 font.setPointSize(fontsize);
453 heading->setFont(font );
455 if (mod==NewBranch && !keepFrame)
457 if (treeItem->depth()==0)
458 setFrameType (FrameObj::Rectangle);
460 setFrameType (FrameObj::NoFrame);
463 setColor (treeItem->getHeadingColor() );
466 // Also set styles for children
467 for (int i=0; i<treeItem->branchCount(); ++i)
468 treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch);
473 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
475 qreal th = bboxTotal.height();
477 if (parObj) depth=1 + parObj->getTreeItem()->depth();
480 QString h=QString (depth+1,' ');
481 h+=treeItem->getHeading();
485 if (parObj) pp=parObj->getChildPos();
486 cout << "BO::alignRelTo ";
487 cout<<h.toStdString();
488 cout << " d="<<depth;
489 cout <<" parO="<<parObj;
490 //cout<< " ref="<<ref<<
491 //cout << " bbox.tL="<<bboxTotal.topLeft();
492 cout<< " absPos="<<absPos<<
495 // " w="<<bbox.width()<<
496 // " h="<<bbox.height()<<
497 // " orient="<<orientation<<
498 // " alignSelf="<<alignSelf<<
499 // " scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
500 // " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
501 // " hidden="<<hidden<<
507 //updateLinkGeometry();
511 move2RelPos (getRelPos() );
515 // Align myself depending on orientation and parent, but
516 // only if I am not a mainbranch or mapcenter itself
518 if (anim.isAnimated())
523 LinkableMapObj::Orientation o;
524 o=parObj->getOrientation();
528 case LinkableMapObj::LeftOfCenter:
529 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
530 //move (ref.x() , ref.y() + (th-bbox.height())/2 );
532 case LinkableMapObj::RightOfCenter:
533 move (ref.x() , ref.y() + (th-bbox.height())/2 );
536 qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
542 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
544 // Set reference point for alignment of children
546 if (orientation==LinkableMapObj::LeftOfCenter)
547 ref2.setX(bbox.topLeft().x() - linkwidth);
549 ref2.setX(bbox.topRight().x() + linkwidth);
552 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
556 // Align the attribute children depending on reference point
557 // on top like in TreeEditor
558 for (int i=0; i<treeItem->attributeCount(); ++i)
560 if (!treeItem->getAttributeNum(i)->isHidden())
562 BranchObj *bo=(BranchObj*)(treeItem->getAttributeNum(i)->getBranchObj());
564 bo->alignRelativeTo (ref2,true);
566 // append next branch below current one
567 ref2.setY(ref2.y() + bo->getBBoxSizeWithChildren().height() );
570 // Align the branch children depending on reference point
571 for (int i=0; i<treeItem->branchCount(); ++i)
573 if (!treeItem->getBranchNum(i)->isHidden())
575 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
577 // append next branch below current one
578 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
584 void BranchObj::reposition()
587 if (!treeItem->getHeading().isEmpty())
588 cout << "BO::reposition "<<qPrintable(treeItem->getHeading())<<endl;
590 cout << "BO::reposition ???"<<endl;
591 // cout << " orient="<<orientation<<endl;
594 if (treeItem->depth()==0)
596 // only calculate the sizes once. If the deepest LMO
597 // changes its height,
598 // all upper LMOs have to change, too.
599 calcBBoxSizeWithChildren();
600 updateLinkGeometry(); // This update is needed if the scene is resized
601 // due to excessive moving of a FIO
603 alignRelativeTo ( QPointF (absPos.x(),
604 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
605 positionBBox(); // Reposition bbox and contents
608 // This is only important for moving branches:
609 // For editing a branch it isn't called...
610 alignRelativeTo ( QPointF (absPos.x(),
611 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
615 void BranchObj::unsetAllRepositionRequests()
617 repositionRequest=false;
618 for (int i=0; i<treeItem->branchCount(); ++i)
619 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
622 QRectF BranchObj::getBBoxSizeWithChildren()
627 ConvexPolygon BranchObj::getBoundingPolygon()
630 if (!pi) //FIXME-3 Testing only
632 pi=scene->addPolygon(MapObj::getBoundingPolygon() );
633 pi->setPen(Qt::NoPen);
634 pi->setBrush( QColor(qrand()%32*8,qrand()%32*8,qrand()%32*8) );
635 pi->setZValue(Z_BBOX);
639 if (treeItem->branchCount()==0 || treeItem->depth()==0)
641 if (pi) pi->setPolygon (MapObj::getBoundingPolygon() );
642 return MapObj::getBoundingPolygon();
645 calcBBoxSizeWithChildren(); //FIXME-3 really needed?
647 p<<bboxTotal.topLeft();
648 p<<bboxTotal.topRight();
649 p<<bboxTotal.bottomRight();
650 p<<bboxTotal.bottomLeft();
651 //cout << "BO::getBP (total) "<<treeItem->getHeadingStd()<<" tL="<<bboxTotal.topLeft()<<" bR="<<bboxTotal.bottomRight()<<endl;
652 //cout << " "<<" tL="<<bbox.topLeft()<<" bR="<<bbox.bottomRight()<<endl;
653 if (pi) pi->setPolygon (p );
657 void BranchObj::calcBBoxSizeWithChildren()
659 // This is initially called only from reposition and
660 // and only for mapcenter. So it won't be
661 // called more than once for a single user
665 // Calculate size of LMO including all children (to align them later)
666 bboxTotal.setX(bbox.x() );
667 bboxTotal.setY(bbox.y() );
669 // if branch is scrolled, ignore children, but still consider floatimages
670 BranchItem *bi=(BranchItem*)treeItem;
671 if ( bi->isScrolled() )
673 bboxTotal.setWidth (bbox.width());
674 bboxTotal.setHeight(bbox.height());
680 bboxTotal.setWidth (0);
681 bboxTotal.setHeight(0);
684 bboxTotal.setX (parObj->x());
685 bboxTotal.setY (parObj->y());
688 bboxTotal.setX (bbox.x());
689 bboxTotal.setY (bbox.y());
696 // Now calculate recursivly
700 for (int i=0; i<treeItem->branchCount(); i++)
702 if (!bi->getBranchNum(i)->isHidden())
704 BranchObj *bo=bi->getBranchObjNum(i);
705 bo->calcBBoxSizeWithChildren();
706 br=bo->getBBoxSizeWithChildren();
707 r.setWidth( max (br.width(), r.width() ));
708 r.setHeight(br.height() + r.height() );
709 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
710 if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
713 for (int i=0; i<treeItem->attributeCount(); i++)
715 if (!bi->getAttributeNum(i)->isHidden())
717 BranchObj *bo=bi->getAttributeNum(i)->getBranchObj();
718 bo->calcBBoxSizeWithChildren();
719 br=bo->getBBoxSizeWithChildren();
720 r.setWidth( max (br.width(), r.width() ));
721 r.setHeight(br.height() + r.height() );
722 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
723 if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
726 // Add myself and also
727 // add width of link to sum if necessary
728 if (bi->branchCount()<1)
729 bboxTotal.setWidth (bbox.width() + r.width() );
731 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
733 bboxTotal.setHeight(max (r.height(), bbox.height()));
736 void BranchObj::setAnimation(const AnimPoint &ap)
741 bool BranchObj::animate()
744 if ( anim.isAnimated() )
749 parObj->reposition(); // we might have been relinked meanwhile