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