-#include <QDebug>
-
-#include "branchobj.h"
-
-#include "attributeitem.h"
-#include "branchitem.h"
-#include "geometry.h"
-#include "mapeditor.h"
-#include "mainwindow.h"
-#include "misc.h"
-
-extern FlagRow *standardFlagsMaster;
-extern FlagRow *systemFlagsMaster;
-extern bool debug;
-
-/////////////////////////////////////////////////////////////////
-// BranchObj
-/////////////////////////////////////////////////////////////////
-
-BranchObj::BranchObj (QGraphicsItem *parent,TreeItem *ti):OrnamentedObj (parent,ti)
-{
- //qDebug ()<< "Const BranchObj (s,ti) ti="<<ti;
- treeItem=ti;
- BranchItem *pi=(BranchItem*)(ti->parent());
- if (pi && pi!=ti->getModel()->getRootItem() )
- parObj=pi->getLMO();
- else
- parObj=NULL;
- init();
-}
-
-BranchObj::~BranchObj ()
-{
- //qDebug()<< "Destr BranchObj of "<<this;
-
- // If I'm animated, I need to un-animate myself first
- if (anim.isAnimated() )
- {
- anim.setAnimated (false);
- VymModel *model=treeItem->getModel();
- model->stopAnimation (this);
- }
-
- clear();
-}
-
-void BranchObj::init ()
-{
- if (parObj) absPos=parObj->getChildRefPos();
-}
-
-void BranchObj::copy (BranchObj* other)
-{
- OrnamentedObj::copy(other);
-
- setVisibility (other->visible);
-
- positionBBox();
-}
-
-void BranchObj::clear()
-{
-}
-
-void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off)
-{
- // Temporary link to dst
- // m is position of mouse pointer
- // offset 0: default 1: below dst -1 above dst (if possible)
-
- BranchItem *dsti=(BranchItem*)(dst->getTreeItem());
-
- BranchItem *pi=(BranchItem*)(dsti->parent());
- int pi_depth=pi->depth();
- BranchObj* bodst=(BranchObj*)dst;
-
- if (!tmpParent)
- {
- tmpParent=true;
- parObjTmpBuf=parObj;
- }
-
- if (pi_depth<1) off=0;
- if (off==0)
- link2ParPos=false;
- else
- link2ParPos=true;
- parObj=bodst;
-
- setLinkStyle (dst->getDefLinkStyle (dsti));
-
- // Move temporary to new position at destination
- // Usually the positioning would be done by reposition(),
- // but then also the destination branch would "Jump" around...
- // Better just do it approximately
- if (dsti->depth()==0)
- { // new parent is a mapcenter
- Vector v= ( m - bodst->getChildRefPos());
- v.normalize();
- v.scale (150);
- move2RelPos (v.toQPointF());
- } else
- {
- qreal y;
- if (off==0)
- {
- // Below is needed e.g. in a freshly loaded map,
- // bboxTotal seems not to be correct yet
- // relinking positions too far below then
- calcBBoxSizeWithChildren();
-
- // new parent is just a branch, link to it
- bodst->calcBBoxSizeWithChildren();
- QRectF t = bodst->getTotalBBox();
- if (dsti->getLastBranch())
- // Move below children of destination
- y = t.y() + t.height() ;
- else
- // Move left or right to destination
- y = t.y() ;
- } else
- {
- if (off < 0)
- // we want to link above dst
- y = bodst->y() - height() + 12;
- else
- // we want to link below dst
- // Bottom of sel should be 5 pixels above
- // the bottom of the branch _below_ the target:
- // Don't try to find that branch, guess 12 pixels
- y = bodst->getChildRefPos().y() -height() + 12;
- }
- if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
- move ( bodst->getChildRefPos().x() - linkwidth - bboxTotal.width(), y );
- else
- move ( bodst->getChildRefPos().x() + linkwidth, y );
- }
-
- // updateLinkGeometry is called implicitly in move
- requestReposition();
-}
-
-void BranchObj::unsetParObjTmp()
-{
- if (tmpParent)
- {
- tmpParent=false;
- link2ParPos=false;
- parObj=parObjTmpBuf;
- parObjTmpBuf=NULL;
- setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
- updateLinkGeometry();
- }
-}
-
-void BranchObj::setVisibility(bool v, int toDepth)
-{
- BranchItem *bi=(BranchItem*)treeItem;
- if (bi->depth() <= toDepth)
- {
- frame->setVisibility(v);
- heading->setVisibility(v);
- systemFlags->setVisibility(v);
- standardFlags->setVisibility(v);
- LinkableMapObj::setVisibility (v);
- int i;
- for (i=0; i<treeItem->imageCount(); ++i)
- treeItem->getImageObjNum(i)->setVisibility (v);
- for (i=0; i<treeItem->xlinkCount(); ++i)
- treeItem->getXLinkObjNum(i)->setVisibility ();
-
- // Only change children, if I am not scrolled
- if (! bi->isScrolled() && (bi->depth() < toDepth))
- {
- // Now go recursivly through all children
- for (i=0; i<treeItem->branchCount(); ++i)
- treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);
- }
- }
-}
-
-void BranchObj::setVisibility(bool v)
-{
- setVisibility (v,MAX_DEPTH);
-}
-
-
-void BranchObj::setLinkColor ()
-{
- // Overloaded from LinkableMapObj
- // BranchObj can use color of heading
-
- VymModel *model=treeItem->getModel();
- if (model)
- {
- if (model->getMapLinkColorHint()==HeadingColor)
- LinkableMapObj::setLinkColor (heading->getColor() );
- else
- LinkableMapObj::setLinkColor ();
- }
-}
-
-void BranchObj::positionContents()
-{
- OrnamentedObj::positionContents();
- updateLinkGeometry();// required before positioning images
- for (int i=0; i<treeItem->imageCount(); ++i)
- treeItem->getImageObjNum(i)->reposition();
-}
-
-void BranchObj::move (double x, double y)
-{
- OrnamentedObj::move (x,y);
-}
-
-void BranchObj::move (QPointF p)
-{
- move (p.x(), p.y());
-}
-
-void BranchObj::moveBy (double x, double y)
-{
- OrnamentedObj::moveBy (x,y);
- for (int i=0; i<treeItem->branchCount(); ++i)
- treeItem->getBranchObjNum(i)->moveBy (x,y);
- positionBBox();
-}
-
-void BranchObj::moveBy (QPointF p)
-{
- moveBy (p.x(), p.y());
-}
-
-void BranchObj::positionBBox() // FIXME-3 consider dimensions of frame (thickness, geometry, padding...
-{
- QPointF ap=getAbsPos();
- bbox.moveTopLeft (ap);
- positionContents(); // this positions FIOs
-
- //Update links to other branches
- XLinkObj *xlo;
- for (int i=0; i<treeItem->xlinkCount(); ++i)
- {
- xlo=treeItem->getXLinkObjNum(i);
- if (xlo) xlo->updateXLink();
- }
-}
-
-void BranchObj::calcBBoxSize()
-{
- QSizeF heading_r=heading->getSize();
- qreal heading_w=(qreal) heading_r.width() ;
- qreal heading_h=(qreal) heading_r.height() ;
- QSizeF sysflags_r=systemFlags->getSize();
- qreal sysflags_h=sysflags_r.height();
- qreal sysflags_w=sysflags_r.width();
- QSizeF stanflags_r=standardFlags->getSize();
- qreal stanflags_h=stanflags_r.height();
- qreal stanflags_w=stanflags_r.width();
- qreal w;
- qreal h;
-
- // set width to sum of all widths
- w=heading_w + sysflags_w + stanflags_w;
-
- // set height to maximum needed height
- h=max (sysflags_h,stanflags_h);
- h=max (h,heading_h);
-
- // Save the dimension of flags and heading
- ornamentsBBox.setSize ( QSizeF(w,h));
-
- // clickBox includes Flags and Heading
- clickPoly=QPolygonF (ornamentsBBox);
-
- // Floatimages
- QPointF rp;
-
- topPad = botPad = leftPad = rightPad = 0;
- bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
- bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
- if (incH || incV)
- {
- FloatImageObj *fio;
- for (int i=0; i<treeItem->imageCount(); ++i )
- {
- fio=treeItem->getImageObjNum(i);
- rp=fio->getRelPos();
- if (incV)
- {
- qreal y;
- if (rp.y() > 0)
- {
- y = rp.y() + fio->height()/2 - ornamentsBBox.height()/2;
- botPad = max(botPad, y);
- } else
- {
- y=-rp.y() + fio->height()/2 - ornamentsBBox.height()/2;
- topPad=max(topPad, y);
- }
- }
- if (incH)
- {
- qreal x;
- if (rp.x() > 0)
- {
- x=rp.x() + fio->width()/2 - ornamentsBBox.width()/2;
- rightPad=max(rightPad, x);
- } else
- {
- x=-rp.x() + fio->width()/2 - ornamentsBBox.width()/2;
- leftPad=max(leftPad, x);
- }
- }
- }
- h += topPad + botPad;
- w += leftPad + rightPad;
- }
-
- // Frame thickness
- w += frame->getTotalPadding() * 2;
- h += frame->getTotalPadding() * 2;
-
- // Finally set size
- bbox.setSize (QSizeF (w,h));
- //if (debug) qDebug()<<"BO: calcBBox "<<treeItem->getHeading()<<" bbox="<<bbox;
-}
-
-void BranchObj::setDockPos()
-{
- floatRefPos=ornamentsBBox.center();
-
- if (treeItem->getType() == TreeItem::MapCenter)
- {
- // set childRefPos to middle of MapCenterObj
- QRectF r=clickPoly.boundingRect();
- childRefPos.setX( r.topLeft().x() + r.width()/2 );
- childRefPos.setY( r.topLeft().y() + r.height()/2 );
- parPos=childRefPos;
- for (int i=0; i<treeItem->branchCount(); ++i)
- treeItem->getBranchObjNum(i)->updateLinkGeometry();
- } else
- {
- if (orientation == LinkableMapObj::LeftOfCenter )
- {
- // Left of center
- if ( ((BranchItem*)treeItem)->getFrameIncludeChildren() )
- {
- childRefPos=QPointF (ornamentsBBox.bottomLeft().x() - leftPad, bottomlineY);
- parPos=QPointF (bboxTotal.bottomRight().x()-frame->getPadding()/2, bottomlineY);
- } else
- {
- childRefPos=QPointF (ornamentsBBox.bottomLeft().x() - frame->getPadding(), bottomlineY);
- parPos=QPointF (ornamentsBBox.bottomRight().x(), bottomlineY);
- }
- } else
- {
- // Right of center
- if ( ((BranchItem*)treeItem)->getFrameIncludeChildren() )
- {
- childRefPos=QPointF(ornamentsBBox.bottomRight().x() + rightPad , bottomlineY);
- parPos=QPointF ( bboxTotal.bottomLeft().x()+frame->getPadding()/2, bottomlineY);
- } else
- {
- childRefPos=QPointF(ornamentsBBox.bottomRight().x() + frame->getPadding(), bottomlineY);
- parPos=QPointF ( ornamentsBBox.bottomLeft().x(), bottomlineY);
- }
- }
- }
-}
-
-void BranchObj::updateData()
-{
- if (!treeItem)
- {
- qWarning ("BranchObj::udpateHeading treeItem==NULL");
- return;
- }
- QString s = treeItem->getHeadingText();
- if ( s!=heading->text()) heading->setText (s);
-
- QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
-
- // Add missing standard flags active in TreeItem
- for (int i=0;i<=TIactiveFlags.size()-1;i++)
- {
- if (!standardFlags->isActive (TIactiveFlags.at(i) ))
- {
- Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
- if (f) standardFlags->activate (f);
- }
- }
- // Remove standard flags no longer active in TreeItem
- QStringList BOactiveFlags=standardFlags->activeFlagNames();
- for (int i=0;i<BOactiveFlags.size();++i)
- if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
- standardFlags->deactivate (BOactiveFlags.at(i));
-
- // Add missing system flags active in TreeItem
- TIactiveFlags=treeItem->activeSystemFlagNames();
- for (int i=0;i<TIactiveFlags.size();++i)
- {
- if (!systemFlags->isActive (TIactiveFlags.at(i) ))
- {
- Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
- if (f) systemFlags->activate (f);
- }
- }
- // Remove system flags no longer active in TreeItem
- BOactiveFlags=systemFlags->activeFlagNames();
- for (int i=0;i<BOactiveFlags.size();++i)
- {
- if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
- systemFlags->deactivate (BOactiveFlags.at(i));
- }
- calcBBoxSize();
-}
-
-void BranchObj::setDefAttr (BranchModification mod, bool keepFrame)
-{
- QFont font=treeItem->getModel()->getMapDefaultFont();
- qreal fontsize=font.pointSizeF();
- switch (treeItem->depth())
- {
- case 0:
- break;
- case 1:
- fontsize=fontsize-2;
- break;
- case 2:
- fontsize=fontsize-4;
- break;
- default:
- fontsize=fontsize-6;
- break;
- }
- setLinkStyle(getDefLinkStyle(treeItem->parent() ));
- setLinkColor ();
- font.setPointSizeF (fontsize);
- heading->setFont(font );
-
- if (mod==NewBranch && !keepFrame)
- {
- if (treeItem->depth()==0)
- setFrameType (FrameObj::Rectangle);
- else
- setFrameType (FrameObj::NoFrame);
- }
- if (mod==NewBranch)
- setColor (treeItem->getHeadingColor() );
- else
- {
- // Relinked mapcenters
- if (!keepFrame && getFrameType()!=FrameObj::NoFrame)
- setFrameType (FrameObj::NoFrame);
-
- // Also set styles for children
- for (int i=0; i<treeItem->branchCount(); ++i)
- treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch, keepFrame);
- }
- calcBBoxSize();
-}
-
-void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
-{
- // Define some heights
- qreal th = bboxTotal.height();
- qreal ch=0; // Sum of childrens heights
- for (int i=0; i<treeItem->branchCount(); ++i)
- ch+=treeItem->getBranchObjNum(i)->getTotalBBox().height();
-
- int depth = 0;
- BranchItem::LayoutHint layoutHint = BranchItem::AutoPositioning;
- if (parObj)
- {
- TreeItem *pi = parObj->getTreeItem();
- depth = 1 + pi->depth();
- layoutHint = ((BranchItem*)treeItem)->parentBranch()->getChildrenLayout();
- }
-
- // set useRelPos, depending on layout
- if (depth > 1)
- {
- if (layoutHint == BranchItem::FreePositioning)
- {
- if (!useRelPos)
- {
- useRelPos = true;
- // if we used relPos before, set known positions
- // "known" means any position != (0,0)
- if (relPos == QPointF(0,0) )
- // use current position to get relPos()
- setRelPos();
- }
- }
- else
- useRelPos = false;
- }
-
-// TODO testing
-/*
- if (debug)
- {
- QString o;
- switch (orientation)
- {
- case UndefinedOrientation: o = "UndefOrientation"; break;
- case LeftOfCenter: o = "LeftOfCenter"; break;
- case RightOfCenter: o = "RightOfCenter"; break;
- }
-
- QString h=QString (depth+1,' ');
- h += treeItem->getHeadingPlain();
- h += QString (25,' ');
- h.truncate (25);
- QPointF pp;
- if (parObj) pp = parObj->getChildRefPos();
- qDebug() << "BO::alignRelTo for "<<h
- // qDebug() << " d="<<depth;
- // qDebug() <<" ref="<<ref;
- // qDebug() <<" th="<<th;
- // qDebug() <<" ch="<<ch;
- // if (ch < th) qDebug()<<" ch<th !";
- // qDebug() <<" parO="<<parObj;
- //qDebug() << " bbox.tL="<<bboxTotal.topLeft();
- << " useRelPos=" << useRelPos
- << " layoutHint= " << layoutHint
- // qDebug() <<"absPos="<<absPos
- << " relPos="<<relPos
- // << " parPos="<<pp
- // << " bbox="<<bbox
- << " orient="<<o<<" "<<orientation;
- // << " alignSelf="<<alignSelf
- // << " scrolled="<<((BranchItem*)treeItem)->isScrolled()
- // << " pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad
- // << " hidden="<<hidden
- // << " th="<<th
- ;
- }
- */
-
- setOrientation();
-
- // Align myself
- if (depth==0)
- move (getAbsPos()); // Trigger update of frames etc.
- else if(depth==1)
- move2RelPos (getRelPos() );
- else if (depth>1)
- {
- if (layoutHint == BranchItem::FreePositioning)
- move2RelPos (getRelPos() );
- else
- {
- if (anim.isAnimated())
- move2RelPos(anim);
- else
- {
- if (alignSelf)
- switch (orientation)
- {
- case LinkableMapObj::LeftOfCenter:
- move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
- break;
- case LinkableMapObj::RightOfCenter:
- move (ref.x() , ref.y() + (th - bbox.height())/2 );
- break;
- default:
- qWarning ("LMO::alignRelativeTo: oops, no orientation given for BO...");
- break;
- }
- }
- }
- }
-
- // Without ancestors I am done
- if ( ((BranchItem*)treeItem)->isScrolled() ) return;
-
- // Set reference point for alignment of children
- QPointF ref2;
- if (orientation==LinkableMapObj::LeftOfCenter)
- ref2.setX(childRefPos.x() - linkwidth);
- else
- ref2.setX(childRefPos.x() + linkwidth);
-
- if (depth==1)
- ref2.setY (absPos.y() + (bbox.height() - ch)/2);
- else
- {
- if (ch > th)
- ref2.setY (ref.y() + frame->getPadding());
- else
- // Parent is bigger than all of childs, center childs vertically
- ref2.setY (ref.y() + (th - ch)/2 );
- }
-
- // Align the branch children depending on reference point
- for (int i=0; i<treeItem->branchCount(); ++i)
- {
- if (!treeItem->getBranchNum(i)->isHidden())
- {
- treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
-
- // append next branch below current one
- ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getTotalBBox().height() );
- }
- }
-}
-
-void BranchObj::reposition()
-{
-/* TODO testing only
- if (debug)
- {
- if (!treeItem->getHeading().isEmpty())
- qDebug()<< " BO::reposition a) d="<<treeItem->depth()<<" "<<treeItem->getHeading();
- else
- qDebug()<< " BO::reposition a) d="<<treeItem->depth()<<" ???";
- }
-*/
-
- if (treeItem->depth()==0)
- // only calculate the sizes once. If the deepest LMO
- // changes its height,
- // all upper LMOs have to change, too.
- calcBBoxSizeWithChildren();
-
- alignRelativeTo ( QPointF (absPos.x(),
- absPos.y()-(bboxTotal.height()-bbox.height())/2) );
-}
-
-void BranchObj::unsetAllRepositionRequests()
-{
- repositionRequest=false;
- for (int i=0; i<treeItem->branchCount(); ++i)
- treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
-}
-
-QRectF BranchObj::getTotalBBox()
-{
- return bboxTotal;
-}
-
-ConvexPolygon BranchObj::getBoundingPolygon()
-{
- if (treeItem->branchCount()==0 || treeItem->depth()==0)
- {
- if (boundingPolygon)
- boundingPolygon->setPolygon (MapObj::getBoundingPolygon() );
- return MapObj::getBoundingPolygon();
- }
-
- QPolygonF p;
- p<<bboxTotal.topLeft();
- p<<bboxTotal.topRight();
- p<<bboxTotal.bottomRight();
- p<<bboxTotal.bottomLeft();
- if (boundingPolygon) boundingPolygon->setPolygon (p );
- return p;
-}
-
-void BranchObj::calcBBoxSizeWithChildren()
-{
- // if branch is scrolled, ignore children, but still consider floatimages
- BranchItem *bi=(BranchItem*)treeItem;
- if ( bi->isScrolled() )
- {
- bboxTotal.setWidth (bbox.width());
- bboxTotal.setHeight(bbox.height());
- return;
- }
-
- if (bi->isHidden())
- {
- bboxTotal.setWidth (0);
- bboxTotal.setHeight(0);
- return;
- }
-
- QRectF r(0,0,0,0);
- QRectF br;
-
- // Now calculate
- // sum of heights
- // maximum of widths
- // minimum of y
- for (int i=0; i<treeItem->branchCount(); i++)
- {
- if (!bi->getBranchNum(i)->isHidden())
- {
- BranchObj *bo=bi->getBranchObjNum(i);
- bo->calcBBoxSizeWithChildren();
- br=bo->getTotalBBox();
- r.setWidth( max (br.width(), r.width() ));
- r.setHeight(br.height() + r.height() );
- }
- }
-
- // Add myself and also
- // add width of link to sum if necessary
- if (bi->branchCount()<1)
- bboxTotal.setWidth (bbox.width() + r.width() );
- else
- bboxTotal.setWidth (bbox.width() + r.width() + linkwidth );
-
- // bbox already contains frame->padding()*2
- bboxTotal.setHeight(max (r.height() + frame->getPadding()*2, bbox.height()) );
-}
-
-void BranchObj::setAnimation(const AnimPoint &ap)
-{
- anim=ap;
-}
-
-void BranchObj::stopAnimation()
-{
- anim.stop();
- if (useRelPos)
- setRelPos (anim);
- else
- move (anim);
-}
-
-bool BranchObj::animate()
-{
- anim.animate ();
- if ( anim.isAnimated() )
- {
- if (useRelPos)
- setRelPos (anim);
- else
- move (anim);
- return true;
- }
- return false;
-}
-