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