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