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