branchobj.cpp
author insilmaril
Mon, 14 Dec 2009 10:17:55 +0000
changeset 817 b486ffd0fa11
parent 815 2881c4424190
child 819 8f987e376035
permissions -rw-r--r--
Bugfix for relinking mainbranches
insilmaril@0
     1
#include "branchobj.h"
insilmaril@616
     2
insilmaril@749
     3
#include "branchitem.h"
insilmaril@643
     4
#include "geometry.h"
insilmaril@0
     5
#include "mapeditor.h"
insilmaril@794
     6
#include "mainwindow.h"   
insilmaril@616
     7
#include "misc.h"
insilmaril@616
     8
insilmaril@767
     9
extern FlagRow *standardFlagsMaster;
insilmaril@767
    10
extern FlagRow *systemFlagsMaster;
insilmaril@0
    11
insilmaril@0
    12
/////////////////////////////////////////////////////////////////
insilmaril@0
    13
// BranchObj
insilmaril@0
    14
/////////////////////////////////////////////////////////////////
insilmaril@0
    15
insilmaril@790
    16
BranchObj::BranchObj (QGraphicsScene* s,TreeItem *ti):OrnamentedObj (s)
insilmaril@0
    17
{
insilmaril@755
    18
//    cout << "Const BranchObj (s)  \n";
insilmaril@408
    19
    scene=s;
insilmaril@790
    20
	treeItem=ti;
insilmaril@794
    21
	BranchItem *pi=(BranchItem*)(ti->parent());
insilmaril@794
    22
	if (pi && pi!=ti->getModel()->getRootItem() )
insilmaril@794
    23
		parObj=pi->getLMO();
insilmaril@794
    24
	else
insilmaril@794
    25
		parObj=NULL;
insilmaril@755
    26
	init();
insilmaril@0
    27
}
insilmaril@0
    28
insilmaril@790
    29
/*
insilmaril@755
    30
BranchObj::BranchObj (QGraphicsScene* s, LinkableMapObj* p):OrnamentedObj (s)// FIXME-3 needed at all?
insilmaril@0
    31
{
insilmaril@408
    32
//    cout << "Const BranchObj (s,p)\n";
insilmaril@408
    33
    scene=s;
insilmaril@0
    34
    setParObj (p);	
insilmaril@773
    35
	if (treeItem->depth()==1)	// FIXME-3 needed to recursively calc depth?
insilmaril@0
    36
		// Calc angle to mapCenter if I am a mainbranch
insilmaril@0
    37
		// needed for reordering the mainbranches clockwise 
insilmaril@0
    38
		// around mapcenter 
insilmaril@408
    39
		angle=getAngle (QPointF (x() - parObj->getChildPos().x() , 
insilmaril@408
    40
								(y() - parObj->getChildPos().y() ) ) );
insilmaril@0
    41
    init();
insilmaril@0
    42
}
insilmaril@790
    43
*/
insilmaril@0
    44
insilmaril@0
    45
BranchObj::~BranchObj ()
insilmaril@0
    46
{
insilmaril@757
    47
//	cout << "Destr BranchObj of "<<this<<" ("<<treeItem->getHeading().toStdString()<<")"<<endl;
insilmaril@757
    48
insilmaril@722
    49
	// If I'm animated, I need to un-animate myself first
insilmaril@722
    50
	if (anim.isAnimated() )
insilmaril@722
    51
	{
insilmaril@722
    52
		anim.setAnimated (false);
insilmaril@773
    53
		VymModel *model=treeItem->getModel();
insilmaril@722
    54
		model->stopAnimation (this);
insilmaril@722
    55
	}
insilmaril@722
    56
insilmaril@0
    57
	// Check, if this branch was the last child to be deleted
insilmaril@749
    58
	// If so, unset the scrolled flags in parent // FIXME-2 better do this in model?
insilmaril@0
    59
insilmaril@749
    60
	/*
insilmaril@425
    61
	BranchObj *po=(BranchObj*)parObj;
insilmaril@83
    62
	BranchObj *bo;
insilmaril@0
    63
	if (po)
insilmaril@0
    64
	{
insilmaril@425
    65
		bo=((BranchObj*)parObj)->getLastBranch();
insilmaril@425
    66
		if (bo) po->unScroll();
insilmaril@0
    67
	}
insilmaril@749
    68
	*/
insilmaril@83
    69
	clear();
insilmaril@0
    70
}
insilmaril@0
    71
insilmaril@0
    72
void BranchObj::init () 
insilmaril@0
    73
{
insilmaril@83
    74
	if (parObj)
insilmaril@83
    75
	{
insilmaril@83
    76
		absPos=getRandPos();
insilmaril@83
    77
		absPos+=parObj->getChildPos();
insilmaril@83
    78
	}
insilmaril@0
    79
}
insilmaril@0
    80
insilmaril@0
    81
void BranchObj::copy (BranchObj* other)
insilmaril@0
    82
{
insilmaril@0
    83
    OrnamentedObj::copy(other);
insilmaril@0
    84
insilmaril@0
    85
	setVisibility (other->visible);
insilmaril@0
    86
insilmaril@0
    87
    positionBBox();
insilmaril@0
    88
}
insilmaril@0
    89
insilmaril@0
    90
void BranchObj::clear() 
insilmaril@0
    91
{
insilmaril@755
    92
	//setVisibility (true); //FIXME-4 needed?
insilmaril@425
    93
insilmaril@95
    94
	while (!xlink.isEmpty())
insilmaril@406
    95
		delete xlink.takeFirst();
insilmaril@0
    96
}
insilmaril@0
    97
insilmaril@804
    98
void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off)	//FIXME-1 when moving a mainbranch to a branch it still has relPos, not moved as child
insilmaril@0
    99
{
insilmaril@796
   100
	// Temporary link to dst
insilmaril@0
   101
	// m is position of mouse pointer 
insilmaril@796
   102
	// offset 0: default 1: below dst   -1 above dst  (if possible)
insilmaril@0
   103
insilmaril@796
   104
	BranchItem *dsti=(BranchItem*)(dst->getTreeItem());
insilmaril@796
   105
insilmaril@796
   106
	BranchItem *pi=(BranchItem*)(dsti->parent());
insilmaril@775
   107
	int pi_depth=pi->depth();
insilmaril@815
   108
	BranchObj* bodst=(BranchObj*)dst;
insilmaril@0
   109
insilmaril@798
   110
	if (!tmpParent) 
insilmaril@798
   111
	{
insilmaril@798
   112
		tmpParent=true;
insilmaril@798
   113
		parObjTmpBuf=parObj;
insilmaril@798
   114
	}
insilmaril@796
   115
insilmaril@775
   116
	if (pi_depth<2) off=0;
insilmaril@0
   117
	if (off==0)
insilmaril@0
   118
		link2ParPos=false;
insilmaril@0
   119
	else
insilmaril@0
   120
		link2ParPos=true;
insilmaril@815
   121
	parObj=bodst;
insilmaril@0
   122
insilmaril@796
   123
	setLinkStyle (dst->getDefLinkStyle (dsti));
insilmaril@814
   124
 
insilmaril@0
   125
	// Move temporary to new position at destination
insilmaril@0
   126
	// Usually the positioning would be done by reposition(),
insilmaril@0
   127
	// but then also the destination branch would "Jump" around...
insilmaril@0
   128
	// Better just do it approximately
insilmaril@814
   129
	if (dsti->depth()==0)	
insilmaril@786
   130
	{	// new parent is a mapcenter
insilmaril@815
   131
		Vector v= ( m - bodst->getChildPos());
insilmaril@798
   132
		if (v.x()<0) v.setX( v.x()-bbox.width() );
insilmaril@798
   133
		v.normalize();
insilmaril@798
   134
		v.scale (100);
insilmaril@798
   135
		move2RelPos (v.toQPointF());
insilmaril@0
   136
	} else
insilmaril@0
   137
	{	
insilmaril@408
   138
		qreal y;
insilmaril@0
   139
		if (off==0)
insilmaril@0
   140
		{
insilmaril@0
   141
			// new parent is just a branch, link to it
insilmaril@815
   142
			QRectF t=bodst->getBBoxSizeWithChildren();
insilmaril@796
   143
			if (dsti->getLastBranch())
insilmaril@0
   144
				y=t.y() + t.height() ;
insilmaril@0
   145
			else
insilmaril@0
   146
				y=t.y();
insilmaril@0
   147
insilmaril@815
   148
			y=t.bottom();
insilmaril@815
   149
insilmaril@0
   150
		} else
insilmaril@0
   151
		{
insilmaril@0
   152
			if (off<0)
insilmaril@796
   153
				// we want to link above dst
insilmaril@815
   154
				y=bodst->y() - height() + 5;
insilmaril@0
   155
			else	
insilmaril@796
   156
				// we want to link below dst
insilmaril@0
   157
				// Bottom of sel should be 5 pixels above
insilmaril@0
   158
				// the bottom of the branch _below_ the target:
insilmaril@0
   159
				// Don't try to find that branch, guess 12 pixels
insilmaril@815
   160
				y=bodst->getChildPos().y()  -height() + 12; 
insilmaril@0
   161
		}	
insilmaril@815
   162
		if (bodst->getOrientation()==LinkableMapObj::LeftOfCenter)
insilmaril@815
   163
			move ( bodst->getChildPos().x() - linkwidth, y );
insilmaril@0
   164
		else	
insilmaril@815
   165
			move (bodst->getChildPos().x() + linkwidth, y );
insilmaril@0
   166
	}	
insilmaril@0
   167
insilmaril@779
   168
	// updateLinkGeometry is called implicitly in move
insilmaril@417
   169
	requestReposition();	
insilmaril@0
   170
}
insilmaril@0
   171
insilmaril@0
   172
void BranchObj::unsetParObjTmp()
insilmaril@0
   173
{
insilmaril@798
   174
	if (tmpParent) 
insilmaril@0
   175
	{
insilmaril@798
   176
		tmpParent=false;
insilmaril@0
   177
		link2ParPos=false;
insilmaril@0
   178
		parObj=parObjTmpBuf;
insilmaril@0
   179
		parObjTmpBuf=NULL;
insilmaril@786
   180
		setLinkStyle (getDefLinkStyle(treeItem->parent() ) );
insilmaril@779
   181
		updateLinkGeometry();
insilmaril@0
   182
	}		
insilmaril@0
   183
}
insilmaril@0
   184
insilmaril@0
   185
void BranchObj::setVisibility(bool v, int toDepth)
insilmaril@0
   186
{
insilmaril@749
   187
	BranchItem *bi=(BranchItem*)treeItem;
insilmaril@755
   188
    if (bi->depth() <= toDepth)
insilmaril@0
   189
    {
insilmaril@0
   190
		frame->setVisibility(v);
insilmaril@0
   191
		heading->setVisibility(v);
insilmaril@0
   192
		systemFlags->setVisibility(v);
insilmaril@0
   193
		standardFlags->setVisibility(v);
insilmaril@0
   194
		LinkableMapObj::setVisibility (v);
insilmaril@730
   195
		int i;
insilmaril@785
   196
		for (i=0; i<treeItem->imageCount(); ++i)
insilmaril@785
   197
			treeItem->getImageObjNum(i)->setVisibility (v);
insilmaril@790
   198
		for (i=0; i<treeItem->xlinkCount(); ++i)	
insilmaril@790
   199
			treeItem->getXLinkObjNum(i)->setVisibility ();	
insilmaril@730
   200
insilmaril@721
   201
		// Only change children, if I am not scrolled
insilmaril@749
   202
		if (! bi->isScrolled() && (bi->depth() < toDepth))
insilmaril@0
   203
		{
insilmaril@785
   204
			// Now go recursivly through all children //FIXME-3 are there multiple calls for lower level items???
insilmaril@750
   205
			for (i=0; i<treeItem->branchCount(); ++i)
insilmaril@753
   206
				treeItem->getBranchObjNum(i)->setVisibility (v,toDepth);	
insilmaril@0
   207
		}
insilmaril@0
   208
    } // depth <= toDepth	
insilmaril@0
   209
	requestReposition();
insilmaril@0
   210
}	
insilmaril@0
   211
insilmaril@0
   212
void BranchObj::setVisibility(bool v)
insilmaril@0
   213
{
insilmaril@0
   214
    setVisibility (v,MAX_DEPTH);
insilmaril@0
   215
}
insilmaril@0
   216
insilmaril@0
   217
insilmaril@0
   218
void BranchObj::setLinkColor ()
insilmaril@0
   219
{
insilmaril@0
   220
	// Overloaded from LinkableMapObj
insilmaril@0
   221
	// BranchObj can use color of heading
insilmaril@0
   222
insilmaril@773
   223
	VymModel *model=treeItem->getModel();
insilmaril@721
   224
	if (model)
insilmaril@611
   225
	{
insilmaril@721
   226
		if (model->getMapLinkColorHint()==HeadingColor)
insilmaril@164
   227
			LinkableMapObj::setLinkColor (heading->getColor() );
insilmaril@164
   228
		else	
insilmaril@164
   229
			LinkableMapObj::setLinkColor ();
insilmaril@611
   230
	}		
insilmaril@0
   231
}
insilmaril@0
   232
insilmaril@753
   233
void BranchObj::updateContentSize()
insilmaril@753
   234
{
insilmaril@753
   235
	calcBBoxSize();
insilmaril@753
   236
	positionBBox();
insilmaril@753
   237
	requestReposition();
insilmaril@100
   238
}
insilmaril@0
   239
insilmaril@333
   240
void BranchObj::positionContents()
insilmaril@333
   241
{
insilmaril@785
   242
	for (int i=0; i<treeItem->imageCount(); ++i)
insilmaril@785
   243
		treeItem->getImageObjNum(i)->reposition();
insilmaril@333
   244
	OrnamentedObj::positionContents();
insilmaril@333
   245
}
insilmaril@0
   246
insilmaril@0
   247
void BranchObj::move (double x, double y)
insilmaril@0
   248
{
insilmaril@0
   249
	OrnamentedObj::move (x,y);
insilmaril@0
   250
    positionBBox();
insilmaril@0
   251
}
insilmaril@0
   252
insilmaril@408
   253
void BranchObj::move (QPointF p)
insilmaril@0
   254
{
insilmaril@0
   255
	move (p.x(), p.y());
insilmaril@0
   256
}
insilmaril@0
   257
insilmaril@0
   258
void BranchObj::moveBy (double x, double y)
insilmaril@0
   259
{
insilmaril@0
   260
	OrnamentedObj::moveBy (x,y);
insilmaril@750
   261
	for (int i=0; i<treeItem->branchCount(); ++i)
insilmaril@753
   262
		treeItem->getBranchObjNum(i)->moveBy (x,y);
insilmaril@333
   263
    positionBBox();
insilmaril@0
   264
}
insilmaril@83
   265
	
insilmaril@408
   266
void BranchObj::moveBy (QPointF p)
insilmaril@0
   267
{
insilmaril@0
   268
	moveBy (p.x(), p.y());
insilmaril@0
   269
}
insilmaril@0
   270
insilmaril@0
   271
insilmaril@0
   272
void BranchObj::positionBBox()
insilmaril@0
   273
{
insilmaril@408
   274
	QPointF ap=getAbsPos();
insilmaril@223
   275
	bbox.moveTopLeft (ap);
insilmaril@169
   276
	positionContents();
insilmaril@0
   277
insilmaril@0
   278
	// set the frame
insilmaril@408
   279
	frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
insilmaril@83
   280
insilmaril@790
   281
	//Update links to other branches
insilmaril@790
   282
	XLinkObj *xlo;
insilmaril@790
   283
	for (int i=0; i<treeItem->xlinkCount(); ++i)	
insilmaril@790
   284
	{
insilmaril@790
   285
		xlo=treeItem->getXLinkObjNum(i);
insilmaril@790
   286
		if (xlo) xlo->updateXLink();
insilmaril@790
   287
	}	
insilmaril@0
   288
}
insilmaril@0
   289
insilmaril@0
   290
void BranchObj::calcBBoxSize()
insilmaril@0
   291
{
insilmaril@408
   292
    QSizeF heading_r=heading->getSize();
insilmaril@408
   293
    qreal heading_w=(qreal) heading_r.width() ;
insilmaril@408
   294
    qreal heading_h=(qreal) heading_r.height() ;
insilmaril@767
   295
    QSizeF sysflags_r=systemFlags->getSize();
insilmaril@767
   296
	qreal sysflags_h=sysflags_r.height();
insilmaril@767
   297
	qreal sysflags_w=sysflags_r.width();
insilmaril@767
   298
    QSizeF stanflags_r=standardFlags->getSize();
insilmaril@767
   299
	qreal stanflags_h=stanflags_r.height();
insilmaril@767
   300
	qreal stanflags_w=stanflags_r.width();
insilmaril@408
   301
    qreal w;
insilmaril@408
   302
    qreal h;
insilmaril@0
   303
insilmaril@0
   304
	// set width to sum of all widths
insilmaril@0
   305
	w=heading_w + sysflags_w + stanflags_w;
insilmaril@0
   306
	// set height to maximum needed height
insilmaril@0
   307
	h=max (sysflags_h,stanflags_h);
insilmaril@0
   308
	h=max (h,heading_h);
insilmaril@0
   309
insilmaril@223
   310
	// Save the dimension of flags and heading
insilmaril@408
   311
	ornamentsBBox.setSize ( QSizeF(w,h));
insilmaril@223
   312
insilmaril@223
   313
	// clickBox includes Flags and Heading
insilmaril@223
   314
    clickBox.setSize (ornamentsBBox.size() );
insilmaril@169
   315
insilmaril@169
   316
	// Floatimages 
insilmaril@408
   317
	QPointF rp;
insilmaril@169
   318
insilmaril@169
   319
	topPad=botPad=leftPad=rightPad=0;
insilmaril@785
   320
	bool incV=((BranchItem*)treeItem)->getIncludeImagesVer();
insilmaril@785
   321
	bool incH=((BranchItem*)treeItem)->getIncludeImagesHor();
insilmaril@785
   322
	if (incH || incV)
insilmaril@169
   323
	{
insilmaril@785
   324
		FloatImageObj *fio;
insilmaril@785
   325
		for (int i=0; i<treeItem->imageCount(); ++i )	
insilmaril@169
   326
		{
insilmaril@785
   327
			fio=treeItem->getImageObjNum(i);
insilmaril@785
   328
			rp=fio->getRelPos();
insilmaril@785
   329
			if (incV)
insilmaril@169
   330
			{
insilmaril@785
   331
				if (rp.y() < 0) 
insilmaril@785
   332
					topPad=max (topPad,-rp.y()-h);
insilmaril@785
   333
				if (rp.y()+fio->height() > 0)
insilmaril@785
   334
					botPad=max (botPad,rp.y()+fio->height());
insilmaril@785
   335
			}		
insilmaril@785
   336
			if (incH)
insilmaril@785
   337
			{
insilmaril@785
   338
				if (orientation==LinkableMapObj::RightOfCenter)
insilmaril@169
   339
				{
insilmaril@785
   340
					if (-rp.x()-w > 0) 
insilmaril@785
   341
						leftPad=max (leftPad,-rp.x()-w);
insilmaril@785
   342
					if (rp.x()+fio->width() > 0)
insilmaril@785
   343
						rightPad=max (rightPad,rp.x()+fio->width());
insilmaril@785
   344
				} else
insilmaril@213
   345
				{
insilmaril@785
   346
					if (rp.x()< 0) 
insilmaril@785
   347
						leftPad=max (leftPad,-rp.x());
insilmaril@785
   348
					if (rp.x()+fio->width() > w)
insilmaril@785
   349
						rightPad=max (rightPad,rp.x()+fio->width()-w);
insilmaril@785
   350
				}
insilmaril@785
   351
			}		
insilmaril@169
   352
		}	
insilmaril@169
   353
		h+=topPad+botPad;
insilmaril@213
   354
		w+=leftPad+rightPad;
insilmaril@169
   355
	}
insilmaril@169
   356
insilmaril@169
   357
	// Frame thickness
insilmaril@462
   358
    w+=frame->getPadding();
insilmaril@462
   359
    h+=frame->getPadding();
insilmaril@169
   360
	
insilmaril@169
   361
	// Finally set size
insilmaril@408
   362
    bbox.setSize (QSizeF (w,h));
insilmaril@0
   363
}
insilmaril@0
   364
insilmaril@223
   365
void BranchObj::setDockPos()
insilmaril@223
   366
{
insilmaril@775
   367
	if (treeItem->getType()==TreeItem::MapCenter)
insilmaril@775
   368
	{
insilmaril@775
   369
		// set childPos to middle of MapCenterObj
insilmaril@775
   370
		childPos.setX( clickBox.topLeft().x() + clickBox.width()/2 );
insilmaril@775
   371
		childPos.setY( clickBox.topLeft().y() + clickBox.height()/2 );
insilmaril@775
   372
		parPos=childPos;		
insilmaril@775
   373
		for (int i=0; i<treeItem->branchCount(); ++i)
insilmaril@779
   374
			treeItem->getBranchObjNum(i)->updateLinkGeometry();
insilmaril@775
   375
insilmaril@775
   376
	} else
insilmaril@775
   377
	{
insilmaril@775
   378
		// Sets childpos and parpos depending on orientation
insilmaril@775
   379
		if (getOrientation()==LinkableMapObj::LeftOfCenter )
insilmaril@775
   380
		{
insilmaril@775
   381
			childPos=QPointF (
insilmaril@775
   382
				ornamentsBBox.bottomLeft().x(), 
insilmaril@775
   383
				bottomlineY);
insilmaril@775
   384
			parPos=QPointF (
insilmaril@775
   385
				ornamentsBBox.bottomRight().x(),
insilmaril@775
   386
				bottomlineY);
insilmaril@775
   387
		} else
insilmaril@775
   388
		{
insilmaril@775
   389
			childPos=QPointF (
insilmaril@775
   390
				ornamentsBBox.bottomRight().x(), 
insilmaril@775
   391
				bottomlineY);
insilmaril@775
   392
			parPos=QPointF (
insilmaril@775
   393
				ornamentsBBox.bottomLeft().x(),
insilmaril@775
   394
				bottomlineY);
insilmaril@775
   395
		}
insilmaril@775
   396
	}
insilmaril@223
   397
}
insilmaril@382
   398
insilmaril@767
   399
void BranchObj::updateData()
insilmaril@0
   400
{
insilmaril@767
   401
	bool changed=false;
insilmaril@753
   402
	if (!treeItem)
insilmaril@254
   403
	{
insilmaril@753
   404
		qWarning ("BranchObj::udpateHeading treeItem==NULL");
insilmaril@753
   405
		return;
insilmaril@753
   406
	}
insilmaril@767
   407
	QString s=treeItem->getHeading();
insilmaril@767
   408
	if (s!=heading->text())
insilmaril@767
   409
	{
insilmaril@767
   410
		heading->setText (s);
insilmaril@767
   411
		changed=true;
insilmaril@767
   412
	}
insilmaril@767
   413
	QStringList TIactiveFlags=treeItem->activeStandardFlagNames();
insilmaril@767
   414
insilmaril@767
   415
	// Add missing standard flags active in TreeItem
insilmaril@767
   416
	for (int i=0;i<=TIactiveFlags.size()-1;i++)
insilmaril@767
   417
	{	
insilmaril@767
   418
		if (!standardFlags->isActive (TIactiveFlags.at(i) ))
insilmaril@767
   419
		{
insilmaril@767
   420
			Flag *f=standardFlagsMaster->getFlag(TIactiveFlags.at(i));
insilmaril@767
   421
			if (f) standardFlags->activate (f);
insilmaril@767
   422
			changed=true;
insilmaril@767
   423
		}
insilmaril@767
   424
	}
insilmaril@767
   425
	// Remove standard flags no longer active in TreeItem
insilmaril@767
   426
	QStringList BOactiveFlags=standardFlags->activeFlagNames();
insilmaril@767
   427
	for (int i=0;i<BOactiveFlags.size();++i)
insilmaril@767
   428
		if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
insilmaril@767
   429
		{
insilmaril@767
   430
			standardFlags->deactivate (BOactiveFlags.at(i));
insilmaril@767
   431
			changed=true;
insilmaril@767
   432
		}	
insilmaril@767
   433
insilmaril@767
   434
	// Add missing system flags active in TreeItem
insilmaril@767
   435
	TIactiveFlags=treeItem->activeSystemFlagNames();
insilmaril@767
   436
	for (int i=0;i<TIactiveFlags.size();++i)
insilmaril@767
   437
	{	
insilmaril@767
   438
		if (!systemFlags->isActive (TIactiveFlags.at(i) ))
insilmaril@767
   439
		{
insilmaril@767
   440
			Flag *f=systemFlagsMaster->getFlag(TIactiveFlags.at(i));
insilmaril@767
   441
			if (f) systemFlags->activate (f);
insilmaril@767
   442
			changed=true;
insilmaril@767
   443
		}
insilmaril@767
   444
	}
insilmaril@767
   445
	// Remove system flags no longer active in TreeItem
insilmaril@767
   446
	BOactiveFlags=systemFlags->activeFlagNames();
insilmaril@767
   447
	for (int i=0;i<BOactiveFlags.size();++i)
insilmaril@767
   448
	{
insilmaril@767
   449
		if (!TIactiveFlags.contains (BOactiveFlags.at(i)))
insilmaril@767
   450
		{
insilmaril@767
   451
			systemFlags->deactivate (BOactiveFlags.at(i));
insilmaril@767
   452
			changed=true;
insilmaril@767
   453
		}	
insilmaril@767
   454
	}
insilmaril@785
   455
	updateContentSize();
insilmaril@254
   456
}
insilmaril@254
   457
insilmaril@146
   458
void BranchObj::setDefAttr (BranchModification mod)
insilmaril@146
   459
{
insilmaril@146
   460
	int fontsize;
insilmaril@755
   461
	switch (treeItem->depth())
insilmaril@146
   462
	{
insilmaril@798
   463
		case 0: 
insilmaril@798
   464
			fontsize=16; 
insilmaril@798
   465
			setFrameType (FrameObj::Rectangle);
insilmaril@798
   466
			break;
insilmaril@798
   467
		case 1: 
insilmaril@804
   468
			fontsize=14; 
insilmaril@804
   469
			setFrameType (FrameObj::NoFrame);
insilmaril@804
   470
			break;
insilmaril@804
   471
		case 2: 
insilmaril@798
   472
			fontsize=12; 
insilmaril@798
   473
			setFrameType (FrameObj::NoFrame);
insilmaril@798
   474
			break;
insilmaril@798
   475
		default: 
insilmaril@798
   476
			fontsize=10; 
insilmaril@798
   477
			setFrameType (FrameObj::NoFrame);
insilmaril@798
   478
			break;
insilmaril@146
   479
	}	
insilmaril@786
   480
	setLinkStyle(getDefLinkStyle(treeItem->parent() ));
insilmaril@146
   481
	setLinkColor ();
insilmaril@146
   482
	QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
insilmaril@146
   483
	font.setPointSize(fontsize);
insilmaril@146
   484
	heading->setFont(font );
insilmaril@146
   485
insilmaril@146
   486
	if (mod==NewBranch)
insilmaril@760
   487
		setColor (treeItem->getHeadingColor() );
insilmaril@798
   488
	else
insilmaril@798
   489
		// Also set styles for children
insilmaril@798
   490
		for (int i=0; i<treeItem->branchCount(); ++i)
insilmaril@798
   491
			treeItem->getBranchObjNum(i)->setDefAttr(MovedBranch);
insilmaril@146
   492
	calcBBoxSize();
insilmaril@146
   493
}
insilmaril@146
   494
insilmaril@721
   495
void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
insilmaril@0
   496
{
insilmaril@408
   497
	qreal th = bboxTotal.height();	
insilmaril@817
   498
	int depth=0;
insilmaril@817
   499
	if (parObj)	depth=1 + parObj->getTreeItem()->depth();
insilmaril@223
   500
// TODO testing
insilmaril@223
   501
/*
insilmaril@817
   502
	QString h=QString (depth+1,' ');
insilmaril@753
   503
	h+=treeItem->getHeading();
insilmaril@753
   504
	h+=QString (15,' ');
insilmaril@753
   505
	h.truncate (15);
insilmaril@817
   506
	QPointF pp; 
insilmaril@817
   507
	if (parObj) pp=parObj->getChildPos();
insilmaril@753
   508
	cout << "BO::alignRelTo ";
insilmaril@753
   509
	cout<<h.toStdString();
insilmaril@817
   510
	cout << "    d="<<depth;
insilmaril@817
   511
	cout <<"  parO="<<parObj;
insilmaril@755
   512
//cout<<  "  ref="<<ref<<
insilmaril@817
   513
//cout <<	"  bbox.tL="<<bboxTotal.topLeft();
insilmaril@817
   514
cout<<	"  absPos="<<absPos<<
insilmaril@795
   515
		"  relPos="<<relPos<<
insilmaril@721
   516
//		"  parPos="<<pp<<
insilmaril@795
   517
//		"  w="<<bbox.width()<<
insilmaril@795
   518
//		"  h="<<bbox.height()<<
insilmaril@753
   519
//		"  orient="<<orientation<<
insilmaril@753
   520
//		"  alignSelf="<<alignSelf<<
insilmaril@753
   521
//		"  scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
insilmaril@254
   522
//		"  pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
insilmaril@382
   523
//		"  hidden="<<hidden<<
insilmaril@817
   524
//		"  th="<<th<<
insilmaril@382
   525
		endl;
insilmaril@394
   526
*/
insilmaril@0
   527
insilmaril@382
   528
	setOrientation();
insilmaril@779
   529
	//updateLinkGeometry();
insilmaril@382
   530
insilmaril@796
   531
	if (depth==1)
insilmaril@796
   532
	{
insilmaril@796
   533
		move2RelPos (getRelPos() );
insilmaril@796
   534
	}
insilmaril@753
   535
	if (depth>1)
insilmaril@0
   536
    {
insilmaril@0
   537
		// Align myself depending on orientation and parent, but
insilmaril@382
   538
		// only if I am not a mainbranch or mapcenter itself
insilmaril@688
   539
insilmaril@688
   540
		if (anim.isAnimated())
insilmaril@0
   541
		{
insilmaril@688
   542
			move2RelPos(anim);
insilmaril@688
   543
		} else
insilmaril@688
   544
		{
insilmaril@688
   545
			LinkableMapObj::Orientation o;
insilmaril@688
   546
			o=parObj->getOrientation();
insilmaril@721
   547
			if (alignSelf)
insilmaril@721
   548
				switch (orientation) 
insilmaril@721
   549
				{
insilmaril@721
   550
					case LinkableMapObj::LeftOfCenter:
insilmaril@721
   551
						move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
insilmaril@721
   552
						//move (ref.x() , ref.y() + (th-bbox.height())/2 );
insilmaril@721
   553
					break;
insilmaril@721
   554
					case LinkableMapObj::RightOfCenter:	
insilmaril@721
   555
						move (ref.x() , ref.y() + (th-bbox.height())/2  );
insilmaril@721
   556
					break;
insilmaril@721
   557
					default:
insilmaril@721
   558
						qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
insilmaril@721
   559
					break;
insilmaril@753
   560
			}
insilmaril@688
   561
		}
insilmaril@0
   562
    }		
insilmaril@0
   563
insilmaril@749
   564
	if ( ((BranchItem*)treeItem)->isScrolled() ) return;
insilmaril@0
   565
insilmaril@721
   566
    // Set reference point for alignment of children
insilmaril@408
   567
    QPointF ref2;
insilmaril@462
   568
    if (orientation==LinkableMapObj::LeftOfCenter)
insilmaril@223
   569
		ref2.setX(bbox.topLeft().x() - linkwidth);
insilmaril@0
   570
    else	
insilmaril@223
   571
		ref2.setX(bbox.topRight().x() + linkwidth);
insilmaril@0
   572
insilmaril@0
   573
	if (depth==1)
insilmaril@0
   574
		ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
insilmaril@0
   575
	else	
insilmaril@0
   576
		ref2.setY(ref.y() );	
insilmaril@0
   577
insilmaril@721
   578
    // Align the children depending on reference point 
insilmaril@750
   579
	for (int i=0; i<treeItem->branchCount(); ++i)
insilmaril@0
   580
    {	
insilmaril@753
   581
		if (!treeItem->getBranchNum(i)->isHidden())
insilmaril@254
   582
		{
insilmaril@753
   583
			treeItem->getBranchObjNum(i)->alignRelativeTo (ref2,true);
insilmaril@721
   584
insilmaril@721
   585
			// append next branch below current one
insilmaril@753
   586
			ref2.setY(ref2.y() + treeItem->getBranchObjNum(i)->getBBoxSizeWithChildren().height() );
insilmaril@254
   587
		}
insilmaril@0
   588
    }
insilmaril@0
   589
}
insilmaril@0
   590
insilmaril@0
   591
insilmaril@0
   592
void BranchObj::reposition()
insilmaril@0
   593
{	
insilmaril@164
   594
/* TODO testing only
insilmaril@753
   595
	if (!treeItem->getHeading().isEmpty())
insilmaril@753
   596
		cout << "BO::reposition  "<<qPrintable(treeItem->getHeading())<<endl;
insilmaril@0
   597
	else	
insilmaril@0
   598
		cout << "BO::reposition  ???"<<endl;
insilmaril@753
   599
//	cout << "  orient="<<orientation<<endl;
insilmaril@0
   600
*/		
insilmaril@382
   601
insilmaril@755
   602
	if (treeItem->depth()==0)
insilmaril@0
   603
	{
insilmaril@0
   604
		// only calculate the sizes once. If the deepest LMO 
insilmaril@0
   605
		// changes its height,
insilmaril@0
   606
		// all upper LMOs have to change, too.
insilmaril@721
   607
		calcBBoxSizeWithChildren();
insilmaril@779
   608
		updateLinkGeometry();	// This update is needed if the scene is resized 
insilmaril@333
   609
						// due to excessive moving of a FIO
insilmaril@333
   610
insilmaril@408
   611
	    alignRelativeTo ( QPointF (absPos.x(),
insilmaril@0
   612
			absPos.y()-(bboxTotal.height()-bbox.height())/2) );
insilmaril@333
   613
		positionBBox();	// Reposition bbox and contents
insilmaril@0
   614
	} else
insilmaril@0
   615
	{
insilmaril@0
   616
		// This is only important for moving branches:
insilmaril@0
   617
		// For editing a branch it isn't called...
insilmaril@408
   618
	    alignRelativeTo ( QPointF (absPos.x(),
insilmaril@0
   619
							absPos.y()-(bboxTotal.height()-bbox.height())/2) );
insilmaril@0
   620
	}
insilmaril@0
   621
}
insilmaril@0
   622
insilmaril@382
   623
void BranchObj::unsetAllRepositionRequests()
insilmaril@382
   624
{
insilmaril@382
   625
	repositionRequest=false;
insilmaril@750
   626
	for (int i=0; i<treeItem->branchCount(); ++i)
insilmaril@753
   627
		treeItem->getBranchObjNum(i)->unsetAllRepositionRequests();
insilmaril@382
   628
}
insilmaril@382
   629
insilmaril@0
   630
insilmaril@408
   631
QRectF BranchObj::getTotalBBox()
insilmaril@0
   632
{
insilmaril@408
   633
	QRectF r=bbox;
insilmaril@0
   634
insilmaril@749
   635
	if ( ((BranchItem*)treeItem)->isScrolled() ) return r;
insilmaril@0
   636
insilmaril@750
   637
	for (int i=0; i<treeItem->branchCount(); ++i)
insilmaril@753
   638
		if (!treeItem->getBranchNum(i)->isHidden())
insilmaril@753
   639
			r=addBBox(treeItem->getBranchObjNum(i)->getTotalBBox(),r);
insilmaril@0
   640
insilmaril@755
   641
/* FIXME-3 lots of occurences of treeItem->getBranchObjNum(i) in branchobj.cpp
insilmaril@755
   642
            better check if they are not NULL and maybe simplify...
insilmaril@755
   643
			(have been NULL at least in calcBBoxSizeWithChilds...)
insilmaril@755
   644
*/			
insilmaril@755
   645
insilmaril@785
   646
	for (int i=0; i<treeItem->imageCount(); ++i)
insilmaril@785
   647
		if (!treeItem->isHidden())
insilmaril@785
   648
			r=addBBox(treeItem->getImageObjNum(i)->getTotalBBox(),r);
insilmaril@0
   649
	return r;
insilmaril@0
   650
}
insilmaril@0
   651
insilmaril@721
   652
QRectF BranchObj::getBBoxSizeWithChildren()
insilmaril@0
   653
{
insilmaril@0
   654
	return bboxTotal;
insilmaril@0
   655
}
insilmaril@0
   656
insilmaril@798
   657
ConvexPolygon BranchObj::getBoundingPolygon()	
insilmaril@793
   658
{
insilmaril@794
   659
/*
insilmaril@794
   660
	if (!pi)	//FIXME-3 Testing only
insilmaril@794
   661
	{
insilmaril@794
   662
		pi=scene->addPolygon(MapObj::getBoundingPolygon() );
insilmaril@794
   663
		pi->setPen(Qt::NoPen);
insilmaril@794
   664
		pi->setBrush( QColor(qrand()%32*8,qrand()%32*8,qrand()%32*8) );
insilmaril@794
   665
		pi->setZValue(Z_BBOX);
insilmaril@794
   666
	}
insilmaril@794
   667
	*/
insilmaril@798
   668
insilmaril@794
   669
	if (treeItem->branchCount()==0 || treeItem->depth()==0)
insilmaril@794
   670
	{
insilmaril@794
   671
		if (pi) pi->setPolygon (MapObj::getBoundingPolygon() );
insilmaril@793
   672
		return MapObj::getBoundingPolygon();
insilmaril@794
   673
	}
insilmaril@793
   674
insilmaril@794
   675
	calcBBoxSizeWithChildren();	//FIXME-3 really needed?
insilmaril@793
   676
	QPolygonF p;
insilmaril@793
   677
	p<<bboxTotal.topLeft();
insilmaril@793
   678
	p<<bboxTotal.topRight();
insilmaril@793
   679
	p<<bboxTotal.bottomRight();
insilmaril@793
   680
	p<<bboxTotal.bottomLeft();
insilmaril@798
   681
	//cout << "BO::getBP (total)  "<<treeItem->getHeadingStd()<<"  tL="<<bboxTotal.topLeft()<<"  bR="<<bboxTotal.bottomRight()<<endl;
insilmaril@798
   682
	//cout << "                   "<<"  tL="<<bbox.topLeft()<<"  bR="<<bbox.bottomRight()<<endl;
insilmaril@798
   683
	if (pi) pi->setPolygon (p );
insilmaril@793
   684
	return p;
insilmaril@793
   685
}
insilmaril@793
   686
insilmaril@721
   687
void BranchObj::calcBBoxSizeWithChildren()
insilmaril@169
   688
{	
insilmaril@169
   689
	// This is initially called only from reposition and
insilmaril@0
   690
	// and only for mapcenter. So it won't be
insilmaril@0
   691
	// called more than once for a single user 
insilmaril@0
   692
	// action
insilmaril@0
   693
	
insilmaril@169
   694
insilmaril@721
   695
	// Calculate size of LMO including all children (to align them later)
insilmaril@0
   696
	bboxTotal.setX(bbox.x() );
insilmaril@0
   697
	bboxTotal.setY(bbox.y() );
insilmaril@0
   698
insilmaril@721
   699
	// if branch is scrolled, ignore children, but still consider floatimages
insilmaril@753
   700
	BranchItem *bi=(BranchItem*)treeItem;
insilmaril@753
   701
	if ( bi->isScrolled() ) 
insilmaril@0
   702
	{
insilmaril@0
   703
		bboxTotal.setWidth (bbox.width());
insilmaril@0
   704
		bboxTotal.setHeight(bbox.height());
insilmaril@0
   705
		return;
insilmaril@0
   706
	}
insilmaril@0
   707
	
insilmaril@753
   708
	if (bi->isHidden())
insilmaril@254
   709
	{
insilmaril@254
   710
		bboxTotal.setWidth (0);
insilmaril@254
   711
		bboxTotal.setHeight(0);
insilmaril@254
   712
		if (parObj)
insilmaril@254
   713
		{
insilmaril@254
   714
			bboxTotal.setX (parObj->x());
insilmaril@254
   715
			bboxTotal.setY (parObj->y());
insilmaril@254
   716
		} else
insilmaril@254
   717
		{
insilmaril@254
   718
			bboxTotal.setX (bbox.x());
insilmaril@254
   719
			bboxTotal.setY (bbox.y());
insilmaril@254
   720
		}
insilmaril@254
   721
		return;
insilmaril@254
   722
	}
insilmaril@254
   723
	
insilmaril@408
   724
	QRectF r(0,0,0,0);
insilmaril@408
   725
	QRectF br;
insilmaril@0
   726
	// Now calculate recursivly
insilmaril@0
   727
	// sum of heights 
insilmaril@0
   728
	// maximum of widths 
insilmaril@0
   729
	// minimum of y
insilmaril@755
   730
	for (int i=0; i<treeItem->branchCount(); i++)
insilmaril@0
   731
	{
insilmaril@753
   732
		if (!bi->getBranchNum(i)->isHidden())
insilmaril@254
   733
		{
insilmaril@753
   734
			bi->getBranchObjNum(i)->calcBBoxSizeWithChildren();
insilmaril@753
   735
			br=bi->getBranchObjNum(i)->getBBoxSizeWithChildren();
insilmaril@254
   736
			r.setWidth( max (br.width(), r.width() ));
insilmaril@254
   737
			r.setHeight(br.height() + r.height() );
insilmaril@254
   738
			if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
insilmaril@798
   739
			if (br.x()<bboxTotal.x()) bboxTotal.setX(br.x());
insilmaril@254
   740
		}
insilmaril@0
   741
	}
insilmaril@0
   742
	// Add myself and also
insilmaril@0
   743
	// add width of link to sum if necessary
insilmaril@753
   744
	if (bi->branchCount()<1)
insilmaril@0
   745
		bboxTotal.setWidth (bbox.width() + r.width() );
insilmaril@0
   746
	else	
insilmaril@0
   747
		bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
insilmaril@169
   748
	
insilmaril@169
   749
	bboxTotal.setHeight(max (r.height(),  bbox.height()));
insilmaril@0
   750
}
insilmaril@0
   751
insilmaril@0
   752
QString BranchObj::getSelectString()
insilmaril@0
   753
{
insilmaril@773
   754
	VymModel *model=treeItem->getModel();
insilmaril@773
   755
	if (model)
insilmaril@773
   756
		return model->getSelectString (this);
insilmaril@773
   757
	else
insilmaril@773
   758
		return QString();
insilmaril@0
   759
}
insilmaril@0
   760
insilmaril@688
   761
void BranchObj::setAnimation(const AnimPoint &ap)
insilmaril@462
   762
{
insilmaril@688
   763
	anim=ap;
insilmaril@462
   764
}
insilmaril@462
   765
insilmaril@688
   766
bool BranchObj::animate()
insilmaril@688
   767
{
insilmaril@688
   768
	anim.animate ();
insilmaril@721
   769
	if ( anim.isAnimated() )
insilmaril@721
   770
	{
insilmaril@721
   771
		setRelPos (anim);
insilmaril@721
   772
		return true;
insilmaril@721
   773
	}
insilmaril@723
   774
	parObj->reposition();	// we might have been relinked meanwhile
insilmaril@721
   775
	return false;
insilmaril@688
   776
}
insilmaril@688
   777