branchitem.cpp
author insilmaril
Tue, 18 Aug 2009 12:39:07 +0000
changeset 788 78ba80b54bc4
parent 787 c6bb4fdcc55f
child 790 133e2ed6b9c5
permissions -rw-r--r--
Fix for segfault when deleting MCO (invalid QModelIndex needs to be returned in index(TreeItem*) )
insilmaril@747
     1
#include "branchitem.h"
insilmaril@747
     2
#include "branchobj.h"
insilmaril@753
     3
#include "vymmodel.h"
insilmaril@747
     4
insilmaril@747
     5
#include <iostream>
insilmaril@753
     6
#include <QDir>
insilmaril@753
     7
insilmaril@747
     8
using namespace std;
insilmaril@747
     9
insilmaril@779
    10
BranchItem::BranchItem(const QList<QVariant> &data, TreeItem *parent):MapItem (data,parent)
insilmaril@747
    11
{
insilmaril@749
    12
	//cout << "Constr. BranchItem\n";
insilmaril@749
    13
insilmaril@788
    14
	if (parent==rootItem)
insilmaril@788
    15
		setType (MapCenter);
insilmaril@788
    16
	else
insilmaril@788
    17
		setType (Branch);
insilmaril@788
    18
insilmaril@749
    19
	scrolled=false;
insilmaril@749
    20
	tmpUnscrolled=false;
insilmaril@785
    21
insilmaril@785
    22
	includeImagesVer=false;
insilmaril@785
    23
	includeImagesHor=false;
insilmaril@787
    24
	 
insilmaril@787
    25
	lastSelectedBranchNum=-1;
insilmaril@787
    26
	lastSelectedBranchNumAlt=-1;
insilmaril@747
    27
}
insilmaril@747
    28
insilmaril@747
    29
BranchItem::~BranchItem()
insilmaril@747
    30
{
insilmaril@788
    31
	//cout << "Destr. BranchItem "<<getHeadingStd()<<endl;
insilmaril@756
    32
	if (lmo) 
insilmaril@756
    33
	{
insilmaril@756
    34
		delete lmo;
insilmaril@756
    35
		lmo=NULL;
insilmaril@756
    36
	}
insilmaril@747
    37
}
insilmaril@747
    38
insilmaril@749
    39
void BranchItem::copy (BranchItem *other)
insilmaril@749
    40
{
insilmaril@749
    41
	scrolled=other->scrolled;
insilmaril@749
    42
	tmpUnscrolled=other->tmpUnscrolled;
insilmaril@749
    43
}
insilmaril@749
    44
insilmaril@756
    45
void BranchItem::insertBranch (int pos, BranchItem *branch)
insilmaril@756
    46
{
insilmaril@756
    47
	if (pos<0) pos=0;
insilmaril@756
    48
	if (pos>branchCounter) pos=branchCounter;
insilmaril@756
    49
    childItems.insert(pos+branchOffset,branch);
insilmaril@756
    50
	branch->parentItem=this;
insilmaril@756
    51
	branch->setModel (model);
insilmaril@756
    52
insilmaril@756
    53
	if (branchCounter==0)
insilmaril@756
    54
		branchOffset=childItems.count()-1;
insilmaril@756
    55
	branchCounter++;
insilmaril@756
    56
}
insilmaril@756
    57
insilmaril@771
    58
QString BranchItem::saveToDir (const QString &tmpdir,const QString &prefix, const QPointF& offset) //FIXME-3 Check if everything is saved...
insilmaril@747
    59
{
insilmaril@747
    60
	// Cloudy stuff can be hidden during exports
insilmaril@748
    61
	if (hidden) return QString();
insilmaril@747
    62
insilmaril@747
    63
    QString s,a;
insilmaril@747
    64
	BranchObj *bo=(BranchObj*)lmo;
insilmaril@747
    65
insilmaril@747
    66
	// Update of note is usually done while unselecting a branch
insilmaril@747
    67
	
insilmaril@747
    68
	QString scrolledAttr;
insilmaril@747
    69
	if (scrolled) 
insilmaril@747
    70
		scrolledAttr=attribut ("scrolled","yes");
insilmaril@747
    71
	else
insilmaril@747
    72
		scrolledAttr="";
insilmaril@747
    73
insilmaril@775
    74
	// save area, if not scrolled	// FIXME-5 not needed if HTML is rewritten...
insilmaril@768
    75
									// also we should check if _any_ of parents is scrolled
insilmaril@747
    76
	QString areaAttr;
insilmaril@775
    77
	if (lmo && parentItem->isBranchLikeType() && !((BranchItem*)parentItem)->isScrolled() )
insilmaril@747
    78
	{
insilmaril@775
    79
		qreal x=lmo->getAbsPos().x();
insilmaril@775
    80
		qreal y=lmo->getAbsPos().y();
insilmaril@747
    81
		areaAttr=
insilmaril@775
    82
			attribut("x1",QString().setNum(x-offset.x())) +
insilmaril@775
    83
			attribut("y1",QString().setNum(y-offset.y())) +
insilmaril@775
    84
			attribut("x2",QString().setNum(x+lmo->width()-offset.x())) +
insilmaril@775
    85
			attribut("y2",QString().setNum(y+lmo->height()-offset.y()));
insilmaril@747
    86
insilmaril@747
    87
	} else
insilmaril@747
    88
		areaAttr="";
insilmaril@747
    89
	
insilmaril@775
    90
	/*	
insilmaril@775
    91
	// FIXME-3 Providing an ID for a branch makes export to XHTML easier
insilmaril@747
    92
	QString idAttr;
insilmaril@747
    93
	if (countXLinks()>0)
insilmaril@747
    94
		idAttr=attribut ("id",model->getSelectString(this)); //TODO directly access model
insilmaril@747
    95
	else
insilmaril@747
    96
		idAttr="";
insilmaril@747
    97
insilmaril@747
    98
	*/
insilmaril@773
    99
	QString elementName;
insilmaril@773
   100
	if (parentItem==rootItem)
insilmaril@773
   101
		elementName="mapcenter";
insilmaril@773
   102
	else	
insilmaril@773
   103
		elementName="branch";
insilmaril@773
   104
insilmaril@773
   105
    s=beginElement (elementName
insilmaril@779
   106
		+getMapAttr()
insilmaril@779
   107
		+getGeneralAttr()
insilmaril@768
   108
		+scrolledAttr 
insilmaril@747
   109
	//	+areaAttr 
insilmaril@747
   110
	//	+idAttr 
insilmaril@785
   111
		+getIncludeImageAttr() 
insilmaril@747
   112
		);
insilmaril@747
   113
    incIndent();
insilmaril@747
   114
insilmaril@747
   115
	// save heading
insilmaril@747
   116
    s+=valueElement("heading", getHeading(),
insilmaril@747
   117
		attribut ("textColor",QColor( bo->getColor()).name()));
insilmaril@747
   118
insilmaril@777
   119
	// Save frame  //FIXME-4 not saved if there is no LMO
insilmaril@777
   120
	if (lmo && ((OrnamentedObj*)lmo)->getFrame()->getFrameType()!=FrameObj::NoFrame) 
insilmaril@777
   121
		s+=((OrnamentedObj*)lmo)->getFrame()->saveToDir ();
insilmaril@747
   122
insilmaril@747
   123
	// save names of flags set
insilmaril@768
   124
	s+=standardFlags.saveToDir(tmpdir,prefix,0);
insilmaril@747
   125
	
insilmaril@776
   126
	// Save Images
insilmaril@776
   127
	for (int i=0; i<imageCount(); ++i)
insilmaril@776
   128
		s+=getImageNum(i)->saveToDir (tmpdir,prefix);
insilmaril@747
   129
insilmaril@747
   130
	// save note
insilmaril@747
   131
	if (!note.isEmpty() )
insilmaril@747
   132
		s+=note.saveToDir();
insilmaril@747
   133
	
insilmaril@747
   134
	// Save branches
insilmaril@760
   135
	int i=0;
insilmaril@760
   136
	TreeItem *ti=getBranchNum(i);
insilmaril@760
   137
	while (ti)
insilmaril@760
   138
	{
insilmaril@760
   139
		s+=getBranchNum(i)->saveToDir(tmpdir,prefix,offset);
insilmaril@760
   140
		i++;
insilmaril@760
   141
		ti=getBranchNum(i);
insilmaril@760
   142
	}	
insilmaril@747
   143
insilmaril@747
   144
	/*
insilmaril@747
   145
	// Save XLinks
insilmaril@747
   146
	QString ol;	// old link
insilmaril@747
   147
	QString cl;	// current link
insilmaril@747
   148
	for (int i=0; i<xlink.size(); ++i)
insilmaril@747
   149
	{
insilmaril@747
   150
		cl=xlink.at(i)->saveToDir();
insilmaril@747
   151
		if (cl!=ol)
insilmaril@747
   152
		{
insilmaril@747
   153
			s+=cl;
insilmaril@747
   154
			ol=cl;
insilmaril@747
   155
		} else
insilmaril@747
   156
		{
insilmaril@747
   157
			qWarning (QString("Ignoring of duplicate xLink in %1").arg(getHeading()));
insilmaril@747
   158
		}
insilmaril@747
   159
	}	
insilmaril@747
   160
	*/
insilmaril@747
   161
insilmaril@747
   162
    decIndent();
insilmaril@773
   163
    s+=endElement   (elementName);
insilmaril@747
   164
    return s;
insilmaril@747
   165
}
insilmaril@747
   166
insilmaril@781
   167
void BranchItem::updateVisibility()	
insilmaril@753
   168
{
insilmaril@781
   169
	// Needed to hide relinked branch, if parent is scrolled
insilmaril@781
   170
	if (lmo)
insilmaril@781
   171
		lmo->setVisibility(!((BranchItem*)parentItem)->isScrolled());
insilmaril@753
   172
}
insilmaril@753
   173
insilmaril@758
   174
void BranchItem::setHeadingColor (QColor color)
insilmaril@758
   175
{
insilmaril@758
   176
	TreeItem::setHeadingColor (color);
insilmaril@758
   177
	if (lmo) ((BranchObj*)lmo)->setColor (color);
insilmaril@758
   178
}
insilmaril@758
   179
insilmaril@749
   180
void BranchItem::unScroll()
insilmaril@749
   181
{
insilmaril@749
   182
	if (tmpUnscrolled) resetTmpUnscroll();
insilmaril@749
   183
	if (scrolled) toggleScroll();
insilmaril@749
   184
}
insilmaril@747
   185
insilmaril@767
   186
bool BranchItem::toggleScroll()	
insilmaril@749
   187
{
insilmaril@763
   188
	BranchObj *bo=NULL;
insilmaril@749
   189
	if (scrolled)
insilmaril@749
   190
	{
insilmaril@749
   191
		scrolled=false;
insilmaril@767
   192
		systemFlags.deactivate("system-scrolledright");
insilmaril@767
   193
		if (branchCounter>0)
insilmaril@763
   194
		{
insilmaril@767
   195
			for (int i=0;i<branchCounter;++i)
insilmaril@767
   196
			{
insilmaril@767
   197
				bo=(BranchObj*)(getBranchNum(i)->getLMO());
insilmaril@767
   198
				if (bo) bo->setVisibility(true);
insilmaril@767
   199
			}
insilmaril@763
   200
		}
insilmaril@749
   201
	} else
insilmaril@749
   202
	{
insilmaril@749
   203
		scrolled=true;
insilmaril@767
   204
		systemFlags.activate("system-scrolledright");
insilmaril@767
   205
		if (branchCounter>0)
insilmaril@763
   206
		{
insilmaril@767
   207
			for (int i=0;i<branchCounter;++i)
insilmaril@767
   208
			{
insilmaril@767
   209
				bo=(BranchObj*)(getBranchNum(i)->getLMO());
insilmaril@767
   210
				if (bo) bo->setVisibility(false);
insilmaril@767
   211
			}
insilmaril@763
   212
		}
insilmaril@749
   213
	}
insilmaril@772
   214
	model->reposition();	// FIXME-3 we don't really want to update view from here...
insilmaril@767
   215
	return true;
insilmaril@749
   216
}
insilmaril@749
   217
insilmaril@749
   218
bool BranchItem::isScrolled()
insilmaril@749
   219
{
insilmaril@749
   220
	return scrolled;
insilmaril@749
   221
}
insilmaril@749
   222
insilmaril@749
   223
bool BranchItem::hasScrolledParent(BranchItem *start)
insilmaril@749
   224
{
insilmaril@749
   225
	// Calls parents recursivly to
insilmaril@749
   226
	// find out, if we are scrolled at all.
insilmaril@749
   227
	// But ignore myself, just look at parents.
insilmaril@749
   228
insilmaril@779
   229
	//cout << "BI::hasScrolledParent this="<<this<<"  "<<getHeadingStd()<<endl;
insilmaril@749
   230
	if (this !=start && scrolled) return true;
insilmaril@749
   231
insilmaril@749
   232
	BranchItem* bi=(BranchItem*)parentItem;
insilmaril@779
   233
	if (bi && bi!=rootItem && bi->isBranchLikeType() ) 
insilmaril@749
   234
		return bi->hasScrolledParent(start);
insilmaril@749
   235
	else
insilmaril@749
   236
		return false;
insilmaril@749
   237
}
insilmaril@749
   238
insilmaril@749
   239
void BranchItem::tmpUnscroll()
insilmaril@749
   240
{
insilmaril@749
   241
	// Unscroll parent (recursivly)
insilmaril@775
   242
	BranchItem * pi=(BranchItem*)parentItem;
insilmaril@775
   243
	if (pi && pi->isBranchLikeType() ) pi->tmpUnscroll();
insilmaril@749
   244
		
insilmaril@749
   245
	// Unscroll myself
insilmaril@749
   246
	if (scrolled)
insilmaril@749
   247
	{
insilmaril@749
   248
		tmpUnscrolled=true;
insilmaril@775
   249
		systemFlags.activate("system-tmpUnscrolledRight");
insilmaril@749
   250
		toggleScroll();
insilmaril@775
   251
		model->emitDataHasChanged (this);
insilmaril@749
   252
	}	
insilmaril@749
   253
}
insilmaril@749
   254
insilmaril@749
   255
void BranchItem::resetTmpUnscroll()
insilmaril@749
   256
{
insilmaril@749
   257
	// Unscroll parent (recursivly)
insilmaril@775
   258
	BranchItem * pi=(BranchItem*)parentItem;
insilmaril@775
   259
	if (pi && pi->isBranchLikeType() ) pi->resetTmpUnscroll();
insilmaril@749
   260
		
insilmaril@749
   261
	// Unscroll myself
insilmaril@749
   262
	if (tmpUnscrolled)
insilmaril@749
   263
	{
insilmaril@749
   264
		tmpUnscrolled=false;
insilmaril@775
   265
		systemFlags.deactivate("system-tmpUnscrolledRight");
insilmaril@749
   266
		toggleScroll();
insilmaril@775
   267
		model->emitDataHasChanged (this);
insilmaril@749
   268
	}	
insilmaril@749
   269
}
insilmaril@749
   270
insilmaril@785
   271
void BranchItem::setIncludeImagesVer(bool b)
insilmaril@785
   272
{
insilmaril@785
   273
	includeImagesVer=b;
insilmaril@785
   274
	/* calcBBoxSize(); FIXME-2
insilmaril@785
   275
	positionBBox();
insilmaril@785
   276
	requestReposition();
insilmaril@785
   277
	*/
insilmaril@785
   278
}
insilmaril@785
   279
insilmaril@785
   280
bool BranchItem::getIncludeImagesVer()
insilmaril@785
   281
{
insilmaril@785
   282
	return includeImagesVer;
insilmaril@785
   283
}
insilmaril@785
   284
insilmaril@785
   285
void BranchItem::setIncludeImagesHor(bool b)
insilmaril@785
   286
{
insilmaril@785
   287
	includeImagesHor=b;
insilmaril@785
   288
	/* calcBBoxSize(); FIXME-2
insilmaril@785
   289
	positionBBox();
insilmaril@785
   290
	requestReposition();
insilmaril@785
   291
	*/
insilmaril@785
   292
}
insilmaril@785
   293
insilmaril@785
   294
bool BranchItem::getIncludeImagesHor()
insilmaril@785
   295
{
insilmaril@785
   296
	return includeImagesHor;
insilmaril@785
   297
}
insilmaril@785
   298
insilmaril@785
   299
QString BranchItem::getIncludeImageAttr()
insilmaril@785
   300
{
insilmaril@785
   301
	QString a;
insilmaril@785
   302
	if (includeImagesVer)
insilmaril@785
   303
		a=attribut ("incImgV","true");
insilmaril@785
   304
	if (includeImagesHor)
insilmaril@785
   305
		a+=attribut ("incImgH","true");
insilmaril@785
   306
	return a;	
insilmaril@785
   307
}
insilmaril@785
   308
insilmaril@787
   309
void BranchItem::setLastSelectedBranch()
insilmaril@787
   310
{
insilmaril@787
   311
	int d=depth();
insilmaril@787
   312
	if (d>=0)
insilmaril@787
   313
	{
insilmaril@787
   314
		if (d==1)
insilmaril@787
   315
			// Hack to save an additional lastSelected for mapcenters in MapEditor
insilmaril@787
   316
			// depending on orientation
insilmaril@787
   317
			// this allows to go both left and right from there
insilmaril@787
   318
			if (lmo && lmo->getOrientation()==LinkableMapObj::LeftOfCenter)
insilmaril@787
   319
			{
insilmaril@787
   320
				((BranchItem*)parentItem)->lastSelectedBranchNumAlt=parentItem->num(this);
insilmaril@787
   321
				return;
insilmaril@787
   322
			}
insilmaril@787
   323
		((BranchItem*)parentItem)->lastSelectedBranchNum=parentItem->num(this);
insilmaril@787
   324
	}
insilmaril@787
   325
}
insilmaril@787
   326
insilmaril@787
   327
void BranchItem::setLastSelectedBranch(int i)
insilmaril@787
   328
{
insilmaril@787
   329
		lastSelectedBranchNum=i;
insilmaril@787
   330
}
insilmaril@787
   331
insilmaril@787
   332
BranchItem* BranchItem::getLastSelectedBranch()
insilmaril@787
   333
{
insilmaril@787
   334
	return getBranchNum (lastSelectedBranchNum);
insilmaril@787
   335
}
insilmaril@787
   336
insilmaril@787
   337
BranchItem* BranchItem::getLastSelectedBranchAlt()
insilmaril@787
   338
{
insilmaril@787
   339
	return getBranchNum (lastSelectedBranchNumAlt);
insilmaril@787
   340
}
insilmaril@787
   341
insilmaril@787
   342
insilmaril@787
   343
insilmaril@785
   344
insilmaril@785
   345
insilmaril@758
   346
TreeItem* BranchItem::findMapItem (QPointF p, TreeItem* excludeTI)
insilmaril@754
   347
{
insilmaril@754
   348
	// Search branches
insilmaril@754
   349
	TreeItem *ti;
insilmaril@754
   350
	for (int i=0; i<branchCount(); ++i)
insilmaril@754
   351
    {	
insilmaril@758
   352
		ti=getBranchNum(i)->findMapItem(p, excludeTI);
insilmaril@754
   353
		if (ti != NULL) return ti;
insilmaril@754
   354
    }
insilmaril@754
   355
	
insilmaril@754
   356
insilmaril@754
   357
	// Search myself
insilmaril@758
   358
    if (getBranchObj()->isInClickBox (p) && (this != excludeTI) && getBranchObj()->isVisibleObj() ) 
insilmaril@754
   359
		return this;
insilmaril@754
   360
insilmaril@776
   361
	// Search images
insilmaril@776
   362
	ImageItem *ii;
insilmaril@776
   363
    for (int i=0; i<imageCount(); ++i )
insilmaril@776
   364
	{
insilmaril@776
   365
		ii=getImageNum (i);
insilmaril@776
   366
		LinkableMapObj *mo=ii->getLMO();
insilmaril@776
   367
		if (mo && mo->isInClickBox(p) && 
insilmaril@776
   368
			(ii != excludeTI) && 
insilmaril@776
   369
			this!= excludeTI &&
insilmaril@776
   370
			mo->isVisibleObj() 
insilmaril@776
   371
		) return ii;
insilmaril@776
   372
	}
insilmaril@776
   373
	return NULL;
insilmaril@754
   374
}
insilmaril@754
   375
insilmaril@754
   376
TreeItem* BranchItem::findID (QString sid)
insilmaril@754
   377
{
insilmaril@754
   378
	// Search branches
insilmaril@754
   379
    TreeItem *ti;
insilmaril@754
   380
	for (int i=0; i<branchCount(); ++i)
insilmaril@754
   381
    {	
insilmaril@754
   382
		ti=getBranchNum(i)->findID (sid);
insilmaril@754
   383
		if (ti != NULL) return ti;
insilmaril@754
   384
    }
insilmaril@754
   385
	
insilmaril@754
   386
	// Search myself
insilmaril@754
   387
	if (sid==objID) return this;
insilmaril@754
   388
insilmaril@754
   389
insilmaril@754
   390
/*
insilmaril@785
   391
	// Search float images //FIXME-4
insilmaril@754
   392
    for (int i=0; i<floatimage.size(); ++i )
insilmaril@754
   393
		if (floatimage.at(i)->inBox(p) && 
insilmaril@754
   394
			(floatimage.at(i) != excludeLMO) && 
insilmaril@754
   395
			floatimage.at(i)->getParObj()!= excludeLMO &&
insilmaril@754
   396
			floatimage.at(i)->isVisibleObj() 
insilmaril@754
   397
		) return floatimage.at(i);
insilmaril@754
   398
*/
insilmaril@754
   399
    return NULL;
insilmaril@754
   400
}
insilmaril@754
   401
insilmaril@773
   402
void BranchItem::updateStyles()
insilmaril@773
   403
{
insilmaril@773
   404
	// FIXME-5 compare also MapItem::initLMO...
insilmaril@773
   405
insilmaril@779
   406
	if (lmo && parentItem != rootItem)
insilmaril@773
   407
	{
insilmaril@779
   408
		lmo->setParObj ( ((MapItem*)parentItem)->getLMO() );
insilmaril@773
   409
	}
insilmaril@773
   410
}
insilmaril@754
   411
insilmaril@750
   412
BranchObj* BranchItem::getBranchObj()	// FIXME-3 only for transition BO->BI
insilmaril@750
   413
{
insilmaril@750
   414
	return (BranchObj*)lmo;
insilmaril@750
   415
}
insilmaril@749
   416
insilmaril@786
   417
BranchObj* BranchItem::createMapObj(QGraphicsScene *scene)	// FIXME-4 maybe move this into MapEditor to get rid of scene in VymModel?
insilmaril@755
   418
{
insilmaril@773
   419
	BranchObj *newbo;
insilmaril@775
   420
	newbo=new BranchObj(scene);
insilmaril@775
   421
	newbo->setTreeItem (this);
insilmaril@775
   422
	lmo=newbo;
insilmaril@775
   423
insilmaril@773
   424
	if (parentItem==rootItem)
insilmaril@773
   425
	{
insilmaril@773
   426
		newbo->setParObj(NULL);
insilmaril@775
   427
		newbo->setFrameType (FrameObj::Rectangle);
insilmaril@773
   428
	} else
insilmaril@773
   429
	{
insilmaril@779
   430
		newbo->setParObj( ((MapItem*)parentItem)->getLMO() );
insilmaril@775
   431
		// Set visibility depending on parents
insilmaril@779
   432
		if (((BranchItem*)parentItem)->scrolled || !((MapItem*)parentItem)->getLMO()->isVisibleObj() )
insilmaril@775
   433
			newbo->setVisibility (false);
insilmaril@773
   434
	}
insilmaril@775
   435
	newbo->setDefAttr(BranchObj::NewBranch);
insilmaril@760
   436
	initLMO();
insilmaril@758
   437
insilmaril@758
   438
	if (!getHeading().isEmpty() ) 
insilmaril@758
   439
	{
insilmaril@775
   440
		newbo->updateData();	//FIXME-3 maybe better model->emitDataHasChanged()?
insilmaril@775
   441
		newbo->setColor (headingColor);
insilmaril@758
   442
	}	
insilmaril@758
   443
		
insilmaril@779
   444
	//newbo->updateLinkGeometry();	//FIXME-3
insilmaril@755
   445
insilmaril@755
   446
	return newbo;
insilmaril@755
   447
}
insilmaril@755
   448