4 #include "linkablemapobj.h"
10 /////////////////////////////////////////////////////////////////
12 /////////////////////////////////////////////////////////////////
14 LinkableMapObj::LinkableMapObj():MapObj()
16 // cout << "Const LinkableMapObj ()\n";
20 LinkableMapObj::LinkableMapObj(QGraphicsScene* s) :MapObj(s)
22 // cout << "Const LinkableMapObj (s)\n";
26 LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->scene)
31 LinkableMapObj::~LinkableMapObj()
37 void LinkableMapObj::delLink()
45 while (!segment.isEmpty()) delete segment.takeFirst();
58 void LinkableMapObj::init ()
66 childPos=QPointF(0,0);
70 orientation=UndefinedOrientation;
77 // TODO instead of linkcolor pen.color() could be used all around
79 pen.setColor (linkcolor);
80 pen.setCapStyle ( Qt::RoundCap );
81 bottomline=scene->addLine(QLineF(1,1,1,1),pen);
82 bottomline->setZValue(Z_LINK);
85 // Prepare showing the selection of a MapObj
88 hideLinkUnselected=false;
90 topPad=botPad=leftPad=rightPad=0;
92 repositionRequest=false;
99 // Crossreference to treemodel
103 void LinkableMapObj::copy (LinkableMapObj* other)
107 bboxTotal=other->bboxTotal;
108 setLinkStyle(other->style);
109 setLinkColor (other->linkcolor);
110 relPos=other->relPos;
111 useOrientation=other->useOrientation;
112 treeItem=other->treeItem;
115 void LinkableMapObj::setTreeItem (TreeItem *ti)
120 TreeItem* LinkableMapObj::getTreeItem () const
125 void LinkableMapObj::setModel (VymModel *vm)
130 VymModel* LinkableMapObj::getModel()
135 void LinkableMapObj::setChildObj(LinkableMapObj* o)
140 void LinkableMapObj::setParObj(LinkableMapObj* o)
143 if (parObj) model=parObj->getModel();
146 void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPointF,int) // FIXME-3 make pure virtual
150 void LinkableMapObj::unsetParObjTmp() // FIXME-3 make pure virtual
154 bool LinkableMapObj::hasParObjTmp()
156 if (parObjTmpBuf) return true;
160 void LinkableMapObj::setUseRelPos (const bool &b)
165 void LinkableMapObj::setRelPos()
169 relPos.setX (absPos.x() - parObj->getChildPos().x() );
170 relPos.setY (absPos.y() - parObj->getChildPos().y() );
171 parObj->calcBBoxSize();
175 void LinkableMapObj::setRelPos(const QPointF &p)
180 parObj->calcBBoxSize();
185 QPointF LinkableMapObj::getRelPos()
187 if (!parObj) return QPointF();
191 qreal LinkableMapObj::getTopPad()
196 qreal LinkableMapObj::getLeftPad()
201 qreal LinkableMapObj::getRightPad()
206 LinkableMapObj::Style LinkableMapObj::getDefLinkStyle ()
210 qWarning ("LMO::getDefLinkStyle model=NULL");
211 //return UndefinedStyle;
213 Style ls=model->getMapLinkStyle();
214 int depth=treeItem->depth();
215 if (depth==0) return UndefinedStyle;
239 return UndefinedStyle;
242 void LinkableMapObj::setLinkStyle(Style newstyle)
244 //if (newstyle=style) return; FIXME-3
249 if (childObj!=NULL && parObj != NULL)
251 QGraphicsLineItem *cl;
258 l = scene->addLine(QLineF(1,1,1,1),pen);
259 l->setZValue(Z_LINK);
266 for (int i=0;i<arcsegs;i++)
268 cl = scene->addLine(QLineF(i*5,0,i*10,100),pen);
269 cl->setZValue(Z_LINK);
276 pa0.resize (arcsegs+1);
279 p =scene->addPolygon(QPolygonF(),pen,linkcolor);
280 p->setZValue(Z_LINK);
288 p = scene->addPolygon(QPolygonF(),pen,linkcolor);
289 p->setZValue(Z_LINK);
294 pa0.resize (arcsegs*2+2);
295 pa1.resize (arcsegs+1);
296 pa2.resize (arcsegs+1);
304 LinkableMapObj::Style LinkableMapObj::getLinkStyle()
309 void LinkableMapObj::setHideLinkUnselected(bool b)
311 hideLinkUnselected=b;
312 setVisibility (visible);
316 bool LinkableMapObj::getHideLinkUnselected()
318 return hideLinkUnselected;
321 void LinkableMapObj::setLinkPos(Position lp)
326 LinkableMapObj::Position LinkableMapObj::getLinkPos()
331 void LinkableMapObj::setLinkColor()
333 // Overloaded in BranchObj and children
334 // here only set default color
336 setLinkColor (model->getMapDefLinkColor());
339 void LinkableMapObj::setLinkColor(QColor col)
343 bottomline->setPen( pen );
350 for (int i=0; i<segment.size(); ++i)
351 segment.at(i)->setPen( pen);
354 p->setBrush( QBrush(col));
358 p->setBrush( QBrush(col));
366 QColor LinkableMapObj::getLinkColor()
371 void LinkableMapObj::setVisibility (bool v)
373 MapObj::setVisibility (v);
376 // We can hide the link, while object is not selected
377 if (hideLinkUnselected && !selected)
389 for (int i=0; i<segment.size(); ++i)
390 segment.at(i)->show();
393 if (!p) cout << "LMO::setVis p==0 (PolyLine)\n"; //FIXME-3
397 if (!p) cout << "LMO::setVis p==0 (PolyParabel) "<<treeItem->getHeading().toStdString()<<endl; //FIXME-3
412 for (int i=0; i<segment.size(); ++i)
413 segment.at(i)->hide();
427 void LinkableMapObj::setOrientation()
429 Orientation orientOld=orientation;
433 orientation=UndefinedOrientation;
437 // Set orientation, first look for orientation of parent
438 if (parObj->getOrientation() != UndefinedOrientation )
439 // use the orientation of the parent:
440 orientation=parObj->getOrientation();
443 // calc orientation depending on position rel to parent
444 if (absPos.x() < QPointF(parObj->getChildPos() ).x() )
445 orientation=LeftOfCenter;
447 orientation=RightOfCenter;
449 if (orientOld!=orientation) requestReposition();
452 void LinkableMapObj::updateLink()
455 // childPos of parent
461 // childPos (by calling setDockPos())
462 // parPos (by calling setDockPos())
464 // drawing of the link itself
466 // updateLink is called from move, but called from constructor we don't
467 // have parents yet...
468 if (style==UndefinedStyle) return;
473 bottomlineY=bbox.top() + bbox.height()/2; // draw link to middle (of frame)
476 bottomlineY=bbox.bottom()-1; // draw link to bottom of box
480 double p2x,p2y; // Set P2 Before setting
483 p2x=QPointF( parObj->getChildPos() ).x(); // P1, we have to look at
484 p2y=QPointF( parObj->getChildPos() ).y(); // orientation
487 p2x=QPointF( parObj->getParPos() ).x();
488 p2y=QPointF( parObj->getParPos() ).y();
491 setDockPos(); // Call overloaded method
494 double p1x=parPos.x(); // Link is drawn from P1 to P2
495 double p1y=parPos.y();
497 double vx=p2x - p1x; // V=P2-P1
500 // Draw the horizontal line below heading (from ChildPos to ParPos)
501 //bottomline->prepareGeometryChange();
502 bottomline->setLine (QLine (qRound(childPos.x()),
503 qRound(childPos.y()),
508 if (vx > -0.000001 && vx < 0.000001)
512 // "turning point" for drawing polygonal links
513 QPointF tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));
519 //l->prepareGeometryChange();
520 l->setLine( QLine(qRound (parPos.x()),
526 parabel (pa0, p1x,p1y,p2x,p2y);
527 for (int i=0; i<segment.size(); ++i)
529 //segment.at(i)->prepareGeometryChange();
530 segment.at(i)->setLine(QLineF( pa0.at(i).x(), pa0.at(i).y(),pa0.at(i+1).x(),pa0.at(i+1).y()));
535 pa0<<QPointF (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
536 pa0<<QPointF (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
537 pa0<<QPointF (qRound (parPos.x()), qRound(parPos.y()) );
538 //p->prepareGeometryChange();
539 p->setPolygon(QPolygonF (pa0));
542 parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
543 parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
545 for (int i=0;i<=arcsegs;i++)
546 pa0 << QPointF (pa1.at(i));
547 for (int i=0;i<=arcsegs;i++)
548 pa0 << QPointF (pa2.at(arcsegs-i));
549 //p->prepareGeometryChange();
550 p->setPolygon(QPolygonF (pa0));
557 LinkableMapObj* LinkableMapObj::getChildObj()
562 LinkableMapObj* LinkableMapObj::getParObj()
567 QPointF LinkableMapObj::getChildPos()
572 QPointF LinkableMapObj::getParPos()
577 void LinkableMapObj::setUseOrientation (const bool &b)
579 if (useOrientation!=b)
586 LinkableMapObj::Orientation LinkableMapObj::getOrientation()
591 QPointF LinkableMapObj::getRandPos()
593 // Choose a random position with given distance to parent:
594 double a=rand()%360 * 2 * M_PI / 360;
595 return QPointF ( (int)( + 150*cos (a)),
596 (int)( + 150*sin (a)));
599 void LinkableMapObj::reposition()
603 void LinkableMapObj::requestReposition()
605 if (!repositionRequest)
607 // Pass on the request to parental objects, if this hasn't
609 repositionRequest=true;
610 if (parObj) parObj->requestReposition();
614 void LinkableMapObj::forceReposition()
616 // Sometimes a reposition has to be done immediatly: For example
617 // if the note editor flag changes, there is no user event in mapeditor
618 // which could collect requests for a reposition.
619 // Then we have to call forceReposition()
620 // But no rule without exception: While loading a map or undoing it,
621 // we want to block expensive repositioning, but just do it once at
622 // the end, thus check first:
624 if (model->isRepositionBlocked()) return;
626 // Pass on the request to parent objects, if this hasn't been done yet
628 parObj->forceReposition();
633 bool LinkableMapObj::repositionRequested()
635 return repositionRequest;
639 void LinkableMapObj::select()
641 // select and unselect are still needed to
642 // handle hiding of links
644 setVisibility (visible);
648 void LinkableMapObj::unselect()
651 // Maybe we have to hide the link:
652 setVisibility (visible);
655 void LinkableMapObj::parabel (QPolygonF &ya, double p1x, double p1y, double p2x, double p2y)
658 double vx=p2x - p1x; // V=P2-P1
661 double dx; // delta x during calculation of parabel
663 double pnx; // next point
667 if (vx > -0.0001 && vx < 0.0001)
673 ya<<QPointF (p1x,p1y);
674 for (int i=1;i<=arcsegs;i++)
677 pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
678 ya<<QPointF (pnx,pny);
684 QString LinkableMapObj::getLinkAttr ()
686 if (hideLinkUnselected)
687 return attribut ("hideLink","true");
689 return attribut ("hideLink","false");