4 #include "linkablemapobj.h"
8 /////////////////////////////////////////////////////////////////
10 /////////////////////////////////////////////////////////////////
12 LinkableMapObj::LinkableMapObj():MapObj()
14 // cout << "Const LinkableMapObj ()\n";
18 LinkableMapObj::LinkableMapObj(QGraphicsScene* s) :MapObj(s)
20 // cout << "Const LinkableMapObj (s)\n";
24 LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->scene)
29 LinkableMapObj::~LinkableMapObj()
35 void LinkableMapObj::delLink()
43 while (!segment.isEmpty()) delete segment.takeFirst();
56 void LinkableMapObj::init ()
64 childPos=QPointF(0,0);
67 orientation=UndefinedOrientation;
74 // TODO instead of linkcolor pen.color() could be used all around
76 pen.setColor (linkcolor);
77 pen.setCapStyle ( Qt::RoundCap );
78 bottomline=scene->addLine(QLineF(1,1,1,1),pen);
79 bottomline->setZValue(Z_LINK);
82 // Prepare showing the selection of a MapObj
85 hideLinkUnselected=false;
87 topPad=botPad=leftPad=rightPad=0;
89 repositionRequest=false;
100 void LinkableMapObj::copy (LinkableMapObj* other)
103 bboxTotal=other->bboxTotal;
104 setLinkStyle(other->style);
105 setLinkColor (other->linkcolor);
106 relPos=other->relPos;
107 useOrientation=other->useOrientation;
111 void LinkableMapObj::setChildObj(LinkableMapObj* o)
116 void LinkableMapObj::setParObj(LinkableMapObj* o)
119 mapEditor=parObj->getMapEditor();
122 void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPointF,int)
126 void LinkableMapObj::unsetParObjTmp()
130 bool LinkableMapObj::hasParObjTmp()
132 if (parObjTmpBuf) return true;
136 void LinkableMapObj::setUseRelPos (const bool &b)
141 void LinkableMapObj::setRelPos()
145 relPos.setX (absPos.x() - parObj->getChildPos().x() );
146 relPos.setY (absPos.y() - parObj->getChildPos().y() );
147 parObj->calcBBoxSize();
151 void LinkableMapObj::setRelPos(const QPointF &p)
156 parObj->calcBBoxSize();
161 QPointF LinkableMapObj::getRelPos()
163 if (!parObj) return QPointF();
167 qreal LinkableMapObj::getTopPad()
172 qreal LinkableMapObj::getLeftPad()
177 qreal LinkableMapObj::getRightPad()
182 LinkableMapObj::Style LinkableMapObj::getDefLinkStyle ()
184 if (!mapEditor) return UndefinedStyle;
185 Style ls=mapEditor->getMapLinkStyle();
209 return UndefinedStyle;
212 void LinkableMapObj::setLinkStyle(Style newstyle)
214 //if (newstyle=style) return;
219 if (childObj!=NULL && parObj != NULL)
221 QGraphicsLineItem *cl;
228 l = scene->addLine(QLineF(1,1,1,1),pen);
229 l->setZValue(Z_LINK);
236 for (int i=0;i<arcsegs;i++)
238 cl = scene->addLine(QLineF(i*5,0,i*10,100),pen);
239 cl->setZValue(Z_LINK);
246 pa0.resize (arcsegs+1);
249 p =scene->addPolygon(QPolygonF(),pen,linkcolor);
250 p->setZValue(Z_LINK);
258 p = scene->addPolygon(QPolygonF(),pen,linkcolor);
259 p->setZValue(Z_LINK);
264 pa0.resize (arcsegs*2+2);
265 pa1.resize (arcsegs+1);
266 pa2.resize (arcsegs+1);
274 LinkableMapObj::Style LinkableMapObj::getLinkStyle()
279 void LinkableMapObj::setHideLinkUnselected(bool b)
281 hideLinkUnselected=b;
282 setVisibility (visible);
286 bool LinkableMapObj::getHideLinkUnselected()
288 return hideLinkUnselected;
291 void LinkableMapObj::setLinkPos(Position lp)
296 LinkableMapObj::Position LinkableMapObj::getLinkPos()
301 void LinkableMapObj::setID (const QString &s)
306 QString LinkableMapObj::getID()
311 void LinkableMapObj::setLinkColor()
313 // Overloaded in BranchObj and childs
314 // here only set default color
316 setLinkColor (mapEditor->getMapDefLinkColor());
319 void LinkableMapObj::setLinkColor(QColor col)
323 bottomline->setPen( pen );
330 for (int i=0; i<segment.size(); ++i)
331 segment.at(i)->setPen( pen);
334 p->setBrush( QBrush(col));
338 p->setBrush( QBrush(col));
346 QColor LinkableMapObj::getLinkColor()
351 void LinkableMapObj::setVisibility (bool v)
353 MapObj::setVisibility (v);
356 // We can hide the link, while object is not selected
357 if (hideLinkUnselected && !selected)
369 for (int i=0; i<segment.size(); ++i)
370 segment.at(i)->show();
390 for (int i=0; i<segment.size(); ++i)
391 segment.at(i)->hide();
405 void LinkableMapObj::setOrientation()
407 Orientation orientOld=orientation;
411 orientation=UndefinedOrientation;
415 // Set orientation, first look for orientation of parent
416 if (parObj->getOrientation() != UndefinedOrientation )
417 // use the orientation of the parent:
418 orientation=parObj->getOrientation();
421 // calc orientation depending on position rel to parent
422 if (absPos.x() < QPointF(parObj->getChildPos() ).x() )
423 orientation=LeftOfCenter;
425 orientation=RightOfCenter;
427 if (orientOld!=orientation) requestReposition();
430 void LinkableMapObj::updateLink()
433 // childPos of parent
439 // childPos (by calling setDockPos())
440 // parPos (by calling setDockPos())
442 // drawing of the link itself
444 // updateLink is called from move, but called from constructor we don't
445 // have parents yet...
446 if (style==UndefinedStyle) return;
451 bottomlineY=bbox.top() + bbox.height()/2; // draw link to middle (of frame)
454 bottomlineY=bbox.bottom()-1; // draw link to bottom of box
458 double p2x,p2y; // Set P2 Before setting
461 p2x=QPointF( parObj->getChildPos() ).x(); // P1, we have to look at
462 p2y=QPointF( parObj->getChildPos() ).y(); // orientation
465 p2x=QPointF( parObj->getParPos() ).x();
466 p2y=QPointF( parObj->getParPos() ).y();
469 setDockPos(); // Call overloaded method
472 double p1x=parPos.x(); // Link is drawn from P1 to P2
473 double p1y=parPos.y();
475 double vx=p2x - p1x; // V=P2-P1
478 // Draw the horizontal line below heading (from ChildPos to ParPos)
479 //bottomline->prepareGeometryChange();
480 bottomline->setLine (QLine (qRound(childPos.x()),
481 qRound(childPos.y()),
486 if (vx > -0.000001 && vx < 0.000001)
490 // "turning point" for drawing polygonal links
491 QPointF tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));
497 //l->prepareGeometryChange();
498 l->setLine( QLine(qRound (parPos.x()),
504 parabel (pa0, p1x,p1y,p2x,p2y);
505 for (int i=0; i<segment.size(); ++i)
507 //segment.at(i)->prepareGeometryChange();
508 segment.at(i)->setLine(QLineF( pa0.at(i).x(), pa0.at(i).y(),pa0.at(i+1).x(),pa0.at(i+1).y()));
513 pa0<<QPointF (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
514 pa0<<QPointF (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
515 pa0<<QPointF (qRound (parPos.x()), qRound(parPos.y()) );
516 //p->prepareGeometryChange();
517 p->setPolygon(QPolygonF (pa0));
520 parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
521 parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
523 for (int i=0;i<=arcsegs;i++)
524 pa0 << QPointF (pa1.at(i));
525 for (int i=0;i<=arcsegs;i++)
526 pa0 << QPointF (pa2.at(arcsegs-i));
527 //p->prepareGeometryChange();
528 p->setPolygon(QPolygonF (pa0));
535 LinkableMapObj* LinkableMapObj::getChildObj()
540 LinkableMapObj* LinkableMapObj::getParObj()
545 LinkableMapObj* LinkableMapObj::findObjBySelect (QString s)
547 LinkableMapObj *lmo=this;
551 while (!s.isEmpty() )
553 part=s.section(",",0,0);
555 num=part.right(part.length() - 3);
559 return false; // in a subtree there is no center
564 lmo=((BranchObj*)lmo)->getBranchNum (num.toInt());
567 lmo=((BranchObj*)lmo)->getFloatImageNum (num.toUInt());
571 s=s.right(s.length() - part.length() -1 );
578 QPointF LinkableMapObj::getChildPos()
583 QPointF LinkableMapObj::getParPos()
588 void LinkableMapObj::setUseOrientation (const bool &b)
590 if (useOrientation!=b)
597 LinkableMapObj::Orientation LinkableMapObj::getOrientation()
602 int LinkableMapObj::getDepth()
607 void LinkableMapObj::setMapEditor (MapEditor *me)
612 MapEditor* LinkableMapObj::getMapEditor ()
617 QPointF LinkableMapObj::getRandPos()
619 // Choose a random position with given distance to parent:
620 double a=rand()%360 * 2 * M_PI / 360;
621 return QPointF ( (int)( + 150*cos (a)),
622 (int)( + 150*sin (a)));
625 void LinkableMapObj::reposition()
629 void LinkableMapObj::requestReposition()
631 if (!repositionRequest)
633 // Pass on the request to parental objects, if this hasn't
635 repositionRequest=true;
636 if (parObj) parObj->requestReposition();
640 void LinkableMapObj::forceReposition()
642 // Sometimes a reposition has to be done immediatly: For example
643 // if the note editor flag changes, there is no user event in mapeditor
644 // which could collect requests for a reposition.
645 // Then we have to call forceReposition()
646 // But no rule without exception: While loading a map or undoing it,
647 // we want to block expensive repositioning, but just do it once at
648 // the end, thus check first:
650 if (mapEditor->isRepositionBlocked()) return;
652 // Pass on the request to parental objects, if this hasn't been done yet
655 parObj->forceReposition();
660 bool LinkableMapObj::repositionRequested()
662 return repositionRequest;
666 void LinkableMapObj::select()
668 // select and unselect are still needed to
669 // handle hiding of links
671 setVisibility (visible);
675 void LinkableMapObj::unselect()
678 // Maybe we have to hide the link:
679 setVisibility (visible);
682 void LinkableMapObj::parabel (QPolygonF &ya, double p1x, double p1y, double p2x, double p2y)
685 double vx=p2x - p1x; // V=P2-P1
688 double dx; // delta x during calculation of parabel
690 double pnx; // next point
694 if (vx > -0.0001 && vx < 0.0001)
700 ya<<QPointF (p1x,p1y);
701 for (int i=1;i<=arcsegs;i++)
704 pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
705 ya<<QPointF (pnx,pny);
711 QString LinkableMapObj::getLinkAttr ()
713 if (hideLinkUnselected)
714 return attribut ("hideLink","true");
716 return attribut ("hideLink","false");