treeitem.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 <iostream>
     2 #include <QStringList>
     3 
     4 #include "treeitem.h"
     5 
     6 #include "branchobj.h"
     7 #include "branchitem.h"
     8 #include "vymmodel.h"
     9 
    10 using namespace std;
    11 
    12 extern FlagRow* standardFlagsMaster;
    13 
    14 TreeItem::TreeItem()
    15 {
    16 	//cout << "Constr. TI  this="<<this<<endl;
    17 	init();
    18 	itemData.clear();
    19 	rootItem=this;
    20 	parentItem=NULL;
    21 }
    22 
    23 TreeItem::TreeItem(const QList<QVariant> &data, TreeItem *parent)
    24 {
    25 	//cout << "Constructor TreeItem this="<<this<<"  parent="<<parent<<endl;
    26 	init();
    27     parentItem = parent;
    28     itemData = data;
    29 	
    30 	rootItem=this;
    31 	if (parentItem )
    32 		rootItem=parentItem->rootItem;
    33 }
    34 
    35 TreeItem::~TreeItem()
    36 {
    37 	//cout << "Destructor TreeItem "<<getHeadingStd()<<endl;
    38 	TreeItem *ti;
    39 	while (!childItems.isEmpty())
    40 	{
    41 		ti=childItems.takeFirst();
    42 		switch (ti->getType() )
    43 		{
    44 			case TreeItem::MapCenter:
    45 				delete (BranchItem*)ti;
    46 				break;
    47 			case TreeItem::Branch:
    48 				delete (BranchItem*)ti;
    49 				break;
    50 			case TreeItem::Image:
    51 				delete (ImageItem*)ti;
    52 				break;
    53 			case TreeItem::Attribute:
    54 				delete (AttributeItem*)ti;
    55 				break;
    56 			default:
    57 				delete ti;
    58 				break;
    59 		}
    60 	}	
    61 }
    62 
    63 
    64 void TreeItem::init()
    65 {
    66 	model=NULL;
    67 
    68 	branchOffset=0;
    69 	branchCounter=0;
    70 
    71 	imageOffset=0;
    72 	imageCounter=0;
    73 
    74 	attributeCounter=0;
    75 	attributeOffset=0;
    76 
    77 	note.setNote(""); 
    78 	// note.setFontHint (textEditor->getFontHintDefault() );	//FIXME-3
    79 	// isNoteInEditor=false;
    80 
    81 	hidden=false;
    82 	hideExport=false;
    83 
    84 	// Reset ID
    85 	objID="";
    86 
    87 	standardFlags.setMasterRow (standardFlagsMaster);
    88 }
    89 
    90 
    91 /*
    92 void TreeItem::copy (OrnamentedObj* other)	//FIXME-3	probably need deep copy of branches and data!
    93 
    94 {
    95 	note.copy (other->note);
    96 	model=other->model;
    97 	hideExport=officially 
    98 	other->hideExport;
    99 }
   100 */
   101 
   102 void TreeItem::setModel (VymModel *m)
   103 {
   104 	model=m;
   105 }
   106 
   107 VymModel* TreeItem::getModel ()
   108 {
   109 	return model;
   110 }
   111 
   112 int TreeItem::getRowNumAppend (TreeItem *item)
   113 {	
   114 	switch (item->type)
   115 	{
   116 		case Attribute: return attributeOffset + attributeCounter;
   117 		case Image: return imageOffset + imageCounter;
   118 		case MapCenter: return branchOffset + branchCounter;
   119 		case Branch: return branchOffset + branchCounter;
   120 		default: return -1;
   121 	}
   122 }
   123 
   124 void TreeItem::appendChild(TreeItem *item)
   125 {
   126 	item->parentItem=this;
   127 	item->rootItem=rootItem;
   128 	item->setModel (model);
   129 
   130 	if (item->type == Attribute)
   131 	{
   132 		// attribute are on top of list
   133 		childItems.insert (attributeCounter,item);
   134 		attributeCounter++;
   135 		imageOffset++;
   136 		branchOffset++;
   137 	}
   138 
   139 	if (item->type == Image)
   140 	{
   141 		childItems.insert (imageCounter+imageOffset,item);
   142 		imageCounter++;
   143 		branchOffset++;
   144 	}
   145 
   146 	if (item->isBranchLikeType())
   147 	{
   148 		// branches are on bottom of list
   149 		childItems.append(item);
   150 		branchCounter++;
   151 
   152 		// Set correct type		//FIXME-3 DUP in constr branchitem
   153 		if (this==rootItem)
   154 			item->setType(MapCenter);
   155 		else
   156 			item->setType (Branch);
   157 	}
   158 }
   159 
   160 void TreeItem::removeChild(int row)
   161 {
   162     if (row<0 || row > childItems.size()-1)
   163 		qWarning ("TreeItem::removeChild tried to remove non existing item?!\n");
   164 	else
   165 	{
   166 		if (childItems.at(row)->type==Attribute)
   167 		{
   168 			attributeCounter--;
   169 			imageOffset--;
   170 			branchOffset--;
   171 		}	
   172 		if (childItems.at(row)->type==Image)
   173 		{
   174 			imageCounter--;
   175 			branchOffset--;
   176 		}	
   177 		if (childItems.at(row)->isBranchLikeType())
   178 			branchCounter--;
   179 
   180 		childItems.removeAt (row);
   181 	}
   182 }
   183 
   184 /*
   185 void TreeItem::clear()	// FIXME-2 used in vymmodel addMapInsert, but needs to be used via model and emit layout changes...
   186 {
   187 	cout << "TI::clear\n";
   188 	while ( childItems.size()>0)
   189 	{
   190 		branchCounter--;
   191 		childItems.removeAt (0);
   192 	}
   193 }
   194 */
   195 
   196 TreeItem *TreeItem::child(int row)
   197 {
   198     return childItems.value(row);
   199 }
   200 
   201 int TreeItem::childCount() const
   202 {
   203     return childItems.count();
   204 }
   205 
   206 int TreeItem::childNumber() const
   207 {
   208     if (parentItem)
   209         return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
   210 
   211     return 0;
   212 }
   213 
   214 int TreeItem::columnCount() const
   215 {
   216     return itemData.count();
   217 }
   218 
   219 int TreeItem::branchCount() const
   220 {
   221     return branchCounter;
   222 }
   223 
   224 int TreeItem::imageCount() const
   225 {
   226     return imageCounter; 
   227 }
   228 
   229 int TreeItem::xlinkCount() const // FIXME-2 check if xlinks are stored in a different way (global to model?)
   230 {
   231 	int xlinkCounter=0;
   232     return xlinkCounter; // FIXME-1 xlinkCounter needs to be calculated...
   233 }
   234 
   235 int TreeItem::attributeCount() const 
   236 {
   237     return attributeCounter; 
   238 }
   239 
   240 int TreeItem::row() const
   241 {
   242     if (parentItem)
   243         return parentItem->childItems.indexOf(const_cast<TreeItem*>(this));
   244 
   245 	cout << "TI::row() pI=NULL this="<<this<<"  ***************\n";
   246     return 0;
   247 }
   248 
   249 int TreeItem::column() const
   250 {
   251     return 0;
   252 }
   253 
   254 int TreeItem::depth() 
   255 {
   256 	// Rootitem d=-1
   257 	// MapCenter d=0
   258 	int d=-2;
   259 	TreeItem *ti=this;
   260 	while (ti!=NULL)
   261 	{
   262 		ti=ti->parent();
   263 		d++;
   264 	}
   265 	return d;
   266 }
   267 
   268 TreeItem *TreeItem::parent()
   269 {
   270     return parentItem;
   271 }
   272 
   273 int TreeItem::childNum()
   274 {
   275 	return parentItem->childItems.indexOf (this);
   276 }
   277 
   278 int TreeItem::num()
   279 {
   280 	switch (type)
   281 	{
   282 		case MapCenter: return parentItem->childItems.indexOf (this) - parentItem->branchOffset;
   283 		case Branch: return parentItem->childItems.indexOf (this) - parentItem->branchOffset;
   284 		case Image: return parentItem->childItems.indexOf (this) - parentItem->imageOffset;
   285 		case Attribute: return parentItem->childItems.indexOf (this) - parentItem->attributeOffset;
   286 		default: return -1;
   287 	}
   288 }
   289 
   290 int TreeItem::num (TreeItem *item)
   291 {
   292 	if (!item) return -1;
   293 	if (!childItems.contains(item)) return -1;
   294 	switch (item->getType())
   295 	{
   296 		case MapCenter: return childItems.indexOf (item) - branchOffset;
   297 		case Branch: return childItems.indexOf (item) - branchOffset;
   298 		case Image: return parentItem->childItems.indexOf (item) - imageOffset;
   299 		case Attribute: return parentItem->childItems.indexOf (item) - attributeOffset;
   300 		default: return -1;
   301 	}
   302 }
   303 void TreeItem::setType(const Type t)
   304 {
   305 	type=t;
   306 	itemData[1]=getTypeName();
   307 }
   308 
   309 TreeItem::Type TreeItem::getType()
   310 {
   311 	if (type==Branch && depth()==0) return MapCenter;	//FIXME-2 should not be necesssary
   312 	return type;
   313 }
   314 
   315 bool TreeItem::isBranchLikeType() const
   316 {
   317 	if (type==Branch ||type==MapCenter) return true;
   318 	return false;
   319 }
   320 
   321 QString TreeItem::getTypeName()
   322 {
   323 	switch (type)
   324 	{
   325 		case Undefined: return QString ("Undefined");
   326 		case MapCenter: return QString ("MapCenter");
   327 		case Branch: return QString ("Branch");
   328 		case Image: return QString ("Image");
   329 		case Attribute: return QString ("Attribute");
   330 		default: return QString ("TreeItem::getTypeName no typename defined?!");
   331 	}
   332 }
   333 
   334 
   335 QVariant TreeItem::data(int column) const
   336 {
   337     return itemData.value(column);
   338 }
   339 
   340 void TreeItem::setHeading (const QString s)
   341 {
   342 	itemData[0]=s;
   343 }
   344 
   345 QString TreeItem::getHeading () const
   346 {
   347 	return itemData[0].toString();
   348 }
   349 
   350 std::string TreeItem::getHeadingStd () const
   351 {
   352 	return itemData[0].toString().toStdString();
   353 }
   354 
   355 void TreeItem::setHeadingColor (QColor color)
   356 {
   357 	headingColor=color;
   358 }
   359 
   360 QColor TreeItem::getHeadingColor ()
   361 {
   362 	return headingColor;
   363 }
   364 
   365 void TreeItem::setURL (const QString &u)
   366 {
   367 	url=u;
   368 	if (!url.isEmpty())
   369 		systemFlags.activate ("system-url");
   370 	else
   371 		systemFlags.deactivate ("system-url");
   372 }
   373 
   374 QString TreeItem::getURL ()
   375 {
   376 	return url;
   377 }
   378 
   379 void TreeItem::setVymLink (const QString &vl)
   380 {
   381 	if (!vl.isEmpty())
   382 	{
   383 		// We need the relative (from loading) 
   384 		// or absolute path (from User event)
   385 		// and build the absolute path.
   386 		// Note: If we have relative, use path of
   387 		// current map to build absolute path
   388 		QDir d(vl);
   389 		if (!d.path().startsWith ("/"))
   390 		{
   391 			QString p=model->getDestPath();
   392 			int i=p.findRev("/",-1);
   393 			d.setPath(p.left(i)+"/"+vl);
   394 			d.convertToAbs();
   395 		}
   396 		vymLink=d.path();
   397 		systemFlags.activate("system-vymLink");
   398 	}	
   399 	else	
   400 	{
   401 		systemFlags.deactivate("system-vymLink");
   402 		vymLink.clear();
   403 	}	
   404 }
   405 
   406 QString TreeItem::getVymLink ()
   407 {
   408 	return vymLink;
   409 }
   410 
   411 void TreeItem::setNote(const QString &s)
   412 {
   413 	NoteObj n;
   414 	n.setNote(s);
   415 	setNoteObj (n,false);
   416 }
   417 
   418 void TreeItem::clearNote()
   419 {
   420 	note.clear();
   421 	systemFlags.deactivate ("system-note");
   422 }
   423 
   424 void TreeItem::setNoteObj(const NoteObj &n, bool updateNoteEditor){
   425 	note=n;
   426 	if (!note.isEmpty() && !systemFlags.isActive ("system-note"))
   427 		systemFlags.activate ("system-note");
   428 	if (note.isEmpty() && systemFlags.isActive ("system-note"))
   429 		systemFlags.deactivate ("system-note");
   430 }
   431 
   432 QString TreeItem::getNote()
   433 {
   434 	return note.getNote();
   435 }
   436 
   437 bool TreeItem::hasEmptyNote()
   438 {
   439 	return note.isEmpty();
   440 }
   441 
   442 NoteObj TreeItem::getNoteObj()
   443 {
   444 	return note;
   445 }
   446 
   447 QString TreeItem::getNoteASCII(const QString &indent, const int &width)
   448 {
   449     return note.getNoteASCII(indent,width);
   450 }
   451 
   452 QString TreeItem::getNoteASCII()
   453 {
   454     return note.getNoteASCII();
   455 }
   456 
   457 QString TreeItem::getNoteOpenDoc()
   458 {
   459     return note.getNoteOpenDoc();
   460 }
   461 
   462 void TreeItem::activateStandardFlag (const QString &name)
   463 {
   464 	standardFlags.activate (name);
   465 	model->emitDataHasChanged(this);
   466 }
   467 
   468 void TreeItem::deactivateStandardFlag (const QString &name)
   469 {
   470 	standardFlags.deactivate (name);
   471 	model->emitDataHasChanged(this);
   472 }
   473 
   474 void TreeItem::deactivateAllStandardFlags ()
   475 {
   476 	standardFlags.deactivateAll ();
   477 	model->emitDataHasChanged(this);
   478 }
   479 
   480 void TreeItem::toggleStandardFlag(const QString &name, FlagRow *master)
   481 {
   482 	standardFlags.toggle (name,master);
   483 	model->emitDataHasChanged(this);
   484 }
   485 
   486 bool TreeItem::isActiveStandardFlag (const QString &name)
   487 {
   488 	return standardFlags.isActive (name);
   489 }
   490 
   491 QStringList TreeItem::activeStandardFlagNames ()
   492 {
   493 	return standardFlags.activeFlagNames();
   494 }
   495 
   496 FlagRow* TreeItem::getStandardFlagRow()
   497 {
   498 	return &standardFlags;
   499 }
   500 
   501 /* FIXME-3 void TreeItem::updateToolBar()
   502 {
   503 	standardFlags.updateToolBar();
   504 }
   505 */
   506 QStringList TreeItem::activeSystemFlagNames ()
   507 {
   508 	return systemFlags.activeFlagNames();
   509 }
   510 
   511 bool TreeItem::canMoveDown()
   512 {
   513 	switch (type)
   514 	{
   515 		case Undefined: return false;
   516 		case MapCenter: 
   517 		case Branch: 
   518 			if (!parentItem) return false;
   519 			if (parentItem->num (this) < parentItem->branchCount()-1)
   520 				return true;
   521 			else
   522 				return false;
   523 			break;	
   524 		case Image: return false;
   525 		default: return false;
   526 	}
   527 }
   528 
   529 bool TreeItem::canMoveUp()
   530 {
   531 	switch (type)
   532 	{
   533 		case Undefined: return false;
   534 		case MapCenter: 
   535 		case Branch: 
   536 			if (!parentItem) return false;
   537 			if (parentItem->num (this) > 0)
   538 				return true;
   539 			else
   540 				return false;
   541 			break;	
   542 		case Image: return false;
   543 		default: return false;
   544 	}
   545 }
   546 
   547 void TreeItem::setID (const QString &s)
   548 {
   549 	objID=s;
   550 }
   551 
   552 QString TreeItem::getID()
   553 {
   554 	return objID;
   555 }
   556 
   557 
   558 TreeItem* TreeItem::getChildNum(const int &n)
   559 {
   560 	if (n>=0 && n<childItems.count() )
   561 		return childItems.at(n);
   562 	else
   563 		return NULL;
   564 }
   565 
   566 BranchItem* TreeItem::getFirstBranch()
   567 {
   568 	if (branchCounter>0)
   569 		return getBranchNum (branchOffset);
   570 	else
   571 		return NULL;
   572 }
   573 
   574 BranchItem* TreeItem::getLastBranch()
   575 {
   576 	if (branchCounter>0)
   577 		return getBranchNum (branchOffset + branchCounter-1);
   578 	else
   579 		return NULL;
   580 }
   581 
   582 BranchItem* TreeItem::getNextBranch(BranchItem *currentBranch)
   583 {
   584 	if (!currentBranch) return NULL;
   585 	int n=num (currentBranch)+1;
   586 	if (n<branchCounter)
   587 		return getBranchNum (branchOffset + n);
   588 	else
   589 		return NULL;
   590 }
   591 
   592 
   593 BranchItem* TreeItem::getBranchNum(const int &n)
   594 {
   595 	if (n>=0 && n<branchCounter)
   596 		return (BranchItem*)getChildNum (branchOffset + n);
   597 	else
   598 		return NULL;
   599 }
   600 
   601 BranchObj* TreeItem::getBranchObjNum(const int &n)
   602 {
   603 	if (n>=0 && n<branchCounter)
   604 	{
   605 		return (BranchObj*)(getBranchNum(n)->getLMO());
   606 	} else
   607 		return NULL;
   608 }
   609 
   610 ImageItem* TreeItem::getImageNum (const int &n)
   611 {
   612 	if (n>=0 && n<imageCounter)
   613 		return (ImageItem*)getChildNum (imageOffset + n);
   614 	else
   615 		return NULL;
   616 }
   617 
   618 FloatImageObj* TreeItem::getImageObjNum (const int &n)	// FIXME-5 what about SVGs later?
   619 {
   620 	if (imageCounter>0 )
   621 		return (FloatImageObj*)(getImageNum(n)->getLMO());
   622 	else
   623 		return NULL;
   624 }
   625 
   626 
   627 void TreeItem::setHideTmp (HideTmpMode mode)  //FIXME-2
   628 {
   629 	if (isBranchLikeType() )
   630 		((BranchItem*)this)->updateVisibility();
   631 		/*
   632 	if (type==Image)
   633 		//updateVisibility();
   634 	*/
   635 
   636 /*
   637 
   638 		if (mode==HideExport && (hideExport || hasHiddenExportParent() ) )
   639 		{
   640 			// Hide stuff according to hideExport flag and parents
   641 			//setVisibility (false);
   642 			updateVisibility();
   643 			//FIXME-2 hidden=true;
   644 		}else
   645 		{
   646 			// Do not hide, but still take care of scrolled status
   647 			
   648 
   649 			XXXXXXXX treeItem should be THIS
   650 
   651 			move visible to TreeItem???
   652 
   653 			BranchObj now has updateContents
   654 
   655 			maybe also start "bool TreeItem::branchlikeType"
   656 
   657 
   658 
   659 			if ( ((BranchItem*)treeItem)->hasScrolledParent((BranchItem*)treeItem))
   660 				setVisibility (false);
   661 			else
   662 				setVisibility (true);
   663 			//FIXME-2 hidden=false;
   664 		}	
   665 
   666 */
   667 		// And take care of my children
   668 		for (int i=0; i<branchCount(); ++i)
   669 			getBranchNum(i)->setHideTmp (mode);
   670 }
   671 
   672 bool TreeItem::hasHiddenExportParent()
   673 {
   674 	// Calls parents recursivly to
   675 	// find out, if we or parents are temp. hidden
   676 
   677 	if (hidden || hideExport) return true;
   678 
   679 	if (parentItem) 
   680 		return parentItem->hasHiddenExportParent();
   681 	else
   682 		return false;
   683 }
   684 
   685 
   686 void TreeItem::setHideInExport(bool b) 
   687 {
   688 	if (type==Branch || type==Image)
   689 	{
   690 		hideExport=b;
   691 		if (b)
   692 			systemFlags.activate("system-hideInExport");
   693 		else	
   694 			systemFlags.deactivate("system-hideInExport");
   695 	}
   696 }	
   697 
   698 bool TreeItem::hideInExport()
   699 {
   700 	return hideExport;
   701 }	
   702 
   703 bool TreeItem::isHidden()
   704 {
   705 	return hidden;
   706 }	
   707 
   708 QString TreeItem::getGeneralAttr()
   709 {
   710 	QString s;
   711 	if (hideExport)
   712 		 s+=attribut("hideInExport","true");
   713 	if (!url.isEmpty())
   714 		s+=attribut ("url",url);
   715 	if (!vymLink.isEmpty())
   716 		s+=attribut ("vymLink",vymLink);
   717 	return s;	
   718 }
   719 
   720