3 #include "linkablemapobj.h"
7 /////////////////////////////////////////////////////////////////
9 /////////////////////////////////////////////////////////////////
11 LinkableMapObj::LinkableMapObj():MapObj()
13 // cout << "Const LinkableMapObj ()\n";
17 LinkableMapObj::LinkableMapObj(QGraphicsScene* s) :MapObj(s)
19 // cout << "Const LinkableMapObj (s)\n";
23 LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->scene)
28 LinkableMapObj::~LinkableMapObj()
34 void LinkableMapObj::delLink()
42 while (!segment.isEmpty()) delete segment.takeFirst();
55 void LinkableMapObj::init ()
63 childPos=QPointF(0,0);
66 orientation=UndefinedOrientation;
73 // TODO instead of linkcolor pen.color() could be used all around
75 pen.setColor (linkcolor);
76 pen.setCapStyle ( Qt::RoundCap );
77 bottomline=scene->addLine(QLineF(1,1,1,1),pen);
78 bottomline->setZValue(Z_LINK);
81 // Prepare showing the selection of a MapObj
84 hideLinkUnselected=false;
86 topPad=botPad=leftPad=rightPad=0;
88 repositionRequest=false;
96 void LinkableMapObj::copy (LinkableMapObj* other)
99 bboxTotal=other->bboxTotal;
100 setLinkStyle(other->style);
101 setLinkColor (other->linkcolor);
102 relPos=other->relPos;
103 useOrientation=other->useOrientation;
107 void LinkableMapObj::setChildObj(LinkableMapObj* o)
112 void LinkableMapObj::setParObj(LinkableMapObj* o)
115 mapEditor=parObj->getMapEditor();
118 void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPointF,int)
122 void LinkableMapObj::unsetParObjTmp()
126 bool LinkableMapObj::hasParObjTmp()
128 if (parObjTmpBuf) return true;
132 void LinkableMapObj::setUseRelPos (const bool &b)
137 void LinkableMapObj::setRelPos()
141 relPos.setX (absPos.x() - parObj->getChildPos().x() );
142 relPos.setY (absPos.y() - parObj->getChildPos().y() );
143 parObj->calcBBoxSize();
146 qWarning ("LMO::setRelPos No parent yet!");
150 void LinkableMapObj::setRelPos(const QPointF &p)
155 parObj->calcBBoxSize();
159 qWarning ("LMO::setRelPos No parent yet!");
163 QPointF LinkableMapObj::getRelPos()
165 if (!parObj) return QPointF();
169 qreal LinkableMapObj::getTopPad()
174 qreal LinkableMapObj::getLeftPad()
179 qreal LinkableMapObj::getRightPad()
184 LinkableMapObj::Style LinkableMapObj::getDefLinkStyle ()
186 if (mapEditor==0) return UndefinedStyle;
187 Style ls=mapEditor->getMapLinkStyle();
211 return UndefinedStyle;
214 void LinkableMapObj::setLinkStyle(Style newstyle)
216 //if (newstyle=style) return;
221 if (childObj!=NULL && parObj != NULL)
223 QGraphicsLineItem *cl;
230 l = scene->addLine(QLineF(1,1,1,1),pen);
231 l->setZValue(Z_LINK);
238 for (int i=0;i<arcsegs;i++)
240 cl = scene->addLine(QLineF(i*5,0,i*10,100),pen);
241 cl->setZValue(Z_LINK);
248 pa0.resize (arcsegs+1);
251 p =scene->addPolygon(QPolygonF(),pen,linkcolor);
252 p->setZValue(Z_LINK);
260 p = scene->addPolygon(QPolygonF(),pen,linkcolor);
261 p->setZValue(Z_LINK);
266 pa0.resize (arcsegs*2+2);
267 pa1.resize (arcsegs+1);
268 pa2.resize (arcsegs+1);
276 LinkableMapObj::Style LinkableMapObj::getLinkStyle()
281 void LinkableMapObj::setHideLinkUnselected(bool b)
283 hideLinkUnselected=b;
284 setVisibility (visible);
288 bool LinkableMapObj::getHideLinkUnselected()
290 return hideLinkUnselected;
293 void LinkableMapObj::setLinkPos(Position lp)
298 LinkableMapObj::Position LinkableMapObj::getLinkPos()
304 void LinkableMapObj::setLinkColor()
306 // Overloaded in BranchObj and childs
307 // here only set default color
309 setLinkColor (mapEditor->getMapDefLinkColor());
312 void LinkableMapObj::setLinkColor(QColor col)
316 bottomline->setPen( pen );
323 for (int i=0; i<segment.size(); ++i)
324 segment.at(i)->setPen( pen);
327 p->setBrush( QBrush(col));
330 p->setBrush( QBrush(col));
337 QColor LinkableMapObj::getLinkColor()
342 void LinkableMapObj::setVisibility (bool v)
344 MapObj::setVisibility (v);
347 // We can hide the link, while object is not selected
348 if (hideLinkUnselected && !selected)
360 for (int i=0; i<segment.size(); ++i)
361 segment.at(i)->show();
381 for (int i=0; i<segment.size(); ++i)
382 segment.at(i)->hide();
396 void LinkableMapObj::setOrientation()
398 Orientation orientOld=orientation;
402 orientation=UndefinedOrientation;
406 // Set orientation, first look for orientation of parent
407 if (parObj->getOrientation() != UndefinedOrientation )
408 // use the orientation of the parent:
409 orientation=parObj->getOrientation();
412 // calc orientation depending on position rel to parent
413 if (absPos.x() < QPointF(parObj->getChildPos() ).x() )
414 orientation=LeftOfCenter;
416 orientation=RightOfCenter;
418 if (orientOld!=orientation) requestReposition();
421 void LinkableMapObj::updateLink()
424 // childPos of parent
430 // childPos (by calling setDockPos())
431 // parPos (by calling setDockPos())
433 // drawing of the link itself
435 // updateLink is called from move, but called from constructor we don't
436 // have parents yet...
437 if (style==UndefinedStyle) return;
442 bottomlineY=bbox.top() + bbox.height()/2; // draw link to middle (of frame)
445 bottomlineY=bbox.bottom()-1; // draw link to bottom of box
449 double p2x,p2y; // Set P2 Before setting
452 p2x=QPointF( parObj->getChildPos() ).x(); // P1, we have to look at
453 p2y=QPointF( parObj->getChildPos() ).y(); // orientation
456 p2x=QPointF( parObj->getParPos() ).x();
457 p2y=QPointF( parObj->getParPos() ).y();
460 setDockPos(); // Call overloaded method
463 double p1x=parPos.x(); // Link is drawn from P1 to P2
464 double p1y=parPos.y();
466 double vx=p2x - p1x; // V=P2-P1
469 // Draw the horizontal line below heading (from ChildPos to ParPos)
470 //bottomline->prepareGeometryChange();
471 bottomline->setLine (QLine (qRound(childPos.x()),
472 qRound(childPos.y()),
477 if (vx > -0.000001 && vx < 0.000001)
481 // "turning point" for drawing polygonal links
482 QPointF tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));
488 //l->prepareGeometryChange();
489 l->setLine( QLine(qRound (parPos.x()),
495 parabel (pa0, p1x,p1y,p2x,p2y);
496 for (int i=0; i<segment.size(); ++i)
498 //segment.at(i)->prepareGeometryChange();
499 segment.at(i)->setLine(QLineF( pa0.at(i).x(), pa0.at(i).y(),pa0.at(i+1).x(),pa0.at(i+1).y()));
504 pa0<<QPointF (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
505 pa0<<QPointF (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
506 pa0<<QPointF (qRound (parPos.x()), qRound(parPos.y()) );
507 //p->prepareGeometryChange();
508 p->setPolygon(QPolygonF (pa0));
511 parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
512 parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
514 for (int i=0;i<=arcsegs;i++)
515 pa0 << QPointF (pa1.at(i));
516 for (int i=0;i<=arcsegs;i++)
517 pa0 << QPointF (pa2.at(arcsegs-i));
518 //p->prepareGeometryChange();
519 p->setPolygon(QPolygonF (pa0));
526 LinkableMapObj* LinkableMapObj::getChildObj()
531 LinkableMapObj* LinkableMapObj::getParObj()
536 LinkableMapObj* LinkableMapObj::findObjBySelect (QString s)
538 LinkableMapObj *lmo=this;
542 while (!s.isEmpty() )
544 part=s.section(",",0,0);
546 num=part.right(part.length() - 3);
550 return false; // in a subtree there is no center
555 lmo=((BranchObj*)(lmo))->getBranchNum (num.toInt());
558 lmo=((BranchObj*)(lmo))->getFloatImageNum (num.toUInt());
562 s=s.right(s.length() - part.length() -1 );
569 QPointF LinkableMapObj::getChildPos()
574 QPointF LinkableMapObj::getParPos()
579 void LinkableMapObj::setUseOrientation (const bool &b)
581 if (useOrientation!=b)
588 LinkableMapObj::Orientation LinkableMapObj::getOrientation()
593 int LinkableMapObj::getDepth()
598 void LinkableMapObj::setMapEditor (MapEditor *me)
603 MapEditor* LinkableMapObj::getMapEditor ()
608 QPointF LinkableMapObj::getRandPos()
610 // Choose a random position with given distance to parent:
611 double a=rand()%360 * 2 * M_PI / 360;
612 return QPointF ( (int)( + 150*cos (a)),
613 (int)( + 150*sin (a)));
616 void LinkableMapObj::reposition()
620 void LinkableMapObj::requestReposition()
622 if (!repositionRequest)
624 // Pass on the request to parental objects, if this hasn't
626 repositionRequest=true;
627 if (parObj) parObj->requestReposition();
631 void LinkableMapObj::forceReposition()
633 // Sometimes a reposition has to be done immediatly: For example
634 // if the note editor flag changes, there is no user event in mapeditor
635 // which could collect requests for a reposition.
636 // Then we have to call forceReposition()
637 // But no rule without exception: While loading a map or undoing it,
638 // we want to block expensive repositioning, but just do it once at
639 // the end, thus check first:
641 if (mapEditor->isRepositionBlocked()) return;
643 // Pass on the request to parental objects, if this hasn't been done yet
646 parObj->forceReposition();
651 bool LinkableMapObj::repositionRequested()
653 return repositionRequest;
657 void LinkableMapObj::select()
659 // select and unselect are still needed to
660 // handle hiding of links
662 setVisibility (visible);
666 void LinkableMapObj::unselect()
669 // Maybe we have to hide the link:
670 setVisibility (visible);
673 void LinkableMapObj::parabel (QPolygonF &ya, double p1x, double p1y, double p2x, double p2y)
676 double vx=p2x - p1x; // V=P2-P1
679 double dx; // delta x during calculation of parabel
681 double pnx; // next point
685 if (vx > -0.0001 && vx < 0.0001)
691 ya<<QPointF (qRound(p1x),qRound(p1y));
692 for (int i=1;i<=arcsegs;i++)
695 pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
696 ya<<QPointF (qRound(pnx),qRound(pny));
702 QString LinkableMapObj::getLinkAttr ()
704 if (hideLinkUnselected)
705 return attribut ("hideLink","true");
707 return attribut ("hideLink","false");