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