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