linkablemapobj.cpp
author insilmaril
Mon Feb 19 12:01:54 2007 +0000 (2007-02-19)
changeset 430 f001beefdec2
parent 412 8059b6aa74d7
child 442 dfbc371b7280
permissions -rw-r--r--
1.8.67 Bugfixes
insilmaril@139
     1
#include <math.h>
insilmaril@139
     2
insilmaril@0
     3
#include "linkablemapobj.h"
insilmaril@0
     4
#include "branchobj.h"
insilmaril@0
     5
#include "mapeditor.h"
insilmaril@0
     6
insilmaril@0
     7
/////////////////////////////////////////////////////////////////
insilmaril@0
     8
// LinkableMapObj
insilmaril@0
     9
/////////////////////////////////////////////////////////////////
insilmaril@0
    10
insilmaril@0
    11
LinkableMapObj::LinkableMapObj():MapObj()
insilmaril@0
    12
{
insilmaril@0
    13
  //  cout << "Const LinkableMapObj ()\n";
insilmaril@0
    14
    init ();
insilmaril@0
    15
}
insilmaril@0
    16
insilmaril@408
    17
LinkableMapObj::LinkableMapObj(QGraphicsScene* s) :MapObj(s)
insilmaril@0
    18
{
insilmaril@408
    19
//    cout << "Const LinkableMapObj (s)\n";
insilmaril@0
    20
    init ();
insilmaril@0
    21
}
insilmaril@0
    22
insilmaril@408
    23
LinkableMapObj::LinkableMapObj (LinkableMapObj* lmo) : MapObj (lmo->scene)
insilmaril@0
    24
{
insilmaril@0
    25
    copy (lmo);
insilmaril@0
    26
}
insilmaril@0
    27
insilmaril@0
    28
LinkableMapObj::~LinkableMapObj()
insilmaril@0
    29
{
insilmaril@0
    30
    delete (bottomline);
insilmaril@0
    31
    delete (selbox);
insilmaril@0
    32
	delete (frame);
insilmaril@0
    33
	delLink();
insilmaril@0
    34
}
insilmaril@0
    35
insilmaril@0
    36
void LinkableMapObj::delLink()
insilmaril@0
    37
{
insilmaril@0
    38
	switch (style)
insilmaril@0
    39
	{
insilmaril@0
    40
		case StyleLine:
insilmaril@0
    41
			delete (l);
insilmaril@0
    42
			break;
insilmaril@0
    43
		case StyleParabel:
insilmaril@406
    44
			while (!segment.isEmpty()) delete segment.takeFirst();
insilmaril@0
    45
			break;
insilmaril@0
    46
		case StylePolyLine:
insilmaril@0
    47
			delete (p);
insilmaril@0
    48
			break;
insilmaril@0
    49
		case StylePolyParabel:
insilmaril@0
    50
			delete (p);
insilmaril@0
    51
			break;
insilmaril@0
    52
		default:
insilmaril@0
    53
			break;
insilmaril@0
    54
	}		
insilmaril@0
    55
}
insilmaril@0
    56
insilmaril@0
    57
void LinkableMapObj::init ()
insilmaril@0
    58
{
insilmaril@0
    59
    depth=-1;	
insilmaril@164
    60
	mapEditor=NULL;
insilmaril@0
    61
    childObj=NULL;
insilmaril@0
    62
    parObj=NULL;
insilmaril@0
    63
    parObjTmpBuf=NULL;
insilmaril@408
    64
    parPos=QPointF(0,0);
insilmaril@408
    65
    childPos=QPointF(0,0);
insilmaril@0
    66
	link2ParPos=false;
insilmaril@0
    67
    l=NULL;
insilmaril@0
    68
    orientation=OrientUndef;
insilmaril@0
    69
    linkwidth=20;		
insilmaril@0
    70
	thickness_start=8;
insilmaril@0
    71
    style=StyleUndef;
insilmaril@0
    72
	linkpos=LinkBottom;
insilmaril@0
    73
    arcsegs=13;
insilmaril@0
    74
    
insilmaril@412
    75
// TODO instead of linkcolor pen.color() could be used	all around
insilmaril@408
    76
	pen.setWidth (1);
insilmaril@408
    77
	pen.setColor (linkcolor);
insilmaril@408
    78
	pen.setCapStyle ( Qt::RoundCap );
insilmaril@408
    79
	bottomline=scene->addLine(QLineF(1,1,1,1),pen);
insilmaril@408
    80
    bottomline->setZValue(Z_LINK);
insilmaril@0
    81
    bottomline->show();
insilmaril@0
    82
insilmaril@0
    83
    // Prepare showing the selection of a MapObj
insilmaril@408
    84
    selbox = scene->addRect(QRectF(0,0,0,0), QPen(QColor(255,255,0) ), QColor(255,255,0));
insilmaril@408
    85
    selbox->setZValue(Z_SELBOX);
insilmaril@0
    86
    selbox->hide();
insilmaril@0
    87
    selected=false;
insilmaril@0
    88
insilmaril@160
    89
	hideLinkUnselected=false;
insilmaril@160
    90
insilmaril@175
    91
	topPad=botPad=leftPad=rightPad=0;
insilmaril@175
    92
insilmaril@0
    93
	// initialize frame
insilmaril@408
    94
	frame = new FrameObj (scene);
insilmaril@0
    95
	
insilmaril@0
    96
	repositionRequest=false;
insilmaril@218
    97
insilmaril@218
    98
	// Rel Positions
insilmaril@408
    99
	relPos=QPointF(0,0);
insilmaril@250
   100
	useRelPos=false;
insilmaril@218
   101
	useOrientation=true;
insilmaril@0
   102
}
insilmaril@0
   103
insilmaril@0
   104
void LinkableMapObj::copy (LinkableMapObj* other)
insilmaril@0
   105
{
insilmaril@0
   106
    MapObj::copy(other);
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@218
   112
insilmaril@0
   113
}
insilmaril@0
   114
insilmaril@0
   115
void LinkableMapObj::setChildObj(LinkableMapObj* o)
insilmaril@0
   116
{
insilmaril@0
   117
    childObj=o;
insilmaril@0
   118
}
insilmaril@0
   119
insilmaril@0
   120
void LinkableMapObj::setParObj(LinkableMapObj* o)
insilmaril@0
   121
{
insilmaril@0
   122
    parObj=o;
insilmaril@0
   123
	mapEditor=parObj->getMapEditor();
insilmaril@0
   124
}
insilmaril@0
   125
insilmaril@408
   126
void LinkableMapObj::setParObjTmp(LinkableMapObj*,QPointF,int)
insilmaril@0
   127
{
insilmaril@0
   128
}
insilmaril@0
   129
insilmaril@0
   130
void LinkableMapObj::unsetParObjTmp()
insilmaril@0
   131
{
insilmaril@0
   132
}
insilmaril@0
   133
insilmaril@164
   134
bool LinkableMapObj::hasParObjTmp()
insilmaril@164
   135
{
insilmaril@164
   136
	if (parObjTmpBuf) return true;
insilmaril@164
   137
	return false;
insilmaril@164
   138
}
insilmaril@164
   139
insilmaril@218
   140
void LinkableMapObj::setUseRelPos (const bool &b)
insilmaril@218
   141
{
insilmaril@218
   142
	useRelPos=b;
insilmaril@218
   143
}
insilmaril@218
   144
insilmaril@218
   145
void LinkableMapObj::setRelPos()
insilmaril@218
   146
{
insilmaril@218
   147
	if (parObj)
insilmaril@218
   148
	{	
insilmaril@395
   149
		relPos.setX (absPos.x() - parObj->getChildPos().x() );
insilmaril@395
   150
		relPos.setY (absPos.y() - parObj->getChildPos().y() );
insilmaril@218
   151
		parObj->calcBBoxSize();
insilmaril@395
   152
	}	else
insilmaril@395
   153
	{
insilmaril@395
   154
		qWarning ("LMO::setRelPos   No parent yet!");
insilmaril@395
   155
	}
insilmaril@218
   156
}
insilmaril@218
   157
insilmaril@408
   158
void LinkableMapObj::setRelPos(const QPointF &p)
insilmaril@218
   159
{
insilmaril@218
   160
	relPos=p;
insilmaril@218
   161
	if (parObj)
insilmaril@388
   162
	{		
insilmaril@388
   163
		parObj->calcBBoxSize();
insilmaril@388
   164
		requestReposition();
insilmaril@395
   165
	}	else
insilmaril@395
   166
	{
insilmaril@395
   167
		qWarning ("LMO::setRelPos   No parent yet!");
insilmaril@395
   168
	}
insilmaril@218
   169
}
insilmaril@218
   170
insilmaril@408
   171
QPointF LinkableMapObj::getRelPos()
insilmaril@366
   172
{
insilmaril@408
   173
	if (!parObj) return QPointF();
insilmaril@366
   174
	return relPos;
insilmaril@366
   175
}
insilmaril@366
   176
insilmaril@408
   177
qreal LinkableMapObj::getTopPad()
insilmaril@175
   178
{
insilmaril@175
   179
	return topPad;
insilmaril@175
   180
}
insilmaril@175
   181
insilmaril@408
   182
qreal LinkableMapObj::getLeftPad()
insilmaril@175
   183
{
insilmaril@175
   184
	return leftPad;
insilmaril@175
   185
}
insilmaril@175
   186
insilmaril@408
   187
qreal LinkableMapObj::getRightPad()
insilmaril@175
   188
{
insilmaril@175
   189
	return rightPad;
insilmaril@175
   190
}
insilmaril@175
   191
insilmaril@0
   192
LinkStyle LinkableMapObj::getDefLinkStyle ()
insilmaril@0
   193
{
insilmaril@406
   194
	if (mapEditor==0) return StyleUndef;
insilmaril@398
   195
	LinkStyle ls=mapEditor->getMapLinkStyle();
insilmaril@0
   196
	switch (ls)
insilmaril@0
   197
	{
insilmaril@0
   198
		case StyleLine: 
insilmaril@0
   199
			return ls;
insilmaril@0
   200
			break;
insilmaril@0
   201
		case StyleParabel:
insilmaril@0
   202
			return ls;
insilmaril@0
   203
			break;
insilmaril@0
   204
		case StylePolyLine:	
insilmaril@0
   205
			if (depth>1)
insilmaril@0
   206
				return StyleLine;
insilmaril@0
   207
			else	
insilmaril@0
   208
				return ls;
insilmaril@0
   209
			break;
insilmaril@0
   210
		case StylePolyParabel:	
insilmaril@0
   211
			if (depth>1)
insilmaril@0
   212
				return StyleParabel;
insilmaril@0
   213
			else	
insilmaril@0
   214
				return ls;
insilmaril@0
   215
			break;
insilmaril@0
   216
		default: 
insilmaril@0
   217
			break;	
insilmaril@0
   218
	}	
insilmaril@0
   219
	return StyleUndef;
insilmaril@0
   220
}
insilmaril@0
   221
insilmaril@0
   222
void LinkableMapObj::setLinkStyle(LinkStyle newstyle)
insilmaril@0
   223
{
insilmaril@83
   224
	//if (newstyle=style) return;
insilmaril@0
   225
	delLink();
insilmaril@0
   226
		
insilmaril@0
   227
	style=newstyle;
insilmaril@0
   228
insilmaril@0
   229
    if (childObj!=NULL && parObj != NULL)
insilmaril@0
   230
    {
insilmaril@408
   231
		QGraphicsLineItem *cl;
insilmaril@0
   232
		switch (style)
insilmaril@0
   233
		{
insilmaril@0
   234
			case StyleUndef:
insilmaril@0
   235
				bottomline->hide();
insilmaril@0
   236
				break;
insilmaril@0
   237
			case StyleLine: 
insilmaril@408
   238
				l = scene->addLine(QLineF(1,1,1,1),pen);
insilmaril@408
   239
				l->setZValue(Z_LINK);
insilmaril@0
   240
				if (visible)
insilmaril@0
   241
					l->show();
insilmaril@0
   242
				else
insilmaril@0
   243
					l->hide();
insilmaril@0
   244
				break;
insilmaril@0
   245
			case StyleParabel:
insilmaril@408
   246
				for (int i=0;i<arcsegs;i++)
insilmaril@0
   247
				{
insilmaril@408
   248
					cl = scene->addLine(QLineF(i*5,0,i*10,100),pen);
insilmaril@408
   249
					cl->setZValue(Z_LINK);
insilmaril@0
   250
					if (visible)
insilmaril@0
   251
						cl->show();
insilmaril@0
   252
					else
insilmaril@0
   253
						cl->hide();
insilmaril@0
   254
					segment.append(cl);
insilmaril@0
   255
				}
insilmaril@0
   256
				pa0.resize (arcsegs+1);
insilmaril@0
   257
				break;
insilmaril@0
   258
			case StylePolyLine:	
insilmaril@408
   259
				p =scene->addPolygon(QPolygonF(),pen,linkcolor);
insilmaril@408
   260
				p->setZValue(Z_LINK);
insilmaril@0
   261
				if (visible)
insilmaril@0
   262
					p->show();
insilmaril@0
   263
				else
insilmaril@0
   264
					p->hide();
insilmaril@0
   265
				pa0.resize (3);
insilmaril@0
   266
				break;
insilmaril@0
   267
			case StylePolyParabel:	
insilmaril@408
   268
				p = scene->addPolygon(QPolygonF(),pen,linkcolor);
insilmaril@408
   269
				p->setZValue(Z_LINK);
insilmaril@0
   270
				if (visible)
insilmaril@0
   271
					p->show();
insilmaril@0
   272
				else
insilmaril@0
   273
					p->hide();
insilmaril@0
   274
				pa0.resize (arcsegs*2+2);
insilmaril@0
   275
				pa1.resize (arcsegs+1);
insilmaril@0
   276
				pa2.resize (arcsegs+1);
insilmaril@0
   277
				break;
insilmaril@0
   278
			default: 
insilmaril@0
   279
				break;	
insilmaril@0
   280
		}	
insilmaril@164
   281
	} 
insilmaril@0
   282
}
insilmaril@0
   283
insilmaril@0
   284
LinkStyle LinkableMapObj::getLinkStyle()
insilmaril@0
   285
{
insilmaril@0
   286
	return style;
insilmaril@0
   287
}
insilmaril@0
   288
insilmaril@160
   289
void LinkableMapObj::setHideLinkUnselected(bool b)
insilmaril@160
   290
{
insilmaril@160
   291
	hideLinkUnselected=b;
insilmaril@160
   292
	setVisibility (visible);
insilmaril@160
   293
	updateLink();
insilmaril@160
   294
}
insilmaril@160
   295
insilmaril@160
   296
bool LinkableMapObj::getHideLinkUnselected()
insilmaril@160
   297
{
insilmaril@160
   298
	return hideLinkUnselected;
insilmaril@160
   299
}
insilmaril@160
   300
insilmaril@0
   301
void LinkableMapObj::setLinkPos(LinkPos lp)
insilmaril@0
   302
{
insilmaril@0
   303
	linkpos=lp;
insilmaril@0
   304
}
insilmaril@0
   305
insilmaril@0
   306
LinkPos LinkableMapObj::getLinkPos()
insilmaril@0
   307
{
insilmaril@0
   308
	return linkpos;
insilmaril@0
   309
}
insilmaril@0
   310
insilmaril@0
   311
insilmaril@0
   312
void LinkableMapObj::setLinkColor()
insilmaril@0
   313
{
insilmaril@0
   314
	// Overloaded in BranchObj and childs
insilmaril@0
   315
	// here only set default color
insilmaril@164
   316
	if (mapEditor)
insilmaril@398
   317
		setLinkColor (mapEditor->getMapDefLinkColor());
insilmaril@0
   318
}
insilmaril@0
   319
insilmaril@0
   320
void LinkableMapObj::setLinkColor(QColor col)
insilmaril@0
   321
{
insilmaril@0
   322
	linkcolor=col;
insilmaril@408
   323
	pen.setColor(col);
insilmaril@408
   324
    bottomline->setPen( pen );
insilmaril@0
   325
	switch (style)
insilmaril@0
   326
	{
insilmaril@0
   327
		case StyleLine:
insilmaril@408
   328
			l->setPen( pen);
insilmaril@0
   329
			break;	
insilmaril@0
   330
		case StyleParabel:	
insilmaril@406
   331
			for (int i=0; i<segment.size(); ++i)
insilmaril@408
   332
				segment.at(i)->setPen( pen);
insilmaril@0
   333
			break;
insilmaril@0
   334
		case StylePolyLine:
insilmaril@0
   335
			p->setBrush( QBrush(col));
insilmaril@0
   336
			break;
insilmaril@0
   337
		case StylePolyParabel:	
insilmaril@0
   338
			p->setBrush( QBrush(col));
insilmaril@0
   339
			break;
insilmaril@0
   340
		default:
insilmaril@0
   341
			break;
insilmaril@0
   342
	} // switch (style)	
insilmaril@0
   343
}
insilmaril@0
   344
insilmaril@0
   345
QColor LinkableMapObj::getLinkColor()
insilmaril@0
   346
{
insilmaril@0
   347
	return linkcolor;
insilmaril@0
   348
}
insilmaril@0
   349
insilmaril@0
   350
FrameType LinkableMapObj::getFrameType()
insilmaril@0
   351
{
insilmaril@0
   352
	return frame->getFrameType();
insilmaril@0
   353
}
insilmaril@0
   354
insilmaril@0
   355
void LinkableMapObj::setFrameType(const FrameType &t)
insilmaril@0
   356
{
insilmaril@0
   357
	frame->setFrameType(t);
insilmaril@0
   358
	calcBBoxSize();
insilmaril@0
   359
	positionBBox();
insilmaril@0
   360
	requestReposition();
insilmaril@0
   361
}
insilmaril@0
   362
insilmaril@0
   363
void LinkableMapObj::setFrameType(const QString &t)
insilmaril@0
   364
{
insilmaril@0
   365
	frame->setFrameType(t);
insilmaril@0
   366
	calcBBoxSize();
insilmaril@0
   367
	positionBBox();
insilmaril@0
   368
	requestReposition();
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@160
   385
			case StyleLine:
insilmaril@160
   386
				if (l) l->show();
insilmaril@160
   387
				break;
insilmaril@160
   388
			case StyleParabel:	
insilmaril@406
   389
				for (int i=0; i<segment.size(); ++i)
insilmaril@406
   390
					segment.at(i)->show();
insilmaril@160
   391
				break;	
insilmaril@160
   392
			case StylePolyLine:
insilmaril@160
   393
				if (p) p->show();
insilmaril@160
   394
				break;
insilmaril@160
   395
			case StylePolyParabel:	
insilmaril@160
   396
				if (p) p->show();
insilmaril@160
   397
				break;
insilmaril@160
   398
			default:
insilmaril@160
   399
				break;
insilmaril@160
   400
		}
insilmaril@0
   401
	} else 
insilmaril@0
   402
	{
insilmaril@0
   403
		bottomline->hide();
insilmaril@160
   404
		switch (style)
insilmaril@0
   405
		{
insilmaril@160
   406
			case StyleLine:
insilmaril@160
   407
				if (l) l->hide();
insilmaril@160
   408
				break;
insilmaril@160
   409
			case StyleParabel:	
insilmaril@406
   410
				for (int i=0; i<segment.size(); ++i)
insilmaril@406
   411
					segment.at(i)->hide();
insilmaril@160
   412
				break;	
insilmaril@160
   413
			case StylePolyLine:
insilmaril@160
   414
				if (p) p->hide();
insilmaril@160
   415
				break;
insilmaril@160
   416
			case StylePolyParabel:	
insilmaril@160
   417
				if (p) p->hide();
insilmaril@160
   418
				break;
insilmaril@160
   419
			default:
insilmaril@160
   420
				break;
insilmaril@160
   421
		}
insilmaril@0
   422
	}	
insilmaril@0
   423
}
insilmaril@0
   424
insilmaril@388
   425
void LinkableMapObj::setOrientation()
insilmaril@388
   426
{
insilmaril@388
   427
	LinkOrient orientOld=orientation;
insilmaril@388
   428
insilmaril@388
   429
	if (!parObj) 
insilmaril@388
   430
	{
insilmaril@388
   431
		orientation=OrientUndef;
insilmaril@388
   432
		return;
insilmaril@388
   433
	}
insilmaril@388
   434
		
insilmaril@388
   435
    // Set orientation, first look for orientation of parent
insilmaril@388
   436
    if (parObj->getOrientation() != OrientUndef ) 
insilmaril@388
   437
		// use the orientation of the parent:
insilmaril@388
   438
		orientation=parObj->getOrientation();
insilmaril@388
   439
    else
insilmaril@388
   440
    {
insilmaril@388
   441
		// calc orientation depending on position rel to parent
insilmaril@408
   442
		if (absPos.x() < QPointF(parObj->getChildPos() ).x() )
insilmaril@388
   443
			orientation=OrientLeftOfCenter; 
insilmaril@388
   444
		else
insilmaril@388
   445
			orientation=OrientRightOfCenter;
insilmaril@388
   446
    }
insilmaril@388
   447
	if (orientOld!=orientation) requestReposition();
insilmaril@388
   448
}
insilmaril@388
   449
insilmaril@0
   450
void LinkableMapObj::updateLink()
insilmaril@0
   451
{
insilmaril@0
   452
    // needs:
insilmaril@0
   453
    //	childPos of parent
insilmaril@0
   454
    //	orient   of parent
insilmaril@0
   455
    //	style
insilmaril@0
   456
    // 
insilmaril@0
   457
    // sets:
insilmaril@0
   458
    //	orientation
insilmaril@225
   459
    //	childPos	(by calling setDockPos())
insilmaril@225
   460
    //	parPos		(by calling setDockPos())
insilmaril@175
   461
	//  bottomlineY
insilmaril@0
   462
    //	drawing of the link itself
insilmaril@0
   463
insilmaril@0
   464
	// updateLink is called from move, but called from constructor we don't
insilmaril@0
   465
	// have parents yet...
insilmaril@0
   466
	if (style==StyleUndef) return;	
insilmaril@0
   467
insilmaril@0
   468
	if (frame->getFrameType() == NoFrame)
insilmaril@0
   469
		linkpos=LinkBottom;
insilmaril@0
   470
	else	
insilmaril@0
   471
		linkpos=LinkMiddle;
insilmaril@0
   472
	switch (linkpos)
insilmaril@0
   473
	{
insilmaril@0
   474
		case LinkMiddle:
insilmaril@225
   475
			bottomlineY=bbox.top()+bbox.height() /2;	// draw link to middle (of frame)
insilmaril@0
   476
			break;
insilmaril@0
   477
		default :
insilmaril@225
   478
			bottomlineY=bbox.bottom()-1;	// draw link to bottom of box
insilmaril@0
   479
			break;
insilmaril@0
   480
	}
insilmaril@0
   481
	
insilmaril@0
   482
    double p2x,p2y;								// Set P2 Before setting
insilmaril@0
   483
	if (!link2ParPos)
insilmaril@0
   484
	{
insilmaril@408
   485
		p2x=QPointF( parObj->getChildPos() ).x();	// P1, we have to look at
insilmaril@408
   486
		p2y=QPointF( parObj->getChildPos() ).y();	// orientation
insilmaril@0
   487
	} else	
insilmaril@0
   488
	{
insilmaril@408
   489
		p2x=QPointF( parObj->getParPos() ).x();	
insilmaril@408
   490
		p2y=QPointF( parObj->getParPos() ).y();
insilmaril@0
   491
	} 
insilmaril@0
   492
insilmaril@388
   493
	setDockPos(); // Call overloaded method
insilmaril@393
   494
	setOrientation();
insilmaril@0
   495
insilmaril@0
   496
	double p1x=parPos.x();	// Link is drawn from P1 to P2
insilmaril@0
   497
	double p1y=parPos.y();
insilmaril@0
   498
insilmaril@0
   499
	double vx=p2x - p1x;	// V=P2-P1
insilmaril@0
   500
	double vy=p2y - p1y;
insilmaril@0
   501
insilmaril@0
   502
	// Draw the horizontal line below heading (from ChildPos to ParPos)
insilmaril@427
   503
	//bottomline->prepareGeometryChange();
insilmaril@408
   504
	bottomline->setLine (QLine (qRound(childPos.x()),
insilmaril@104
   505
		qRound(childPos.y()),
insilmaril@104
   506
		qRound(p1x),
insilmaril@408
   507
		qRound(p1y) ));
insilmaril@0
   508
insilmaril@0
   509
	double a;	// angle
insilmaril@0
   510
	if (vx > -0.000001 && vx < 0.000001)
insilmaril@0
   511
		a=M_PI_2;
insilmaril@0
   512
	else
insilmaril@0
   513
		a=atan( vy / vx );
insilmaril@0
   514
	// "turning point" for drawing polygonal links
insilmaril@408
   515
	QPointF tp (-qRound(sin (a)*thickness_start), qRound(cos (a)*thickness_start));	
insilmaril@0
   516
	
insilmaril@0
   517
    // Draw the link
insilmaril@0
   518
	switch (style)
insilmaril@0
   519
	{
insilmaril@0
   520
		case StyleLine:
insilmaril@427
   521
			//l->prepareGeometryChange();
insilmaril@408
   522
			l->setLine( QLine(qRound (parPos.x()),
insilmaril@104
   523
				qRound(parPos.y()),
insilmaril@104
   524
				qRound(p2x),
insilmaril@408
   525
				qRound(p2y) ));
insilmaril@0
   526
			break;	
insilmaril@0
   527
		case StyleParabel:	
insilmaril@0
   528
			parabel (pa0, p1x,p1y,p2x,p2y);
insilmaril@406
   529
			for (int i=0; i<segment.size(); ++i)
insilmaril@427
   530
			{
insilmaril@427
   531
				//segment.at(i)->prepareGeometryChange();
insilmaril@408
   532
				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
   533
			}	
insilmaril@0
   534
			break;
insilmaril@0
   535
		case StylePolyLine:
insilmaril@408
   536
			pa0.clear();
insilmaril@408
   537
			pa0<<QPointF (qRound(p2x+tp.x()), qRound(p2y+tp.y()));
insilmaril@408
   538
			pa0<<QPointF (qRound(p2x-tp.x()), qRound(p2y-tp.y()));
insilmaril@408
   539
			pa0<<QPointF (qRound (parPos.x()), qRound(parPos.y()) );
insilmaril@427
   540
			//p->prepareGeometryChange();
insilmaril@408
   541
			p->setPolygon(QPolygonF (pa0));
insilmaril@0
   542
			break;
insilmaril@0
   543
		case StylePolyParabel:	
insilmaril@0
   544
			parabel (pa1, p1x,p1y,p2x+tp.x(),p2y+tp.y());
insilmaril@0
   545
			parabel (pa2, p1x,p1y,p2x-tp.x(),p2y-tp.y());
insilmaril@408
   546
			pa0.clear();
insilmaril@406
   547
			for (int i=0;i<=arcsegs;i++)
insilmaril@408
   548
				pa0 << QPointF (pa1.at(i));
insilmaril@408
   549
			for (int i=0;i<=arcsegs;i++)
insilmaril@408
   550
				pa0 << QPointF (pa2.at(arcsegs-i));
insilmaril@427
   551
			//p->prepareGeometryChange();
insilmaril@408
   552
			p->setPolygon(QPolygonF (pa0));
insilmaril@0
   553
			break;
insilmaril@0
   554
		default:
insilmaril@0
   555
			break;
insilmaril@0
   556
	} // switch (style)	
insilmaril@0
   557
}
insilmaril@0
   558
	
insilmaril@0
   559
LinkableMapObj* LinkableMapObj::getChildObj()
insilmaril@0
   560
{
insilmaril@0
   561
    return childObj;
insilmaril@0
   562
}
insilmaril@0
   563
insilmaril@0
   564
LinkableMapObj* LinkableMapObj::getParObj()
insilmaril@0
   565
{
insilmaril@0
   566
    return parObj;
insilmaril@0
   567
}
insilmaril@0
   568
insilmaril@106
   569
LinkableMapObj* LinkableMapObj::findObjBySelect (QString s)
insilmaril@95
   570
{
insilmaril@95
   571
	LinkableMapObj *lmo=this;
insilmaril@95
   572
	QString part;
insilmaril@95
   573
	QString typ;
insilmaril@95
   574
	QString num;
insilmaril@95
   575
	while (!s.isEmpty() )
insilmaril@95
   576
	{
insilmaril@95
   577
		part=s.section(",",0,0);
insilmaril@95
   578
		typ=part.left (3);
insilmaril@95
   579
		num=part.right(part.length() - 3);
insilmaril@95
   580
		if (typ=="mc:")
insilmaril@95
   581
		{
insilmaril@95
   582
			if (depth>0)
insilmaril@95
   583
				return false;	// in a subtree there is no center
insilmaril@95
   584
			else
insilmaril@95
   585
				break;
insilmaril@95
   586
		} else
insilmaril@95
   587
			if (typ=="bo:")
insilmaril@406
   588
				lmo=((BranchObj*)(lmo))->getBranchNum (num.toInt());
insilmaril@95
   589
			else
insilmaril@95
   590
				if (typ=="fi:")
insilmaril@95
   591
					lmo=((BranchObj*)(lmo))->getFloatImageNum (num.toUInt());
insilmaril@95
   592
		if (!lmo) break;
insilmaril@95
   593
		
insilmaril@95
   594
		if (s.contains(","))
insilmaril@95
   595
			s=s.right(s.length() - part.length() -1 );
insilmaril@95
   596
		else	
insilmaril@95
   597
			break;
insilmaril@95
   598
	}
insilmaril@95
   599
	return lmo;
insilmaril@95
   600
}
insilmaril@95
   601
insilmaril@408
   602
QPointF LinkableMapObj::getChildPos()
insilmaril@0
   603
{
insilmaril@0
   604
    return childPos;
insilmaril@0
   605
}
insilmaril@0
   606
insilmaril@408
   607
QPointF LinkableMapObj::getParPos()
insilmaril@0
   608
{
insilmaril@0
   609
    return parPos;
insilmaril@0
   610
}
insilmaril@0
   611
insilmaril@218
   612
void LinkableMapObj::setUseOrientation (const bool &b)
insilmaril@218
   613
{	
insilmaril@218
   614
	if (useOrientation!=b)
insilmaril@218
   615
	{
insilmaril@218
   616
		useOrientation=b;
insilmaril@218
   617
		requestReposition();
insilmaril@218
   618
	}	
insilmaril@218
   619
}
insilmaril@218
   620
insilmaril@0
   621
LinkOrient LinkableMapObj::getOrientation()
insilmaril@0
   622
{
insilmaril@0
   623
    return orientation;
insilmaril@0
   624
}
insilmaril@0
   625
insilmaril@0
   626
int LinkableMapObj::getDepth()
insilmaril@0
   627
{
insilmaril@0
   628
    return depth;
insilmaril@0
   629
}
insilmaril@0
   630
insilmaril@0
   631
void LinkableMapObj::setMapEditor (MapEditor *me)
insilmaril@0
   632
{
insilmaril@0
   633
	mapEditor=me;
insilmaril@0
   634
}
insilmaril@0
   635
insilmaril@0
   636
MapEditor* LinkableMapObj::getMapEditor ()
insilmaril@0
   637
{
insilmaril@0
   638
	return mapEditor;
insilmaril@0
   639
}
insilmaril@0
   640
insilmaril@408
   641
QPointF LinkableMapObj::getRandPos()
insilmaril@0
   642
{
insilmaril@0
   643
	// Choose a random position with given distance to parent:
insilmaril@0
   644
	double a=rand()%360 * 2 * M_PI / 360;
insilmaril@408
   645
    return QPointF ( (int)( + 150*cos (a)),
insilmaril@0
   646
                    (int)( + 150*sin (a)));
insilmaril@0
   647
}
insilmaril@0
   648
insilmaril@0
   649
void LinkableMapObj::reposition()
insilmaril@0
   650
{
insilmaril@0
   651
}
insilmaril@0
   652
insilmaril@0
   653
void LinkableMapObj::requestReposition()
insilmaril@0
   654
{
insilmaril@0
   655
	if (!repositionRequest)
insilmaril@0
   656
	{
insilmaril@0
   657
		// Pass on the request to parental objects, if this hasn't
insilmaril@0
   658
		// been done yet
insilmaril@0
   659
		repositionRequest=true;
insilmaril@0
   660
		if (parObj) parObj->requestReposition();
insilmaril@0
   661
	}
insilmaril@0
   662
}
insilmaril@0
   663
insilmaril@0
   664
void LinkableMapObj::forceReposition()
insilmaril@0
   665
{
insilmaril@0
   666
	// Sometimes a reposition has to be done immediatly: For example
insilmaril@0
   667
	// if the note editor flag changes, there is no user event in mapeditor
insilmaril@0
   668
	// which could collect requests for a reposition.
insilmaril@0
   669
	// Then we have to call forceReposition()
insilmaril@0
   670
	// But no rule without exception: While loading a map or undoing it,
insilmaril@0
   671
	// we want to block expensive repositioning, but just do it once at
insilmaril@0
   672
	// the end, thus check first:
insilmaril@0
   673
insilmaril@139
   674
	if (mapEditor->isRepositionBlocked()) return;
insilmaril@0
   675
	
insilmaril@0
   676
	// Pass on the request to parental objects, if this hasn't been done yet
insilmaril@0
   677
	
insilmaril@0
   678
	if (parObj) 
insilmaril@0
   679
		parObj->forceReposition(); 
insilmaril@0
   680
	else 
insilmaril@83
   681
		reposition(); 
insilmaril@83
   682
}
insilmaril@0
   683
insilmaril@0
   684
bool LinkableMapObj::repositionRequested()
insilmaril@0
   685
{
insilmaril@0
   686
	return repositionRequest;
insilmaril@0
   687
}
insilmaril@0
   688
insilmaril@0
   689
insilmaril@0
   690
void LinkableMapObj::setSelBox()
insilmaril@0
   691
{
insilmaril@427
   692
	//selbox->prepareGeometryChange();
insilmaril@408
   693
	selbox->setRect (clickBox);
insilmaril@0
   694
}
insilmaril@0
   695
insilmaril@0
   696
void LinkableMapObj::select()
insilmaril@0
   697
{
insilmaril@0
   698
	setSelBox();
insilmaril@0
   699
    selected=true;
insilmaril@0
   700
    selbox->show();
insilmaril@261
   701
	setVisibility (visible);
insilmaril@0
   702
}
insilmaril@0
   703
insilmaril@0
   704
insilmaril@0
   705
void LinkableMapObj::unselect()
insilmaril@0
   706
{
insilmaril@0
   707
    selected=false;
insilmaril@0
   708
    selbox->hide();
insilmaril@261
   709
	// Maybe we have to hide the link:
insilmaril@261
   710
	setVisibility (visible);
insilmaril@0
   711
}
insilmaril@0
   712
insilmaril@408
   713
void LinkableMapObj::parabel (QPolygonF &ya, double p1x, double p1y, double p2x, double p2y)
insilmaril@0
   714
insilmaril@0
   715
{
insilmaril@0
   716
	double vx=p2x - p1x;	// V=P2-P1
insilmaril@0
   717
	double vy=p2y - p1y;
insilmaril@0
   718
insilmaril@0
   719
	double dx;				// delta x during calculation of parabel
insilmaril@0
   720
	
insilmaril@0
   721
	double pnx;				// next point
insilmaril@0
   722
	double pny;
insilmaril@0
   723
	double m;
insilmaril@0
   724
insilmaril@0
   725
	if (vx > -0.0001 && vx < 0.0001)
insilmaril@0
   726
		m=0;
insilmaril@0
   727
	else	
insilmaril@0
   728
		m=(vy / (vx*vx));
insilmaril@0
   729
	dx=vx/(arcsegs);
insilmaril@408
   730
	ya.clear();
insilmaril@408
   731
	ya<<QPointF (qRound(p1x),qRound(p1y));
insilmaril@408
   732
	for (int i=1;i<=arcsegs;i++)
insilmaril@0
   733
	{	
insilmaril@0
   734
		pnx=p1x+dx;
insilmaril@0
   735
		pny=m*(pnx-parPos.x())*(pnx-parPos.x())+parPos.y();
insilmaril@408
   736
		ya<<QPointF (qRound(pnx),qRound(pny));
insilmaril@0
   737
		p1x=pnx;
insilmaril@0
   738
		p1y=pny;
insilmaril@0
   739
	}	
insilmaril@0
   740
}
insilmaril@0
   741
insilmaril@160
   742
QString LinkableMapObj::getLinkAttr ()
insilmaril@160
   743
{
insilmaril@160
   744
	if (hideLinkUnselected)
insilmaril@175
   745
		return attribut ("hideLink","true");
insilmaril@160
   746
	else
insilmaril@175
   747
		return attribut ("hideLink","false");
insilmaril@160
   748
	
insilmaril@160
   749
}