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