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