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 //qDebug()<< "Destr BranchObj of "<<this<<" ("<<treeItem->getHeading()<<")";
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?
68 void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off)
70 // Temporary link to dst
71 // m is position of mouse pointer
72 // offset 0: default 1: below dst -1 above dst (if possible)
74 BranchItem *dsti=(BranchItem*)(dst->getTreeItem());
76 BranchItem *pi=(BranchItem*)(dsti->parent());
77 int pi_depth=pi->depth();
78 BranchObj* bodst=(BranchObj*)dst;
86 if (pi_depth<2) off=0;
93 setLinkStyle (dst->getDefLinkStyle (dsti));
95 // Move temporary to new position at destination
96 // Usually the positioning would be done by reposition(),
97 // but then also the destination branch would "Jump" around...
98 // Better just do it approximately
100 { // new parent is a mapcenter
101 Vector v= ( m - bodst->getChildPos());
102 if (v.x()<0) v.setX( v.x()-bbox.width() );
105 move2RelPos (v.toQPointF());
111 // Below is needed e.g. in a freshly loaded map,
112 // bboxTotal seems not to be correct yet
113 // relinking positions too far below then
114 calcBBoxSizeWithChildren();
116 // new parent is just a branch, link to it
117 bodst->calcBBoxSizeWithChildren();
118 QRectF t=bodst->getBBoxSizeWithChildren();
119 if (dsti->getLastBranch())
120 y=t.y() + t.height() ;
129 // we want to link above dst
130 y=bodst->y() - height() + 5;
132 // we want to link below dst
133 // Bottom of sel should be 5 pixels above
134 // the bottom of the branch _below_ the target:
135 // Don't try to find that branch, guess 12 pixels
136 y=bodst->getChildPos().y() -height() + 12;
138 if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
139 move ( bodst->getChildPos().x() - linkwidth, y );
141 move (bodst->getChildPos().x() + linkwidth, y );
144 // updateLinkGeometry is called implicitly in move
148 void BranchObj::unsetParObjTmp()
156 setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
157 updateLinkGeometry();
161 void BranchObj::setVisibility(bool v, int toDepth)
163 BranchItem *bi=(BranchItem*)treeItem;
164 if (bi->depth() <= toDepth)
166 frame->setVisibility(v);
167 heading->setVisibility(v);
168 systemFlags->setVisibility(v);
169 standardFlags->setVisibility(v);
170 LinkableMapObj::setVisibility (v);
172 for (i=0; i<treeItem->imageCount(); ++i)
173 treeItem->getImageObjNum(i)->setVisibility (v);
174 for (i=0; i<treeItem->xlinkCount(); ++i)
175 treeItem->getXLinkObjNum(i)->setVisibility ();
177 // Only change children, if I am not scrolled
178 if (! bi->isScrolled() && (bi->depth() < toDepth))
180 // Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
181 for (i=0; i<treeItem->branchCount(); ++i)
182 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
184 } // depth <= toDepth
188 void BranchObj::setVisibility(bool v)
190 setVisibility (v,MAX_DEPTH);
194 void BranchObj::setLinkColor ()
196 // Overloaded from LinkableMapObj
197 // BranchObj can use color of heading
199 VymModel *model=treeItem->getModel();
202 if (model->getMapLinkColorHint()==HeadingColor)
203 LinkableMapObj::setLinkColor (heading->getColor() );
205 LinkableMapObj::setLinkColor ();
209 void BranchObj::updateContentSize()
216 void BranchObj::positionContents()
218 for (int i=0; i<treeItem->imageCount(); ++i)
219 treeItem->getImageObjNum(i)->reposition();
220 OrnamentedObj::positionContents();
223 void BranchObj::move (double x, double y)
225 OrnamentedObj::move (x,y);
229 void BranchObj::move (QPointF p)
234 void BranchObj::moveBy (double x, double y)
236 OrnamentedObj::moveBy (x,y);
237 for (int i=0; i<treeItem->branchCount(); ++i)
238 treeItem->getBranchObjNum(i)->moveBy (x,y);
242 void BranchObj::moveBy (QPointF p)
244 moveBy (p.x(), p.y());
248 void BranchObj::positionBBox()
250 QPointF ap=getAbsPos();
251 bbox.moveTopLeft (ap);
255 frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
257 //Update links to other branches
259 for (int i=0; i<treeItem->xlinkCount(); ++i)
261 xlo=treeItem->getXLinkObjNum(i);
262 if (xlo) xlo->updateXLink();
266 void BranchObj::calcBBoxSize()
268 QSizeF heading_r=heading->getSize();
269 qreal heading_w=(qreal) heading_r.width() ;
270 qreal heading_h=(qreal) heading_r.height() ;
271 QSizeF sysflags_r=systemFlags->getSize();
272 qreal sysflags_h=sysflags_r.height();
273 qreal sysflags_w=sysflags_r.width();
274 QSizeF stanflags_r=standardFlags->getSize();
275 qreal stanflags_h=stanflags_r.height();
276 qreal stanflags_w=stanflags_r.width();
280 // set width to sum of all widths
281 w=heading_w + sysflags_w + stanflags_w;
282 // set height to maximum needed height
283 h=max (sysflags_h,stanflags_h);
286 // Save the dimension of flags and heading
287 ornamentsBBox.setSize ( QSizeF(w,h));
289 // clickBox includes Flags and Heading
290 clickBox.setSize (ornamentsBBox.size() );
295 topPad=botPad=leftPad=rightPad=0;
296 bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
297 bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
301 for (int i=0; i<treeItem->imageCount(); ++i )
303 fio=treeItem->getImageObjNum(i);
308 topPad=max (topPad,-rp.y()-h);
309 if (rp.y()+fio->height() > 0)
310 botPad=max (botPad,rp.y()+fio->height());
314 if (orientation==LinkableMapObj::RightOfCenter)
317 leftPad=max (leftPad,-rp.x()-w);
318 if (rp.x()+fio->width() > 0)
319 rightPad=max (rightPad,rp.x()+fio->width());
323 leftPad=max (leftPad,-rp.x());
324 if (rp.x()+fio->width() > w)
325 rightPad=max (rightPad,rp.x()+fio->width()-w);
334 w+=frame->getPadding();
335 h+=frame->getPadding();
338 bbox.setSize (QSizeF (w,h));
341 void BranchObj::setDockPos()
343 if (treeItem->getType()==TreeItem::MapCenter)
345 // set childPos to middle of MapCenterObj
346 childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
347 childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
349 for (int i=0; i<treeItem->branchCount(); ++i)
350 treeItem->getBranchObjNum(i)->updateLinkGeometry();
354 // Sets childpos and parpos depending on orientation
355 if (getOrientation()==LinkableMapObj::LeftOfCenter )
358 ornamentsBBox.bottomLeft().x(),
361 ornamentsBBox.bottomRight().x(),
366 ornamentsBBox.bottomRight().x(),
369 ornamentsBBox.bottomLeft().x(),
375 void BranchObj::updateData()
380 qWarning ("BranchObj::udpateHeading treeItem==NULL");
383 QString s=treeItem->getHeading();
384 if (s!=heading->text())
386 heading->setText (s);
389 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
391 // Add missing standard flags active in TreeItem
392 for (int i=0;i<=TIactiveFlags.size()-1;i++)
394 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
396 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
397 if (f) standardFlags->activate (f);
401 // Remove standard flags no longer active in TreeItem
402 QStringList BOactiveFlags=standardFlags->activeFlagNames();
403 for (int i=0;i<BOactiveFlags.size();++i)
404 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
406 standardFlags->deactivate (BOactiveFlags.at(i));
410 // Add missing system flags active in TreeItem
411 TIactiveFlags=treeItem->activeSystemFlagNames();
412 for (int i=0;i<TIactiveFlags.size();++i)
414 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
416 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
417 if (f) systemFlags->activate (f);
421 // Remove system flags no longer active in TreeItem
422 BOactiveFlags=systemFlags->activeFlagNames();
423 for (int i=0;i<BOactiveFlags.size();++i)
425 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
427 systemFlags->deactivate (BOactiveFlags.at(i));
431 if (changed) updateContentSize();
434 void BranchObj::setDefAttr (BranchModification mod, bool keepFrame)
437 switch (treeItem->depth())
452 setLinkStyle(getDefLinkStyle(treeItem->parent() ));
454 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
455 font.setPointSize(fontsize);
456 heading->setFont(font );
458 if (mod==NewBranch && !keepFrame)
460 if (treeItem->depth()==0)
461 setFrameType (FrameObj::Rectangle);
463 setFrameType (FrameObj::NoFrame);
466 setColor (treeItem->getHeadingColor() );
469 // Also set styles for children
470 for (int i=0; i<treeItem->branchCount(); ++i)
471 treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch);
476 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
478 qreal th = bboxTotal.height();
480 if (parObj) depth=1 + parObj->getTreeItem()->depth();
483 QString h=QString (depth+1,' ');
484 h+=treeItem->getHeading();
488 if (parObj) pp=parObj->getChildPos();
489 cout << "BO::alignRelTo ";
490 cout<<h.toStdString();
491 cout << " d="<<depth;
492 cout <<" parO="<<parObj;
493 //cout<< " ref="<<ref<<
494 //cout << " bbox.tL="<<bboxTotal.topLeft();
495 cout<< " absPos="<<absPos<<
498 // " w="<<bbox.width()<<
499 // " h="<<bbox.height()<<
500 // " orient="<<orientation<<
501 // " alignSelf="<<alignSelf<<
502 // " scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
503 // " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
504 // " hidden="<<hidden<<
510 //updateLinkGeometry();
514 move2RelPos (getRelPos() );
518 // Align myself depending on orientation and parent, but
519 // only if I am not a mainbranch or mapcenter itself
521 if (anim.isAnimated())
526 LinkableMapObj::Orientation o;
527 o=parObj->getOrientation();
531 case LinkableMapObj::LeftOfCenter:
532 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
533 //move (ref.x() , ref.y() + (th-bbox.height())/2 );
535 case LinkableMapObj::RightOfCenter:
536 move (ref.x() , ref.y() + (th-bbox.height())/2 );
539 qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
545 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
547 // Set reference point for alignment of children
549 if (orientation==LinkableMapObj::LeftOfCenter)
550 ref2.setX(bbox.topLeft().x() - linkwidth);
552 ref2.setX(bbox.topRight().x() + linkwidth);
555 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
559 // Align the attribute children depending on reference point
560 // on top like in TreeEditor
561 for (int i=0; i<treeItem->attributeCount(); ++i)
563 if (!treeItem->getAttributeNum(i)->isHidden())
565 BranchObj *bo=(BranchObj*)(treeItem->getAttributeNum(i)->getBranchObj());
567 bo->alignRelativeTo (ref2,true);
569 // append next branch below current one
570 ref2.setY(ref2.y() + bo->getBBoxSizeWithChildren().height() );
573 // Align the branch children depending on reference point
574 for (int i=0; i<treeItem->branchCount(); ++i)
576 if (!treeItem->getBranchNum(i)->isHidden())
578 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
580 // append next branch below current one
581 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
587 void BranchObj::reposition()
590 if (!treeItem->getHeading().isEmpty())
591 cout << "BO::reposition "<<qPrintable(treeItem->getHeading())<<endl;
593 cout << "BO::reposition ???"<<endl;
594 // cout << " orient="<<orientation<<endl;
597 if (treeItem->depth()==0)
599 // only calculate the sizes once. If the deepest LMO
600 // changes its height,
601 // all upper LMOs have to change, too.
602 calcBBoxSizeWithChildren();
603 updateLinkGeometry(); // This update is needed if the scene is resized
604 // due to excessive moving of a FIO
606 alignRelativeTo ( QPointF (absPos.x(),
607 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
608 positionBBox(); // Reposition bbox and contents
611 // This is only important for moving branches:
612 // For editing a branch it isn't called...
613 alignRelativeTo ( QPointF (absPos.x(),
614 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
618 void BranchObj::unsetAllRepositionRequests()
620 repositionRequest=false;
621 for (int i=0; i<treeItem->branchCount(); ++i)
622 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
625 QRectF BranchObj::getBBoxSizeWithChildren()
630 ConvexPolygon BranchObj::getBoundingPolygon()
633 if (!pi) //FIXME-3 Testing only
635 pi=scene->addPolygon(MapObj::getBoundingPolygon() );
636 pi->setPen(Qt::NoPen);
637 pi->setBrush( QColor(qrand()%32*8,qrand()%32*8,qrand()%32*8) );
638 pi->setZValue(Z_BBOX);
642 if (treeItem->branchCount()==0 || treeItem->depth()==0)
644 if (pi) pi->setPolygon (MapObj::getBoundingPolygon() );
645 return MapObj::getBoundingPolygon();
648 calcBBoxSizeWithChildren(); //FIXME-3 really needed?
650 p<<bboxTotal.topLeft();
651 p<<bboxTotal.topRight();
652 p<<bboxTotal.bottomRight();
653 p<<bboxTotal.bottomLeft();
654 //cout << "BO::getBP (total) "<<treeItem->getHeadingStd()<<" tL="<<bboxTotal.topLeft()<<" bR="<<bboxTotal.bottomRight()<<endl;
655 //cout << " "<<" tL="<<bbox.topLeft()<<" bR="<<bbox.bottomRight()<<endl;
656 if (pi) pi->setPolygon (p );
660 void BranchObj::calcBBoxSizeWithChildren()
662 // This is initially called only from reposition and
663 // and only for mapcenter. So it won't be
664 // called more than once for a single user
668 // Calculate size of LMO including all children (to align them later)
669 bboxTotal.setX(bbox.x() );
670 bboxTotal.setY(bbox.y() );
672 // if branch is scrolled, ignore children, but still consider floatimages
673 BranchItem *bi=(BranchItem*)treeItem;
674 if ( bi->isScrolled() )
676 bboxTotal.setWidth (bbox.width());
677 bboxTotal.setHeight(bbox.height());
683 bboxTotal.setWidth (0);
684 bboxTotal.setHeight(0);
687 bboxTotal.setX (parObj->x());
688 bboxTotal.setY (parObj->y());
691 bboxTotal.setX (bbox.x());
692 bboxTotal.setY (bbox.y());
699 // Now calculate recursivly
703 for (int i=0; i<treeItem->branchCount(); i++)
705 if (!bi->getBranchNum(i)->isHidden())
707 BranchObj *bo=bi->getBranchObjNum(i);
708 bo->calcBBoxSizeWithChildren();
709 br=bo->getBBoxSizeWithChildren();
710 r.setWidth( max (br.width(), r.width() ));
711 r.setHeight(br.height() + r.height() );
712 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
713 if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
716 for (int i=0; i<treeItem->attributeCount(); i++)
718 if (!bi->getAttributeNum(i)->isHidden())
720 BranchObj *bo=bi->getAttributeNum(i)->getBranchObj();
721 bo->calcBBoxSizeWithChildren();
722 br=bo->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 void BranchObj::stopAnimation()
753 bool BranchObj::animate()
756 if ( anim.isAnimated() )
764 /*FIXME-3 reposition in BO:animate nearly never reached? needed?
765 if (((MapItem*)treeItem)->getPositionMode()==MapItem::Relative)
766 parObj->reposition(); // we might have been relinked meanwhile