Deleting an animated part no longer segfaults release-1-12-maintained
authorinsilmaril
Thu, 17 Jul 2008 11:11:55 +0000
branchrelease-1-12-maintained
changeset 40394b2f297e1d
parent 39 e37153bea487
child 41 6f28020b33d1
Deleting an animated part no longer segfaults
INSTALL.txt
branchobj.cpp
tex/vym.changelog
vymmodel.cpp
vymmodel.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/INSTALL.txt	Thu Jul 17 11:11:55 2008 +0000
     1.3 @@ -0,0 +1,59 @@
     1.4 +Installation of vym - view your mind
     1.5 +====================================
     1.6 +
     1.7 +Contents
     1.8 +--------
     1.9 +
    1.10 +A) openSUSE 10.2
    1.11 +B) openSUSE 10.3 and 11.0
    1.12 +C) Mac OS X 10.3+
    1.13 +
    1.14 +More systems like Debian are likely to be added later. Please
    1.15 +send feedback about installation on your Operating System to
    1.16 +vym@InSilmaril.de
    1.17 +
    1.18 +For general questions please contact the vym mailinglist:
    1.19 +
    1.20 +	vym-forum@lists.sourceforge.net
    1.21 +
    1.22 +
    1.23 +A) openSUSE 10.2
    1.24 +================
    1.25 +
    1.26 +vym needs a newer version of Trolltechs Qt libraries than the one on the
    1.27 +10.2 installation media. This new version can be installed easily in
    1.28 +YaST:
    1.29 +
    1.30 +	- Select "Installation Source"
    1.31 +	- Add a HTTP source:
    1.32 +		        Server: repos.opensuse.org
    1.33 +		     Directory: /KDE:/Qt/openSUSE_10.2/
    1.34 +		Authentication: Anonymous
    1.35 +
    1.36 +	- Select "Software Management"
    1.37 +	- Search for "libqt4"
    1.38 +	- Install all found packages. (They have a version >= 4.3.0-55.1)
    1.39 +
    1.40 +B) openSUSE 10.2 and later
    1.41 +==========================
    1.42 +
    1.43 +Get the rpms e.g. from here:
    1.44 +
    1.45 +http://download.opensuse.org/repositories/home://insilmaril/
    1.46 +
    1.47 +and install the (as root):
    1.48 +
    1.49 +yast -i vym-[VERSION].rpm
    1.50 +
    1.51 +C) Mac OS X 10.3+
    1.52 +=================
    1.53 +
    1.54 +After opening the disk image vym-1.9.0.dmg you can copy vym.app to
    1.55 +/Applications. This will need administrator rights.
    1.56 +
    1.57 +
    1.58 +This release of vym includes the Qt libraries. For more information on
    1.59 +Qt see http://www.trolltech.com.
    1.60 +		
    1.61 +
    1.62 +
     2.1 --- a/branchobj.cpp	Thu Jul 17 09:27:20 2008 +0000
     2.2 +++ b/branchobj.cpp	Thu Jul 17 11:11:55 2008 +0000
     2.3 @@ -1,12 +1,16 @@
     2.4  #include "branchobj.h"
     2.5 -#include "texteditor.h"
     2.6 +
     2.7 +// #include "texteditor.h"
     2.8 +#include "geometry.h"
     2.9  #include "mapeditor.h"
    2.10  #include "mainwindow.h"
    2.11 +#include "misc.h"
    2.12 +
    2.13 +class TextEditor;
    2.14  
    2.15  extern TextEditor *textEditor;
    2.16  extern Main *mainWindow;
    2.17  extern FlagRowObj *standardFlagsDefault;
    2.18 -extern QAction *actionEditOpenURL;
    2.19  
    2.20  
    2.21  /////////////////////////////////////////////////////////////////
    2.22 @@ -14,6 +18,7 @@
    2.23  /////////////////////////////////////////////////////////////////
    2.24  
    2.25  BranchObj* BranchObj::itLast=NULL;
    2.26 +BranchObj* BranchObj::itFirst=NULL;
    2.27  
    2.28  
    2.29  BranchObj::BranchObj () :OrnamentedObj()
    2.30 @@ -24,39 +29,50 @@
    2.31      depth=-1;
    2.32  }
    2.33  
    2.34 -BranchObj::BranchObj (QCanvas* c):OrnamentedObj (c)
    2.35 +BranchObj::BranchObj (QGraphicsScene* s):OrnamentedObj (s)
    2.36  {
    2.37 -//    cout << "Const BranchObj (c)  called from MapCenterObj (c)\n";
    2.38 -    canvas=c;
    2.39 +//    cout << "Const BranchObj (s)  called from MapCenterObj (s)\n";
    2.40 +	parObj=NULL;
    2.41 +    scene=s;
    2.42  }
    2.43  
    2.44 -BranchObj::BranchObj (QCanvas* c, LinkableMapObj* p):OrnamentedObj (c)
    2.45 +BranchObj::BranchObj (QGraphicsScene* s, LinkableMapObj* p):OrnamentedObj (s)
    2.46  {
    2.47 -//    cout << "Const BranchObj (c,p)\n";
    2.48 -    canvas=c;
    2.49 +//    cout << "Const BranchObj (s,p)\n";
    2.50 +    scene=s;
    2.51      setParObj (p);	
    2.52      depth=p->getDepth()+1;
    2.53  	if (depth==1)
    2.54  		// Calc angle to mapCenter if I am a mainbranch
    2.55  		// needed for reordering the mainbranches clockwise 
    2.56  		// around mapcenter 
    2.57 -		angle=getAngle (QPoint ((int)(x() - parObj->getChildPos().x() ), 
    2.58 -								(int)(y() - parObj->getChildPos().y() ) ) );
    2.59 +		angle=getAngle (QPointF (x() - parObj->getChildPos().x() , 
    2.60 +								(y() - parObj->getChildPos().y() ) ) );
    2.61      init();
    2.62  }
    2.63  
    2.64  BranchObj::~BranchObj ()
    2.65  {
    2.66 -    //cout << "Destr BranchObj\n";
    2.67 +	// If I'm animated, I need to un-animate myself first
    2.68 +	if (anim.isAnimated() )
    2.69 +	{
    2.70 +		anim.setAnimated (false);
    2.71 +		mapEditor->getModel()->stopAnimation (this);
    2.72 +	}
    2.73 +
    2.74 +
    2.75 +	//cout << "Destr BranchObj of "<<this<<endl;
    2.76  	// Check, if this branch was the last child to be deleted
    2.77  	// If so, unset the scrolled flags
    2.78  
    2.79 -	BranchObj *po=(BranchObj*)(parObj);
    2.80 +	BranchObj *po=(BranchObj*)parObj;
    2.81 +	BranchObj *bo;
    2.82  	if (po)
    2.83  	{
    2.84 -		BranchObj *bo=((BranchObj*)(parObj))->getLastBranch();
    2.85 -		if (!bo) po->unScroll();
    2.86 +		bo=((BranchObj*)parObj)->getLastBranch();
    2.87 +		if (bo) po->unScroll();
    2.88  	}
    2.89 +	clear();
    2.90  }
    2.91  
    2.92  bool BranchObj::operator< ( const BranchObj & other )
    2.93 @@ -69,40 +85,23 @@
    2.94      return angle == other.angle;
    2.95  }
    2.96  
    2.97 -int BranchObjPtrList::compareItems ( QPtrCollection::Item i, QPtrCollection::Item j)
    2.98 -{
    2.99 -	// Make sure PtrList::find works
   2.100 -	if (i==j) return 0;
   2.101 -
   2.102 -	if ( ((BranchObj*)(i))->angle > ((BranchObj*)(j))->angle )
   2.103 -		return 1;
   2.104 -	else
   2.105 -		return -1;
   2.106 -}
   2.107 -
   2.108  void BranchObj::init () 
   2.109  {
   2.110 -    branch.setAutoDelete (true);
   2.111 -    floatimage.setAutoDelete (true);
   2.112 +	if (parObj)
   2.113 +	{
   2.114 +		absPos=getRandPos();
   2.115 +		absPos+=parObj->getChildPos();
   2.116 +	}
   2.117  
   2.118 -	absPos=getRandPos();
   2.119 -	absPos+=parObj->getChildPos();
   2.120 -
   2.121 -    // TODO This should be done in TextObj later
   2.122 -    QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
   2.123 -//    font.setPointSize(12);
   2.124 -   heading->setFont(font );
   2.125 -//    heading->setText(QObject::tr("new branch"));
   2.126 -
   2.127 -    lastSelectedBranch=-1;
   2.128 +    lastSelectedBranch=0;
   2.129  
   2.130      setChildObj(this);
   2.131  
   2.132  	scrolled=false;
   2.133  	tmpUnscrolled=false;
   2.134  
   2.135 -	url="";
   2.136 -	vymLink="";
   2.137 +	includeImagesVer=false;
   2.138 +	includeImagesHor=false;
   2.139  }
   2.140  
   2.141  void BranchObj::copy (BranchObj* other)
   2.142 @@ -110,24 +109,18 @@
   2.143      OrnamentedObj::copy(other);
   2.144  
   2.145  	branch.clear();
   2.146 -    BranchObj* b;
   2.147 -    for (b=other->branch.first(); b;b=other->branch.next() ) 
   2.148 +	for (int i=0; i<other->branch.size(); ++i)
   2.149  		// Make deep copy of b
   2.150  		// Because addBranch again calls copy for the childs,
   2.151  		// Those will get a deep copy, too
   2.152 -		addBranch(b);	
   2.153 +		addBranch(other->branch.at(i) );	
   2.154  
   2.155 -	FloatImageObj *fi;
   2.156 -	for (fi=other->floatimage.first(); fi;fi=other->floatimage.next() )
   2.157 -		addFloatImage (fi);
   2.158 -
   2.159 +	for (int i=0; i<other->floatimage.size(); ++i)
   2.160 +		addFloatImage  (other->floatimage.at(i));
   2.161  	scrolled=other->scrolled;
   2.162  	tmpUnscrolled=other->tmpUnscrolled;
   2.163  	setVisibility (other->visible);
   2.164  
   2.165 -	url=other->url;
   2.166 -	vymLink=other->vymLink;
   2.167 -
   2.168  	angle=other->angle;
   2.169  
   2.170      positionBBox();
   2.171 @@ -135,26 +128,42 @@
   2.172  
   2.173  void BranchObj::clear() 
   2.174  {
   2.175 -	branch.clear();
   2.176 -	floatimage.clear();
   2.177 +	setVisibility (true);
   2.178 +
   2.179 +	while (!floatimage.isEmpty())
   2.180 +		delete floatimage.takeFirst();
   2.181 +
   2.182 +	while (!xlink.isEmpty())
   2.183 +		delete xlink.takeFirst();
   2.184 +
   2.185 +	while (!branch.isEmpty())
   2.186 +		delete branch.takeFirst();
   2.187 +}
   2.188 +
   2.189 +bool isAbove (BranchObj* a, BranchObj *b)
   2.190 +{
   2.191 +	if (a->angle < b->angle)
   2.192 +		return true;
   2.193 +	else	
   2.194 +		return false;
   2.195  }
   2.196  
   2.197  int BranchObj::getNum()
   2.198  {
   2.199  	if (parObj)
   2.200 -		return ((BranchObj*)(parObj))->getNum ((BranchObj*)(this));
   2.201 +		return ((BranchObj*)parObj)->getNum (this);
   2.202  	else
   2.203  		return 0;
   2.204  }
   2.205  
   2.206  int BranchObj::getNum(BranchObj *bo)
   2.207  {
   2.208 -	return branch.findRef (bo);
   2.209 +	return branch.indexOf (bo);
   2.210  }
   2.211  
   2.212  int BranchObj::getFloatImageNum(FloatImageObj *fio)
   2.213  {
   2.214 -	return floatimage.findRef (fio);
   2.215 +	return floatimage.indexOf(fio);
   2.216  }
   2.217  
   2.218  int BranchObj::countBranches()
   2.219 @@ -167,7 +176,12 @@
   2.220  	return floatimage.count();
   2.221  }
   2.222  
   2.223 -void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPoint m, int off)
   2.224 +int BranchObj::countXLinks()
   2.225 +{
   2.226 +	return xlink.count();
   2.227 +}
   2.228 +
   2.229 +void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPointF m, int off)
   2.230  {
   2.231  	// Temporary link to lmo
   2.232  	// m is position of mouse pointer 
   2.233 @@ -181,19 +195,10 @@
   2.234  	// ignore mapcenter and mainbranch
   2.235  	if (lmo->getDepth()<2) off=0;
   2.236  	if (off==0)
   2.237 -	{
   2.238  		link2ParPos=false;
   2.239 -		parObj=o;
   2.240 -	}	
   2.241  	else
   2.242 -	{	
   2.243  		link2ParPos=true;
   2.244 -		if (off>0)
   2.245 -			parObj=o->getParObj();
   2.246 -		else	
   2.247 -			parObj=o->getParObj();
   2.248 -		parObj=o;
   2.249 -	}		
   2.250 +	parObj=o;
   2.251  
   2.252  	depth=parObj->getDepth()+1;
   2.253  
   2.254 @@ -207,17 +212,17 @@
   2.255  	if (depth==1)
   2.256  	{	// new parent is the mapcenter itself
   2.257  
   2.258 -		QPoint p= normalise ( QPoint (m.x() - o->getChildPos().x(),
   2.259 +		QPointF p= normalise ( QPointF (m.x() - o->getChildPos().x(),
   2.260  									  m.y() - o->getChildPos().y() ));
   2.261  		if (p.x()<0) p.setX( p.x()-bbox.width() );
   2.262  		move2RelPos (p);
   2.263  	} else
   2.264  	{	
   2.265 -		int y;
   2.266 +		qreal y;
   2.267  		if (off==0)
   2.268  		{
   2.269  			// new parent is just a branch, link to it
   2.270 -			QRect t=o->getBBoxSizeWithChilds();
   2.271 +			QRectF t=o->getBBoxSizeWithChilds();
   2.272  			if (o->getLastBranch())
   2.273  				y=t.y() + t.height() ;
   2.274  			else
   2.275 @@ -235,14 +240,14 @@
   2.276  				// Don't try to find that branch, guess 12 pixels
   2.277  				y=o->getChildPos().y()  -height() + 12; 
   2.278  		}	
   2.279 -		if (o->getOrientation()==OrientLeftOfCenter)
   2.280 +		if (o->getOrientation()==LinkableMapObj::LeftOfCenter)
   2.281  			move ( o->getChildPos().x() - linkwidth, y );
   2.282  		else	
   2.283  			move (o->getChildPos().x() + linkwidth, y );
   2.284  	}	
   2.285  
   2.286  	// updateLink is called implicitly in move
   2.287 -	reposition();	// FIXME shouldn't be this a request?
   2.288 +	requestReposition();	
   2.289  }
   2.290  
   2.291  void BranchObj::unsetParObjTmp()
   2.292 @@ -254,6 +259,7 @@
   2.293  		parObjTmpBuf=NULL;
   2.294  		depth=parObj->getDepth()+1;
   2.295  		setLinkStyle (getDefLinkStyle() );
   2.296 +		updateLink();
   2.297  	}		
   2.298  }
   2.299  
   2.300 @@ -265,23 +271,18 @@
   2.301  
   2.302  void BranchObj::toggleScroll()
   2.303  {
   2.304 -	BranchObj *bo;
   2.305  	if (scrolled)
   2.306  	{
   2.307  		scrolled=false;
   2.308  		systemFlags->deactivate("scrolledright");
   2.309 -		for (bo=branch.first(); bo; bo=branch.next() )
   2.310 -		{
   2.311 -			bo->setVisibility(true);
   2.312 -		}
   2.313 +		for (int i=0; i<branch.size(); ++i)
   2.314 +			branch.at(i)->setVisibility(true);
   2.315  	} else
   2.316  	{
   2.317  		scrolled=true;
   2.318  		systemFlags->activate("scrolledright");
   2.319 -		for (bo=branch.first(); bo; bo=branch.next() )
   2.320 -		{
   2.321 -			bo->setVisibility(false);
   2.322 -		}
   2.323 +		for (int i=0; i<branch.size(); ++i)
   2.324 +			branch.at(i)->setVisibility(false);
   2.325  	}
   2.326  	calcBBoxSize();
   2.327  	positionBBox();	
   2.328 @@ -350,18 +351,19 @@
   2.329  		standardFlags->setVisibility(v);
   2.330  		LinkableMapObj::setVisibility (v);
   2.331  		
   2.332 +		// Only change childs, if I am not scrolled
   2.333  		if (!scrolled && (depth < toDepth))
   2.334  		{
   2.335  			// Now go recursivly through all childs
   2.336 -			BranchObj* b;
   2.337 -			for (b=branch.first(); b;b=branch.next() ) 
   2.338 -				b->setVisibility (v,toDepth);	
   2.339 -			FloatImageObj *fio;
   2.340 -			for (fio=floatimage.first(); fio; fio=floatimage.next())
   2.341 -				fio->setVisibility (v);
   2.342 +			int i;
   2.343 +			for (i=0; i<branch.size(); ++i)
   2.344 +				branch.at(i)->setVisibility (v,toDepth);	
   2.345 +			for (i=0; i<floatimage.size(); ++i)
   2.346 +				floatimage.at(i)->setVisibility (v);
   2.347 +			for (i=0; i<xlink.size(); ++i)	
   2.348 +				xlink.at(i)->setVisibility ();	
   2.349  		}
   2.350      } // depth <= toDepth	
   2.351 -	move (absPos.x(), absPos.y() );
   2.352  	requestReposition();
   2.353  }	
   2.354  
   2.355 @@ -376,53 +378,60 @@
   2.356  	// Overloaded from LinkableMapObj
   2.357  	// BranchObj can use color of heading
   2.358  
   2.359 -	if (mapEditor->getLinkColorHint()==HeadingColor)
   2.360 -		LinkableMapObj::setLinkColor (heading->getColor() );
   2.361 -	else	
   2.362 -		LinkableMapObj::setLinkColor ();
   2.363 +	if (mapEditor)
   2.364 +	{
   2.365 +		if (mapEditor->getMapLinkColorHint()==HeadingColor)
   2.366 +			LinkableMapObj::setLinkColor (heading->getColor() );
   2.367 +		else	
   2.368 +			LinkableMapObj::setLinkColor ();
   2.369 +	}		
   2.370  }
   2.371  
   2.372 -void BranchObj::setColor (QColor col, bool colorChilds)
   2.373 +void BranchObj::setColorSubtree(QColor col)
   2.374  {
   2.375 -    heading->setColor(col);
   2.376 -	setLinkColor();
   2.377 -    if (colorChilds) 
   2.378 -    {
   2.379 -		BranchObj *bo;
   2.380 -		for (bo=branch.first(); bo; bo=branch.next() )
   2.381 -			bo->setColor(col,colorChilds);
   2.382 -    }	
   2.383 +	setColor (col);
   2.384 +	for (int i=0; i<branch.size(); ++i)
   2.385 +		branch.at(i)->setColorSubtree(col);
   2.386  }
   2.387  
   2.388 -
   2.389  BranchObj* BranchObj::first()
   2.390  {
   2.391  	itLast=NULL;	
   2.392 +	itFirst=this;
   2.393  	return this; 
   2.394  }
   2.395  	
   2.396  BranchObj* BranchObj::next()
   2.397  {
   2.398 +	BranchObj *bo;
   2.399  	BranchObj *lmo;
   2.400 -	BranchObj *bo=branch.first();
   2.401 -	BranchObj *po=(BranchObj*)(parObj);
   2.402 +	BranchObj *po=(BranchObj*)parObj;
   2.403 +
   2.404 +	if (branch.isEmpty())
   2.405 +		bo=NULL;
   2.406 +	else
   2.407 +		bo=branch.first();
   2.408  
   2.409  	if (!itLast)
   2.410 -	{	// We are just beginning at the mapCenter
   2.411 +	{
   2.412 +		// no itLast, we are just beginning
   2.413  		if (bo) 
   2.414  		{
   2.415 +			// we have childs, return first one
   2.416  			itLast=this;
   2.417  			return bo;
   2.418  		}	
   2.419  		else
   2.420  		{
   2.421 -			itLast=NULL;
   2.422 +			// No childs, so there is no next
   2.423 +			itLast=this;
   2.424  			return NULL;
   2.425  		}	
   2.426  	}
   2.427  
   2.428 -	if (itLast==parObj)
   2.429 -	{	// We come from above
   2.430 +	// We have an itLast
   2.431 +	if (itLast==po)
   2.432 +	{	// We come from parent
   2.433  		if (bo)
   2.434  		{
   2.435  			// there are childs, go there
   2.436 @@ -433,7 +442,7 @@
   2.437  		{	// no childs, try to go up again
   2.438  			if (po)
   2.439  			{
   2.440 -				// go up
   2.441 +				// go back to parent and try to find next there
   2.442  				itLast=this;
   2.443  				lmo=po->next();
   2.444  				itLast=this;
   2.445 @@ -442,22 +451,35 @@
   2.446  			}	
   2.447  			else
   2.448  			{
   2.449 -				// can't go up, I am mapCenter
   2.450 +				// can't go up, I am mapCenter, no next
   2.451  				itLast=NULL;
   2.452  				return NULL;
   2.453  			}	
   2.454  		}
   2.455  	}
   2.456  
   2.457 -	// Try to find last child, we came from, in my own childs
   2.458 +	// We don't come from parent, but from brother or childs
   2.459 +
   2.460 +	// Try to find last child, where we came from, in my own childs
   2.461  	bool searching=true;
   2.462 -	while (bo && searching)
   2.463 +	int i=0;
   2.464 +	while (i<branch.size())
   2.465  	{
   2.466 -		if (itLast==bo) searching=false;
   2.467 -		bo=branch.next();
   2.468 +		// Try to find itLast in my own childs
   2.469 +		if (itLast==branch.at(i))
   2.470 +		{
   2.471 +			// ok, we come from my own childs
   2.472 +			if (i<branch.size()-1)
   2.473 +				bo=branch.at(i+1);
   2.474 +			 else
   2.475 +				bo=NULL;
   2.476 +			searching=false;
   2.477 +			i=branch.size();
   2.478 +		} 	
   2.479 +		++i;	
   2.480  	}
   2.481  	if (!searching)
   2.482 -	{	// found lastLMO in my childs
   2.483 +	{	// found itLast in my childs
   2.484  		if (bo)
   2.485  		{
   2.486  			// found a brother of lastLMO 
   2.487 @@ -468,6 +490,7 @@
   2.488  		{
   2.489  			if (po)
   2.490  			{
   2.491 +				if (this==itFirst) return NULL;	// Stop at starting point
   2.492  				// go up
   2.493  				itLast=this;
   2.494  				lmo=po->next();
   2.495 @@ -484,12 +507,11 @@
   2.496  	}
   2.497  
   2.498  	// couldn't find last child, it must be a nephew of mine
   2.499 -	bo=branch.first();
   2.500 -	if (bo)
   2.501 +	if (branch.size()>0)
   2.502  	{
   2.503  		// proceed with my first child
   2.504  		itLast=this;	
   2.505 -		return bo;
   2.506 +		return branch.first();
   2.507  	}	
   2.508  	else
   2.509  	{
   2.510 @@ -521,14 +543,22 @@
   2.511  	itLast=it;
   2.512  }
   2.513  
   2.514 +void BranchObj::positionContents()
   2.515 +{
   2.516 +    for (int i=0; i<floatimage.size(); ++i )
   2.517 +		floatimage.at(i)->reposition();
   2.518 +	OrnamentedObj::positionContents();
   2.519 +}
   2.520  
   2.521  void BranchObj::move (double x, double y)
   2.522  {
   2.523  	OrnamentedObj::move (x,y);
   2.524 +    for (int i=0; i<floatimage.size(); ++i )
   2.525 +		floatimage.at(i)->reposition();
   2.526      positionBBox();
   2.527  }
   2.528  
   2.529 -void BranchObj::move (QPoint p)
   2.530 +void BranchObj::move (QPointF p)
   2.531  {
   2.532  	move (p.x(), p.y());
   2.533  }
   2.534 @@ -536,13 +566,12 @@
   2.535  void BranchObj::moveBy (double x, double y)
   2.536  {
   2.537  	OrnamentedObj::moveBy (x,y);
   2.538 +	for (int i=0; i<branch.size(); ++i)
   2.539 +		branch.at(i)->moveBy (x,y);
   2.540      positionBBox();
   2.541 -    BranchObj* b;
   2.542 -    for (b=branch.first(); b;b=branch.next() ) 
   2.543 -		b->moveBy (x,y);
   2.544  }
   2.545 -
   2.546 -void BranchObj::moveBy (QPoint p)
   2.547 +	
   2.548 +void BranchObj::moveBy (QPointF p)
   2.549  {
   2.550  	moveBy (p.x(), p.y());
   2.551  }
   2.552 @@ -550,38 +579,31 @@
   2.553  
   2.554  void BranchObj::positionBBox()
   2.555  {
   2.556 -
   2.557 -    heading->positionBBox();
   2.558 -	systemFlags->positionBBox();
   2.559 -	standardFlags->positionBBox();
   2.560 -	// It seems that setting x,y also affects width,height
   2.561 -	int w_old=bbox.width();
   2.562 -	int h_old=bbox.height();
   2.563 -    bbox.setX (absPos.x() );
   2.564 -	bbox.setY (absPos.y() );
   2.565 -	bbox.setWidth(w_old);
   2.566 -	bbox.setHeight(h_old);
   2.567 -
   2.568 -
   2.569 -	setSelBox();
   2.570 +	QPointF ap=getAbsPos();
   2.571 +	bbox.moveTopLeft (ap);
   2.572 +	positionContents();
   2.573  
   2.574  	// set the frame
   2.575 -	frame->setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
   2.576 +	frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
   2.577 +
   2.578 +	// Update links to other branches
   2.579 +	for (int i=0; i<xlink.size(); ++i)
   2.580 +		xlink.at(i)->updateXLink();
   2.581  }
   2.582  
   2.583  void BranchObj::calcBBoxSize()
   2.584  {
   2.585 -    QSize heading_r=heading->getSize();
   2.586 -    int heading_w=static_cast <int> (heading_r.width() );
   2.587 -    int heading_h=static_cast <int> (heading_r.height() );
   2.588 -    QSize sysflags_r=systemFlags->getSize();
   2.589 -	int sysflags_h=sysflags_r.height();
   2.590 -	int sysflags_w=sysflags_r.width();
   2.591 -    QSize stanflags_r=standardFlags->getSize();
   2.592 -	int stanflags_h=stanflags_r.height();
   2.593 -	int stanflags_w=stanflags_r.width();
   2.594 -    int w;
   2.595 -    int h;
   2.596 +    QSizeF heading_r=heading->getSize();
   2.597 +    qreal heading_w=(qreal) heading_r.width() ;
   2.598 +    qreal heading_h=(qreal) heading_r.height() ;
   2.599 +    QSizeF sysflags_r=systemFlags->getSize();
   2.600 +	qreal sysflags_h=sysflags_r.height();
   2.601 +	qreal sysflags_w=sysflags_r.width();
   2.602 +    QSizeF stanflags_r=standardFlags->getSize();
   2.603 +	qreal stanflags_h=stanflags_r.height();
   2.604 +	qreal stanflags_w=stanflags_r.width();
   2.605 +    qreal w;
   2.606 +    qreal h;
   2.607  
   2.608  	// set width to sum of all widths
   2.609  	w=heading_w + sysflags_w + stanflags_w;
   2.610 @@ -589,106 +611,186 @@
   2.611  	h=max (sysflags_h,stanflags_h);
   2.612  	h=max (h,heading_h);
   2.613  
   2.614 -    w+=frame->getBorder();
   2.615 -    h+=frame->getBorder();
   2.616 -    bbox.setSize (QSize (w,h));
   2.617 +	// Save the dimension of flags and heading
   2.618 +	ornamentsBBox.setSize ( QSizeF(w,h));
   2.619 +
   2.620 +	// clickBox includes Flags and Heading
   2.621 +    clickBox.setSize (ornamentsBBox.size() );
   2.622 +
   2.623 +	// Floatimages 
   2.624 +	QPointF rp;
   2.625 +
   2.626 +	topPad=botPad=leftPad=rightPad=0;
   2.627 +	if (includeImagesVer || includeImagesHor)
   2.628 +	{
   2.629 +		if (countFloatImages()>0)
   2.630 +		{
   2.631 +			for (int i=0; i<floatimage.size(); ++i )
   2.632 +			{
   2.633 +				rp=floatimage.at(i)->getRelPos();
   2.634 +				if (includeImagesVer)
   2.635 +				{
   2.636 +					if (rp.y() < 0) 
   2.637 +						topPad=max (topPad,-rp.y()-h);
   2.638 +					if (rp.y()+floatimage.at(i)->height() > 0)
   2.639 +						botPad=max (botPad,rp.y()+floatimage.at(i)->height());
   2.640 +				}		
   2.641 +				if (includeImagesHor)
   2.642 +				{
   2.643 +					if (orientation==LinkableMapObj::RightOfCenter)
   2.644 +					{
   2.645 +						if (-rp.x()-w > 0) 
   2.646 +							leftPad=max (leftPad,-rp.x()-w);
   2.647 +						if (rp.x()+floatimage.at(i)->width() > 0)
   2.648 +							rightPad=max (rightPad,rp.x()+floatimage.at(i)->width());
   2.649 +					} else
   2.650 +					{
   2.651 +						if (rp.x()< 0) 
   2.652 +							leftPad=max (leftPad,-rp.x());
   2.653 +						if (rp.x()+floatimage.at(i)->width() > w)
   2.654 +							rightPad=max (rightPad,rp.x()+floatimage.at(i)->width()-w);
   2.655 +					}
   2.656 +				}		
   2.657 +			}	
   2.658 +		}	
   2.659 +		h+=topPad+botPad;
   2.660 +		w+=leftPad+rightPad;
   2.661 +	}
   2.662 +
   2.663 +	// Frame thickness
   2.664 +    w+=frame->getPadding();
   2.665 +    h+=frame->getPadding();
   2.666 +	
   2.667 +	// Finally set size
   2.668 +    bbox.setSize (QSizeF (w,h));
   2.669  }
   2.670  
   2.671 -LinkableMapObj* BranchObj::findMapObj(QPoint p, LinkableMapObj* excludeLMO)
   2.672 +void BranchObj::setDockPos()
   2.673 +{
   2.674 +	// Sets childpos and parpos depending on orientation
   2.675 +	if (getOrientation()==LinkableMapObj::LeftOfCenter )
   2.676 +    {
   2.677 +		childPos=QPointF (
   2.678 +			ornamentsBBox.bottomLeft().x(), 
   2.679 +			bottomlineY);
   2.680 +		parPos=QPointF (
   2.681 +			ornamentsBBox.bottomRight().x(),
   2.682 +			bottomlineY);
   2.683 +    } else
   2.684 +    {
   2.685 +		childPos=QPointF (
   2.686 +			ornamentsBBox.bottomRight().x(), 
   2.687 +			bottomlineY);
   2.688 +		parPos=QPointF (
   2.689 +			ornamentsBBox.bottomLeft().x(),
   2.690 +			bottomlineY);
   2.691 +    }
   2.692 +}
   2.693 +
   2.694 +LinkableMapObj* BranchObj::findMapObj(QPointF p, LinkableMapObj* excludeLMO)
   2.695  {
   2.696  	// Search branches
   2.697 -    BranchObj *b;
   2.698      LinkableMapObj *lmo;
   2.699 -    for (b=branch.first(); b; b=branch.next() )
   2.700 +	for (int i=0; i<branch.size(); ++i)
   2.701      {	
   2.702 -		lmo=b->findMapObj(p, excludeLMO);
   2.703 +		lmo=branch.at(i)->findMapObj(p, excludeLMO);
   2.704 +		if (lmo != NULL) return lmo;
   2.705 +    }
   2.706 +	
   2.707 +
   2.708 +	// Search myself
   2.709 +    if (inBox (p,clickBox) && (this != excludeLMO) && isVisibleObj() ) 
   2.710 +		return this;
   2.711 +
   2.712 +	// Search float images
   2.713 +    for (int i=0; i<floatimage.size(); ++i )
   2.714 +		if (inBox(p,floatimage.at(i)->getClickBox()) && 
   2.715 +			(floatimage.at(i) != excludeLMO) && 
   2.716 +			floatimage.at(i)->getParObj()!= excludeLMO &&
   2.717 +			floatimage.at(i)->isVisibleObj() 
   2.718 +		) return floatimage.at(i);
   2.719 +
   2.720 +    return NULL;
   2.721 +}
   2.722 +
   2.723 +LinkableMapObj* BranchObj::findID (QString sid)
   2.724 +{
   2.725 +	// Search branches
   2.726 +    LinkableMapObj *lmo;
   2.727 +	for (int i=0; i<branch.size(); ++i)
   2.728 +    {	
   2.729 +		lmo=branch.at(i)->findID (sid);
   2.730  		if (lmo != NULL) return lmo;
   2.731      }
   2.732  	
   2.733  	// Search myself
   2.734 -    if (inBBox (p) && (this != excludeLMO) && isVisibleObj() ) 
   2.735 -		return this;
   2.736 +	if (sid==objID) return this;
   2.737  
   2.738 +
   2.739 +/*
   2.740  	// Search float images
   2.741 -	FloatImageObj *foi;
   2.742 -    for (foi=floatimage.first(); foi; foi=floatimage.next() )
   2.743 -		if (foi->inBBox(p) && (foi != excludeLMO) && foi->getParObj()!= excludeLMO) return foi;
   2.744 -
   2.745 +    for (int i=0; i<floatimage.size(); ++i )
   2.746 +		if (floatimage.at(i)->inBox(p) && 
   2.747 +			(floatimage.at(i) != excludeLMO) && 
   2.748 +			floatimage.at(i)->getParObj()!= excludeLMO &&
   2.749 +			floatimage.at(i)->isVisibleObj() 
   2.750 +		) return floatimage.at(i);
   2.751 +*/
   2.752      return NULL;
   2.753  }
   2.754  
   2.755  void BranchObj::setHeading(QString s)
   2.756  {
   2.757 -    // Adjusting font size
   2.758 -    QFont font=heading->getFont();
   2.759 -	if (depth==0)
   2.760 -		font.setPointSize(16);
   2.761 -	else	
   2.762 -		if (depth>1) 
   2.763 -			font.setPointSize(10);
   2.764 -		else
   2.765 -			font.setPointSize(12);
   2.766 -    heading->setFont(font);
   2.767      heading->setText(s);	// set new heading
   2.768  	calcBBoxSize();			// recalculate bbox
   2.769      positionBBox();			// rearrange contents
   2.770  	requestReposition();
   2.771  }
   2.772  
   2.773 -void BranchObj::setURL(QString s)
   2.774 +void BranchObj::setHideTmp (HideTmpMode mode)
   2.775  {
   2.776 -	url=s;
   2.777 -	if (!url.isEmpty())
   2.778 -		systemFlags->activate("url");
   2.779 -	else	
   2.780 -		systemFlags->deactivate("url");
   2.781 -	calcBBoxSize();			// recalculate bbox
   2.782 -    positionBBox();			// rearrange contents
   2.783 -	forceReposition();
   2.784 +	if (mode==HideExport && (hideExport|| hasHiddenExportParent() ) )
   2.785 +	{
   2.786 +		// Hide stuff according to hideExport flag and parents
   2.787 +		setVisibility (false);
   2.788 +		hidden=true;
   2.789 +	}else
   2.790 +	{
   2.791 +		// Do not hide, but still take care of scrolled status
   2.792 +		if (hasScrolledParent(this))
   2.793 +			setVisibility (false);
   2.794 +		else
   2.795 +			setVisibility (true);
   2.796 +		hidden=false;
   2.797 +	}	
   2.798 +
   2.799 +	// And take care of my childs
   2.800 +	for (int i=0; i<branch.size(); ++i)
   2.801 +		branch.at(i)->setHideTmp (mode);
   2.802  }
   2.803  
   2.804 -QString BranchObj::getURL()
   2.805 +bool BranchObj::hasHiddenExportParent()
   2.806  {
   2.807 -	return url;
   2.808 +	// Calls parents recursivly to
   2.809 +	// find out, if we or parents are temp. hidden
   2.810 +
   2.811 +	if (hidden || hideExport) return true;
   2.812 +
   2.813 +	BranchObj* bo=(BranchObj*)parObj;
   2.814 +	if (bo) 
   2.815 +		return bo->hasHiddenExportParent();
   2.816 +	else
   2.817 +		return false;
   2.818  }
   2.819  
   2.820 -void BranchObj::setVymLink(QString s)
   2.821 +QString BranchObj::saveToDir (const QString &tmpdir,const QString &prefix, const QPointF& offset)
   2.822  {
   2.823 -	if (!s.isEmpty())
   2.824 -	{
   2.825 -		// We need the relative (from loading) 
   2.826 -		// or absolute path (from User event)
   2.827 -		// and build the absolute path.
   2.828 -		// Note: If we have relative, use path of
   2.829 -		// current map to build absolute path
   2.830 -		QDir d(s);
   2.831 -		if (!d.path().startsWith ("/"))
   2.832 -		{
   2.833 -			QString p=mapEditor->getDestPath();
   2.834 -			int i=p.findRev("/",-1);
   2.835 -			d.setPath(p.left(i)+"/"+s);
   2.836 -			d.convertToAbs();
   2.837 -		}
   2.838 -		vymLink=d.path();
   2.839 -		systemFlags->activate("vymLink");
   2.840 -	}	
   2.841 -	else	
   2.842 -	{
   2.843 -		systemFlags->deactivate("vymLink");
   2.844 -		vymLink="";
   2.845 -	}	
   2.846 -	calcBBoxSize();			// recalculate bbox
   2.847 -    positionBBox();			// rearrange contents
   2.848 -	forceReposition();
   2.849 -}
   2.850 +	// Cloudy stuff can be hidden during exports
   2.851 +	if (hidden) return "";
   2.852  
   2.853 -QString BranchObj::getVymLink()
   2.854 -{
   2.855 -	return vymLink;
   2.856 -}
   2.857 -
   2.858 -QString BranchObj::saveToDir (const QString &tmpdir,const QString &prefix, const QPoint& offset)
   2.859 -{
   2.860 +	// Update of note is usually done while unselecting a branch
   2.861 +	if (isNoteInEditor) getNoteFromTextEditor();
   2.862 +	
   2.863      QString s,a;
   2.864  	QString scrolledAttr;
   2.865  	if (scrolled) 
   2.866 @@ -696,90 +798,192 @@
   2.867  	else
   2.868  		scrolledAttr="";
   2.869  
   2.870 -	QString posAttr;
   2.871 -	if (depth<2) posAttr=
   2.872 -		attribut("absPosX",QString().setNum(absPos.x(),10)) +
   2.873 -		attribut("absPosY",QString().setNum(absPos.y(),10)); 
   2.874 -	else
   2.875 -		posAttr="";
   2.876 -
   2.877 -	QString urlAttr;
   2.878 -	if (!url.isEmpty())
   2.879 -		urlAttr=attribut ("url",url);
   2.880 -
   2.881 -	QString vymLinkAttr;
   2.882 -	if (!vymLink.isEmpty())
   2.883 -		vymLinkAttr=attribut ("vymLink",convertToRel(mapEditor->getDestPath(),vymLink) );
   2.884 -
   2.885 -	QString frameAttr;
   2.886 -	if (frame->getFrameType()!=NoFrame)
   2.887 -		frameAttr=attribut ("frameType",frame->getFrameTypeName());
   2.888 -	else
   2.889 -		frameAttr="";
   2.890 -
   2.891  	// save area, if not scrolled
   2.892  	QString areaAttr;
   2.893  	if (!((BranchObj*)(parObj))->isScrolled() )
   2.894  	{
   2.895  		areaAttr=
   2.896 -			attribut("x1",QString().setNum(absPos.x()-offset.x(),10)) +
   2.897 -			attribut("y1",QString().setNum(absPos.y()-offset.y(),10)) +
   2.898 -			attribut("x2",QString().setNum(absPos.x()+width()-offset.x(),10)) +
   2.899 -			attribut("y2",QString().setNum(absPos.y()+height()-offset.y(),10));
   2.900 +			attribut("x1",QString().setNum(absPos.x()-offset.x())) +
   2.901 +			attribut("y1",QString().setNum(absPos.y()-offset.y())) +
   2.902 +			attribut("x2",QString().setNum(absPos.x()+width()-offset.x())) +
   2.903 +			attribut("y2",QString().setNum(absPos.y()+height()-offset.y()));
   2.904  
   2.905  	} else
   2.906  		areaAttr="";
   2.907  	
   2.908 -    s=beginElement ("branch" +scrolledAttr +posAttr +urlAttr +vymLinkAttr +frameAttr +areaAttr);
   2.909 +	// Providing an ID for a branch makes export to XHTML easier
   2.910 +	QString idAttr;
   2.911 +	if (countXLinks()>0)
   2.912 +		idAttr=attribut ("id",mapEditor->getModel()->getSelectString(this)); //TODO directly access model
   2.913 +	else
   2.914 +		idAttr="";
   2.915 +
   2.916 +    s=beginElement ("branch" 
   2.917 +		+getOrnXMLAttr() 
   2.918 +		+scrolledAttr 
   2.919 +		+areaAttr 
   2.920 +		+idAttr 
   2.921 +		+getIncludeImageAttr() );
   2.922      incIndent();
   2.923  
   2.924  	// save heading
   2.925 -    s=s+valueElement("heading", getHeading(),
   2.926 +    s+=valueElement("heading", getHeading(),
   2.927  		attribut ("textColor",QColor(heading->getColor()).name()));
   2.928  
   2.929 +	// Save frame
   2.930 +	if (frame->getFrameType()!=FrameObj::NoFrame) 
   2.931 +		s+=frame->saveToDir ();
   2.932 +
   2.933  	// save names of flags set
   2.934  	s+=standardFlags->saveToDir(tmpdir,prefix,0);
   2.935  	
   2.936 +	// Save FloatImages
   2.937 +	for (int i=0; i<floatimage.size(); ++i)
   2.938 +		s+=floatimage.at(i)->saveToDir (tmpdir,prefix);
   2.939 +
   2.940  	// save note
   2.941  	if (!note.isEmpty() )
   2.942  		s+=note.saveToDir();
   2.943  	
   2.944  	// Save branches
   2.945 -    BranchObj *bo;
   2.946 -    for (bo=branch.first(); bo; bo=branch.next() )
   2.947 -		s+=bo->saveToDir(tmpdir,prefix,offset);
   2.948 +	for (int i=0; i<branch.size(); ++i)
   2.949 +		s+=branch.at(i)->saveToDir(tmpdir,prefix,offset);
   2.950 +
   2.951 +	// Save XLinks
   2.952 +	QString ol;	// old link
   2.953 +	QString cl;	// current link
   2.954 +	for (int i=0; i<xlink.size(); ++i)
   2.955 +	{
   2.956 +		cl=xlink.at(i)->saveToDir();
   2.957 +		if (cl!=ol)
   2.958 +		{
   2.959 +			s+=cl;
   2.960 +			ol=cl;
   2.961 +		} else
   2.962 +		{
   2.963 +			qWarning (QString("Ignoring of duplicate xLink in %1").arg(getHeading()));
   2.964 +		}
   2.965 +	}	
   2.966 +
   2.967      decIndent();
   2.968 -
   2.969 -	// Save FloatImages
   2.970 -	FloatImageObj *fio;
   2.971 -	for (fio=floatimage.first(); fio; fio=floatimage.next() )
   2.972 -		s+=fio->saveToDir (tmpdir,prefix);
   2.973 -
   2.974      s+=endElement   ("branch");
   2.975      return s;
   2.976  }
   2.977  
   2.978 -LinkableMapObj* BranchObj::addFloatImage ()
   2.979 +void BranchObj::addXLink (XLinkObj *xlo)
   2.980  {
   2.981 -	FloatImageObj *newfi=new FloatImageObj (canvas,this);
   2.982 +	xlink.append (xlo);
   2.983 +	
   2.984 +}
   2.985 +
   2.986 +void BranchObj::removeXLinkRef (XLinkObj *xlo)
   2.987 +{
   2.988 +	xlink.removeAt (xlink.indexOf(xlo));
   2.989 +}
   2.990 +
   2.991 +void BranchObj::deleteXLink(XLinkObj *xlo)
   2.992 +{
   2.993 +	xlo->deactivate();
   2.994 +	if (!xlo->isUsed()) delete (xlo);
   2.995 +}
   2.996 +
   2.997 +void BranchObj::deleteXLinkAt (int i)
   2.998 +{
   2.999 +	XLinkObj *xlo=xlink.at(i);
  2.1000 +	xlo->deactivate();
  2.1001 +	if (!xlo->isUsed()) delete(xlo);
  2.1002 +}
  2.1003 +
  2.1004 +XLinkObj* BranchObj::XLinkAt (int i)
  2.1005 +{
  2.1006 +	return xlink.at(i);
  2.1007 +}
  2.1008 +
  2.1009 +int BranchObj::countXLink()
  2.1010 +{
  2.1011 +	return xlink.count();
  2.1012 +}
  2.1013 +
  2.1014 +
  2.1015 +BranchObj* BranchObj::XLinkTargetAt (int i)
  2.1016 +{
  2.1017 +	if (i>=0 && i<xlink.size())
  2.1018 +	{
  2.1019 +		if (xlink.at(i))
  2.1020 +			return xlink.at(i)->otherBranch (this);
  2.1021 +	}
  2.1022 +	return NULL;
  2.1023 +}
  2.1024 +
  2.1025 +void BranchObj::setIncludeImagesVer(bool b)
  2.1026 +{
  2.1027 +	includeImagesVer=b;
  2.1028 +	calcBBoxSize();
  2.1029 +	positionBBox();
  2.1030 +	requestReposition();
  2.1031 +}
  2.1032 +
  2.1033 +bool BranchObj::getIncludeImagesVer()
  2.1034 +{
  2.1035 +	return includeImagesVer;
  2.1036 +}
  2.1037 +
  2.1038 +void BranchObj::setIncludeImagesHor(bool b)
  2.1039 +{
  2.1040 +	includeImagesHor=b;
  2.1041 +	calcBBoxSize();
  2.1042 +	positionBBox();
  2.1043 +	requestReposition();
  2.1044 +}
  2.1045 +
  2.1046 +bool BranchObj::getIncludeImagesHor()
  2.1047 +{
  2.1048 +	return includeImagesHor;
  2.1049 +}
  2.1050 +
  2.1051 +QString BranchObj::getIncludeImageAttr()
  2.1052 +{
  2.1053 +	QString a;
  2.1054 +	if (includeImagesVer)
  2.1055 +		a=attribut ("incImgV","true");
  2.1056 +	else
  2.1057 +		a=attribut ("incImgV","false");
  2.1058 +	if (includeImagesHor)
  2.1059 +		a+=attribut ("incImgH","true");
  2.1060 +	else
  2.1061 +		a+=attribut ("incImgH","false");
  2.1062 +	return a;	
  2.1063 +}
  2.1064 +
  2.1065 +FloatImageObj* BranchObj::addFloatImage ()
  2.1066 +{
  2.1067 +	FloatImageObj *newfi=new FloatImageObj (scene,this);
  2.1068  	floatimage.append (newfi);
  2.1069  	if (hasScrolledParent(this) )
  2.1070  		newfi->setVisibility (false);
  2.1071  	else	
  2.1072  		newfi->setVisibility(visible);
  2.1073 +		/*
  2.1074 +	calcBBoxSize();
  2.1075 +	positionBBox();
  2.1076 +	*/
  2.1077  	requestReposition();
  2.1078  	return newfi;
  2.1079  }
  2.1080  
  2.1081 -LinkableMapObj* BranchObj::addFloatImage (FloatImageObj *fio)
  2.1082 +FloatImageObj* BranchObj::addFloatImage (FloatImageObj *fio)
  2.1083  {
  2.1084 -	FloatImageObj *newfi=new FloatImageObj (canvas,this);
  2.1085 +	FloatImageObj *newfi=new FloatImageObj (scene,this);
  2.1086  	floatimage.append (newfi);
  2.1087  	newfi->copy (fio);
  2.1088  	if (hasScrolledParent(this) )
  2.1089  		newfi->setVisibility (false);
  2.1090  	else	
  2.1091  		newfi->setVisibility(visible);
  2.1092 +		/*
  2.1093 +	calcBBoxSize();
  2.1094 +	positionBBox();
  2.1095 +	*/
  2.1096  	requestReposition();
  2.1097  	return newfi;
  2.1098  }
  2.1099 @@ -801,62 +1005,92 @@
  2.1100  
  2.1101  void BranchObj::removeFloatImage (FloatImageObj *fio)
  2.1102  {
  2.1103 -	floatimage.remove (fio);
  2.1104 +	int i=floatimage.indexOf (fio);
  2.1105 +	if (i>-1) delete (floatimage.takeAt (i));
  2.1106 +	calcBBoxSize();
  2.1107 +	positionBBox();
  2.1108  	requestReposition();
  2.1109  }
  2.1110  
  2.1111  void BranchObj::savePosInAngle ()
  2.1112  {
  2.1113  	// Save position in angle
  2.1114 -    BranchObj *b;
  2.1115 -	int i=0;
  2.1116 -    for (b=branch.first(); b; b=branch.next() )
  2.1117 +	for (int i=0; i<branch.size(); ++i)
  2.1118 +		branch.at(i)->angle=i;
  2.1119 +}
  2.1120 +
  2.1121 +void BranchObj::setDefAttr (BranchModification mod)
  2.1122 +{
  2.1123 +	int fontsize;
  2.1124 +	switch (depth)
  2.1125  	{
  2.1126 -		b->angle=i;
  2.1127 -		i++;
  2.1128 -	}
  2.1129 +		case 0: fontsize=16; break;
  2.1130 +		case 1: fontsize=12; break;
  2.1131 +		default: fontsize=10; break;
  2.1132 +	}	
  2.1133 +
  2.1134 +	setLinkColor ();
  2.1135 +	setLinkStyle(getDefLinkStyle());
  2.1136 +	QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
  2.1137 +	font.setPointSize(fontsize);
  2.1138 +	heading->setFont(font );
  2.1139 +
  2.1140 +	if (mod==NewBranch)
  2.1141 +		setColor (((BranchObj*)(parObj))->getColor());
  2.1142 +	
  2.1143 +	calcBBoxSize();
  2.1144  }
  2.1145  
  2.1146  BranchObj* BranchObj::addBranch()
  2.1147  {
  2.1148 -    BranchObj* newbo=new BranchObj(canvas,this);
  2.1149 +    BranchObj* newbo=new BranchObj(scene,this);
  2.1150      branch.append (newbo);
  2.1151      newbo->setParObj(this);
  2.1152 -    newbo->setColor(getColor(),false);	
  2.1153 -    newbo->setLinkColor();	
  2.1154 +	newbo->setDefAttr(NewBranch);
  2.1155      newbo->setHeading ("new");
  2.1156 -	newbo->setLinkStyle (newbo->getDefLinkStyle());
  2.1157  	if (scrolled)
  2.1158  		newbo->setVisibility (false);
  2.1159  	else	
  2.1160  		newbo->setVisibility(visible);
  2.1161 +	newbo->updateLink();	
  2.1162  	requestReposition();
  2.1163  	return newbo;
  2.1164  }
  2.1165  
  2.1166  BranchObj* BranchObj::addBranch(BranchObj* bo)
  2.1167  {
  2.1168 -    BranchObj* newbo=new BranchObj(canvas,this);
  2.1169 +    BranchObj* newbo=new BranchObj(scene,this);
  2.1170      branch.append (newbo);
  2.1171      newbo->copy(bo);
  2.1172      newbo->setParObj(this);
  2.1173 -	newbo->setHeading (newbo->getHeading());	// adjust fontsize to depth
  2.1174 -	newbo->setLinkStyle (newbo->getDefLinkStyle());
  2.1175 +	newbo->setDefAttr(MovedBranch);
  2.1176  	if (scrolled)
  2.1177  		newbo->setVisibility (false);
  2.1178  	else	
  2.1179  		newbo->setVisibility(bo->visible);
  2.1180 +	newbo->updateLink();	
  2.1181  	requestReposition();
  2.1182  	return newbo;
  2.1183  }
  2.1184  
  2.1185 +BranchObj* BranchObj::addBranchPtr(BranchObj* bo)
  2.1186 +{
  2.1187 +	branch.append (bo);
  2.1188 +	bo->setParObj (this);
  2.1189 +	bo->depth=depth+1;
  2.1190 +	bo->setDefAttr(MovedBranch);
  2.1191 +	if (scrolled) tmpUnscroll();
  2.1192 +	setLastSelectedBranch (bo);
  2.1193 +	return bo;
  2.1194 +}
  2.1195 +
  2.1196  BranchObj* BranchObj::insertBranch(int pos)
  2.1197  {
  2.1198  	savePosInAngle();
  2.1199  	// Add new bo and resort branches
  2.1200  	BranchObj *newbo=addBranch ();
  2.1201  	newbo->angle=pos-0.5;
  2.1202 -	branch.sort();
  2.1203 +	qSort (branch.begin(),branch.end(), isAbove);
  2.1204  	return newbo;
  2.1205  }
  2.1206  
  2.1207 @@ -866,133 +1100,288 @@
  2.1208  	// Add new bo and resort branches
  2.1209  	bo->angle=pos-0.5;
  2.1210  	BranchObj *newbo=addBranch (bo);
  2.1211 -	branch.sort();
  2.1212 +	qSort (branch.begin(),branch.end(), isAbove);
  2.1213  	return newbo;
  2.1214  }
  2.1215  
  2.1216 +BranchObj* BranchObj::insertBranchPtr (BranchObj* bo, int pos)
  2.1217 +{
  2.1218 +	savePosInAngle();
  2.1219 +	// Add new bo and resort branches
  2.1220 +	bo->angle=pos-0.5;
  2.1221 +	branch.append (bo);
  2.1222 +	bo->setParObj (this);
  2.1223 +	bo->depth=depth+1;
  2.1224 +	bo->setDefAttr (MovedBranch);
  2.1225 +	if (scrolled) tmpUnscroll();
  2.1226 +	setLastSelectedBranch (bo);
  2.1227 +	qSort (branch.begin(),branch.end(), isAbove);
  2.1228 +	return bo;
  2.1229 +}
  2.1230 +
  2.1231 +void BranchObj::removeBranchHere(BranchObj* borem)
  2.1232 +{
  2.1233 +	// This removes the branch bo from list, but 
  2.1234 +	// inserts its childs at the place of bo
  2.1235 +	BranchObj *bo;
  2.1236 +	bo=borem->getLastBranch();
  2.1237 +	int pos=borem->getNum();
  2.1238 +	while (bo)
  2.1239 +	{
  2.1240 +		bo->linkTo (this,pos+1);
  2.1241 +		bo=borem->getLastBranch();
  2.1242 +	}	
  2.1243 +	removeBranch (borem);
  2.1244 +}
  2.1245 +
  2.1246 +void BranchObj::removeChilds()
  2.1247 +{
  2.1248 +	clear();
  2.1249 +}
  2.1250 +
  2.1251  void BranchObj::removeBranch(BranchObj* bo)
  2.1252  {
  2.1253      // if bo is not in branch remove returns false, we
  2.1254      // don't care...
  2.1255 -    branch.remove (bo);
  2.1256 +	
  2.1257 +	int i=branch.indexOf(bo);
  2.1258 +    if (i>=0)
  2.1259 +	{
  2.1260 +		delete (bo);
  2.1261 +		branch.removeAt (i);
  2.1262 +	} else
  2.1263 +		qWarning ("BranchObj::removeBranch tried to remove non existing branch?!\n");
  2.1264 +	requestReposition();
  2.1265 +}
  2.1266 +
  2.1267 +void BranchObj::removeBranchPtr(BranchObj* bo)
  2.1268 +{
  2.1269 +	int i=branch.indexOf(bo);
  2.1270 +	
  2.1271 +	if (i>=0)
  2.1272 +		branch.removeAt (i);
  2.1273 +	else	
  2.1274 +		qWarning ("BranchObj::removeBranchPtr tried to remove non existing branch?!\n");
  2.1275  	requestReposition();
  2.1276  }
  2.1277  
  2.1278  void BranchObj::setLastSelectedBranch (BranchObj* bo)
  2.1279  {
  2.1280 -    lastSelectedBranch=branch.find(bo);
  2.1281 +    lastSelectedBranch=branch.indexOf(bo);
  2.1282  }
  2.1283  
  2.1284  BranchObj* BranchObj::getLastSelectedBranch ()
  2.1285  {
  2.1286 -    if (lastSelectedBranch>=0) 
  2.1287 +    if (lastSelectedBranch>=0)
  2.1288  	{
  2.1289 -		BranchObj* bo=branch.at(lastSelectedBranch);
  2.1290 -		if (bo) return bo;
  2.1291 -    }	
  2.1292 -    return branch.first();
  2.1293 +		if ( branch.size()>lastSelectedBranch) 
  2.1294 +			return branch.at(lastSelectedBranch);
  2.1295 +		if (branch.size()>0)
  2.1296 +			return branch.last();
  2.1297 +	}	
  2.1298 +    return NULL;
  2.1299  }
  2.1300  
  2.1301  BranchObj* BranchObj::getFirstBranch ()
  2.1302  {
  2.1303 -    return branch.first();
  2.1304 +	if (branch.size()>0)
  2.1305 +		return branch.first();
  2.1306 +	else
  2.1307 +		return NULL;
  2.1308  }
  2.1309  
  2.1310  BranchObj* BranchObj::getLastBranch ()
  2.1311  {
  2.1312 -    return branch.last();
  2.1313 +	if (branch.size()>0)
  2.1314 +		return branch.last();
  2.1315 +	else
  2.1316 +		return NULL;
  2.1317  }
  2.1318  
  2.1319 -BranchObj* BranchObj::getBranchNum (const uint &i)
  2.1320 +BranchObj* BranchObj::getBranchNum (int i)
  2.1321  {
  2.1322 -    return branch.at(i);
  2.1323 +	if (i>=0 && i<branch.size())
  2.1324 +		return branch.at(i);
  2.1325 +	else	
  2.1326 +		return	NULL;
  2.1327  }
  2.1328  
  2.1329 +bool BranchObj::canMoveBranchUp() 
  2.1330 +{
  2.1331 +	if (!parObj || depth==1) return false;
  2.1332 +	BranchObj* par=(BranchObj*)parObj;
  2.1333 +	if (this==par->getFirstBranch())
  2.1334 +		return false;
  2.1335 +	else
  2.1336 +		return true;
  2.1337 +}
  2.1338  
  2.1339 -BranchObj* BranchObj::moveBranchUp(BranchObj* bo1) // move a branch up (modify myself)
  2.1340 +BranchObj* BranchObj::moveBranchUp(BranchObj* bo1) // modify my childlist
  2.1341  {
  2.1342  	savePosInAngle();
  2.1343 -    int i=branch.find(bo1);
  2.1344 +    int i=branch.indexOf(bo1);
  2.1345      if (i>0) 
  2.1346  	{	// -1 if bo1 not found 
  2.1347  		branch.at(i)->angle--;
  2.1348  		branch.at(i-1)->angle++;
  2.1349 -		branch.sort();
  2.1350 -		return branch.at(i-1);
  2.1351 +		qSort (branch.begin(),branch.end(), isAbove);
  2.1352 +		return branch.at(i);
  2.1353  	} else
  2.1354 -		return branch.at(i);
  2.1355 +		return NULL;
  2.1356  }
  2.1357  
  2.1358 -BranchObj* BranchObj::moveBranchDown(BranchObj* bo1)
  2.1359 +bool BranchObj::canMoveBranchDown() 
  2.1360 +{
  2.1361 +	if (!parObj|| depth==1) return false;
  2.1362 +	BranchObj* par=(BranchObj*)parObj;
  2.1363 +	if (this==par->getLastBranch())
  2.1364 +		return false;
  2.1365 +	else
  2.1366 +		return true;
  2.1367 +}
  2.1368 +
  2.1369 +BranchObj* BranchObj::moveBranchDown(BranchObj* bo1)// modify my childlist
  2.1370  {
  2.1371  	savePosInAngle();
  2.1372 -    int i=branch.find(bo1);
  2.1373 +    int i=branch.indexOf(bo1);
  2.1374  	int j;
  2.1375 -	if (branch.next())
  2.1376 +	if (i <branch.size())
  2.1377  	{
  2.1378 -		j = branch.at();
  2.1379 +		j = i+1;
  2.1380  		branch.at(i)->angle++;
  2.1381  		branch.at(j)->angle--;
  2.1382 -		branch.sort();
  2.1383 -		return branch.at(j);
  2.1384 +		qSort (branch.begin(),branch.end(), isAbove);
  2.1385 +		return branch.at(i);
  2.1386  	} else
  2.1387 -		return branch.at(i);
  2.1388 +		return NULL;
  2.1389  }
  2.1390  
  2.1391 -void BranchObj::alignRelativeTo (QPoint ref)
  2.1392 +void BranchObj::sortChildren()
  2.1393  {
  2.1394 -/* FIXME testing
  2.1395 -	if (!getHeading().isEmpty())
  2.1396 -		cout << "BO::alignRelTo "<<getHeading()<<endl;
  2.1397 -	else	
  2.1398 -		cout << "BO::alignRelTo  ???"<<endl;
  2.1399 -	cout << "  d="<<depth<<endl;
  2.1400 -*/	
  2.1401 -	int th = bboxTotal.height();	
  2.1402 +	int childCount=branch.count();
  2.1403 +	int curChildIndex;
  2.1404 +	bool madeChanges=false;
  2.1405 +	do
  2.1406 +	{
  2.1407 +		madeChanges=false;
  2.1408 +		for(curChildIndex=1;curChildIndex<childCount;curChildIndex++){
  2.1409 +			BranchObj* curChild=(BranchObj*)branch.at(curChildIndex);
  2.1410 +			BranchObj* prevChild=(BranchObj*)branch.at(curChildIndex-1);
  2.1411 +			if(prevChild->heading->text().compare(curChild->heading->text())>0)
  2.1412 +			{
  2.1413 +				this->moveBranchUp(curChild);
  2.1414 +				madeChanges=true;
  2.1415 +			}
  2.1416 +		}
  2.1417 +	}while(madeChanges);
  2.1418 +}
  2.1419  
  2.1420 -	// If I am the mapcenter or a mainbranch, reposition heading
  2.1421 +
  2.1422 +BranchObj* BranchObj::linkTo (BranchObj* dst, int pos)
  2.1423 +{
  2.1424 +	// Find current parent and 
  2.1425 +	// remove pointer to myself there
  2.1426 +	if (!dst) return NULL;
  2.1427 +	BranchObj *par=(BranchObj*)parObj;
  2.1428 +	if (par)
  2.1429 +		par->removeBranchPtr (this);
  2.1430 +	else
  2.1431 +		return NULL;
  2.1432 +
  2.1433 +	// Create new pointer to myself at dst
  2.1434 +	if (pos<0||dst->getDepth()==0)
  2.1435 +	{	
  2.1436 +		// links myself as last branch at dst
  2.1437 +		dst->addBranchPtr (this);
  2.1438 +		updateLink();
  2.1439 +		return this;
  2.1440 +	} else
  2.1441 +	{
  2.1442 +		// inserts me at pos in parent of dst
  2.1443 +		if (par)
  2.1444 +		{
  2.1445 +			BranchObj *bo=dst->insertBranchPtr (this,pos);
  2.1446 +			bo->setDefAttr(MovedBranch);
  2.1447 +			updateLink();
  2.1448 +			return bo;
  2.1449 +
  2.1450 +		} else
  2.1451 +			return NULL;
  2.1452 +	}	
  2.1453 +}
  2.1454 +
  2.1455 +void BranchObj::alignRelativeTo (QPointF ref)
  2.1456 +{
  2.1457 +	qreal th = bboxTotal.height();	
  2.1458 +// TODO testing
  2.1459 +/*
  2.1460 +	QPointF pp; if (parObj) pp=parObj->getChildPos();
  2.1461 +	cout << "BO::alignRelTo "<<qPrintable (getHeading());
  2.1462 +	cout << "    d="<<depth<<
  2.1463 +		"  ref="<<ref<<
  2.1464 +//		"  bbox.topLeft="<<bboxTotal.topLeft()<<
  2.1465 +		"  absPos="<<absPos<<
  2.1466 +		"  relPos="<<relPos<<
  2.1467 +		"  parPos="<<pp<<
  2.1468 +		"  orient="<<orientation<<
  2.1469 +//		"  pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
  2.1470 +//		"  hidden="<<hidden<<
  2.1471 +//		"  th="<<th<<
  2.1472 +		endl;
  2.1473 +*/
  2.1474 +
  2.1475 +	setOrientation();
  2.1476 +	//updateLink();
  2.1477 +
  2.1478  	if (depth<2)
  2.1479  	{
  2.1480 -		move (absPos.x(),absPos.y());
  2.1481  		if (depth==1)
  2.1482  		{
  2.1483 +			// Position relatively, if needed
  2.1484 +			//if (useRelPos) move2RelPos (relPos.x(), relPos.y());
  2.1485 +
  2.1486  			// Calc angle to mapCenter if I am a mainbranch
  2.1487  			// needed for reordering the mainbranches clockwise 
  2.1488  			// around mapcenter 
  2.1489 -			angle=getAngle (QPoint ((int)(x() - parObj->getChildPos().x() ), 
  2.1490 +			angle=getAngle (QPointF ((int)(x() - parObj->getChildPos().x() ), 
  2.1491  									(int)(y() - parObj->getChildPos().y() ) ) );
  2.1492 -		}	
  2.1493 +		}							
  2.1494  	} 
  2.1495  	else
  2.1496      {
  2.1497  		// Align myself depending on orientation and parent, but
  2.1498 -		// only if I am not the mainbranch or mapcenter itself
  2.1499 -		switch (orientation) 
  2.1500 +		// only if I am not a mainbranch or mapcenter itself
  2.1501 +
  2.1502 +		if (anim.isAnimated())
  2.1503  		{
  2.1504 -			case OrientLeftOfCenter:
  2.1505 -				move (ref.x()-bbox.width(), ref.y() + (th-bbox.height())/2 );
  2.1506 -			break;
  2.1507 -			case OrientRightOfCenter:	
  2.1508 -				move (ref.x(), ref.y() + (th-bbox.height())/2 );
  2.1509 -			break;
  2.1510 -			default:
  2.1511 -				cout <<"LMO::alignRelativeTo: oops, no orientation given...\n";
  2.1512 -			break;
  2.1513 -		}		
  2.1514 +			move2RelPos(anim);
  2.1515 +		} else
  2.1516 +		{
  2.1517 +			LinkableMapObj::Orientation o;
  2.1518 +			o=parObj->getOrientation();
  2.1519 +			switch (orientation) 
  2.1520 +			{
  2.1521 +				case LinkableMapObj::LeftOfCenter:
  2.1522 +					move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
  2.1523 +				break;
  2.1524 +				case LinkableMapObj::RightOfCenter:	
  2.1525 +					move (ref.x() , ref.y() + (th-bbox.height())/2  );
  2.1526 +				break;
  2.1527 +				default:
  2.1528 +					qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
  2.1529 +				break;
  2.1530 +			}	
  2.1531 +		}
  2.1532      }		
  2.1533  
  2.1534 -	FloatImageObj *fio;
  2.1535 -    for (fio=floatimage.first(); fio; fio=floatimage.next() )
  2.1536 -		fio->reposition();
  2.1537 -
  2.1538  	if (scrolled) return;
  2.1539  
  2.1540      // Set reference point for alignment of childs
  2.1541 -    QPoint ref2;
  2.1542 -    if (orientation==OrientLeftOfCenter)
  2.1543 -		ref2.setX(childPos.x() - linkwidth);
  2.1544 +    QPointF ref2;
  2.1545 +    if (orientation==LinkableMapObj::LeftOfCenter)
  2.1546 +		ref2.setX(bbox.topLeft().x() - linkwidth);
  2.1547      else	
  2.1548 -		ref2.setX(childPos.x() + linkwidth);
  2.1549 +		ref2.setX(bbox.topRight().x() + linkwidth);
  2.1550  
  2.1551  	if (depth==1)
  2.1552  		ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
  2.1553 @@ -1000,73 +1389,111 @@
  2.1554  		ref2.setY(ref.y() );	
  2.1555  
  2.1556      // Align the childs depending on reference point 
  2.1557 -    BranchObj *b;
  2.1558 -    for (b=branch.first(); b; b=branch.next() )
  2.1559 +	for (int i=0; i<branch.size(); ++i)
  2.1560      {	
  2.1561 -		b->alignRelativeTo (ref2);
  2.1562 -		ref2.setY(ref2.y() + b->getBBoxSizeWithChilds().height() );
  2.1563 +		if (!branch.at(i)->isHidden())
  2.1564 +		{
  2.1565 +			branch.at(i)->alignRelativeTo (ref2);
  2.1566 +			ref2.setY(ref2.y() + branch.at(i)->getBBoxSizeWithChilds().height() );
  2.1567 +		}
  2.1568      }
  2.1569  }
  2.1570  
  2.1571  
  2.1572  void BranchObj::reposition()
  2.1573  {	
  2.1574 -/* FIXME testing
  2.1575 +/* TODO testing only
  2.1576  	if (!getHeading().isEmpty())
  2.1577 -		cout << "BO::reposition  "<<getHeading()<<endl;
  2.1578 +		cout << "BO::reposition  "<<qPrintable(getHeading())<<endl;
  2.1579  	else	
  2.1580  		cout << "BO::reposition  ???"<<endl;
  2.1581 +
  2.1582 +	cout << "  orient="<<orientation<<endl;
  2.1583  */		
  2.1584 +
  2.1585  	if (depth==0)
  2.1586  	{
  2.1587  		// only calculate the sizes once. If the deepest LMO 
  2.1588  		// changes its height,
  2.1589  		// all upper LMOs have to change, too.
  2.1590  		calcBBoxSizeWithChilds();
  2.1591 -	    alignRelativeTo ( QPoint (absPos.x(),
  2.1592 +		updateLink();	// This update is needed if the scene is resized 
  2.1593 +						// due to excessive moving of a FIO
  2.1594 +
  2.1595 +	    alignRelativeTo ( QPointF (absPos.x(),
  2.1596  			absPos.y()-(bboxTotal.height()-bbox.height())/2) );
  2.1597 -		branch.sort();	
  2.1598 +		qSort (branch.begin(),branch.end(), isAbove);
  2.1599 +		positionBBox();	// Reposition bbox and contents
  2.1600  	} else
  2.1601  	{
  2.1602  		// This is only important for moving branches:
  2.1603  		// For editing a branch it isn't called...
  2.1604 -	    alignRelativeTo ( QPoint (absPos.x(),
  2.1605 +	    alignRelativeTo ( QPointF (absPos.x(),
  2.1606  							absPos.y()-(bboxTotal.height()-bbox.height())/2) );
  2.1607  	}
  2.1608  }
  2.1609  
  2.1610 +void BranchObj::unsetAllRepositionRequests()
  2.1611 +{
  2.1612 +	repositionRequest=false;
  2.1613 +	for (int i=0; i<branch.size(); ++i)
  2.1614 +		branch.at(i)->unsetAllRepositionRequests();
  2.1615 +}
  2.1616  
  2.1617 -QRect BranchObj::getTotalBBox()
  2.1618 +
  2.1619 +QPolygonF BranchObj::shape()
  2.1620  {
  2.1621 -	QRect r=bbox;
  2.1622 +	QPolygonF p;
  2.1623 +
  2.1624 +	QRectF r=getTotalBBox();
  2.1625 +	if (orientation==LinkableMapObj::LeftOfCenter)
  2.1626 +		p   <<r.bottomLeft()
  2.1627 +			<<r.topLeft()
  2.1628 +			<<QPointF (bbox.topLeft().x(), r.topLeft().y() )
  2.1629 +			<<bbox.topRight()
  2.1630 +			<<bbox.bottomRight()
  2.1631 +			<<QPointF (bbox.bottomLeft().x(), r.bottomLeft().y() ) ;
  2.1632 +	else		
  2.1633 +		p   <<r.bottomRight()
  2.1634 +			<<r.topRight()
  2.1635 +			<<QPointF (bbox.topRight().x(), r.topRight().y() )
  2.1636 +			<<bbox.topLeft()
  2.1637 +			<<bbox.bottomLeft()
  2.1638 +			<<QPointF (bbox.bottomRight().x(), r.bottomRight().y() ) ;
  2.1639 +	return p;
  2.1640 +}
  2.1641 +
  2.1642 +QRectF BranchObj::getTotalBBox()
  2.1643 +{
  2.1644 +	QRectF r=bbox;
  2.1645  
  2.1646  	if (scrolled) return r;
  2.1647  
  2.1648 -	BranchObj* b;
  2.1649 -	for (b=branch.first();b ;b=branch.next() )
  2.1650 -		r=addBBox(b->getTotalBBox(),r);
  2.1651 +	for (int i=0; i<branch.size(); ++i)
  2.1652 +		if (!branch.at(i)->isHidden())
  2.1653 +			r=addBBox(branch.at(i)->getTotalBBox(),r);
  2.1654  
  2.1655 -	FloatImageObj* fio;
  2.1656 -	for (fio=floatimage.first();fio ;fio=floatimage.next() )
  2.1657 -		r=addBBox(fio->getTotalBBox(),r);
  2.1658 +	for (int i=0; i<floatimage.size(); ++i)
  2.1659 +		if (!floatimage.at(i)->isHidden())
  2.1660 +			r=addBBox(floatimage.at(i)->getTotalBBox(),r);
  2.1661  		
  2.1662  	return r;
  2.1663  }
  2.1664  
  2.1665 -QRect BranchObj::getBBoxSizeWithChilds()
  2.1666 +QRectF BranchObj::getBBoxSizeWithChilds()
  2.1667  {
  2.1668  	return bboxTotal;
  2.1669  }
  2.1670  
  2.1671  void BranchObj::calcBBoxSizeWithChilds()
  2.1672 -{
  2.1673 -	// This is called only from reposition and
  2.1674 +{	
  2.1675 +	// This is initially called only from reposition and
  2.1676  	// and only for mapcenter. So it won't be
  2.1677  	// called more than once for a single user 
  2.1678  	// action
  2.1679  	
  2.1680 +
  2.1681  	// Calculate size of LMO including all childs (to align them later)
  2.1682 -
  2.1683  	bboxTotal.setX(bbox.x() );
  2.1684  	bboxTotal.setY(bbox.y() );
  2.1685  
  2.1686 @@ -1078,20 +1505,38 @@
  2.1687  		return;
  2.1688  	}
  2.1689  	
  2.1690 -	QRect r(0,0,0,0);
  2.1691 -	QRect br;
  2.1692 +	if (hidden)
  2.1693 +	{
  2.1694 +		bboxTotal.setWidth (0);
  2.1695 +		bboxTotal.setHeight(0);
  2.1696 +		if (parObj)
  2.1697 +		{
  2.1698 +			bboxTotal.setX (parObj->x());
  2.1699 +			bboxTotal.setY (parObj->y());
  2.1700 +		} else
  2.1701 +		{
  2.1702 +			bboxTotal.setX (bbox.x());
  2.1703 +			bboxTotal.setY (bbox.y());
  2.1704 +		}
  2.1705 +		return;
  2.1706 +	}
  2.1707 +	
  2.1708 +	QRectF r(0,0,0,0);
  2.1709 +	QRectF br;
  2.1710  	// Now calculate recursivly
  2.1711  	// sum of heights 
  2.1712  	// maximum of widths 
  2.1713  	// minimum of y
  2.1714 -	BranchObj* b;
  2.1715 -	for (b=branch.first();b ;b=branch.next() )
  2.1716 +	for (int i=0; i<branch.size(); ++i)
  2.1717  	{
  2.1718 -		b->calcBBoxSizeWithChilds();
  2.1719 -		br=b->getBBoxSizeWithChilds();
  2.1720 -		r.setWidth( max (br.width(), r.width() ));
  2.1721 -		r.setHeight(br.height() + r.height() );
  2.1722 -		if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
  2.1723 +		if (!branch.at(i)->isHidden())
  2.1724 +		{
  2.1725 +			branch.at(i)->calcBBoxSizeWithChilds();
  2.1726 +			br=branch.at(i)->getBBoxSizeWithChilds();
  2.1727 +			r.setWidth( max (br.width(), r.width() ));
  2.1728 +			r.setHeight(br.height() + r.height() );
  2.1729 +			if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
  2.1730 +		}
  2.1731  	}
  2.1732  	// Add myself and also
  2.1733  	// add width of link to sum if necessary
  2.1734 @@ -1099,13 +1544,25 @@
  2.1735  		bboxTotal.setWidth (bbox.width() + r.width() );
  2.1736  	else	
  2.1737  		bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
  2.1738 -	bboxTotal.setHeight(max (r.height(),  bbox.height() ) );
  2.1739 -//	frame->setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
  2.1740 +	
  2.1741 +	bboxTotal.setHeight(max (r.height(),  bbox.height()));
  2.1742  }
  2.1743  
  2.1744  void BranchObj::select()
  2.1745  {
  2.1746 +	// update NoteEditor
  2.1747 +	textEditor->setText(note.getNote() );
  2.1748 +	QString fnh=note.getFilenameHint();
  2.1749 +	if (fnh!="")
  2.1750 +		textEditor->setFilenameHint(note.getFilenameHint() );
  2.1751 +	else	
  2.1752 +		textEditor->setFilenameHint(getHeading() );
  2.1753 +	textEditor->setFontHint (note.getFontHint() );
  2.1754 +	isNoteInEditor=true;
  2.1755 +
  2.1756 +	// set selected and visible
  2.1757      LinkableMapObj::select();
  2.1758 +
  2.1759  	// Tell parent that I am selected now:
  2.1760  	BranchObj* po=(BranchObj*)(parObj);
  2.1761      if (po)	// TODO	    Try to get rid of this cast...
  2.1762 @@ -1114,13 +1571,6 @@
  2.1763  	// temporary unscroll, if we have scrolled parents somewhere
  2.1764  	if (parObj) ((BranchObj*)(parObj))->tmpUnscroll();
  2.1765  
  2.1766 -	// set Text in Editor	
  2.1767 -	textEditor->setText(note.getNote() );
  2.1768 -	textEditor->setFilename(note.getFilenameHint() );
  2.1769 -	textEditor->setFontHint (note.getFontHint() );
  2.1770 -	connect (textEditor, SIGNAL (textHasChanged() ), this, SLOT (updateNoteFlag() ) ); 
  2.1771 -	connect (textEditor, SIGNAL (fontSizeHasChanged() ), this, SLOT (updateNoteFlag() ) ); 
  2.1772 -
  2.1773  	// Show URL and link in statusbar
  2.1774  	QString status;
  2.1775  	if (!url.isEmpty()) status+="URL: "+url+"  ";
  2.1776 @@ -1128,15 +1578,9 @@
  2.1777  	if (!status.isEmpty()) mainWindow->statusMessage (status);
  2.1778  
  2.1779  	// Update Toolbar
  2.1780 -	standardFlags->updateToolBar();
  2.1781 +	updateFlagsToolbar();
  2.1782  
  2.1783 -	// Update Browserbutton
  2.1784 -	if (!url.isEmpty())
  2.1785 -		actionEditOpenURL->setEnabled (true);
  2.1786 -	else	
  2.1787 -		actionEditOpenURL->setEnabled (false);
  2.1788 -
  2.1789 -	// Update actions in mapeditor
  2.1790 +	// Update actions
  2.1791  	mapEditor->updateActions();
  2.1792  }
  2.1793  
  2.1794 @@ -1146,39 +1590,38 @@
  2.1795  	// Delete any messages like vymLink in StatusBar
  2.1796  	mainWindow->statusMessage ("");
  2.1797  
  2.1798 -	// save note from editor and set flag
  2.1799 -	// text is done by updateNoteFlag(), just save
  2.1800 -	// filename here
  2.1801 -	note.setFilenameHint (textEditor->getFilename());
  2.1802 +	// Save current note
  2.1803 +	if (isNoteInEditor) getNoteFromTextEditor();
  2.1804 +	isNoteInEditor=false;
  2.1805  
  2.1806  	// reset temporary unscroll, if we have scrolled parents somewhere
  2.1807  	if (parObj) ((BranchObj*)(parObj))->resetTmpUnscroll();
  2.1808  
  2.1809 -	// Disconnect textEditor from this LMO
  2.1810 -	disconnect( textEditor, SIGNAL(textHasChanged()), 0, 0 );
  2.1811 -	disconnect( textEditor, SIGNAL (fontSizeHasChanged()),0,0 ); 
  2.1812 -
  2.1813  	// Erase content of editor 
  2.1814  	textEditor->setInactive();
  2.1815  
  2.1816  	// unselect all buttons in toolbar
  2.1817 -	standardFlagsDefault->updateToolBar();
  2.1818 +	standardFlagsDefault->updateToolbar();
  2.1819  }
  2.1820  
  2.1821  QString BranchObj::getSelectString()
  2.1822  {
  2.1823 -	QString s;
  2.1824 -	if (parObj)
  2.1825 -	{
  2.1826 -		if (parObj->getDepth()==0)
  2.1827 -			s= "bo:" + QString("%1").arg(getNum());
  2.1828 -		else	
  2.1829 -			s= ((BranchObj*)(parObj))->getSelectString() + ",bo:" + QString("%1").arg(getNum());
  2.1830 -	} else
  2.1831 -	{
  2.1832 -		s="mc:";
  2.1833 -	}
  2.1834 -	
  2.1835 -	return s;
  2.1836 +	return mapEditor->getModel()->getSelectString (this);
  2.1837  }
  2.1838  
  2.1839 +void BranchObj::setAnimation(const AnimPoint &ap)
  2.1840 +{
  2.1841 +	anim=ap;
  2.1842 +}
  2.1843 +
  2.1844 +bool BranchObj::animate()
  2.1845 +{
  2.1846 +	anim.animate ();
  2.1847 +	if ( anim.isAnimated() )
  2.1848 +	{
  2.1849 +		setRelPos (anim);
  2.1850 +		return true;
  2.1851 +	}
  2.1852 +	return false;
  2.1853 +}
  2.1854 +
     3.1 --- a/tex/vym.changelog	Thu Jul 17 09:27:20 2008 +0000
     3.2 +++ b/tex/vym.changelog	Thu Jul 17 11:11:55 2008 +0000
     3.3 @@ -1,6 +1,7 @@
     3.4  -------------------------------------------------------------------
     3.5 -Thu Jul 17 11:25:39 CEST 2008 - uwedr@suse.de
     3.6 +Thu Jul 17 13:11:39 CEST 2008 - uwedr@suse.de
     3.7  
     3.8 +- Bugfix: Deleting an animated part no longer segfaults
     3.9  - Bugfix: smaller image for export to elliminate pixel jitter on right
    3.10            side 
    3.11  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/vymmodel.cpp	Thu Jul 17 11:11:55 2008 +0000
     4.3 @@ -0,0 +1,395 @@
     4.4 +#include <QApplication>
     4.5 +#include <typeinfo>
     4.6 +
     4.7 +#include "geometry.h"		// for addBBox
     4.8 +#include "vymmodel.h"
     4.9 +
    4.10 +
    4.11 +extern Settings settings;
    4.12 +
    4.13 +VymModel::VymModel() 
    4.14 +{
    4.15 +//    cout << "Const VymModel\n";
    4.16 +}
    4.17 +
    4.18 +
    4.19 +VymModel::~VymModel() 
    4.20 +{
    4.21 +//    cout << "Destr VymModel\n";
    4.22 +}	
    4.23 +
    4.24 +void VymModel::clear() 
    4.25 +{
    4.26 +	while (!mapCenters.isEmpty())
    4.27 +		delete mapCenters.takeFirst();
    4.28 +}
    4.29 +
    4.30 +void VymModel::init () 
    4.31 +{
    4.32 +	addMapCenter();
    4.33 +
    4.34 +	// animations
    4.35 +	animationUse=settings.readBoolEntry("/animation/use",false);
    4.36 +	animationTicks=settings.readNumEntry("/animation/ticks",10);
    4.37 +	animationInterval=settings.readNumEntry("/animation/interval",50);
    4.38 +	animObjList.clear();
    4.39 +	animationTimer=new QTimer (this);
    4.40 +	connect(animationTimer, SIGNAL(timeout()), this, SLOT(animate()));
    4.41 +
    4.42 +}
    4.43 +
    4.44 +void VymModel::setMapEditor(MapEditor *me)
    4.45 +{
    4.46 +	mapEditor=me;
    4.47 +	for (int i=0; i<mapCenters.count(); i++)
    4.48 +		mapCenters.at(i)->setMapEditor(mapEditor);
    4.49 +}
    4.50 +
    4.51 +MapEditor* VymModel::getMapEditor()
    4.52 +{
    4.53 +	return mapEditor;
    4.54 +}
    4.55 +
    4.56 +void VymModel::setVersion (const QString &s)
    4.57 +{
    4.58 +	version=s;
    4.59 +}
    4.60 +
    4.61 +void VymModel::setAuthor (const QString &s)
    4.62 +{
    4.63 +	author=s;
    4.64 +}
    4.65 +
    4.66 +QString VymModel::getAuthor()
    4.67 +{
    4.68 +	return author;
    4.69 +}
    4.70 +
    4.71 +void VymModel::setComment (const QString &s)
    4.72 +{
    4.73 +	comment=s;
    4.74 +}
    4.75 +
    4.76 +QString VymModel::getComment ()
    4.77 +{
    4.78 +	return comment;
    4.79 +}
    4.80 +
    4.81 +QString VymModel::getDate ()
    4.82 +{
    4.83 +	return QDate::currentDate().toString ("yyyy-MM-dd");
    4.84 +}
    4.85 +
    4.86 +void VymModel::setScene (QGraphicsScene *s)
    4.87 +{
    4.88 +	mapScene=s;
    4.89 +    init();	// Here we have a mapScene set, 
    4.90 +			// which is (still) needed to create MapCenters
    4.91 +}
    4.92 +
    4.93 +QGraphicsScene* VymModel::getScene ()
    4.94 +{
    4.95 +	return mapScene;
    4.96 +}
    4.97 +
    4.98 +MapCenterObj* VymModel::addMapCenter()
    4.99 +{
   4.100 +	return addMapCenter (QPointF(0,0));
   4.101 +}
   4.102 +
   4.103 +MapCenterObj* VymModel::addMapCenter(QPointF absPos)
   4.104 +{
   4.105 +	MapCenterObj *mapCenter = new MapCenterObj(mapScene);
   4.106 +	mapCenter->move (absPos);
   4.107 +    mapCenter->setVisibility (true);
   4.108 +	mapCenter->setHeading (QApplication::translate("Heading of mapcenter in new map", "New map"));
   4.109 +	mapCenter->setMapEditor(mapEditor);		//FIXME needed to get defLinkStyle, mapLinkColorHint ... for later added objects
   4.110 +	mapCenters.append(mapCenter);
   4.111 +	return mapCenter;
   4.112 +}
   4.113 +
   4.114 +MapCenterObj *VymModel::removeMapCenter(MapCenterObj* mco)
   4.115 +{
   4.116 +	int i=mapCenters.indexOf (mco);
   4.117 +	if (i>=0)
   4.118 +	{
   4.119 +		mapCenters.removeAt (i);
   4.120 +		delete (mco);
   4.121 +		if (i>0) return mapCenters.at(i-1);	// Return previous MCO
   4.122 +	}
   4.123 +	return NULL;
   4.124 +}
   4.125 +
   4.126 +BranchObj* VymModel::first()
   4.127 +{
   4.128 +	if (mapCenters.count()>0) 
   4.129 +		return mapCenters.first();
   4.130 +	else	
   4.131 +		return NULL;
   4.132 +}
   4.133 +	
   4.134 +BranchObj* VymModel::next(BranchObj *bo_start)
   4.135 +{
   4.136 +	BranchObj *rbo;
   4.137 +	BranchObj *bo=bo_start;
   4.138 +	if (bo)
   4.139 +	{
   4.140 +		// Try to find next branch in current MapCenter
   4.141 +		rbo=bo->next();
   4.142 +		if (rbo) return rbo;
   4.143 +
   4.144 +		// Try to find MapCenter of bo
   4.145 +		while (bo->getDepth()>0) bo=(BranchObj*)bo->getParObj();
   4.146 +
   4.147 +		// Try to find next MapCenter
   4.148 +		int i=mapCenters.indexOf ((MapCenterObj*)bo);
   4.149 +		if (i+2 > mapCenters.count() || i<0) return NULL;
   4.150 +		if (mapCenters.at(i+1)!=bo_start)
   4.151 +			return mapCenters.at(i+1);
   4.152 +	} 
   4.153 +	return NULL;
   4.154 +}
   4.155 +
   4.156 +LinkableMapObj* VymModel::findMapObj(QPointF p, LinkableMapObj *excludeLMO)
   4.157 +{
   4.158 +	LinkableMapObj *lmo;
   4.159 +
   4.160 +	for (int i=0;i<mapCenters.count(); i++)
   4.161 +	{
   4.162 +		lmo=mapCenters.at(i)->findMapObj (p,excludeLMO);
   4.163 +		if (lmo) return lmo;
   4.164 +	}
   4.165 +	return NULL;
   4.166 +}
   4.167 +
   4.168 +LinkableMapObj* VymModel::findObjBySelect(const QString &s)
   4.169 +{
   4.170 +	LinkableMapObj *lmo;
   4.171 +	if (!s.isEmpty() )
   4.172 +	{
   4.173 +		QString part;
   4.174 +		QString typ;
   4.175 +		QString num;
   4.176 +		part=s.section(",",0,0);
   4.177 +		typ=part.left (2);
   4.178 +		num=part.right(part.length() - 3);
   4.179 +		if (typ=="mc" && num.toInt()>=0 && num.toInt() <mapCenters.count() )
   4.180 +			return mapCenters.at(num.toInt() );
   4.181 +	}		
   4.182 +
   4.183 +	for (int i=0; i<mapCenters.count(); i++)
   4.184 +	{
   4.185 +		lmo=mapCenters.at(i)->findObjBySelect(s);
   4.186 +		if (lmo) return lmo;
   4.187 +	}	
   4.188 +	return NULL;
   4.189 +}
   4.190 +
   4.191 +LinkableMapObj* VymModel::findID (const QString &s)
   4.192 +{
   4.193 +	LinkableMapObj *lmo;
   4.194 +	for (int i=0; i<mapCenters.count(); i++)
   4.195 +	{
   4.196 +		lmo=mapCenters.at(i)->findID (s);
   4.197 +		if (lmo) return lmo;
   4.198 +	}	
   4.199 +	return NULL;
   4.200 +}
   4.201 +
   4.202 +QString VymModel::saveToDir (const QString &tmpdir,const QString &prefix, int verbose, const QPointF &offset)
   4.203 +{
   4.204 +    QString s;
   4.205 +
   4.206 +	for (int i=0; i<mapCenters.count(); i++)
   4.207 +		s+=mapCenters.at(i)->saveToDir (tmpdir,prefix,verbose,offset);
   4.208 +    return s;
   4.209 +}
   4.210 +
   4.211 +
   4.212 +//////////////////////////////////////////////
   4.213 +// View related
   4.214 +//////////////////////////////////////////////
   4.215 +
   4.216 +void VymModel::updateRelPositions()
   4.217 +{
   4.218 +	for (int i=0; i<mapCenters.count(); i++)
   4.219 +		mapCenters.at(i)->updateRelPositions();
   4.220 +}
   4.221 +
   4.222 +void VymModel::reposition()
   4.223 +{
   4.224 +	for (int i=0;i<mapCenters.count(); i++)
   4.225 +		mapCenters.at(i)->reposition();	//	for positioning heading
   4.226 +}
   4.227 +
   4.228 +QPolygonF VymModel::shape(BranchObj *bo)
   4.229 +{
   4.230 +	// Creating (arbitrary) shapes
   4.231 +
   4.232 +	QPolygonF p;
   4.233 +	QRectF rb=bo->getBBox();
   4.234 +	if (bo->getDepth()==0)
   4.235 +	{
   4.236 +		// Just take BBox of this mapCenter
   4.237 +		p<<rb.topLeft()<<rb.topRight()<<rb.bottomRight()<<rb.bottomLeft();
   4.238 +		return p;
   4.239 +	}
   4.240 +
   4.241 +	// Take union of BBox and TotalBBox 
   4.242 +
   4.243 +	QRectF ra=bo->getTotalBBox();
   4.244 +	if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
   4.245 +		p   <<ra.bottomLeft()
   4.246 +			<<ra.topLeft()
   4.247 +			<<QPointF (rb.topLeft().x(), ra.topLeft().y() )
   4.248 +			<<rb.topRight()
   4.249 +			<<rb.bottomRight()
   4.250 +			<<QPointF (rb.bottomLeft().x(), ra.bottomLeft().y() ) ;
   4.251 +	else		
   4.252 +		p   <<ra.bottomRight()
   4.253 +			<<ra.topRight()
   4.254 +			<<QPointF (rb.topRight().x(), ra.topRight().y() )
   4.255 +			<<rb.topLeft()
   4.256 +			<<rb.bottomLeft()
   4.257 +			<<QPointF (rb.bottomRight().x(), ra.bottomRight().y() ) ;
   4.258 +	return p;		
   4.259 +
   4.260 +}
   4.261 +
   4.262 +void VymModel::moveAway(LinkableMapObj *lmo)
   4.263 +{
   4.264 +	// Autolayout:
   4.265 +	//
   4.266 +	// Move all branches and MapCenters away from lmo 
   4.267 +	// to avoid collisions 
   4.268 +
   4.269 +	QPolygonF pA;
   4.270 +	QPolygonF pB;
   4.271 +
   4.272 +	BranchObj *boA=(BranchObj*)lmo;
   4.273 +	BranchObj *boB;
   4.274 +	for (int i=0; i<mapCenters.count(); i++)
   4.275 +	{
   4.276 +		boB=mapCenters.at(i);
   4.277 +		pA=shape (boA);
   4.278 +		pB=shape (boB);
   4.279 +		PolygonCollisionResult r = PolygonCollision(pA, pB, QPoint(0,0));
   4.280 +		cout <<"------->"
   4.281 +			<<"="<<r.intersect
   4.282 +			<<"  ("<<qPrintable(boA->getHeading() )<<")"
   4.283 +			<<"  with ("<< qPrintable (boB->getHeading() )
   4.284 +			<<")  willIntersect"
   4.285 +			<<r.willIntersect 
   4.286 +			<<"  minT="<<r.minTranslation<<endl<<endl;
   4.287 +	}
   4.288 +}
   4.289 +
   4.290 +void VymModel::animate()
   4.291 +{
   4.292 +	animationTimer->stop();
   4.293 +	BranchObj *bo;
   4.294 +	int i=0;
   4.295 +	while (i<animObjList.size() )
   4.296 +	{
   4.297 +		bo=(BranchObj*)animObjList.at(i);
   4.298 +		if (!bo->animate())
   4.299 +		{
   4.300 +			if (i>=0) animObjList.removeAt(i);
   4.301 +			i--;
   4.302 +		}
   4.303 +		bo->reposition();
   4.304 +		i++;
   4.305 +	} 
   4.306 +	mapEditor->updateSelection();
   4.307 +	mapScene->update();
   4.308 +	animationTimer->start();
   4.309 +}
   4.310 +
   4.311 +
   4.312 +void VymModel::startAnimation(const QPointF &start, const QPointF &dest)
   4.313 +{
   4.314 +	BranchObj *bo=getSelectedBranch();
   4.315 +	if (bo && bo->getDepth()>0) 
   4.316 +	{
   4.317 +		AnimPoint ap;
   4.318 +		ap.setStart (start);
   4.319 +		ap.setDest  (dest);
   4.320 +		ap.setTicks (animationTicks);
   4.321 +		ap.setAnimated (true);
   4.322 +		bo->setAnimation (ap);
   4.323 +		animObjList.append( bo );
   4.324 +		animationTimer->setSingleShot (true);
   4.325 +		animationTimer->start(animationInterval);
   4.326 +	}
   4.327 +}
   4.328 +
   4.329 +void VymModel::stopAnimation(MapObj *mo)
   4.330 +{
   4.331 +	int i=animObjList.indexOf(mo);
   4.332 +    if (i>=0)
   4.333 +		animObjList.removeAt (i);
   4.334 +}
   4.335 +
   4.336 +//////////////////////////////////////////////
   4.337 +// Selection related
   4.338 +//////////////////////////////////////////////
   4.339 +
   4.340 +
   4.341 +// Only as long as we dont have Model/View yet
   4.342 +LinkableMapObj* VymModel::getSelection()
   4.343 +{
   4.344 +	return mapEditor->getSelection();
   4.345 +}
   4.346 +BranchObj* VymModel::getSelectedBranch()
   4.347 +{
   4.348 +	return mapEditor->getSelectedBranch();
   4.349 +}
   4.350 +
   4.351 +
   4.352 +bool VymModel::select (const QString &s)
   4.353 +{
   4.354 +	return mapEditor->select (s);
   4.355 +}
   4.356 +
   4.357 +QString VymModel::getSelectString (LinkableMapObj *lmo)
   4.358 +{
   4.359 +	QString s;
   4.360 +	if (!lmo) return s;
   4.361 +	if (typeid(*lmo)==typeid(BranchObj) ||
   4.362 +		typeid(*lmo)==typeid(MapCenterObj) )
   4.363 +	{	
   4.364 +		LinkableMapObj *par=lmo->getParObj();
   4.365 +		if (par)
   4.366 +		{
   4.367 +			if (lmo->getDepth() ==1)
   4.368 +				// Mainbranch, return 
   4.369 +				s= "bo:" + QString("%1").arg(((BranchObj*)lmo)->getNum());
   4.370 +			else	
   4.371 +				// Branch, call myself recursively
   4.372 +				s= getSelectString(par) + ",bo:" + QString("%1").arg(((BranchObj*)lmo)->getNum());
   4.373 +		} else
   4.374 +		{
   4.375 +			// MapCenter
   4.376 +			int i=mapCenters.indexOf ((MapCenterObj*)lmo);
   4.377 +			if (i>=0) s=QString("mc:%1").arg(i);
   4.378 +		}	
   4.379 +	}	
   4.380 +	return s;
   4.381 +
   4.382 +}
   4.383 +
   4.384 +	
   4.385 +void VymModel::setHideTmp (HideTmpMode mode)
   4.386 +{
   4.387 +	for (int i=0;i<mapCenters.count(); i++)
   4.388 +		mapCenters.at(i)->setHideTmp (mode);	
   4.389 +}
   4.390 +
   4.391 +QRectF VymModel::getTotalBBox()
   4.392 +{
   4.393 +	QRectF r;
   4.394 +	for (int i=0;i<mapCenters.count(); i++)
   4.395 +		r=addBBox (mapCenters.at(i)->getTotalBBox(), r);
   4.396 +	return r;	
   4.397 +}
   4.398 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/vymmodel.h	Thu Jul 17 11:11:55 2008 +0000
     5.3 @@ -0,0 +1,86 @@
     5.4 +#ifndef VYMMODEL_H
     5.5 +#define VYMMODEL_H
     5.6 +
     5.7 +#include <QGraphicsScene>
     5.8 +
     5.9 +#include "mapcenterobj.h"
    5.10 +#include "mapeditor.h"
    5.11 +
    5.12 +
    5.13 +/*! \brief This will later be divided into Model/View
    5.14 +*/
    5.15 +
    5.16 +class VymModel : public QObject{
    5.17 +	Q_OBJECT
    5.18 +
    5.19 +public:
    5.20 +	VymModel();
    5.21 +	~VymModel ();
    5.22 +    void clear();
    5.23 +    void init();
    5.24 +	void setMapEditor(MapEditor *me);	// FIXME should not be necessary in Model/View
    5.25 +	MapEditor* getMapEditor();
    5.26 +	void setVersion(const  QString &);
    5.27 +	void setAuthor  (const QString &);
    5.28 +	QString getAuthor ();
    5.29 +	void setComment (const QString &);
    5.30 +	QString getComment ();
    5.31 +	QString getDate();
    5.32 +	void setScene(QGraphicsScene *s);
    5.33 +	QGraphicsScene *getScene();
    5.34 +	MapCenterObj* addMapCenter();
    5.35 +	MapCenterObj* addMapCenter(QPointF absPos);
    5.36 +	MapCenterObj* removeMapCenter(MapCenterObj *mco);
    5.37 +
    5.38 +	BranchObj* first();					// FIXME replaced by ModelIndex later
    5.39 +	BranchObj* next(BranchObj *bo);		// FIXME replaced by ModelIndex later
    5.40 +
    5.41 +    LinkableMapObj* findMapObj(QPointF,LinkableMapObj*);	// find MapObj 
    5.42 +    LinkableMapObj* findObjBySelect (const QString &s);		// find MapObj by select string
    5.43 +    LinkableMapObj* findID (const QString &s);				// find MapObj by previously set ID
    5.44 +	QString saveToDir (const QString&,const QString&,int, const QPointF&);// Save data recursivly to tempdir
    5.45 +
    5.46 +
    5.47 +////////////////////////////////////////// View related
    5.48 +    // void updateLink();  FIXME needed?
    5.49 +    void updateRelPositions();
    5.50 +
    5.51 +	QRectF getTotalBBox();
    5.52 +	void reposition();					//!< Call reposition for all MCOs
    5.53 +	void setHideTmp (HideTmpMode mode);	
    5.54 +	QPolygonF shape(BranchObj *bo);		//!< Returns arbitrary shape of subtree
    5.55 +	void moveAway (LinkableMapObj *lmo);//!< Autolayout: Move all out of the way
    5.56 +
    5.57 +	// Animation  **experimental**
    5.58 +private slots:
    5.59 +	void animate();						//!< Called by timer to animate stuff
    5.60 +public:
    5.61 +	void startAnimation (const QPointF &start, const QPointF &dest);
    5.62 +	void stopAnimation  (MapObj *mo);
    5.63 +private:	
    5.64 +	QTimer *animationTimer;
    5.65 +	bool animationUse;
    5.66 +	uint animationTicks;
    5.67 +	uint animationInterval;
    5.68 +	int timerId;				// animation timer
    5.69 +	QList <MapObj*> animObjList;// list with animated objects
    5.70 +
    5.71 +////////////////////////////////////////// Selection related 
    5.72 +public:
    5.73 +	LinkableMapObj* getSelection();
    5.74 +	BranchObj* getSelectedBranch();
    5.75 +	bool select (const QString &s);
    5.76 +	QString getSelectString (LinkableMapObj *lmo);
    5.77 +
    5.78 +private:
    5.79 +	QGraphicsScene *mapScene;
    5.80 +	MapEditor *mapEditor;
    5.81 +	QList <MapCenterObj*> mapCenters;
    5.82 +	QString version;	//!< version string saved in vym file
    5.83 +	QString author;
    5.84 +	QString comment;
    5.85 +	QDate date;
    5.86 +};
    5.87 +
    5.88 +
    5.89 +#endif