linkablemapobj.cpp
author insilmaril
Tue, 07 Jul 2009 09:34:24 +0000
changeset 779 1fb50e79661c
parent 775 6e4b586aa88a
child 780 fe839bdfd10c
permissions -rw-r--r--
Hiding of links works again
insilmaril@721
     1
#include <iostream>
insilmaril@139
     2
#include <math.h>
insilmaril@139
     3
insilmaril@0
     4
#include "linkablemapobj.h"
insilmaril@0
     5
#include "branchobj.h"
insilmaril@721
     6
#include "vymmodel.h"
insilmaril@721
     7
insilmaril@721
     8
using namespace std;
insilmaril@0
     9
insilmaril@0
    10
/////////////////////////////////////////////////////////////////
insilmaril@0
    11
// LinkableMapObj
insilmaril@0
    12
/////////////////////////////////////////////////////////////////
insilmaril@0
    13
insilmaril@0
    14
LinkableMapObj::LinkableMapObj():MapObj()
insilmaril@0
    15
{
insilmaril@0
    16
  //  cout << "Const LinkableMapObj ()\n";
insilmaril@0
    17
    init ();
insilmaril@0
    18
}
insilmaril@0
    19
insilmaril@408
    20
LinkableMapObj::LinkableMapObj(QGraphicsScene* s) :MapObj(s)
insilmaril@0
    21
{
insilmaril@408
    22
//    cout << "Const LinkableMapObj (s)\n";
insilmaril@0
    23
    init ();
insilmaril@0
    24
}
insilmaril@0
    25
insilmaril@408
    26
LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->scene)
insilmaril@0
    27
{
insilmaril@0
    28
    copy (lmo);
insilmaril@0
    29
}
insilmaril@0
    30
insilmaril@0
    31
LinkableMapObj::~LinkableMapObj()
insilmaril@0
    32
{
insilmaril@0
    33
    delete (bottomline);
insilmaril@0
    34
	delLink();
insilmaril@0
    35
}
insilmaril@0
    36
insilmaril@0
    37
void LinkableMapObj::delLink()
insilmaril@0
    38
{
insilmaril@0
    39
	switch (style)
insilmaril@0
    40
	{
insilmaril@473
    41
		case Line:
insilmaril@0
    42
			delete (l);
insilmaril@0
    43
			break;
insilmaril@473
    44
		case Parabel:
insilmaril@406
    45
			while (!segment.isEmpty()) delete segment.takeFirst();
insilmaril@0
    46
			break;
insilmaril@473
    47
		case PolyLine:
insilmaril@0
    48
			delete (p);
insilmaril@0
    49
			break;
insilmaril@473
    50
		case PolyParabel:
insilmaril@0
    51
			delete (p);
insilmaril@0
    52
			break;
insilmaril@0
    53
		default:
insilmaril@0
    54
			break;
insilmaril@0
    55
	}		
insilmaril@0
    56
}
insilmaril@0
    57
insilmaril@0
    58
void LinkableMapObj::init ()
insilmaril@0
    59
{
insilmaril@0
    60
    parObj=NULL;
insilmaril@0
    61
    parObjTmpBuf=NULL;
insilmaril@408
    62
    parPos=QPointF(0,0);
insilmaril@408
    63
    childPos=QPointF(0,0);
insilmaril@0
    64
	link2ParPos=false;
insilmaril@0
    65
    l=NULL;
insilmaril@727
    66
	p=NULL;
insilmaril@473
    67
    orientation=UndefinedOrientation;
insilmaril@0
    68
    linkwidth=20;		
insilmaril@0
    69
	thickness_start=8;
insilmaril@473
    70
    style=UndefinedStyle;
insilmaril@473
    71
	linkpos=Bottom;
insilmaril@0
    72
    arcsegs=13;
insilmaril@0
    73
    
insilmaril@412
    74
// TODO instead of linkcolor pen.color() could be used	all around
insilmaril@408
    75
	pen.setWidth (1);
insilmaril@408
    76
	pen.setColor (linkcolor);
insilmaril@408
    77
	pen.setCapStyle ( Qt::RoundCap );
insilmaril@408
    78
	bottomline=scene->addLine(QLineF(1,1,1,1),pen);
insilmaril@408
    79
    bottomline->setZValue(Z_LINK);
insilmaril@0
    80
    bottomline->show();
insilmaril@0
    81
insilmaril@175
    82
	topPad=botPad=leftPad=rightPad=0;
insilmaril@175
    83
insilmaril@0
    84
	repositionRequest=false;
insilmaril@218
    85
insilmaril@218
    86
	// Rel Positions
insilmaril@408
    87
	relPos=QPointF(0,0);
insilmaril@250
    88
	useRelPos=false;
insilmaril@218
    89
	useOrientation=true;
insilmaril@531
    90
insilmaril@726
    91
	// Crossreference to treemodel
insilmaril@726
    92
	treeItem=NULL;
insilmaril@0
    93
}
insilmaril@0
    94
insilmaril@0
    95
void LinkableMapObj::copy (LinkableMapObj* other)
insilmaril@0
    96
{
insilmaril@0
    97
    MapObj::copy(other);
insilmaril@0
    98
	bboxTotal=other->bboxTotal;
insilmaril@0
    99
    setLinkStyle(other->style);
insilmaril@0
   100
    setLinkColor (other->linkcolor);
insilmaril@218
   101
	relPos=other->relPos;
insilmaril@218
   102
	useOrientation=other->useOrientation;
insilmaril@726
   103
	treeItem=other->treeItem;
insilmaril@726
   104
}
insilmaril@726
   105
insilmaril@726
   106
void LinkableMapObj::setTreeItem (TreeItem *ti)
insilmaril@726
   107
{
insilmaril@726
   108
	treeItem=ti;
insilmaril@726
   109
}
insilmaril@726
   110
insilmaril@753
   111
TreeItem* LinkableMapObj::getTreeItem () const
insilmaril@726
   112
{
insilmaril@726
   113
	return treeItem;
insilmaril@0
   114
}
insilmaril@0
   115
insilmaril@0
   116
void LinkableMapObj::setParObj(LinkableMapObj* o)
insilmaril@0
   117
{
insilmaril@0
   118
    parObj=o;
insilmaril@0
   119
}
insilmaril@0
   120
insilmaril@746
   121
void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPointF,int)	// FIXME-3 make pure virtual
insilmaril@0
   122
{
insilmaril@0
   123
}
insilmaril@0
   124
insilmaril@746
   125
void LinkableMapObj::unsetParObjTmp()	// FIXME-3 make pure virtual
insilmaril@0
   126
{
insilmaril@0
   127
}
insilmaril@0
   128
insilmaril@164
   129
bool LinkableMapObj::hasParObjTmp()
insilmaril@164
   130
{
insilmaril@164
   131
	if (parObjTmpBuf) return true;
insilmaril@164
   132
	return false;
insilmaril@164
   133
}
insilmaril@164
   134
insilmaril@218
   135
void LinkableMapObj::setUseRelPos (const bool &b)
insilmaril@218
   136
{
insilmaril@218
   137
	useRelPos=b;
insilmaril@218
   138
}
insilmaril@218
   139
insilmaril@218
   140
void LinkableMapObj::setRelPos()
insilmaril@218
   141
{
insilmaril@218
   142
	if (parObj)
insilmaril@218
   143
	{	
insilmaril@395
   144
		relPos.setX (absPos.x() - parObj->getChildPos().x() );
insilmaril@395
   145
		relPos.setY (absPos.y() - parObj->getChildPos().y() );
insilmaril@218
   146
		parObj->calcBBoxSize();
insilmaril@494
   147
	}	
insilmaril@218
   148
}
insilmaril@218
   149
insilmaril@408
   150
void LinkableMapObj::setRelPos(const QPointF &p)
insilmaril@218
   151
{
insilmaril@218
   152
	relPos=p;
insilmaril@218
   153
	if (parObj)
insilmaril@388
   154
	{		
insilmaril@388
   155
		parObj->calcBBoxSize();
insilmaril@388
   156
		requestReposition();
insilmaril@395
   157
	}
insilmaril@218
   158
}
insilmaril@218
   159
insilmaril@408
   160
QPointF LinkableMapObj::getRelPos()
insilmaril@366
   161
{
insilmaril@408
   162
	if (!parObj) return QPointF();
insilmaril@366
   163
	return relPos;
insilmaril@366
   164
}
insilmaril@366
   165
insilmaril@408
   166
qreal LinkableMapObj::getTopPad()
insilmaril@175
   167
{
insilmaril@175
   168
	return topPad;
insilmaril@175
   169
}
insilmaril@175
   170
insilmaril@408
   171
qreal LinkableMapObj::getLeftPad()
insilmaril@175
   172
{
insilmaril@175
   173
	return leftPad;
insilmaril@175
   174
}
insilmaril@175
   175
insilmaril@408
   176
qreal LinkableMapObj::getRightPad()
insilmaril@175
   177
{
insilmaril@175
   178
	return rightPad;
insilmaril@175
   179
}
insilmaril@175
   180
insilmaril@473
   181
LinkableMapObj::Style LinkableMapObj::getDefLinkStyle ()
insilmaril@0
   182
{
insilmaril@773
   183
	VymModel *model=treeItem->getModel();
insilmaril@721
   184
	if (!model)
insilmaril@721
   185
	{
insilmaril@721
   186
		qWarning ("LMO::getDefLinkStyle   model=NULL");
insilmaril@727
   187
		//return UndefinedStyle;
insilmaril@721
   188
	}
insilmaril@721
   189
	Style ls=model->getMapLinkStyle();
insilmaril@755
   190
	int depth=treeItem->depth();
insilmaril@727
   191
	if (depth==0) return UndefinedStyle;
insilmaril@0
   192
	switch (ls)
insilmaril@0
   193
	{
insilmaril@473
   194
		case Line: 
insilmaril@0
   195
			return ls;
insilmaril@0
   196
			break;
insilmaril@473
   197
		case Parabel:
insilmaril@0
   198
			return ls;
insilmaril@0
   199
			break;
insilmaril@473
   200
		case PolyLine:	
insilmaril@0
   201
			if (depth>1)
insilmaril@473
   202
				return Line;
insilmaril@0
   203
			else	
insilmaril@0
   204
				return ls;
insilmaril@0
   205
			break;
insilmaril@473
   206
		case PolyParabel:	
insilmaril@0
   207
			if (depth>1)
insilmaril@473
   208
				return Parabel;
insilmaril@0
   209
			else	
insilmaril@0
   210
				return ls;
insilmaril@0
   211
			break;
insilmaril@0
   212
		default: 
insilmaril@0
   213
			break;	
insilmaril@0
   214
	}	
insilmaril@473
   215
	return UndefinedStyle;
insilmaril@0
   216
}
insilmaril@0
   217
insilmaril@473
   218
void LinkableMapObj::setLinkStyle(Style newstyle)
insilmaril@0
   219
{
insilmaril@746
   220
	//if (newstyle=style) return; FIXME-3
insilmaril@0
   221
	delLink();
insilmaril@0
   222
		
insilmaril@0
   223
	style=newstyle;
insilmaril@0
   224
insilmaril@773
   225
    if (parObj != NULL)
insilmaril@0
   226
    {
insilmaril@408
   227
		QGraphicsLineItem *cl;
insilmaril@0
   228
		switch (style)
insilmaril@0
   229
		{
insilmaril@473
   230
			case UndefinedStyle:
insilmaril@0
   231
				bottomline->hide();
insilmaril@0
   232
				break;
insilmaril@473
   233
			case Line: 
insilmaril@408
   234
				l = scene->addLine(QLineF(1,1,1,1),pen);
insilmaril@408
   235
				l->setZValue(Z_LINK);
insilmaril@0
   236
				if (visible)
insilmaril@0
   237
					l->show();
insilmaril@0
   238
				else
insilmaril@0
   239
					l->hide();
insilmaril@0
   240
				break;
insilmaril@473
   241
			case Parabel:
insilmaril@408
   242
				for (int i=0;i<arcsegs;i++)
insilmaril@0
   243
				{
insilmaril@408
   244
					cl = scene->addLine(QLineF(i*5,0,i*10,100),pen);
insilmaril@408
   245
					cl->setZValue(Z_LINK);
insilmaril@0
   246
					if (visible)
insilmaril@0
   247
						cl->show();
insilmaril@0
   248
					else
insilmaril@0
   249
						cl->hide();
insilmaril@0
   250
					segment.append(cl);
insilmaril@0
   251
				}
insilmaril@0
   252
				pa0.resize (arcsegs+1);
insilmaril@0
   253
				break;
insilmaril@473
   254
			case PolyLine:	
insilmaril@408
   255
				p =scene->addPolygon(QPolygonF(),pen,linkcolor);
insilmaril@408
   256
				p->setZValue(Z_LINK);
insilmaril@0
   257
				if (visible)
insilmaril@0
   258
					p->show();
insilmaril@0
   259
				else
insilmaril@0
   260
					p->hide();
insilmaril@0
   261
				pa0.resize (3);
insilmaril@0
   262
				break;
insilmaril@473
   263
			case PolyParabel:	
insilmaril@408
   264
				p = scene->addPolygon(QPolygonF(),pen,linkcolor);
insilmaril@408
   265
				p->setZValue(Z_LINK);
insilmaril@0
   266
				if (visible)
insilmaril@0
   267
					p->show();
insilmaril@0
   268
				else
insilmaril@0
   269
					p->hide();
insilmaril@0
   270
				pa0.resize (arcsegs*2+2);
insilmaril@0
   271
				pa1.resize (arcsegs+1);
insilmaril@0
   272
				pa2.resize (arcsegs+1);
insilmaril@0
   273
				break;
insilmaril@0
   274
			default: 
insilmaril@0
   275
				break;	
insilmaril@0
   276
		}	
insilmaril@164
   277
	} 
insilmaril@0
   278
}
insilmaril@0
   279
insilmaril@473
   280
LinkableMapObj::Style LinkableMapObj::getLinkStyle()
insilmaril@0
   281
{
insilmaril@0
   282
	return style;
insilmaril@0
   283
}
insilmaril@0
   284
insilmaril@779
   285
void LinkableMapObj::setHideLinkUnselected()
insilmaril@160
   286
{
insilmaril@160
   287
	setVisibility (visible);
insilmaril@779
   288
	updateLinkGeometry();
insilmaril@160
   289
}
insilmaril@160
   290
insilmaril@473
   291
void LinkableMapObj::setLinkPos(Position lp)
insilmaril@0
   292
{
insilmaril@0
   293
	linkpos=lp;
insilmaril@0
   294
}
insilmaril@0
   295
insilmaril@473
   296
LinkableMapObj::Position LinkableMapObj::getLinkPos()
insilmaril@0
   297
{
insilmaril@0
   298
	return linkpos;
insilmaril@0
   299
}
insilmaril@0
   300
insilmaril@0
   301
void LinkableMapObj::setLinkColor()
insilmaril@0
   302
{
insilmaril@721
   303
	// Overloaded in BranchObj and children
insilmaril@0
   304
	// here only set default color
insilmaril@773
   305
	VymModel *model=treeItem->getModel();
insilmaril@721
   306
	if (model)
insilmaril@721
   307
		setLinkColor (model->getMapDefLinkColor());
insilmaril@0
   308
}
insilmaril@0
   309
insilmaril@0
   310
void LinkableMapObj::setLinkColor(QColor col)
insilmaril@0
   311
{
insilmaril@0
   312
	linkcolor=col;
insilmaril@408
   313
	pen.setColor(col);
insilmaril@408
   314
    bottomline->setPen( pen );
insilmaril@0
   315
	switch (style)
insilmaril@0
   316
	{
insilmaril@473
   317
		case Line:
insilmaril@408
   318
			l->setPen( pen);
insilmaril@0
   319
			break;	
insilmaril@473
   320
		case Parabel:	
insilmaril@406
   321
			for (int i=0; i<segment.size(); ++i)
insilmaril@408
   322
				segment.at(i)->setPen( pen);
insilmaril@0
   323
			break;
insilmaril@473
   324
		case PolyLine:
insilmaril@0
   325
			p->setBrush( QBrush(col));
insilmaril@497
   326
			p->setPen( pen);
insilmaril@0
   327
			break;
insilmaril@473
   328
		case PolyParabel:	
insilmaril@0
   329
			p->setBrush( QBrush(col));
insilmaril@497
   330
			p->setPen( pen);
insilmaril@0
   331
			break;
insilmaril@0
   332
		default:
insilmaril@0
   333
			break;
insilmaril@755
   334
	} 
insilmaril@0
   335
}
insilmaril@0
   336
insilmaril@0
   337
QColor LinkableMapObj::getLinkColor()
insilmaril@0
   338
{
insilmaril@0
   339
	return linkcolor;
insilmaril@0
   340
}
insilmaril@0
   341
insilmaril@0
   342
void LinkableMapObj::setVisibility (bool v)
insilmaril@0
   343
{
insilmaril@0
   344
	MapObj::setVisibility (v);
insilmaril@779
   345
	updateVisibility();
insilmaril@779
   346
}
insilmaril@779
   347
insilmaril@779
   348
void LinkableMapObj::setOrientation()
insilmaril@779
   349
{
insilmaril@779
   350
	Orientation orientOld=orientation;
insilmaril@779
   351
insilmaril@779
   352
	if (!parObj) 
insilmaril@779
   353
	{
insilmaril@779
   354
		orientation=UndefinedOrientation;
insilmaril@779
   355
		return;
insilmaril@779
   356
	}
insilmaril@779
   357
		
insilmaril@779
   358
    // Set orientation, first look for orientation of parent
insilmaril@779
   359
    if (parObj->getOrientation() != UndefinedOrientation ) 
insilmaril@779
   360
		// use the orientation of the parent:
insilmaril@779
   361
		orientation=parObj->getOrientation();
insilmaril@779
   362
    else
insilmaril@779
   363
    {
insilmaril@779
   364
		// calc orientation depending on position rel to parent
insilmaril@779
   365
		if (absPos.x() < QPointF(parObj->getChildPos() ).x() )
insilmaril@779
   366
			orientation=LeftOfCenter; 
insilmaril@779
   367
		else
insilmaril@779
   368
			orientation=RightOfCenter;
insilmaril@779
   369
    }
insilmaril@779
   370
	if (orientOld!=orientation) requestReposition();
insilmaril@779
   371
}
insilmaril@779
   372
insilmaril@779
   373
void LinkableMapObj::updateVisibility()
insilmaril@779
   374
{
insilmaril@160
   375
	bool visnow=visible;
insilmaril@260
   376
insilmaril@779
   377
	if (((MapItem*)treeItem)->getHideLinkUnselected()
insilmaril@779
   378
		&& treeItem->getModel()->getSelectedLMO() !=this)
insilmaril@160
   379
		visnow=false;
insilmaril@160
   380
insilmaril@160
   381
	if (visnow) 
insilmaril@0
   382
	{
insilmaril@0
   383
		bottomline->show();
insilmaril@160
   384
		switch (style)
insilmaril@0
   385
		{
insilmaril@473
   386
			case Line:
insilmaril@160
   387
				if (l) l->show();
insilmaril@160
   388
				break;
insilmaril@473
   389
			case Parabel:	
insilmaril@406
   390
				for (int i=0; i<segment.size(); ++i)
insilmaril@406
   391
					segment.at(i)->show();
insilmaril@160
   392
				break;	
insilmaril@473
   393
			case PolyLine:
insilmaril@779
   394
				if (!p) cout << "LMO::updateVis p==0 (PolyLine)\n"; //FIXME-3
insilmaril@160
   395
				if (p) p->show();
insilmaril@160
   396
				break;
insilmaril@473
   397
			case PolyParabel:	
insilmaril@779
   398
				if (!p) cout << "LMO::updateVis p==0 (PolyParabel) "<<treeItem->getHeading().toStdString()<<endl; //FIXME-3
insilmaril@160
   399
				if (p) p->show();
insilmaril@160
   400
				break;
insilmaril@160
   401
			default:
insilmaril@160
   402
				break;
insilmaril@160
   403
		}
insilmaril@0
   404
	} else 
insilmaril@0
   405
	{
insilmaril@0
   406
		bottomline->hide();
insilmaril@160
   407
		switch (style)
insilmaril@0
   408
		{
insilmaril@473
   409
			case Line:
insilmaril@160
   410
				if (l) l->hide();
insilmaril@160
   411
				break;
insilmaril@473
   412
			case Parabel:	
insilmaril@406
   413
				for (int i=0; i<segment.size(); ++i)
insilmaril@406
   414
					segment.at(i)->hide();
insilmaril@160
   415
				break;	
insilmaril@473
   416
			case PolyLine:
insilmaril@160
   417
				if (p) p->hide();
insilmaril@160
   418
				break;
insilmaril@473
   419
			case PolyParabel:	
insilmaril@160
   420
				if (p) p->hide();
insilmaril@160
   421
				break;
insilmaril@160
   422
			default:
insilmaril@160
   423
				break;
insilmaril@160
   424
		}
insilmaril@0
   425
	}	
insilmaril@0
   426
}
insilmaril@0
   427
insilmaril@779
   428
void LinkableMapObj::updateLinkGeometry()
insilmaril@0
   429
{
insilmaril@0
   430
    // needs:
insilmaril@0
   431
    //	childPos of parent
insilmaril@0
   432
    //	orient   of parent
insilmaril@0
   433
    //	style
insilmaril@0
   434
    // 
insilmaril@0
   435
    // sets:
insilmaril@0
   436
    //	orientation
insilmaril@225
   437
    //	childPos	(by calling setDockPos())
insilmaril@225
   438
    //	parPos		(by calling setDockPos())
insilmaril@175
   439
	//  bottomlineY
insilmaril@0
   440
    //	drawing of the link itself
insilmaril@0
   441
insilmaril@779
   442
	// updateLinkGeometry is called from move, but called from constructor we don't
insilmaril@0
   443
	// have parents yet...
insilmaril@775
   444
insilmaril@775
   445
	if (!parObj)	
insilmaril@775
   446
	{
insilmaril@775
   447
		// If I am a mapcenter, set childPos to middle of MapCenterObj
insilmaril@775
   448
		childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
insilmaril@775
   449
		childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
insilmaril@775
   450
		parPos=childPos;		
insilmaril@775
   451
		// Redraw links to children
insilmaril@775
   452
		for (int i=0; i<treeItem->branchCount(); ++i)
insilmaril@779
   453
			treeItem->getBranchObjNum(i)->updateLinkGeometry();
insilmaril@775
   454
		return;	
insilmaril@775
   455
	}
insilmaril@775
   456
insilmaril@473
   457
	if (style==UndefinedStyle) return;	
insilmaril@0
   458
insilmaril@0
   459
	switch (linkpos)
insilmaril@0
   460
	{
insilmaril@473
   461
		case Middle:
insilmaril@442
   462
			bottomlineY=bbox.top() + bbox.height()/2;	// draw link to middle (of frame)
insilmaril@0
   463
			break;
insilmaril@473
   464
		case Bottom:
insilmaril@225
   465
			bottomlineY=bbox.bottom()-1;	// draw link to bottom of box
insilmaril@0
   466
			break;
insilmaril@0
   467
	}
insilmaril@0
   468
	
insilmaril@0
   469
    double p2x,p2y;								// Set P2 Before setting
insilmaril@0
   470
	if (!link2ParPos)
insilmaril@0
   471
	{
insilmaril@408
   472
		p2x=QPointF( parObj->getChildPos() ).x();	// P1, we have to look at
insilmaril@408
   473
		p2y=QPointF( parObj->getChildPos() ).y();	// orientation
insilmaril@0
   474
	} else	
insilmaril@0
   475
	{
insilmaril@408
   476
		p2x=QPointF( parObj->getParPos() ).x();	
insilmaril@408
   477
		p2y=QPointF( parObj->getParPos() ).y();
insilmaril@0
   478
	} 
insilmaril@0
   479
insilmaril@388
   480
	setDockPos(); // Call overloaded method
insilmaril@393
   481
	setOrientation();
insilmaril@0
   482
insilmaril@0
   483
	double p1x=parPos.x();	// Link is drawn from P1 to P2
insilmaril@0
   484
	double p1y=parPos.y();
insilmaril@0
   485
insilmaril@0
   486
	double vx=p2x - p1x;	// V=P2-P1
insilmaril@0
   487
	double vy=p2y - p1y;
insilmaril@0
   488
insilmaril@0
   489
	// Draw the horizontal line below heading (from ChildPos to ParPos)
insilmaril@427
   490
	//bottomline->prepareGeometryChange();
insilmaril@408
   491
	bottomline->setLine (QLine (qRound(childPos.x()),
insilmaril@104
   492
		qRound(childPos.y()),
insilmaril@104
   493
		qRound(p1x),
insilmaril@408
   494
		qRound(p1y) ));
insilmaril@0
   495
insilmaril@0
   496
	double a;	// angle
insilmaril@0
   497
	if (vx > -0.000001 && vx < 0.000001)
insilmaril@0
   498
		a=M_PI_2;
insilmaril@0
   499
	else
insilmaril@0
   500
		a=atan( vy / vx );
insilmaril@0
   501
	// "turning point" for drawing polygonal links
insilmaril@408
   502
	QPointF tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));	
insilmaril@0
   503
	
insilmaril@0
   504
    // Draw the link
insilmaril@0
   505
	switch (style)
insilmaril@0
   506
	{
insilmaril@473
   507
		case Line:
insilmaril@408
   508
			l->setLine( QLine(qRound (parPos.x()),
insilmaril@104
   509
				qRound(parPos.y()),
insilmaril@104
   510
				qRound(p2x),
insilmaril@408
   511
				qRound(p2y) ));
insilmaril@0
   512
			break;	
insilmaril@473
   513
		case Parabel:	
insilmaril@0
   514
			parabel (pa0, p1x,p1y,p2x,p2y);
insilmaril@406
   515
			for (int i=0; i<segment.size(); ++i)
insilmaril@408
   516
				segment.at(i)->setLine(QLineF( pa0.at(i).x(), pa0.at(i).y(),pa0.at(i+1).x(),pa0.at(i+1).y()));
insilmaril@0
   517
			break;
insilmaril@473
   518
		case PolyLine:
insilmaril@408
   519
			pa0.clear();
insilmaril@408
   520
			pa0<<QPointF (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
insilmaril@408
   521
			pa0<<QPointF (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
insilmaril@408
   522
			pa0<<QPointF (qRound (parPos.x()), qRound(parPos.y()) );
insilmaril@408
   523
			p->setPolygon(QPolygonF (pa0));
insilmaril@0
   524
			break;
insilmaril@473
   525
		case PolyParabel:	
insilmaril@0
   526
			parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
insilmaril@0
   527
			parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
insilmaril@408
   528
			pa0.clear();
insilmaril@406
   529
			for (int i=0;i<=arcsegs;i++)
insilmaril@408
   530
				pa0 << QPointF (pa1.at(i));
insilmaril@408
   531
			for (int i=0;i<=arcsegs;i++)
insilmaril@408
   532
				pa0 << QPointF (pa2.at(arcsegs-i));
insilmaril@408
   533
			p->setPolygon(QPolygonF (pa0));
insilmaril@0
   534
			break;
insilmaril@0
   535
		default:
insilmaril@0
   536
			break;
insilmaril@779
   537
	} 
insilmaril@0
   538
}
insilmaril@0
   539
	
insilmaril@0
   540
LinkableMapObj* LinkableMapObj::getParObj()
insilmaril@0
   541
{
insilmaril@0
   542
    return parObj;
insilmaril@0
   543
}
insilmaril@0
   544
insilmaril@408
   545
QPointF LinkableMapObj::getChildPos()
insilmaril@0
   546
{
insilmaril@0
   547
    return childPos;
insilmaril@0
   548
}
insilmaril@0
   549
insilmaril@408
   550
QPointF LinkableMapObj::getParPos()
insilmaril@0
   551
{
insilmaril@0
   552
    return parPos;
insilmaril@0
   553
}
insilmaril@0
   554
insilmaril@218
   555
void LinkableMapObj::setUseOrientation (const bool &b)
insilmaril@218
   556
{	
insilmaril@218
   557
	if (useOrientation!=b)
insilmaril@218
   558
	{
insilmaril@218
   559
		useOrientation=b;
insilmaril@218
   560
		requestReposition();
insilmaril@218
   561
	}	
insilmaril@218
   562
}
insilmaril@218
   563
insilmaril@473
   564
LinkableMapObj::Orientation LinkableMapObj::getOrientation()
insilmaril@0
   565
{
insilmaril@0
   566
    return orientation;
insilmaril@0
   567
}
insilmaril@0
   568
insilmaril@408
   569
QPointF LinkableMapObj::getRandPos()
insilmaril@0
   570
{
insilmaril@0
   571
	// Choose a random position with given distance to parent:
insilmaril@0
   572
	double a=rand()%360 * 2 * M_PI / 360;
insilmaril@408
   573
    return QPointF ( (int)( + 150*cos (a)),
insilmaril@0
   574
                    (int)( + 150*sin (a)));
insilmaril@0
   575
}
insilmaril@0
   576
insilmaril@0
   577
void LinkableMapObj::reposition()
insilmaril@0
   578
{
insilmaril@0
   579
}
insilmaril@0
   580
insilmaril@0
   581
void LinkableMapObj::requestReposition()
insilmaril@0
   582
{
insilmaril@0
   583
	if (!repositionRequest)
insilmaril@0
   584
	{
insilmaril@0
   585
		// Pass on the request to parental objects, if this hasn't
insilmaril@0
   586
		// been done yet
insilmaril@0
   587
		repositionRequest=true;
insilmaril@0
   588
		if (parObj) parObj->requestReposition();
insilmaril@0
   589
	}
insilmaril@0
   590
}
insilmaril@0
   591
insilmaril@0
   592
void LinkableMapObj::forceReposition()
insilmaril@0
   593
{
insilmaril@0
   594
	// Sometimes a reposition has to be done immediatly: For example
insilmaril@0
   595
	// if the note editor flag changes, there is no user event in mapeditor
insilmaril@0
   596
	// which could collect requests for a reposition.
insilmaril@0
   597
	// Then we have to call forceReposition()
insilmaril@0
   598
	// But no rule without exception: While loading a map or undoing it,
insilmaril@0
   599
	// we want to block expensive repositioning, but just do it once at
insilmaril@0
   600
	// the end, thus check first:
insilmaril@0
   601
insilmaril@773
   602
	VymModel *model=treeItem->getModel();
insilmaril@724
   603
	if (model->isRepositionBlocked()) return;	
insilmaril@0
   604
	
insilmaril@724
   605
	// Pass on the request to parent objects, if this hasn't been done yet
insilmaril@0
   606
	if (parObj) 
insilmaril@0
   607
		parObj->forceReposition(); 
insilmaril@0
   608
	else 
insilmaril@83
   609
		reposition(); 
insilmaril@83
   610
}
insilmaril@0
   611
insilmaril@0
   612
bool LinkableMapObj::repositionRequested()
insilmaril@0
   613
{
insilmaril@0
   614
	return repositionRequest;
insilmaril@0
   615
}
insilmaril@0
   616
insilmaril@408
   617
void LinkableMapObj::parabel (QPolygonF &ya, double p1x, double p1y, double p2x, double p2y)
insilmaril@0
   618
insilmaril@0
   619
{
insilmaril@0
   620
	double vx=p2x - p1x;	// V=P2-P1
insilmaril@0
   621
	double vy=p2y - p1y;
insilmaril@0
   622
insilmaril@0
   623
	double dx;				// delta x during calculation of parabel
insilmaril@0
   624
	
insilmaril@0
   625
	double pnx;				// next point
insilmaril@0
   626
	double pny;
insilmaril@0
   627
	double m;
insilmaril@0
   628
insilmaril@0
   629
	if (vx > -0.0001 && vx < 0.0001)
insilmaril@0
   630
		m=0;
insilmaril@0
   631
	else	
insilmaril@0
   632
		m=(vy / (vx*vx));
insilmaril@0
   633
	dx=vx/(arcsegs);
insilmaril@408
   634
	ya.clear();
insilmaril@579
   635
	ya<<QPointF (p1x,p1y);
insilmaril@408
   636
	for (int i=1;i<=arcsegs;i++)
insilmaril@0
   637
	{	
insilmaril@0
   638
		pnx=p1x+dx;
insilmaril@0
   639
		pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
insilmaril@579
   640
		ya<<QPointF (pnx,pny);
insilmaril@0
   641
		p1x=pnx;
insilmaril@0
   642
		p1y=pny;
insilmaril@0
   643
	}	
insilmaril@0
   644
}
insilmaril@0
   645