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);
42 // Check, if this branch was the last child to be deleted
43 // If so, unset the scrolled flags in parent // FIXME-2 better do this in model?
46 BranchObj *po=(BranchObj*)parObj;
50 bo=((BranchObj*)parObj)->getLastBranch();
51 if (bo) po->unScroll();
57 void BranchObj::init ()
62 absPos+=parObj->getChildPos();
66 void BranchObj::copy (BranchObj* other)
68 OrnamentedObj::copy(other);
70 setVisibility (other->visible);
75 void BranchObj::clear()
77 //setVisibility (true); //FIXME-4 needed?
79 while (!xlink.isEmpty())
80 delete xlink.takeFirst();
83 void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off)
85 // Temporary link to dst
86 // m is position of mouse pointer
87 // offset 0: default 1: below dst -1 above dst (if possible)
89 BranchItem *dsti=(BranchItem*)(dst->getTreeItem());
91 BranchItem *pi=(BranchItem*)(dsti->parent());
92 int pi_depth=pi->depth();
93 BranchObj* bodst=(BranchObj*)dst;
101 if (pi_depth<2) off=0;
108 setLinkStyle (dst->getDefLinkStyle (dsti));
110 // Move temporary to new position at destination
111 // Usually the positioning would be done by reposition(),
112 // but then also the destination branch would "Jump" around...
113 // Better just do it approximately
114 if (dsti->depth()==0)
115 { // new parent is a mapcenter
116 Vector v= ( m - bodst->getChildPos());
117 if (v.x()<0) v.setX( v.x()-bbox.width() );
120 move2RelPos (v.toQPointF());
126 // new parent is just a branch, link to it
127 QRectF t=bodst->getBBoxSizeWithChildren();
128 if (dsti->getLastBranch())
129 y=t.y() + t.height() ;
138 // we want to link above dst
139 y=bodst->y() - height() + 5;
141 // we want to link below dst
142 // Bottom of sel should be 5 pixels above
143 // the bottom of the branch _below_ the target:
144 // Don't try to find that branch, guess 12 pixels
145 y=bodst->getChildPos().y() -height() + 12;
147 if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
148 move ( bodst->getChildPos().x() - linkwidth, y );
150 move (bodst->getChildPos().x() + linkwidth, y );
153 // updateLinkGeometry is called implicitly in move
157 void BranchObj::unsetParObjTmp()
165 setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
166 updateLinkGeometry();
170 void BranchObj::setVisibility(bool v, int toDepth)
172 BranchItem *bi=(BranchItem*)treeItem;
173 if (bi->depth() <= toDepth)
175 frame->setVisibility(v);
176 heading->setVisibility(v);
177 systemFlags->setVisibility(v);
178 standardFlags->setVisibility(v);
179 LinkableMapObj::setVisibility (v);
181 for (i=0; i<treeItem->imageCount(); ++i)
182 treeItem->getImageObjNum(i)->setVisibility (v);
183 for (i=0; i<treeItem->xlinkCount(); ++i)
184 treeItem->getXLinkObjNum(i)->setVisibility ();
186 // Only change children, if I am not scrolled
187 if (! bi->isScrolled() && (bi->depth() < toDepth))
189 // Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
190 for (i=0; i<treeItem->branchCount(); ++i)
191 treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
193 } // depth <= toDepth
197 void BranchObj::setVisibility(bool v)
199 setVisibility (v,MAX_DEPTH);
203 void BranchObj::setLinkColor ()
205 // Overloaded from LinkableMapObj
206 // BranchObj can use color of heading
208 VymModel *model=treeItem->getModel();
211 if (model->getMapLinkColorHint()==HeadingColor)
212 LinkableMapObj::setLinkColor (heading->getColor() );
214 LinkableMapObj::setLinkColor ();
218 void BranchObj::updateContentSize()
225 void BranchObj::positionContents()
227 for (int i=0; i<treeItem->imageCount(); ++i)
228 treeItem->getImageObjNum(i)->reposition();
229 OrnamentedObj::positionContents();
232 void BranchObj::move (double x, double y)
234 OrnamentedObj::move (x,y);
238 void BranchObj::move (QPointF p)
243 void BranchObj::moveBy (double x, double y)
245 OrnamentedObj::moveBy (x,y);
246 for (int i=0; i<treeItem->branchCount(); ++i)
247 treeItem->getBranchObjNum(i)->moveBy (x,y);
251 void BranchObj::moveBy (QPointF p)
253 moveBy (p.x(), p.y());
257 void BranchObj::positionBBox()
259 QPointF ap=getAbsPos();
260 bbox.moveTopLeft (ap);
264 frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
266 //Update links to other branches
268 for (int i=0; i<treeItem->xlinkCount(); ++i)
270 xlo=treeItem->getXLinkObjNum(i);
271 if (xlo) xlo->updateXLink();
275 void BranchObj::calcBBoxSize()
277 QSizeF heading_r=heading->getSize();
278 qreal heading_w=(qreal) heading_r.width() ;
279 qreal heading_h=(qreal) heading_r.height() ;
280 QSizeF sysflags_r=systemFlags->getSize();
281 qreal sysflags_h=sysflags_r.height();
282 qreal sysflags_w=sysflags_r.width();
283 QSizeF stanflags_r=standardFlags->getSize();
284 qreal stanflags_h=stanflags_r.height();
285 qreal stanflags_w=stanflags_r.width();
289 // set width to sum of all widths
290 w=heading_w + sysflags_w + stanflags_w;
291 // set height to maximum needed height
292 h=max (sysflags_h,stanflags_h);
295 // Save the dimension of flags and heading
296 ornamentsBBox.setSize ( QSizeF(w,h));
298 // clickBox includes Flags and Heading
299 clickBox.setSize (ornamentsBBox.size() );
304 topPad=botPad=leftPad=rightPad=0;
305 bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
306 bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
310 for (int i=0; i<treeItem->imageCount(); ++i )
312 fio=treeItem->getImageObjNum(i);
317 topPad=max (topPad,-rp.y()-h);
318 if (rp.y()+fio->height() > 0)
319 botPad=max (botPad,rp.y()+fio->height());
323 if (orientation==LinkableMapObj::RightOfCenter)
326 leftPad=max (leftPad,-rp.x()-w);
327 if (rp.x()+fio->width() > 0)
328 rightPad=max (rightPad,rp.x()+fio->width());
332 leftPad=max (leftPad,-rp.x());
333 if (rp.x()+fio->width() > w)
334 rightPad=max (rightPad,rp.x()+fio->width()-w);
343 w+=frame->getPadding();
344 h+=frame->getPadding();
347 bbox.setSize (QSizeF (w,h));
350 void BranchObj::setDockPos()
352 if (treeItem->getType()==TreeItem::MapCenter)
354 // set childPos to middle of MapCenterObj
355 childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
356 childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
358 for (int i=0; i<treeItem->branchCount(); ++i)
359 treeItem->getBranchObjNum(i)->updateLinkGeometry();
363 // Sets childpos and parpos depending on orientation
364 if (getOrientation()==LinkableMapObj::LeftOfCenter )
367 ornamentsBBox.bottomLeft().x(),
370 ornamentsBBox.bottomRight().x(),
375 ornamentsBBox.bottomRight().x(),
378 ornamentsBBox.bottomLeft().x(),
384 void BranchObj::updateData()
389 qWarning ("BranchObj::udpateHeading treeItem==NULL");
392 QString s=treeItem->getHeading();
393 if (s!=heading->text())
395 heading->setText (s);
398 QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
400 // Add missing standard flags active in TreeItem
401 for (int i=0;i<=TIactiveFlags.size()-1;i++)
403 if (!standardFlags->isActive (TIactiveFlags.at(i) ))
405 Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
406 if (f) standardFlags->activate (f);
410 // Remove standard flags no longer active in TreeItem
411 QStringList BOactiveFlags=standardFlags->activeFlagNames();
412 for (int i=0;i<BOactiveFlags.size();++i)
413 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
415 standardFlags->deactivate (BOactiveFlags.at(i));
419 // Add missing system flags active in TreeItem
420 TIactiveFlags=treeItem->activeSystemFlagNames();
421 for (int i=0;i<TIactiveFlags.size();++i)
423 if (!systemFlags->isActive (TIactiveFlags.at(i) ))
425 Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
426 if (f) systemFlags->activate (f);
430 // Remove system flags no longer active in TreeItem
431 BOactiveFlags=systemFlags->activeFlagNames();
432 for (int i=0;i<BOactiveFlags.size();++i)
434 if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
436 systemFlags->deactivate (BOactiveFlags.at(i));
440 if (changed) updateContentSize();
443 void BranchObj::setDefAttr (BranchModification mod, bool keepFrame)
446 switch (treeItem->depth())
461 setLinkStyle(getDefLinkStyle(treeItem->parent() ));
463 QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
464 font.setPointSize(fontsize);
465 heading->setFont(font );
467 if (mod==NewBranch && !keepFrame)
468 if (treeItem->depth()==0)
469 setFrameType (FrameObj::Rectangle);
471 setFrameType (FrameObj::NoFrame);
474 setColor (treeItem->getHeadingColor() );
477 // Also set styles for children
478 for (int i=0; i<treeItem->branchCount(); ++i)
479 treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch);
484 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
486 qreal th = bboxTotal.height();
488 if (parObj) depth=1 + parObj->getTreeItem()->depth();
491 QString h=QString (depth+1,' ');
492 h+=treeItem->getHeading();
496 if (parObj) pp=parObj->getChildPos();
497 cout << "BO::alignRelTo ";
498 cout<<h.toStdString();
499 cout << " d="<<depth;
500 cout <<" parO="<<parObj;
501 //cout<< " ref="<<ref<<
502 //cout << " bbox.tL="<<bboxTotal.topLeft();
503 cout<< " absPos="<<absPos<<
506 // " w="<<bbox.width()<<
507 // " h="<<bbox.height()<<
508 // " orient="<<orientation<<
509 // " alignSelf="<<alignSelf<<
510 // " scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
511 // " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
512 // " hidden="<<hidden<<
518 //updateLinkGeometry();
522 move2RelPos (getRelPos() );
526 // Align myself depending on orientation and parent, but
527 // only if I am not a mainbranch or mapcenter itself
529 if (anim.isAnimated())
534 LinkableMapObj::Orientation o;
535 o=parObj->getOrientation();
539 case LinkableMapObj::LeftOfCenter:
540 move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
541 //move (ref.x() , ref.y() + (th-bbox.height())/2 );
543 case LinkableMapObj::RightOfCenter:
544 move (ref.x() , ref.y() + (th-bbox.height())/2 );
547 qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
553 if ( ((BranchItem*)treeItem)->isScrolled() ) return;
555 // Set reference point for alignment of children
557 if (orientation==LinkableMapObj::LeftOfCenter)
558 ref2.setX(bbox.topLeft().x() - linkwidth);
560 ref2.setX(bbox.topRight().x() + linkwidth);
563 ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
567 // Align the attribute children depending on reference point
568 // on top like in TreeEditor
569 for (int i=0; i<treeItem->attributeCount(); ++i)
571 if (!treeItem->getAttributeNum(i)->isHidden())
573 BranchObj *bo=(BranchObj*)(treeItem->getAttributeNum(i)->getBranchObj());
575 bo->alignRelativeTo (ref2,true);
577 // append next branch below current one
578 ref2.setY(ref2.y() + bo->getBBoxSizeWithChildren().height() );
581 // Align the branch children depending on reference point
582 for (int i=0; i<treeItem->branchCount(); ++i)
584 if (!treeItem->getBranchNum(i)->isHidden())
586 treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
588 // append next branch below current one
589 ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
595 void BranchObj::reposition()
598 if (!treeItem->getHeading().isEmpty())
599 cout << "BO::reposition "<<qPrintable(treeItem->getHeading())<<endl;
601 cout << "BO::reposition ???"<<endl;
602 // cout << " orient="<<orientation<<endl;
605 if (treeItem->depth()==0)
607 // only calculate the sizes once. If the deepest LMO
608 // changes its height,
609 // all upper LMOs have to change, too.
610 calcBBoxSizeWithChildren();
611 updateLinkGeometry(); // This update is needed if the scene is resized
612 // due to excessive moving of a FIO
614 alignRelativeTo ( QPointF (absPos.x(),
615 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
616 positionBBox(); // Reposition bbox and contents
619 // This is only important for moving branches:
620 // For editing a branch it isn't called...
621 alignRelativeTo ( QPointF (absPos.x(),
622 absPos.y()-(bboxTotal.height()-bbox.height())/2) );
626 void BranchObj::unsetAllRepositionRequests()
628 repositionRequest=false;
629 for (int i=0; i<treeItem->branchCount(); ++i)
630 treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
634 QRectF BranchObj::getTotalBBox() // FIXME-2 not really needed, get rid of this
638 if ( ((BranchItem*)treeItem)->isScrolled() ) return r;
640 /* FIXME-2 really include children _here_ ? likely not needed anymore, but done in TreeItem */
641 for (int i=0; i<treeItem->branchCount(); ++i)
642 if (!treeItem->getBranchNum(i)->isHidden())
643 r=addBBox(treeItem->getBranchObjNum(i)->getTotalBBox(),r);
645 /* FIXME-3 lots of occurences of treeItem->getBranchObjNum(i) in branchobj.cpp
646 better check if they are not NULL and maybe simplify...
647 (have been NULL at least in calcBBoxSizeWithChilds...)
651 for (int i=0; i<treeItem->imageCount(); ++i
652 if (!treeItem->isHidden())
653 r=addBBox(treeItem->getImageObjNum(i)->getTotalBBox(),r);
658 QRectF BranchObj::getBBoxSizeWithChildren()
663 ConvexPolygon BranchObj::getBoundingPolygon()
666 if (!pi) //FIXME-3 Testing only
668 pi=scene->addPolygon(MapObj::getBoundingPolygon() );
669 pi->setPen(Qt::NoPen);
670 pi->setBrush( QColor(qrand()%32*8,qrand()%32*8,qrand()%32*8) );
671 pi->setZValue(Z_BBOX);
675 if (treeItem->branchCount()==0 || treeItem->depth()==0)
677 if (pi) pi->setPolygon (MapObj::getBoundingPolygon() );
678 return MapObj::getBoundingPolygon();
681 calcBBoxSizeWithChildren(); //FIXME-2 really needed?
683 p<<bboxTotal.topLeft();
684 p<<bboxTotal.topRight();
685 p<<bboxTotal.bottomRight();
686 p<<bboxTotal.bottomLeft();
687 //cout << "BO::getBP (total) "<<treeItem->getHeadingStd()<<" tL="<<bboxTotal.topLeft()<<" bR="<<bboxTotal.bottomRight()<<endl;
688 //cout << " "<<" tL="<<bbox.topLeft()<<" bR="<<bbox.bottomRight()<<endl;
689 if (pi) pi->setPolygon (p );
693 void BranchObj::calcBBoxSizeWithChildren()
695 // This is initially called only from reposition and
696 // and only for mapcenter. So it won't be
697 // called more than once for a single user
701 // Calculate size of LMO including all children (to align them later)
702 bboxTotal.setX(bbox.x() );
703 bboxTotal.setY(bbox.y() );
705 // if branch is scrolled, ignore children, but still consider floatimages
706 BranchItem *bi=(BranchItem*)treeItem;
707 if ( bi->isScrolled() )
709 bboxTotal.setWidth (bbox.width());
710 bboxTotal.setHeight(bbox.height());
716 bboxTotal.setWidth (0);
717 bboxTotal.setHeight(0);
720 bboxTotal.setX (parObj->x());
721 bboxTotal.setY (parObj->y());
724 bboxTotal.setX (bbox.x());
725 bboxTotal.setY (bbox.y());
732 // Now calculate recursivly
736 for (int i=0; i<treeItem->branchCount(); i++)
738 if (!bi->getBranchNum(i)->isHidden())
740 BranchObj *bo=bi->getBranchObjNum(i);
741 bo->calcBBoxSizeWithChildren();
742 br=bo->getBBoxSizeWithChildren();
743 r.setWidth( max (br.width(), r.width() ));
744 r.setHeight(br.height() + r.height() );
745 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
746 if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
749 for (int i=0; i<treeItem->attributeCount(); i++)
751 if (!bi->getAttributeNum(i)->isHidden())
753 BranchObj *bo=bi->getAttributeNum(i)->getBranchObj();
754 bo->calcBBoxSizeWithChildren();
755 br=bo->getBBoxSizeWithChildren();
756 r.setWidth( max (br.width(), r.width() ));
757 r.setHeight(br.height() + r.height() );
758 if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
759 if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
762 // Add myself and also
763 // add width of link to sum if necessary
764 if (bi->branchCount()<1)
765 bboxTotal.setWidth (bbox.width() + r.width() );
767 bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
769 bboxTotal.setHeight(max (r.height(), bbox.height()));
772 void BranchObj::setAnimation(const AnimPoint &ap)
777 bool BranchObj::animate()
780 if ( anim.isAnimated() )
785 parObj->reposition(); // we might have been relinked meanwhile