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