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