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