linkablemapobj.cpp
author insilmaril
Wed, 15 Mar 2006 13:53:53 +0000
changeset 249 e7acede0377c
parent 225 d5c70aaca22d
child 250 0e994bf2346b
permissions -rw-r--r--
hide export for floatimages.
     1 #include <math.h>
     2 
     3 #include "linkablemapobj.h"
     4 #include "branchobj.h"
     5 #include "mapeditor.h"
     6 
     7 #include "version.h"
     8 
     9 
    10 /////////////////////////////////////////////////////////////////
    11 // LinkableMapObj
    12 /////////////////////////////////////////////////////////////////
    13 
    14 LinkableMapObj::LinkableMapObj():MapObj()
    15 {
    16   //  cout << "Const LinkableMapObj ()\n";
    17     init ();
    18 }
    19 
    20 LinkableMapObj::LinkableMapObj(QCanvas* c) :MapObj(c)
    21 {
    22 //    cout << "Const LinkableMapObj\n";
    23     init ();
    24 }
    25 
    26 LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->canvas)
    27 {
    28     copy (lmo);
    29 }
    30 
    31 LinkableMapObj::~LinkableMapObj()
    32 {
    33     delete (bottomline);
    34     delete (selbox);
    35 	delete (frame);
    36 	delLink();
    37 }
    38 
    39 void LinkableMapObj::delLink()
    40 {
    41 	switch (style)
    42 	{
    43 		case StyleLine:
    44 			delete (l);
    45 			break;
    46 		case StyleParabel:
    47 			segment.clear();
    48 			break;
    49 		case StylePolyLine:
    50 			delete (p);
    51 			delete (l);
    52 			break;
    53 		case StylePolyParabel:
    54 			delete (p);
    55 			segment.clear();
    56 			break;
    57 		default:
    58 			break;
    59 	}		
    60 }
    61 
    62 void LinkableMapObj::init ()
    63 {
    64     depth=-1;	
    65 	mapEditor=NULL;
    66     childObj=NULL;
    67     parObj=NULL;
    68     parObjTmpBuf=NULL;
    69     parPos=QPoint(0,0);
    70     childPos=QPoint(0,0);
    71 	link2ParPos=false;
    72     l=NULL;
    73     orientation=OrientUndef;
    74     linkwidth=20;		
    75 	thickness_start=8;
    76     style=StyleUndef;
    77 	linkpos=LinkBottom;
    78     segment.setAutoDelete (TRUE);
    79     arcsegs=13;
    80 	QPointArray pa(arcsegs*2+2);
    81     
    82     bottomline=new QCanvasLine(canvas);
    83     bottomline->setPen( QPen(linkcolor, 1) );
    84     bottomline->setZ(Z_LINK);
    85     bottomline->show();
    86 
    87     // Prepare showing the selection of a MapObj
    88     selbox = new QCanvasRectangle (canvas);
    89     selbox->setZ(Z_SELBOX);
    90     selbox->setBrush( QColor(255,255,0) );
    91     selbox->setPen( QPen(QColor(255,255,0) ));
    92     selbox->hide();
    93     selected=false;
    94 
    95 	hideLinkUnselected=false;
    96 
    97 	topPad=botPad=leftPad=rightPad=0;
    98 
    99 	// initialize frame
   100 	frame = new FrameObj (canvas);
   101 	
   102 	repositionRequest=false;
   103 
   104 	// Rel Positions
   105 	relPos=QPoint(0,0);
   106 	useOrientation=true;
   107 }
   108 
   109 void LinkableMapObj::copy (LinkableMapObj* other)
   110 {
   111     MapObj::copy(other);
   112 	bboxTotal=other->bboxTotal;
   113     setLinkStyle(other->style);
   114     setLinkColor (other->linkcolor);
   115 	relPos=other->relPos;
   116 	useOrientation=other->useOrientation;
   117 
   118 }
   119 
   120 void LinkableMapObj::setChildObj(LinkableMapObj* o)
   121 {
   122     childObj=o;
   123 }
   124 
   125 void LinkableMapObj::setParObj(LinkableMapObj* o)
   126 {
   127     parObj=o;
   128 	mapEditor=parObj->getMapEditor();
   129 }
   130 
   131 void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPoint,int)
   132 {
   133 }
   134 
   135 void LinkableMapObj::unsetParObjTmp()
   136 {
   137 }
   138 
   139 bool LinkableMapObj::hasParObjTmp()
   140 {
   141 	if (parObjTmpBuf) return true;
   142 	return false;
   143 }
   144 
   145 void LinkableMapObj::setUseRelPos (const bool &b)
   146 {
   147 	useRelPos=b;
   148 }
   149 
   150 void LinkableMapObj::setRelPos()
   151 {
   152 	if (parObj)
   153 	{	
   154 		relPos.setX (absPos.x() - parObj->getChildPos().x() );
   155 		relPos.setY (absPos.y() - parObj->getChildPos().y() );
   156 
   157 		parObj->calcBBoxSize();
   158 		parObj->requestReposition();
   159 	}	
   160 }
   161 
   162 void LinkableMapObj::setRelPos(const QPoint &p)
   163 {
   164 	relPos=p;
   165 	if (parObj)
   166 	{	parObj->calcBBoxSize();
   167 		parObj->requestReposition();
   168 	}	
   169 }
   170 
   171 int LinkableMapObj::getTopPad()
   172 {
   173 	return topPad;
   174 }
   175 
   176 int LinkableMapObj::getLeftPad()
   177 {
   178 	return leftPad;
   179 }
   180 
   181 int LinkableMapObj::getRightPad()
   182 {
   183 	return rightPad;
   184 }
   185 
   186 LinkStyle LinkableMapObj::getDefLinkStyle ()
   187 {
   188 	if (!mapEditor) return StyleUndef;
   189 
   190 	LinkStyle ls=mapEditor->getLinkStyle();
   191 	switch (ls)
   192 	{
   193 		case StyleLine: 
   194 			return ls;
   195 			break;
   196 		case StyleParabel:
   197 			return ls;
   198 			break;
   199 		case StylePolyLine:	
   200 			if (depth>1)
   201 				return StyleLine;
   202 			else	
   203 				return ls;
   204 			break;
   205 		case StylePolyParabel:	
   206 			if (depth>1)
   207 				return StyleParabel;
   208 			else	
   209 				return ls;
   210 			break;
   211 		default: 
   212 			break;	
   213 	}	
   214 	return StyleUndef;
   215 }
   216 
   217 void LinkableMapObj::setLinkStyle(LinkStyle newstyle)
   218 {
   219 	//if (newstyle=style) return;
   220 	delLink();
   221 		
   222 	style=newstyle;
   223 
   224     if (childObj!=NULL && parObj != NULL)
   225     {
   226 		int i;
   227 		QCanvasLine* cl;
   228 		switch (style)
   229 		{
   230 			case StyleUndef:
   231 				bottomline->hide();
   232 				break;
   233 			case StyleLine: 
   234 				l = new QCanvasLine(canvas);
   235 				l->setPen( QPen(linkcolor, 1) );
   236 				l->setZ(Z_LINK);
   237 				if (visible)
   238 					l->show();
   239 				else
   240 					l->hide();
   241 				break;
   242 			case StyleParabel:
   243 				for (i=0;i<arcsegs;i++)
   244 				{
   245 					cl = new QCanvasLine(canvas);
   246 					cl->setPen( QPen(linkcolor, 1) );
   247 					cl->setPoints( 0,0,i*10,100);
   248 					cl->setZ(Z_LINK);
   249 					if (visible)
   250 						cl->show();
   251 					else
   252 						cl->hide();
   253 					segment.append(cl);
   254 				}
   255 				pa0.resize (arcsegs+1);
   256 				break;
   257 			case StylePolyLine:	
   258 				p = new QCanvasPolygon(canvas);
   259 				p->setBrush( linkcolor );
   260 				p->setZ(Z_LINK);
   261 				if (visible)
   262 					p->show();
   263 				else
   264 					p->hide();
   265 				pa0.resize (3);
   266 				// TODO a bit awkward: draw the lines additionally to polygon, to avoid
   267 				// missing pixels, when polygon is extremly flat
   268 				l = new QCanvasLine(canvas);
   269 				l->setPen( QPen(linkcolor, 1) );
   270 				l->setZ(Z_LINK);
   271 				if (visible)
   272 					l->show();
   273 				else
   274 					l->hide();
   275 				break;
   276 			case StylePolyParabel:	
   277 				p = new QCanvasPolygon(canvas);
   278 				p->setBrush( linkcolor );
   279 				p->setZ(Z_LINK);
   280 				if (visible)
   281 					p->show();
   282 				else
   283 					p->hide();
   284 				pa0.resize (arcsegs*2+2);
   285 				pa1.resize (arcsegs+1);
   286 				pa2.resize (arcsegs+1);
   287 
   288 				// TODO a bit awkward: draw the lines additionally 
   289 				// to polygon, to avoid missing pixels, 
   290 				// if polygon is extremly flat
   291 				for (i=0;i<arcsegs;i++)
   292 				{
   293 					cl = new QCanvasLine(canvas);
   294 					cl->setPen( QPen(linkcolor, 1) );
   295 					cl->setPoints( 0,0,i*10,100);
   296 					cl->setZ(Z_LINK);
   297 					if (visible)
   298 						cl->show();
   299 					else
   300 						cl->hide();
   301 					segment.append(cl);
   302 				}
   303 				break;
   304 			default: 
   305 				break;	
   306 		}	
   307 	} 
   308 }
   309 
   310 LinkStyle LinkableMapObj::getLinkStyle()
   311 {
   312 	return style;
   313 }
   314 
   315 void LinkableMapObj::setHideLinkUnselected(bool b)
   316 {
   317 	hideLinkUnselected=b;
   318 	setVisibility (visible);
   319 	updateLink();
   320 }
   321 
   322 bool LinkableMapObj::getHideLinkUnselected()
   323 {
   324 	return hideLinkUnselected;
   325 }
   326 
   327 void LinkableMapObj::setLinkPos(LinkPos lp)
   328 {
   329 	linkpos=lp;
   330 }
   331 
   332 LinkPos LinkableMapObj::getLinkPos()
   333 {
   334 	return linkpos;
   335 }
   336 
   337 
   338 void LinkableMapObj::setLinkColor()
   339 {
   340 	// Overloaded in BranchObj and childs
   341 	// here only set default color
   342 	if (mapEditor)
   343 		setLinkColor (mapEditor->getDefLinkColor());
   344 }
   345 
   346 void LinkableMapObj::setLinkColor(QColor col)
   347 {
   348 	linkcolor=col;
   349     bottomline->setPen( QPen(linkcolor, 1) );
   350 	QCanvasLine *cl;
   351 	switch (style)
   352 	{
   353 		case StyleLine:
   354 			l->setPen( QPen(col,1));
   355 			break;	
   356 		case StyleParabel:	
   357 			for (cl=segment.first(); cl; cl=segment.next() )
   358 				cl->setPen( QPen(col,1));
   359 			break;
   360 		case StylePolyLine:
   361 			p->setBrush( QBrush(col));
   362 			l->setPen( QPen(col,1));
   363 			break;
   364 		case StylePolyParabel:	
   365 			p->setBrush( QBrush(col));
   366 			for (cl=segment.first(); cl; cl=segment.next() )
   367 				cl->setPen( QPen(col,1));
   368 			break;
   369 		default:
   370 			break;
   371 	} // switch (style)	
   372 }
   373 
   374 QColor LinkableMapObj::getLinkColor()
   375 {
   376 	return linkcolor;
   377 }
   378 
   379 FrameType LinkableMapObj::getFrameType()
   380 {
   381 	return frame->getFrameType();
   382 }
   383 
   384 void LinkableMapObj::setFrameType(const FrameType &t)
   385 {
   386 	frame->setFrameType(t);
   387 	calcBBoxSize();
   388 	positionBBox();
   389 	requestReposition();
   390 }
   391 
   392 void LinkableMapObj::setFrameType(const QString &t)
   393 {
   394 	frame->setFrameType(t);
   395 	calcBBoxSize();
   396 	positionBBox();
   397 	requestReposition();
   398 }
   399 
   400 void LinkableMapObj::setVisibility (bool v)
   401 {
   402 	QCanvasLine* cl;
   403 	MapObj::setVisibility (v);
   404 	bool visnow=visible;
   405 	if (hideLinkUnselected && !selected)
   406 		visnow=false;
   407 
   408 	if (visnow) 
   409 	{
   410 		bottomline->show();
   411 		switch (style)
   412 		{
   413 			case StyleLine:
   414 				if (l) l->show();
   415 				break;
   416 			case StyleParabel:	
   417 				for (cl=segment.first(); cl; cl=segment.next() )
   418 					cl->show();
   419 				break;	
   420 			case StylePolyLine:
   421 				if (p) p->show();
   422 				if (l) l->show();
   423 				break;
   424 			case StylePolyParabel:	
   425 				for (cl=segment.first(); cl; cl=segment.next() )
   426 					cl->show();
   427 				if (p) p->show();
   428 				break;
   429 			default:
   430 				break;
   431 		}
   432 	} else 
   433 	{
   434 		bottomline->hide();
   435 		switch (style)
   436 		{
   437 			case StyleLine:
   438 				if (l) l->hide();
   439 				break;
   440 			case StyleParabel:	
   441 				for (cl=segment.first(); cl; cl=segment.next() )
   442 					cl->hide();
   443 				break;	
   444 			case StylePolyLine:
   445 				if (p) p->hide();
   446 				if (l) l->hide();
   447 				break;
   448 			case StylePolyParabel:	
   449 				for (cl=segment.first(); cl; cl=segment.next() )
   450 					cl->hide();
   451 				if (p) p->hide();
   452 				break;
   453 			default:
   454 				break;
   455 		}
   456 	}	
   457 }
   458 
   459 void LinkableMapObj::updateLink()
   460 {
   461     // needs:
   462     //	childPos of parent
   463     //	orient   of parent
   464     //	style
   465     // 
   466     // sets:
   467     //	orientation
   468     //	childPos	(by calling setDockPos())
   469     //	parPos		(by calling setDockPos())
   470 	//  bottomlineY
   471     //	drawing of the link itself
   472 
   473 	// updateLink is called from move, but called from constructor we don't
   474 	// have parents yet...
   475 	if (style==StyleUndef) return;	
   476 
   477 	if (frame->getFrameType() == NoFrame)
   478 		linkpos=LinkBottom;
   479 	else	
   480 		linkpos=LinkMiddle;
   481 	switch (linkpos)
   482 	{
   483 		case LinkMiddle:
   484 			bottomlineY=bbox.top()+bbox.height() /2;	// draw link to middle (of frame)
   485 			break;
   486 		default :
   487 			bottomlineY=bbox.bottom()-1;	// draw link to bottom of box
   488 			break;
   489 	}
   490 	
   491     double p2x,p2y;								// Set P2 Before setting
   492 	if (!link2ParPos)
   493 	{
   494 		p2x=QPoint( parObj->getChildPos() ).x();	// P1, we have to look at
   495 		p2y=QPoint( parObj->getChildPos() ).y();	// orientation
   496 	} else	
   497 	{
   498 		p2x=QPoint( parObj->getParPos() ).x();	
   499 		p2y=QPoint( parObj->getParPos() ).y();
   500 	} 
   501 
   502 	LinkOrient orientOld=orientation;
   503 
   504     // Set orientation, first look for orientation of parent
   505     if (parObj->getOrientation() != OrientUndef ) 
   506 		// use the orientation of the parent:
   507 		orientation=parObj->getOrientation();
   508     else
   509     {
   510 		// calc orientation depending on position rel to mapCenter
   511 		if (absPos.x() < QPoint(parObj->getChildPos() ).x() )
   512 			orientation=OrientLeftOfCenter; 
   513 		else
   514 			orientation=OrientRightOfCenter;
   515     }
   516 
   517 	if ((orientation!=orientOld) && (orientOld!= OrientUndef))
   518 	{
   519 		// Orientation just changed. Reorient this subbranch, because move is called
   520 		// before updateLink => Position is still the old one, which could lead to 
   521 		// linking of subranch to itself => segfault
   522 		//
   523 		// Also possible: called in BranchObj::init(), then orientOld==OrientUndef,
   524 		// no need to reposition now
   525 		reposition();
   526 	}
   527 	
   528 	setDockPos();
   529 
   530 	double p1x=parPos.x();	// Link is drawn from P1 to P2
   531 	double p1y=parPos.y();
   532 
   533 	double vx=p2x - p1x;	// V=P2-P1
   534 	double vy=p2y - p1y;
   535 
   536 	// Draw the horizontal line below heading (from ChildPos to ParPos)
   537 	bottomline->setPoints (qRound(childPos.x()),
   538 		qRound(childPos.y()),
   539 		qRound(p1x),
   540 		qRound(p1y) );
   541 
   542 	double a;	// angle
   543 	if (vx > -0.000001 && vx < 0.000001)
   544 		a=M_PI_2;
   545 	else
   546 		a=atan( vy / vx );
   547 	// "turning point" for drawing polygonal links
   548 	QPoint tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));	
   549 	
   550 	QCanvasLine *cl;
   551 
   552 	int i;
   553 
   554     // Draw the link
   555 	switch (style)
   556 	{
   557 		case StyleLine:
   558 			l->setPoints( qRound (parPos.x()),
   559 				qRound(parPos.y()),
   560 				qRound(p2x),
   561 				qRound(p2y) );
   562 			break;	
   563 		case StyleParabel:	
   564 			parabel (pa0, p1x,p1y,p2x,p2y);
   565 			i=0;
   566 			for (cl=segment.first(); cl; cl=segment.next() )
   567 			{	
   568 				cl->setPoints( pa0.point(i).x(), pa0.point(i).y(),pa0.point(i+1).x(),pa0.point(i+1).y());
   569 				i++;
   570 			}
   571 			break;
   572 		case StylePolyLine:
   573 			pa0[0]=QPoint (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
   574 			pa0[1]=QPoint (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
   575 			pa0[2]=QPoint (qRound (parPos.x()), qRound(parPos.y()) );
   576 			p->setPoints (pa0);
   577 			// here too, draw line to avoid missing pixels
   578 			l->setPoints( qRound (parPos.x()),
   579 				qRound(parPos.y()),
   580 				qRound(p2x),
   581 				qRound(p2y) );
   582 			break;
   583 		case StylePolyParabel:	
   584 			parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
   585 			parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
   586 			for (i=0;i<=arcsegs;i++)
   587 			{
   588 				// Combine the arrays to a single one
   589 				pa0[i]=pa1[i];
   590 				pa0[i+arcsegs+1]=pa2[arcsegs-i];
   591 			}	
   592 			p->setPoints (pa0);
   593 			i=0;
   594 			for (cl=segment.first(); cl; cl=segment.next() )
   595 			{	
   596 				cl->setPoints( pa1.point(i).x(), pa1.point(i).y(),pa1.point(i+1).x(),pa1.point(i+1).y());
   597 				i++;
   598 			}
   599 			break;
   600 		default:
   601 			break;
   602 	} // switch (style)	
   603 }
   604 	
   605 LinkableMapObj* LinkableMapObj::getChildObj()
   606 {
   607     return childObj;
   608 }
   609 
   610 LinkableMapObj* LinkableMapObj::getParObj()
   611 {
   612     return parObj;
   613 }
   614 
   615 LinkableMapObj* LinkableMapObj::findObjBySelect (QString s)
   616 {
   617 	LinkableMapObj *lmo=this;
   618 	QString part;
   619 	QString typ;
   620 	QString num;
   621 	while (!s.isEmpty() )
   622 	{
   623 		part=s.section(",",0,0);
   624 		typ=part.left (3);
   625 		num=part.right(part.length() - 3);
   626 		if (typ=="mc:")
   627 		{
   628 			if (depth>0)
   629 				return false;	// in a subtree there is no center
   630 			else
   631 				break;
   632 		} else
   633 			if (typ=="bo:")
   634 				lmo=((BranchObj*)(lmo))->getBranchNum (num.toUInt());
   635 			else
   636 				if (typ=="fi:")
   637 					lmo=((BranchObj*)(lmo))->getFloatImageNum (num.toUInt());
   638 		if (!lmo) break;
   639 		
   640 		if (s.contains(","))
   641 			s=s.right(s.length() - part.length() -1 );
   642 		else	
   643 			break;
   644 	}
   645 	return lmo;
   646 }
   647 
   648 void LinkableMapObj::setDockPos()
   649 {
   650 	cout <<"LMO::setDockPos()\n";
   651 }
   652 
   653 QPoint LinkableMapObj::getChildPos()
   654 {
   655     return childPos;
   656 }
   657 
   658 QPoint LinkableMapObj::getParPos()
   659 {
   660     return parPos;
   661 }
   662 
   663 QPoint LinkableMapObj::getRelPos()
   664 {
   665 	return relPos;
   666 /* FIXME not needed? relPos was moved in 1.7.10 from
   667    floatobj to linkablemapobj. Before we had:
   668 	
   669 	if (!parObj) return QPoint (0,0);
   670     return QPoint(
   671 		absPos.x() - parObj->x(),
   672 		absPos.y() - parObj->y()
   673 	);
   674 */	
   675 }
   676 
   677 
   678 void LinkableMapObj::setUseOrientation (const bool &b)
   679 {	
   680 	if (useOrientation!=b)
   681 	{
   682 		useOrientation=b;
   683 		requestReposition();
   684 	}	
   685 }
   686 
   687 LinkOrient LinkableMapObj::getOrientation()
   688 {
   689     return orientation;
   690 }
   691 
   692 int LinkableMapObj::getDepth()
   693 {
   694     return depth;
   695 }
   696 
   697 void LinkableMapObj::setMapEditor (MapEditor *me)
   698 {
   699 	mapEditor=me;
   700 }
   701 
   702 MapEditor* LinkableMapObj::getMapEditor ()
   703 {
   704 	return mapEditor;
   705 }
   706 
   707 QPoint LinkableMapObj::getRandPos()
   708 {
   709 	// Choose a random position with given distance to parent:
   710 	double a=rand()%360 * 2 * M_PI / 360;
   711     return QPoint ( (int)( + 150*cos (a)),
   712                     (int)( + 150*sin (a)));
   713 }
   714 
   715 void LinkableMapObj::alignRelativeTo (QPoint ref)
   716 {
   717 	// FIXME testing, seems not to be used right now...
   718 	cout << "LMO::alignRelTo   ref="<<ref<<endl;
   719 }
   720 
   721 void LinkableMapObj::reposition()
   722 {
   723 	if (depth==0)
   724 	{
   725 		// only calculate the sizes once. If the deepest LMO changes its height,
   726 		// all upper LMOs have to change, too.
   727 		calcBBoxSizeWithChilds();
   728 
   729 	    alignRelativeTo ( QPoint (absPos.x(),
   730 							absPos.y()-(bboxTotal.height()-bbox.height())/2) );
   731 	} else
   732 	{
   733 		// This is only important for moving branches:
   734 		// For editing a branch it isn't called...
   735 	    alignRelativeTo ( QPoint (absPos.x(),
   736 							absPos.y()-(bboxTotal.height()-bbox.height())/2) );
   737 	}
   738 }
   739 
   740 void LinkableMapObj::requestReposition()
   741 {
   742 	if (!repositionRequest)
   743 	{
   744 		// Pass on the request to parental objects, if this hasn't
   745 		// been done yet
   746 		repositionRequest=true;
   747 		if (parObj) parObj->requestReposition();
   748 	}
   749 }
   750 
   751 void LinkableMapObj::forceReposition()
   752 {
   753 	// Sometimes a reposition has to be done immediatly: For example
   754 	// if the note editor flag changes, there is no user event in mapeditor
   755 	// which could collect requests for a reposition.
   756 	// Then we have to call forceReposition()
   757 	// But no rule without exception: While loading a map or undoing it,
   758 	// we want to block expensive repositioning, but just do it once at
   759 	// the end, thus check first:
   760 
   761 	if (mapEditor->isRepositionBlocked()) return;
   762 	
   763 	// Pass on the request to parental objects, if this hasn't been done yet
   764 	
   765 	if (parObj) 
   766 		parObj->forceReposition(); 
   767 	else 
   768 		reposition(); 
   769 }
   770 
   771 bool LinkableMapObj::repositionRequested()
   772 {
   773 	return repositionRequest;
   774 }
   775 
   776 
   777 void LinkableMapObj::setSelBox()
   778 {
   779     selbox->setX (clickBox.x() );
   780     selbox->setY (clickBox.y() );
   781     selbox->setSize (clickBox.width(), clickBox.height() );
   782 }
   783 
   784 void LinkableMapObj::select()
   785 {
   786 	setSelBox();
   787     selected=true;
   788     selbox->show();
   789 	setVisibility (visible);
   790 }
   791 
   792 
   793 void LinkableMapObj::unselect()
   794 {
   795     selected=false;
   796     selbox->hide();
   797 	setVisibility (visible);
   798 }
   799 
   800 void LinkableMapObj::parabel (QPointArray &ya, double p1x, double p1y, double p2x, double p2y)
   801 
   802 {
   803 	double vx=p2x - p1x;	// V=P2-P1
   804 	double vy=p2y - p1y;
   805 
   806 	double dx;				// delta x during calculation of parabel
   807 	
   808 	double pnx;				// next point
   809 	double pny;
   810 	double m;
   811 
   812 	if (vx > -0.0001 && vx < 0.0001)
   813 		m=0;
   814 	else	
   815 		m=(vy / (vx*vx));
   816 	dx=vx/(arcsegs);
   817 	int i;
   818 	ya.setPoint (0,QPoint (qRound(p1x),qRound(p1y)));
   819 	for (i=1;i<=arcsegs;i++)
   820 	{	
   821 		pnx=p1x+dx;
   822 		pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
   823 		ya.setPoint (i,QPoint (qRound(pnx),qRound(pny)));
   824 		p1x=pnx;
   825 		p1y=pny;
   826 	}	
   827 }
   828 
   829 QString LinkableMapObj::getLinkAttr ()
   830 {
   831 	if (hideLinkUnselected)
   832 		return attribut ("hideLink","true");
   833 	else
   834 		return attribut ("hideLink","false");
   835 	
   836 }