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