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 // new parent is just a branch, link to it
112 QRectF t=bodst->getBBoxSizeWithChildren();
113 if (dsti->getLastBranch())
114 y=t.y() + t.height() ;
123 // we want to link above dst
124 y=bodst->y() - height() + 5;
126 // we want to link below dst
127 // Bottom of sel should be 5 pixels above
128 // the bottom of the branch _below_ the target:
129 // Don't try to find that branch, guess 12 pixels
130 y=bodst->getChildPos().y() -height() + 12;
132 if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
133 move ( bodst->getChildPos().x() - linkwidth, y );
135 move (bodst->getChildPos().x() + linkwidth, y );
138 // updateLinkGeometry is called implicitly in move
142 void BranchObj::unsetParObjTmp()
150 setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
151 updateLinkGeometry();
155 void BranchObj::setVisibility(bool v, int toDepth)
157 BranchItem *bi=(BranchItem*)treeItem;
158 if (bi->depth() <= toDepth)
160 frame->setVisibility(v);
161 heading->setVisibility(v);
162 systemFlags->setVisibility(v);
163 standardFlags->setVisibility(v);
164 LinkableMapObj::setVisibility (v);
166 for (i=0; i<treeItem->imageCount(); ++i)
167 treeItem->getImageObjNum(i)->setVisibility (v);
168 for (i=0; i<treeItem->xlinkCount(); ++i)
169 treeItem->getXLinkObjNum(i)->setVisibility ();
171 // Only change children, if I am not scrolled
172 if (! bi->isScrolled() && (bi->depth() < toDepth))
174 // Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
175 for (i=0; i<treeItem->branchCount(); ++i)
176 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
178 } // depth <= 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::updateContentSize()
210 void BranchObj::positionContents()
212 for (int i=0; i<treeItem->imageCount(); ++i)
213 treeItem->getImageObjNum(i)->reposition();
214 OrnamentedObj::positionContents();
217 void BranchObj::move (double x, double y)
219 OrnamentedObj::move (x,y);
223 void BranchObj::move (QPointF p)
228 void BranchObj::moveBy (double x, double y)
230 OrnamentedObj::moveBy (x,y);
231 for (int i=0; i<treeItem->branchCount(); ++i)
232 treeItem->getBranchObjNum(i)->moveBy (x,y);
236 void BranchObj::moveBy (QPointF p)
238 moveBy (p.x(), p.y());
242 void BranchObj::positionBBox()
244 QPointF ap=getAbsPos();
245 bbox.moveTopLeft (ap);
249 frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
251 //Update links to other branches
253 for (int i=0; i<treeItem->xlinkCount(); ++i)
255 xlo=treeItem->getXLinkObjNum(i);
256 if (xlo) xlo->updateXLink();
260 void BranchObj::calcBBoxSize()
262 QSizeF heading_r=heading->getSize();
263 qreal heading_w=(qreal) heading_r.width() ;
264 qreal heading_h=(qreal) heading_r.height() ;
265 QSizeF sysflags_r=systemFlags->getSize();
266 qreal sysflags_h=sysflags_r.height();
267 qreal sysflags_w=sysflags_r.width();
268 QSizeF stanflags_r=standardFlags->getSize();
269 qreal stanflags_h=stanflags_r.height();
270 qreal stanflags_w=stanflags_r.width();
274 // set width to sum of all widths
275 w=heading_w + sysflags_w + stanflags_w;
276 // set height to maximum needed height
277 h=max (sysflags_h,stanflags_h);
280 // Save the dimension of flags and heading
281 ornamentsBBox.setSize ( QSizeF(w,h));
283 // clickBox includes Flags and Heading
284 clickBox.setSize (ornamentsBBox.size() );
289 topPad=botPad=leftPad=rightPad=0;
290 bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
291 bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
295 for (int i=0; i<treeItem->imageCount(); ++i )
297 fio=treeItem->getImageObjNum(i);
302 topPad=max (topPad,-rp.y()-h);
303 if (rp.y()+fio->height() > 0)
304 botPad=max (botPad,rp.y()+fio->height());
308 if (orientation==LinkableMapObj::RightOfCenter)
311 leftPad=max (leftPad,-rp.x()-w);
312 if (rp.x()+fio->width() > 0)
313 rightPad=max (rightPad,rp.x()+fio->width());
317 leftPad=max (leftPad,-rp.x());
318 if (rp.x()+fio->width() > w)
319 rightPad=max (rightPad,rp.x()+fio->width()-w);
328 w+=frame->getPadding();
329 h+=frame->getPadding();
332 bbox.setSize (QSizeF (w,h));
335 void BranchObj::setDockPos()
337 if (treeItem->getType()==TreeItem::MapCenter)
339 // set childPos to middle of MapCenterObj
340 childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
341 childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
343 for (int i=0; i<treeItem->branchCount(); ++i)
344 treeItem->getBranchObjNum(i)->updateLinkGeometry();
348 // Sets childpos and parpos depending on orientation
349 if (getOrientation()==LinkableMapObj::LeftOfCenter )
352 ornamentsBBox.bottomLeft().x(),
355 ornamentsBBox.bottomRight().x(),
360 ornamentsBBox.bottomRight().x(),
363 ornamentsBBox.bottomLeft().x(),
369 void BranchObj::updateData()
374 qWarning ("BranchObj::udpateHeading treeItem==NULL");
377 QString s=treeItem->getHeading();
378 if (s!=heading->text())
380 heading->setText (s);
383 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
385 // Add missing standard flags active in TreeItem
386 for (int i=0;i<=TIactiveFlags.size()-1;i++)
388 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
390 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
391 if (f) standardFlags->activate (f);
395 // Remove standard flags no longer active in TreeItem
396 QStringList BOactiveFlags=standardFlags->activeFlagNames();
397 for (int i=0;i<BOactiveFlags.size();++i)
398 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
400 standardFlags->deactivate (BOactiveFlags.at(i));
404 // Add missing system flags active in TreeItem
405 TIactiveFlags=treeItem->activeSystemFlagNames();
406 for (int i=0;i<TIactiveFlags.size();++i)
408 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
410 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
411 if (f) systemFlags->activate (f);
415 // Remove system flags no longer active in TreeItem
416 BOactiveFlags=systemFlags->activeFlagNames();
417 for (int i=0;i<BOactiveFlags.size();++i)
419 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
421 systemFlags->deactivate (BOactiveFlags.at(i));
425 if (changed) updateContentSize();
428 void BranchObj::setDefAttr (BranchModification mod, bool keepFrame)
431 switch (treeItem->depth())
446 setLinkStyle(getDefLinkStyle(treeItem->parent() ));
448 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
449 font.setPointSize(fontsize);
450 heading->setFont(font );
452 if (mod==NewBranch && !keepFrame)
454 if (treeItem->depth()==0)
455 setFrameType (FrameObj::Rectangle);
457 setFrameType (FrameObj::NoFrame);
460 setColor (treeItem->getHeadingColor() );
463 // Also set styles for children
464 for (int i=0; i<treeItem->branchCount(); ++i)
465 treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch);
470 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
472 qreal th = bboxTotal.height();
474 if (parObj) depth=1 + parObj->getTreeItem()->depth();
477 QString h=QString (depth+1,' ');
478 h+=treeItem->getHeading();
482 if (parObj) pp=parObj->getChildPos();
483 cout << "BO::alignRelTo ";
484 cout<<h.toStdString();
485 cout << " d="<<depth;
486 cout <<" parO="<<parObj;
487 //cout<< " ref="<<ref<<
488 //cout << " bbox.tL="<<bboxTotal.topLeft();
489 cout<< " absPos="<<absPos<<
492 // " w="<<bbox.width()<<
493 // " h="<<bbox.height()<<
494 // " orient="<<orientation<<
495 // " alignSelf="<<alignSelf<<
496 // " scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
497 // " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
498 // " hidden="<<hidden<<
504 //updateLinkGeometry();
508 move2RelPos (getRelPos() );
512 // Align myself depending on orientation and parent, but
513 // only if I am not a mainbranch or mapcenter itself
515 if (anim.isAnimated())
520 LinkableMapObj::Orientation o;
521 o=parObj->getOrientation();
525 case LinkableMapObj::LeftOfCenter:
526 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
527 //move (ref.x() , ref.y() + (th-bbox.height())/2 );
529 case LinkableMapObj::RightOfCenter:
530 move (ref.x() , ref.y() + (th-bbox.height())/2 );
533 qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
539 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
541 // Set reference point for alignment of children
543 if (orientation==LinkableMapObj::LeftOfCenter)
544 ref2.setX(bbox.topLeft().x() - linkwidth);
546 ref2.setX(bbox.topRight().x() + linkwidth);
549 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
553 // Align the attribute children depending on reference point
554 // on top like in TreeEditor
555 for (int i=0; i<treeItem->attributeCount(); ++i)
557 if (!treeItem->getAttributeNum(i)->isHidden())
559 BranchObj *bo=(BranchObj*)(treeItem->getAttributeNum(i)->getBranchObj());
561 bo->alignRelativeTo (ref2,true);
563 // append next branch below current one
564 ref2.setY(ref2.y() + bo->getBBoxSizeWithChildren().height() );
567 // Align the branch children depending on reference point
568 for (int i=0; i<treeItem->branchCount(); ++i)
570 if (!treeItem->getBranchNum(i)->isHidden())
572 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
574 // append next branch below current one
575 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
581 void BranchObj::reposition()
584 if (!treeItem->getHeading().isEmpty())
585 cout << "BO::reposition "<<qPrintable(treeItem->getHeading())<<endl;
587 cout << "BO::reposition ???"<<endl;
588 // cout << " orient="<<orientation<<endl;
591 if (treeItem->depth()==0)
593 // only calculate the sizes once. If the deepest LMO
594 // changes its height,
595 // all upper LMOs have to change, too.
596 calcBBoxSizeWithChildren();
597 updateLinkGeometry(); // This update is needed if the scene is resized
598 // due to excessive moving of a FIO
600 alignRelativeTo ( QPointF (absPos.x(),
601 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
602 positionBBox(); // Reposition bbox and contents
605 // This is only important for moving branches:
606 // For editing a branch it isn't called...
607 alignRelativeTo ( QPointF (absPos.x(),
608 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
612 void BranchObj::unsetAllRepositionRequests()
614 repositionRequest=false;
615 for (int i=0; i<treeItem->branchCount(); ++i)
616 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
619 QRectF BranchObj::getBBoxSizeWithChildren()
624 ConvexPolygon BranchObj::getBoundingPolygon()
627 if (!pi) //FIXME-3 Testing only
629 pi=scene->addPolygon(MapObj::getBoundingPolygon() );
630 pi->setPen(Qt::NoPen);
631 pi->setBrush( QColor(qrand()%32*8,qrand()%32*8,qrand()%32*8) );
632 pi->setZValue(Z_BBOX);
636 if (treeItem->branchCount()==0 || treeItem->depth()==0)
638 if (pi) pi->setPolygon (MapObj::getBoundingPolygon() );
639 return MapObj::getBoundingPolygon();
642 calcBBoxSizeWithChildren(); //FIXME-3 really needed?
644 p<<bboxTotal.topLeft();
645 p<<bboxTotal.topRight();
646 p<<bboxTotal.bottomRight();
647 p<<bboxTotal.bottomLeft();
648 //cout << "BO::getBP (total) "<<treeItem->getHeadingStd()<<" tL="<<bboxTotal.topLeft()<<" bR="<<bboxTotal.bottomRight()<<endl;
649 //cout << " "<<" tL="<<bbox.topLeft()<<" bR="<<bbox.bottomRight()<<endl;
650 if (pi) pi->setPolygon (p );
654 void BranchObj::calcBBoxSizeWithChildren()
656 // This is initially called only from reposition and
657 // and only for mapcenter. So it won't be
658 // called more than once for a single user
662 // Calculate size of LMO including all children (to align them later)
663 bboxTotal.setX(bbox.x() );
664 bboxTotal.setY(bbox.y() );
666 // if branch is scrolled, ignore children, but still consider floatimages
667 BranchItem *bi=(BranchItem*)treeItem;
668 if ( bi->isScrolled() )
670 bboxTotal.setWidth (bbox.width());
671 bboxTotal.setHeight(bbox.height());
677 bboxTotal.setWidth (0);
678 bboxTotal.setHeight(0);
681 bboxTotal.setX (parObj->x());
682 bboxTotal.setY (parObj->y());
685 bboxTotal.setX (bbox.x());
686 bboxTotal.setY (bbox.y());
693 // Now calculate recursivly
697 for (int i=0; i<treeItem->branchCount(); i++)
699 if (!bi->getBranchNum(i)->isHidden())
701 BranchObj *bo=bi->getBranchObjNum(i);
702 bo->calcBBoxSizeWithChildren();
703 br=bo->getBBoxSizeWithChildren();
704 r.setWidth( max (br.width(), r.width() ));
705 r.setHeight(br.height() + r.height() );
706 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
707 if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
710 for (int i=0; i<treeItem->attributeCount(); i++)
712 if (!bi->getAttributeNum(i)->isHidden())
714 BranchObj *bo=bi->getAttributeNum(i)->getBranchObj();
715 bo->calcBBoxSizeWithChildren();
716 br=bo->getBBoxSizeWithChildren();
717 r.setWidth( max (br.width(), r.width() ));
718 r.setHeight(br.height() + r.height() );
719 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
720 if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
723 // Add myself and also
724 // add width of link to sum if necessary
725 if (bi->branchCount()<1)
726 bboxTotal.setWidth (bbox.width() + r.width() );
728 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
730 bboxTotal.setHeight(max (r.height(), bbox.height()));
733 void BranchObj::setAnimation(const AnimPoint &ap)
738 void BranchObj::stopAnimation()
747 bool BranchObj::animate()
750 if ( anim.isAnimated() )
758 /*FIXME-3 reposition in BO:animate nearly never reached? needed?
759 if (((MapItem*)treeItem)->getPositionMode()==MapItem::Relative)
760 parObj->reposition(); // we might have been relinked meanwhile