# HG changeset patch
# User insilmaril
# Date 1216293115 0
# Node ID 394b2f297e1d6f8c141ebba597750914f0c6fb55
# Parent  e37153bea487db698000c8f5a0f880401681131d
Deleting an animated part no longer segfaults

diff -r e37153bea487 -r 394b2f297e1d INSTALL.txt
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/INSTALL.txt	Thu Jul 17 11:11:55 2008 +0000
@@ -0,0 +1,59 @@
+Installation of vym - view your mind
+====================================
+
+Contents
+--------
+
+A) openSUSE 10.2
+B) openSUSE 10.3 and 11.0
+C) Mac OS X 10.3+
+
+More systems like Debian are likely to be added later. Please
+send feedback about installation on your Operating System to
+vym@InSilmaril.de
+
+For general questions please contact the vym mailinglist:
+
+	vym-forum@lists.sourceforge.net
+
+
+A) openSUSE 10.2
+================
+
+vym needs a newer version of Trolltechs Qt libraries than the one on the
+10.2 installation media. This new version can be installed easily in
+YaST:
+
+	- Select "Installation Source"
+	- Add a HTTP source:
+		        Server: repos.opensuse.org
+		     Directory: /KDE:/Qt/openSUSE_10.2/
+		Authentication: Anonymous
+
+	- Select "Software Management"
+	- Search for "libqt4"
+	- Install all found packages. (They have a version >= 4.3.0-55.1)
+
+B) openSUSE 10.2 and later
+==========================
+
+Get the rpms e.g. from here:
+
+http://download.opensuse.org/repositories/home://insilmaril/
+
+and install the (as root):
+
+yast -i vym-[VERSION].rpm
+
+C) Mac OS X 10.3+
+=================
+
+After opening the disk image vym-1.9.0.dmg you can copy vym.app to
+/Applications. This will need administrator rights.
+
+
+This release of vym includes the Qt libraries. For more information on
+Qt see http://www.trolltech.com.
+		
+
+
diff -r e37153bea487 -r 394b2f297e1d branchobj.cpp
--- a/branchobj.cpp	Thu Jul 17 09:27:20 2008 +0000
+++ b/branchobj.cpp	Thu Jul 17 11:11:55 2008 +0000
@@ -1,12 +1,16 @@
 #include "branchobj.h"
-#include "texteditor.h"
+
+// #include "texteditor.h"
+#include "geometry.h"
 #include "mapeditor.h"
 #include "mainwindow.h"
+#include "misc.h"
+
+class TextEditor;
 
 extern TextEditor *textEditor;
 extern Main *mainWindow;
 extern FlagRowObj *standardFlagsDefault;
-extern QAction *actionEditOpenURL;
 
 
 /////////////////////////////////////////////////////////////////
@@ -14,6 +18,7 @@
 /////////////////////////////////////////////////////////////////
 
 BranchObj* BranchObj::itLast=NULL;
+BranchObj* BranchObj::itFirst=NULL;
 
 
 BranchObj::BranchObj () :OrnamentedObj()
@@ -24,39 +29,50 @@
     depth=-1;
 }
 
-BranchObj::BranchObj (QCanvas* c):OrnamentedObj (c)
+BranchObj::BranchObj (QGraphicsScene* s):OrnamentedObj (s)
 {
-//    cout << "Const BranchObj (c)  called from MapCenterObj (c)\n";
-    canvas=c;
+//    cout << "Const BranchObj (s)  called from MapCenterObj (s)\n";
+	parObj=NULL;
+    scene=s;
 }
 
-BranchObj::BranchObj (QCanvas* c, LinkableMapObj* p):OrnamentedObj (c)
+BranchObj::BranchObj (QGraphicsScene* s, LinkableMapObj* p):OrnamentedObj (s)
 {
-//    cout << "Const BranchObj (c,p)\n";
-    canvas=c;
+//    cout << "Const BranchObj (s,p)\n";
+    scene=s;
     setParObj (p);	
     depth=p->getDepth()+1;
 	if (depth==1)
 		// Calc angle to mapCenter if I am a mainbranch
 		// needed for reordering the mainbranches clockwise 
 		// around mapcenter 
-		angle=getAngle (QPoint ((int)(x() - parObj->getChildPos().x() ), 
-								(int)(y() - parObj->getChildPos().y() ) ) );
+		angle=getAngle (QPointF (x() - parObj->getChildPos().x() , 
+								(y() - parObj->getChildPos().y() ) ) );
     init();
 }
 
 BranchObj::~BranchObj ()
 {
-    //cout << "Destr BranchObj\n";
+	// If I'm animated, I need to un-animate myself first
+	if (anim.isAnimated() )
+	{
+		anim.setAnimated (false);
+		mapEditor->getModel()->stopAnimation (this);
+	}
+
+
+	//cout << "Destr BranchObj of "<<this<<endl;
 	// Check, if this branch was the last child to be deleted
 	// If so, unset the scrolled flags
 
-	BranchObj *po=(BranchObj*)(parObj);
+	BranchObj *po=(BranchObj*)parObj;
+	BranchObj *bo;
 	if (po)
 	{
-		BranchObj *bo=((BranchObj*)(parObj))->getLastBranch();
-		if (!bo) po->unScroll();
+		bo=((BranchObj*)parObj)->getLastBranch();
+		if (bo) po->unScroll();
 	}
+	clear();
 }
 
 bool BranchObj::operator< ( const BranchObj & other )
@@ -69,40 +85,23 @@
     return angle == other.angle;
 }
 
-int BranchObjPtrList::compareItems ( QPtrCollection::Item i, QPtrCollection::Item j)
-{
-	// Make sure PtrList::find works
-	if (i==j) return 0;
-
-	if ( ((BranchObj*)(i))->angle > ((BranchObj*)(j))->angle )
-		return 1;
-	else
-		return -1;
-}
-
 void BranchObj::init () 
 {
-    branch.setAutoDelete (true);
-    floatimage.setAutoDelete (true);
+	if (parObj)
+	{
+		absPos=getRandPos();
+		absPos+=parObj->getChildPos();
+	}
 
-	absPos=getRandPos();
-	absPos+=parObj->getChildPos();
-
-    // TODO This should be done in TextObj later
-    QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
-//    font.setPointSize(12);
-   heading->setFont(font );
-//    heading->setText(QObject::tr("new branch"));
-
-    lastSelectedBranch=-1;
+    lastSelectedBranch=0;
 
     setChildObj(this);
 
 	scrolled=false;
 	tmpUnscrolled=false;
 
-	url="";
-	vymLink="";
+	includeImagesVer=false;
+	includeImagesHor=false;
 }
 
 void BranchObj::copy (BranchObj* other)
@@ -110,24 +109,18 @@
     OrnamentedObj::copy(other);
 
 	branch.clear();
-    BranchObj* b;
-    for (b=other->branch.first(); b;b=other->branch.next() ) 
+	for (int i=0; i<other->branch.size(); ++i)
 		// Make deep copy of b
 		// Because addBranch again calls copy for the childs,
 		// Those will get a deep copy, too
-		addBranch(b);	
+		addBranch(other->branch.at(i) );	
 
-	FloatImageObj *fi;
-	for (fi=other->floatimage.first(); fi;fi=other->floatimage.next() )
-		addFloatImage (fi);
-
+	for (int i=0; i<other->floatimage.size(); ++i)
+		addFloatImage  (other->floatimage.at(i));
 	scrolled=other->scrolled;
 	tmpUnscrolled=other->tmpUnscrolled;
 	setVisibility (other->visible);
 
-	url=other->url;
-	vymLink=other->vymLink;
-
 	angle=other->angle;
 
     positionBBox();
@@ -135,26 +128,42 @@
 
 void BranchObj::clear() 
 {
-	branch.clear();
-	floatimage.clear();
+	setVisibility (true);
+
+	while (!floatimage.isEmpty())
+		delete floatimage.takeFirst();
+
+	while (!xlink.isEmpty())
+		delete xlink.takeFirst();
+
+	while (!branch.isEmpty())
+		delete branch.takeFirst();
+}
+
+bool isAbove (BranchObj* a, BranchObj *b)
+{
+	if (a->angle < b->angle)
+		return true;
+	else	
+		return false;
 }
 
 int BranchObj::getNum()
 {
 	if (parObj)
-		return ((BranchObj*)(parObj))->getNum ((BranchObj*)(this));
+		return ((BranchObj*)parObj)->getNum (this);
 	else
 		return 0;
 }
 
 int BranchObj::getNum(BranchObj *bo)
 {
-	return branch.findRef (bo);
+	return branch.indexOf (bo);
 }
 
 int BranchObj::getFloatImageNum(FloatImageObj *fio)
 {
-	return floatimage.findRef (fio);
+	return floatimage.indexOf(fio);
 }
 
 int BranchObj::countBranches()
@@ -167,7 +176,12 @@
 	return floatimage.count();
 }
 
-void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPoint m, int off)
+int BranchObj::countXLinks()
+{
+	return xlink.count();
+}
+
+void BranchObj::setParObjTmp(LinkableMapObj* lmo, QPointF m, int off)
 {
 	// Temporary link to lmo
 	// m is position of mouse pointer 
@@ -181,19 +195,10 @@
 	// ignore mapcenter and mainbranch
 	if (lmo->getDepth()<2) off=0;
 	if (off==0)
-	{
 		link2ParPos=false;
-		parObj=o;
-	}	
 	else
-	{	
 		link2ParPos=true;
-		if (off>0)
-			parObj=o->getParObj();
-		else	
-			parObj=o->getParObj();
-		parObj=o;
-	}		
+	parObj=o;
 
 	depth=parObj->getDepth()+1;
 
@@ -207,17 +212,17 @@
 	if (depth==1)
 	{	// new parent is the mapcenter itself
 
-		QPoint p= normalise ( QPoint (m.x() - o->getChildPos().x(),
+		QPointF p= normalise ( QPointF (m.x() - o->getChildPos().x(),
 									  m.y() - o->getChildPos().y() ));
 		if (p.x()<0) p.setX( p.x()-bbox.width() );
 		move2RelPos (p);
 	} else
 	{	
-		int y;
+		qreal y;
 		if (off==0)
 		{
 			// new parent is just a branch, link to it
-			QRect t=o->getBBoxSizeWithChilds();
+			QRectF t=o->getBBoxSizeWithChilds();
 			if (o->getLastBranch())
 				y=t.y() + t.height() ;
 			else
@@ -235,14 +240,14 @@
 				// Don't try to find that branch, guess 12 pixels
 				y=o->getChildPos().y()  -height() + 12; 
 		}	
-		if (o->getOrientation()==OrientLeftOfCenter)
+		if (o->getOrientation()==LinkableMapObj::LeftOfCenter)
 			move ( o->getChildPos().x() - linkwidth, y );
 		else	
 			move (o->getChildPos().x() + linkwidth, y );
 	}	
 
 	// updateLink is called implicitly in move
-	reposition();	// FIXME shouldn't be this a request?
+	requestReposition();	
 }
 
 void BranchObj::unsetParObjTmp()
@@ -254,6 +259,7 @@
 		parObjTmpBuf=NULL;
 		depth=parObj->getDepth()+1;
 		setLinkStyle (getDefLinkStyle() );
+		updateLink();
 	}		
 }
 
@@ -265,23 +271,18 @@
 
 void BranchObj::toggleScroll()
 {
-	BranchObj *bo;
 	if (scrolled)
 	{
 		scrolled=false;
 		systemFlags->deactivate("scrolledright");
-		for (bo=branch.first(); bo; bo=branch.next() )
-		{
-			bo->setVisibility(true);
-		}
+		for (int i=0; i<branch.size(); ++i)
+			branch.at(i)->setVisibility(true);
 	} else
 	{
 		scrolled=true;
 		systemFlags->activate("scrolledright");
-		for (bo=branch.first(); bo; bo=branch.next() )
-		{
-			bo->setVisibility(false);
-		}
+		for (int i=0; i<branch.size(); ++i)
+			branch.at(i)->setVisibility(false);
 	}
 	calcBBoxSize();
 	positionBBox();	
@@ -350,18 +351,19 @@
 		standardFlags->setVisibility(v);
 		LinkableMapObj::setVisibility (v);
 		
+		// Only change childs, if I am not scrolled
 		if (!scrolled && (depth < toDepth))
 		{
 			// Now go recursivly through all childs
-			BranchObj* b;
-			for (b=branch.first(); b;b=branch.next() ) 
-				b->setVisibility (v,toDepth);	
-			FloatImageObj *fio;
-			for (fio=floatimage.first(); fio; fio=floatimage.next())
-				fio->setVisibility (v);
+			int i;
+			for (i=0; i<branch.size(); ++i)
+				branch.at(i)->setVisibility (v,toDepth);	
+			for (i=0; i<floatimage.size(); ++i)
+				floatimage.at(i)->setVisibility (v);
+			for (i=0; i<xlink.size(); ++i)	
+				xlink.at(i)->setVisibility ();	
 		}
     } // depth <= toDepth	
-	move (absPos.x(), absPos.y() );
 	requestReposition();
 }	
 
@@ -376,53 +378,60 @@
 	// Overloaded from LinkableMapObj
 	// BranchObj can use color of heading
 
-	if (mapEditor->getLinkColorHint()==HeadingColor)
-		LinkableMapObj::setLinkColor (heading->getColor() );
-	else	
-		LinkableMapObj::setLinkColor ();
+	if (mapEditor)
+	{
+		if (mapEditor->getMapLinkColorHint()==HeadingColor)
+			LinkableMapObj::setLinkColor (heading->getColor() );
+		else	
+			LinkableMapObj::setLinkColor ();
+	}		
 }
 
-void BranchObj::setColor (QColor col, bool colorChilds)
+void BranchObj::setColorSubtree(QColor col)
 {
-    heading->setColor(col);
-	setLinkColor();
-    if (colorChilds) 
-    {
-		BranchObj *bo;
-		for (bo=branch.first(); bo; bo=branch.next() )
-			bo->setColor(col,colorChilds);
-    }	
+	setColor (col);
+	for (int i=0; i<branch.size(); ++i)
+		branch.at(i)->setColorSubtree(col);
 }
 
-
 BranchObj* BranchObj::first()
 {
 	itLast=NULL;	
+	itFirst=this;
 	return this; 
 }
 	
 BranchObj* BranchObj::next()
 {
+	BranchObj *bo;
 	BranchObj *lmo;
-	BranchObj *bo=branch.first();
-	BranchObj *po=(BranchObj*)(parObj);
+	BranchObj *po=(BranchObj*)parObj;
+
+	if (branch.isEmpty())
+		bo=NULL;
+	else
+		bo=branch.first();
 
 	if (!itLast)
-	{	// We are just beginning at the mapCenter
+	{
+		// no itLast, we are just beginning
 		if (bo) 
 		{
+			// we have childs, return first one
 			itLast=this;
 			return bo;
 		}	
 		else
 		{
-			itLast=NULL;
+			// No childs, so there is no next
+			itLast=this;
 			return NULL;
 		}	
 	}
 
-	if (itLast==parObj)
-	{	// We come from above
+	// We have an itLast
+	if (itLast==po)
+	{	// We come from parent
 		if (bo)
 		{
 			// there are childs, go there
@@ -433,7 +442,7 @@
 		{	// no childs, try to go up again
 			if (po)
 			{
-				// go up
+				// go back to parent and try to find next there
 				itLast=this;
 				lmo=po->next();
 				itLast=this;
@@ -442,22 +451,35 @@
 			}	
 			else
 			{
-				// can't go up, I am mapCenter
+				// can't go up, I am mapCenter, no next
 				itLast=NULL;
 				return NULL;
 			}	
 		}
 	}
 
-	// Try to find last child, we came from, in my own childs
+	// We don't come from parent, but from brother or childs
+
+	// Try to find last child, where we came from, in my own childs
 	bool searching=true;
-	while (bo && searching)
+	int i=0;
+	while (i<branch.size())
 	{
-		if (itLast==bo) searching=false;
-		bo=branch.next();
+		// Try to find itLast in my own childs
+		if (itLast==branch.at(i))
+		{
+			// ok, we come from my own childs
+			if (i<branch.size()-1)
+				bo=branch.at(i+1);
+			 else
+				bo=NULL;
+			searching=false;
+			i=branch.size();
+		} 	
+		++i;	
 	}
 	if (!searching)
-	{	// found lastLMO in my childs
+	{	// found itLast in my childs
 		if (bo)
 		{
 			// found a brother of lastLMO 
@@ -468,6 +490,7 @@
 		{
 			if (po)
 			{
+				if (this==itFirst) return NULL;	// Stop at starting point
 				// go up
 				itLast=this;
 				lmo=po->next();
@@ -484,12 +507,11 @@
 	}
 
 	// couldn't find last child, it must be a nephew of mine
-	bo=branch.first();
-	if (bo)
+	if (branch.size()>0)
 	{
 		// proceed with my first child
 		itLast=this;	
-		return bo;
+		return branch.first();
 	}	
 	else
 	{
@@ -521,14 +543,22 @@
 	itLast=it;
 }
 
+void BranchObj::positionContents()
+{
+    for (int i=0; i<floatimage.size(); ++i )
+		floatimage.at(i)->reposition();
+	OrnamentedObj::positionContents();
+}
 
 void BranchObj::move (double x, double y)
 {
 	OrnamentedObj::move (x,y);
+    for (int i=0; i<floatimage.size(); ++i )
+		floatimage.at(i)->reposition();
     positionBBox();
 }
 
-void BranchObj::move (QPoint p)
+void BranchObj::move (QPointF p)
 {
 	move (p.x(), p.y());
 }
@@ -536,13 +566,12 @@
 void BranchObj::moveBy (double x, double y)
 {
 	OrnamentedObj::moveBy (x,y);
+	for (int i=0; i<branch.size(); ++i)
+		branch.at(i)->moveBy (x,y);
     positionBBox();
-    BranchObj* b;
-    for (b=branch.first(); b;b=branch.next() ) 
-		b->moveBy (x,y);
 }
-
-void BranchObj::moveBy (QPoint p)
+	
+void BranchObj::moveBy (QPointF p)
 {
 	moveBy (p.x(), p.y());
 }
@@ -550,38 +579,31 @@
 
 void BranchObj::positionBBox()
 {
-
-    heading->positionBBox();
-	systemFlags->positionBBox();
-	standardFlags->positionBBox();
-	// It seems that setting x,y also affects width,height
-	int w_old=bbox.width();
-	int h_old=bbox.height();
-    bbox.setX (absPos.x() );
-	bbox.setY (absPos.y() );
-	bbox.setWidth(w_old);
-	bbox.setHeight(h_old);
-
-
-	setSelBox();
+	QPointF ap=getAbsPos();
+	bbox.moveTopLeft (ap);
+	positionContents();
 
 	// set the frame
-	frame->setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
+	frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
+
+	// Update links to other branches
+	for (int i=0; i<xlink.size(); ++i)
+		xlink.at(i)->updateXLink();
 }
 
 void BranchObj::calcBBoxSize()
 {
-    QSize heading_r=heading->getSize();
-    int heading_w=static_cast <int> (heading_r.width() );
-    int heading_h=static_cast <int> (heading_r.height() );
-    QSize sysflags_r=systemFlags->getSize();
-	int sysflags_h=sysflags_r.height();
-	int sysflags_w=sysflags_r.width();
-    QSize stanflags_r=standardFlags->getSize();
-	int stanflags_h=stanflags_r.height();
-	int stanflags_w=stanflags_r.width();
-    int w;
-    int h;
+    QSizeF heading_r=heading->getSize();
+    qreal heading_w=(qreal) heading_r.width() ;
+    qreal heading_h=(qreal) heading_r.height() ;
+    QSizeF sysflags_r=systemFlags->getSize();
+	qreal sysflags_h=sysflags_r.height();
+	qreal sysflags_w=sysflags_r.width();
+    QSizeF stanflags_r=standardFlags->getSize();
+	qreal stanflags_h=stanflags_r.height();
+	qreal stanflags_w=stanflags_r.width();
+    qreal w;
+    qreal h;
 
 	// set width to sum of all widths
 	w=heading_w + sysflags_w + stanflags_w;
@@ -589,106 +611,186 @@
 	h=max (sysflags_h,stanflags_h);
 	h=max (h,heading_h);
 
-    w+=frame->getBorder();
-    h+=frame->getBorder();
-    bbox.setSize (QSize (w,h));
+	// Save the dimension of flags and heading
+	ornamentsBBox.setSize ( QSizeF(w,h));
+
+	// clickBox includes Flags and Heading
+    clickBox.setSize (ornamentsBBox.size() );
+
+	// Floatimages 
+	QPointF rp;
+
+	topPad=botPad=leftPad=rightPad=0;
+	if (includeImagesVer || includeImagesHor)
+	{
+		if (countFloatImages()>0)
+		{
+			for (int i=0; i<floatimage.size(); ++i )
+			{
+				rp=floatimage.at(i)->getRelPos();
+				if (includeImagesVer)
+				{
+					if (rp.y() < 0) 
+						topPad=max (topPad,-rp.y()-h);
+					if (rp.y()+floatimage.at(i)->height() > 0)
+						botPad=max (botPad,rp.y()+floatimage.at(i)->height());
+				}		
+				if (includeImagesHor)
+				{
+					if (orientation==LinkableMapObj::RightOfCenter)
+					{
+						if (-rp.x()-w > 0) 
+							leftPad=max (leftPad,-rp.x()-w);
+						if (rp.x()+floatimage.at(i)->width() > 0)
+							rightPad=max (rightPad,rp.x()+floatimage.at(i)->width());
+					} else
+					{
+						if (rp.x()< 0) 
+							leftPad=max (leftPad,-rp.x());
+						if (rp.x()+floatimage.at(i)->width() > w)
+							rightPad=max (rightPad,rp.x()+floatimage.at(i)->width()-w);
+					}
+				}		
+			}	
+		}	
+		h+=topPad+botPad;
+		w+=leftPad+rightPad;
+	}
+
+	// Frame thickness
+    w+=frame->getPadding();
+    h+=frame->getPadding();
+	
+	// Finally set size
+    bbox.setSize (QSizeF (w,h));
 }
 
-LinkableMapObj* BranchObj::findMapObj(QPoint p, LinkableMapObj* excludeLMO)
+void BranchObj::setDockPos()
+{
+	// Sets childpos and parpos depending on orientation
+	if (getOrientation()==LinkableMapObj::LeftOfCenter )
+    {
+		childPos=QPointF (
+			ornamentsBBox.bottomLeft().x(), 
+			bottomlineY);
+		parPos=QPointF (
+			ornamentsBBox.bottomRight().x(),
+			bottomlineY);
+    } else
+    {
+		childPos=QPointF (
+			ornamentsBBox.bottomRight().x(), 
+			bottomlineY);
+		parPos=QPointF (
+			ornamentsBBox.bottomLeft().x(),
+			bottomlineY);
+    }
+}
+
+LinkableMapObj* BranchObj::findMapObj(QPointF p, LinkableMapObj* excludeLMO)
 {
 	// Search branches
-    BranchObj *b;
     LinkableMapObj *lmo;
-    for (b=branch.first(); b; b=branch.next() )
+	for (int i=0; i<branch.size(); ++i)
     {	
-		lmo=b->findMapObj(p, excludeLMO);
+		lmo=branch.at(i)->findMapObj(p, excludeLMO);
+		if (lmo != NULL) return lmo;
+    }
+	
+
+	// Search myself
+    if (inBox (p,clickBox) && (this != excludeLMO) && isVisibleObj() ) 
+		return this;
+
+	// Search float images
+    for (int i=0; i<floatimage.size(); ++i )
+		if (inBox(p,floatimage.at(i)->getClickBox()) && 
+			(floatimage.at(i) != excludeLMO) && 
+			floatimage.at(i)->getParObj()!= excludeLMO &&
+			floatimage.at(i)->isVisibleObj() 
+		) return floatimage.at(i);
+
+    return NULL;
+}
+
+LinkableMapObj* BranchObj::findID (QString sid)
+{
+	// Search branches
+    LinkableMapObj *lmo;
+	for (int i=0; i<branch.size(); ++i)
+    {	
+		lmo=branch.at(i)->findID (sid);
 		if (lmo != NULL) return lmo;
     }
 	
 	// Search myself
-    if (inBBox (p) && (this != excludeLMO) && isVisibleObj() ) 
-		return this;
+	if (sid==objID) return this;
 
+
+/*
 	// Search float images
-	FloatImageObj *foi;
-    for (foi=floatimage.first(); foi; foi=floatimage.next() )
-		if (foi->inBBox(p) && (foi != excludeLMO) && foi->getParObj()!= excludeLMO) return foi;
-
+    for (int i=0; i<floatimage.size(); ++i )
+		if (floatimage.at(i)->inBox(p) && 
+			(floatimage.at(i) != excludeLMO) && 
+			floatimage.at(i)->getParObj()!= excludeLMO &&
+			floatimage.at(i)->isVisibleObj() 
+		) return floatimage.at(i);
+*/
     return NULL;
 }
 
 void BranchObj::setHeading(QString s)
 {
-    // Adjusting font size
-    QFont font=heading->getFont();
-	if (depth==0)
-		font.setPointSize(16);
-	else	
-		if (depth>1) 
-			font.setPointSize(10);
-		else
-			font.setPointSize(12);
-    heading->setFont(font);
     heading->setText(s);	// set new heading
 	calcBBoxSize();			// recalculate bbox
     positionBBox();			// rearrange contents
 	requestReposition();
 }
 
-void BranchObj::setURL(QString s)
+void BranchObj::setHideTmp (HideTmpMode mode)
 {
-	url=s;
-	if (!url.isEmpty())
-		systemFlags->activate("url");
-	else	
-		systemFlags->deactivate("url");
-	calcBBoxSize();			// recalculate bbox
-    positionBBox();			// rearrange contents
-	forceReposition();
+	if (mode==HideExport && (hideExport|| hasHiddenExportParent() ) )
+	{
+		// Hide stuff according to hideExport flag and parents
+		setVisibility (false);
+		hidden=true;
+	}else
+	{
+		// Do not hide, but still take care of scrolled status
+		if (hasScrolledParent(this))
+			setVisibility (false);
+		else
+			setVisibility (true);
+		hidden=false;
+	}	
+
+	// And take care of my childs
+	for (int i=0; i<branch.size(); ++i)
+		branch.at(i)->setHideTmp (mode);
 }
 
-QString BranchObj::getURL()
+bool BranchObj::hasHiddenExportParent()
 {
-	return url;
+	// Calls parents recursivly to
+	// find out, if we or parents are temp. hidden
+
+	if (hidden || hideExport) return true;
+
+	BranchObj* bo=(BranchObj*)parObj;
+	if (bo) 
+		return bo->hasHiddenExportParent();
+	else
+		return false;
 }
 
-void BranchObj::setVymLink(QString s)
+QString BranchObj::saveToDir (const QString &tmpdir,const QString &prefix, const QPointF& offset)
 {
-	if (!s.isEmpty())
-	{
-		// We need the relative (from loading) 
-		// or absolute path (from User event)
-		// and build the absolute path.
-		// Note: If we have relative, use path of
-		// current map to build absolute path
-		QDir d(s);
-		if (!d.path().startsWith ("/"))
-		{
-			QString p=mapEditor->getDestPath();
-			int i=p.findRev("/",-1);
-			d.setPath(p.left(i)+"/"+s);
-			d.convertToAbs();
-		}
-		vymLink=d.path();
-		systemFlags->activate("vymLink");
-	}	
-	else	
-	{
-		systemFlags->deactivate("vymLink");
-		vymLink="";
-	}	
-	calcBBoxSize();			// recalculate bbox
-    positionBBox();			// rearrange contents
-	forceReposition();
-}
+	// Cloudy stuff can be hidden during exports
+	if (hidden) return "";
 
-QString BranchObj::getVymLink()
-{
-	return vymLink;
-}
-
-QString BranchObj::saveToDir (const QString &tmpdir,const QString &prefix, const QPoint& offset)
-{
+	// Update of note is usually done while unselecting a branch
+	if (isNoteInEditor) getNoteFromTextEditor();
+	
     QString s,a;
 	QString scrolledAttr;
 	if (scrolled) 
@@ -696,90 +798,192 @@
 	else
 		scrolledAttr="";
 
-	QString posAttr;
-	if (depth<2) posAttr=
-		attribut("absPosX",QString().setNum(absPos.x(),10)) +
-		attribut("absPosY",QString().setNum(absPos.y(),10)); 
-	else
-		posAttr="";
-
-	QString urlAttr;
-	if (!url.isEmpty())
-		urlAttr=attribut ("url",url);
-
-	QString vymLinkAttr;
-	if (!vymLink.isEmpty())
-		vymLinkAttr=attribut ("vymLink",convertToRel(mapEditor->getDestPath(),vymLink) );
-
-	QString frameAttr;
-	if (frame->getFrameType()!=NoFrame)
-		frameAttr=attribut ("frameType",frame->getFrameTypeName());
-	else
-		frameAttr="";
-
 	// save area, if not scrolled
 	QString areaAttr;
 	if (!((BranchObj*)(parObj))->isScrolled() )
 	{
 		areaAttr=
-			attribut("x1",QString().setNum(absPos.x()-offset.x(),10)) +
-			attribut("y1",QString().setNum(absPos.y()-offset.y(),10)) +
-			attribut("x2",QString().setNum(absPos.x()+width()-offset.x(),10)) +
-			attribut("y2",QString().setNum(absPos.y()+height()-offset.y(),10));
+			attribut("x1",QString().setNum(absPos.x()-offset.x())) +
+			attribut("y1",QString().setNum(absPos.y()-offset.y())) +
+			attribut("x2",QString().setNum(absPos.x()+width()-offset.x())) +
+			attribut("y2",QString().setNum(absPos.y()+height()-offset.y()));
 
 	} else
 		areaAttr="";
 	
-    s=beginElement ("branch" +scrolledAttr +posAttr +urlAttr +vymLinkAttr +frameAttr +areaAttr);
+	// Providing an ID for a branch makes export to XHTML easier
+	QString idAttr;
+	if (countXLinks()>0)
+		idAttr=attribut ("id",mapEditor->getModel()->getSelectString(this)); //TODO directly access model
+	else
+		idAttr="";
+
+    s=beginElement ("branch" 
+		+getOrnXMLAttr() 
+		+scrolledAttr 
+		+areaAttr 
+		+idAttr 
+		+getIncludeImageAttr() );
     incIndent();
 
 	// save heading
-    s=s+valueElement("heading", getHeading(),
+    s+=valueElement("heading", getHeading(),
 		attribut ("textColor",QColor(heading->getColor()).name()));
 
+	// Save frame
+	if (frame->getFrameType()!=FrameObj::NoFrame) 
+		s+=frame->saveToDir ();
+
 	// save names of flags set
 	s+=standardFlags->saveToDir(tmpdir,prefix,0);
 	
+	// Save FloatImages
+	for (int i=0; i<floatimage.size(); ++i)
+		s+=floatimage.at(i)->saveToDir (tmpdir,prefix);
+
 	// save note
 	if (!note.isEmpty() )
 		s+=note.saveToDir();
 	
 	// Save branches
-    BranchObj *bo;
-    for (bo=branch.first(); bo; bo=branch.next() )
-		s+=bo->saveToDir(tmpdir,prefix,offset);
+	for (int i=0; i<branch.size(); ++i)
+		s+=branch.at(i)->saveToDir(tmpdir,prefix,offset);
+
+	// Save XLinks
+	QString ol;	// old link
+	QString cl;	// current link
+	for (int i=0; i<xlink.size(); ++i)
+	{
+		cl=xlink.at(i)->saveToDir();
+		if (cl!=ol)
+		{
+			s+=cl;
+			ol=cl;
+		} else
+		{
+			qWarning (QString("Ignoring of duplicate xLink in %1").arg(getHeading()));
+		}
+	}	
+
     decIndent();
-
-	// Save FloatImages
-	FloatImageObj *fio;
-	for (fio=floatimage.first(); fio; fio=floatimage.next() )
-		s+=fio->saveToDir (tmpdir,prefix);
-
     s+=endElement   ("branch");
     return s;
 }
 
-LinkableMapObj* BranchObj::addFloatImage ()
+void BranchObj::addXLink (XLinkObj *xlo)
 {
-	FloatImageObj *newfi=new FloatImageObj (canvas,this);
+	xlink.append (xlo);
+	
+}
+
+void BranchObj::removeXLinkRef (XLinkObj *xlo)
+{
+	xlink.removeAt (xlink.indexOf(xlo));
+}
+
+void BranchObj::deleteXLink(XLinkObj *xlo)
+{
+	xlo->deactivate();
+	if (!xlo->isUsed()) delete (xlo);
+}
+
+void BranchObj::deleteXLinkAt (int i)
+{
+	XLinkObj *xlo=xlink.at(i);
+	xlo->deactivate();
+	if (!xlo->isUsed()) delete(xlo);
+}
+
+XLinkObj* BranchObj::XLinkAt (int i)
+{
+	return xlink.at(i);
+}
+
+int BranchObj::countXLink()
+{
+	return xlink.count();
+}
+
+
+BranchObj* BranchObj::XLinkTargetAt (int i)
+{
+	if (i>=0 && i<xlink.size())
+	{
+		if (xlink.at(i))
+			return xlink.at(i)->otherBranch (this);
+	}
+	return NULL;
+}
+
+void BranchObj::setIncludeImagesVer(bool b)
+{
+	includeImagesVer=b;
+	calcBBoxSize();
+	positionBBox();
+	requestReposition();
+}
+
+bool BranchObj::getIncludeImagesVer()
+{
+	return includeImagesVer;
+}
+
+void BranchObj::setIncludeImagesHor(bool b)
+{
+	includeImagesHor=b;
+	calcBBoxSize();
+	positionBBox();
+	requestReposition();
+}
+
+bool BranchObj::getIncludeImagesHor()
+{
+	return includeImagesHor;
+}
+
+QString BranchObj::getIncludeImageAttr()
+{
+	QString a;
+	if (includeImagesVer)
+		a=attribut ("incImgV","true");
+	else
+		a=attribut ("incImgV","false");
+	if (includeImagesHor)
+		a+=attribut ("incImgH","true");
+	else
+		a+=attribut ("incImgH","false");
+	return a;	
+}
+
+FloatImageObj* BranchObj::addFloatImage ()
+{
+	FloatImageObj *newfi=new FloatImageObj (scene,this);
 	floatimage.append (newfi);
 	if (hasScrolledParent(this) )
 		newfi->setVisibility (false);
 	else	
 		newfi->setVisibility(visible);
+		/*
+	calcBBoxSize();
+	positionBBox();
+	*/
 	requestReposition();
 	return newfi;
 }
 
-LinkableMapObj* BranchObj::addFloatImage (FloatImageObj *fio)
+FloatImageObj* BranchObj::addFloatImage (FloatImageObj *fio)
 {
-	FloatImageObj *newfi=new FloatImageObj (canvas,this);
+	FloatImageObj *newfi=new FloatImageObj (scene,this);
 	floatimage.append (newfi);
 	newfi->copy (fio);
 	if (hasScrolledParent(this) )
 		newfi->setVisibility (false);
 	else	
 		newfi->setVisibility(visible);
+		/*
+	calcBBoxSize();
+	positionBBox();
+	*/
 	requestReposition();
 	return newfi;
 }
@@ -801,62 +1005,92 @@
 
 void BranchObj::removeFloatImage (FloatImageObj *fio)
 {
-	floatimage.remove (fio);
+	int i=floatimage.indexOf (fio);
+	if (i>-1) delete (floatimage.takeAt (i));
+	calcBBoxSize();
+	positionBBox();
 	requestReposition();
 }
 
 void BranchObj::savePosInAngle ()
 {
 	// Save position in angle
-    BranchObj *b;
-	int i=0;
-    for (b=branch.first(); b; b=branch.next() )
+	for (int i=0; i<branch.size(); ++i)
+		branch.at(i)->angle=i;
+}
+
+void BranchObj::setDefAttr (BranchModification mod)
+{
+	int fontsize;
+	switch (depth)
 	{
-		b->angle=i;
-		i++;
-	}
+		case 0: fontsize=16; break;
+		case 1: fontsize=12; break;
+		default: fontsize=10; break;
+	}	
+
+	setLinkColor ();
+	setLinkStyle(getDefLinkStyle());
+	QFont font("Sans Serif,8,-1,5,50,0,0,0,0,0");
+	font.setPointSize(fontsize);
+	heading->setFont(font );
+
+	if (mod==NewBranch)
+		setColor (((BranchObj*)(parObj))->getColor());
+	
+	calcBBoxSize();
 }
 
 BranchObj* BranchObj::addBranch()
 {
-    BranchObj* newbo=new BranchObj(canvas,this);
+    BranchObj* newbo=new BranchObj(scene,this);
     branch.append (newbo);
     newbo->setParObj(this);
-    newbo->setColor(getColor(),false);	
-    newbo->setLinkColor();	
+	newbo->setDefAttr(NewBranch);
     newbo->setHeading ("new");
-	newbo->setLinkStyle (newbo->getDefLinkStyle());
 	if (scrolled)
 		newbo->setVisibility (false);
 	else	
 		newbo->setVisibility(visible);
+	newbo->updateLink();	
 	requestReposition();
 	return newbo;
 }
 
 BranchObj* BranchObj::addBranch(BranchObj* bo)
 {
-    BranchObj* newbo=new BranchObj(canvas,this);
+    BranchObj* newbo=new BranchObj(scene,this);
     branch.append (newbo);
     newbo->copy(bo);
     newbo->setParObj(this);
-	newbo->setHeading (newbo->getHeading());	// adjust fontsize to depth
-	newbo->setLinkStyle (newbo->getDefLinkStyle());
+	newbo->setDefAttr(MovedBranch);
 	if (scrolled)
 		newbo->setVisibility (false);
 	else	
 		newbo->setVisibility(bo->visible);
+	newbo->updateLink();	
 	requestReposition();
 	return newbo;
 }
 
+BranchObj* BranchObj::addBranchPtr(BranchObj* bo)
+{
+	branch.append (bo);
+	bo->setParObj (this);
+	bo->depth=depth+1;
+	bo->setDefAttr(MovedBranch);
+	if (scrolled) tmpUnscroll();
+	setLastSelectedBranch (bo);
+	return bo;
+}
+
 BranchObj* BranchObj::insertBranch(int pos)
 {
 	savePosInAngle();
 	// Add new bo and resort branches
 	BranchObj *newbo=addBranch ();
 	newbo->angle=pos-0.5;
-	branch.sort();
+	qSort (branch.begin(),branch.end(), isAbove);
 	return newbo;
 }
 
@@ -866,133 +1100,288 @@
 	// Add new bo and resort branches
 	bo->angle=pos-0.5;
 	BranchObj *newbo=addBranch (bo);
-	branch.sort();
+	qSort (branch.begin(),branch.end(), isAbove);
 	return newbo;
 }
 
+BranchObj* BranchObj::insertBranchPtr (BranchObj* bo, int pos)
+{
+	savePosInAngle();
+	// Add new bo and resort branches
+	bo->angle=pos-0.5;
+	branch.append (bo);
+	bo->setParObj (this);
+	bo->depth=depth+1;
+	bo->setDefAttr (MovedBranch);
+	if (scrolled) tmpUnscroll();
+	setLastSelectedBranch (bo);
+	qSort (branch.begin(),branch.end(), isAbove);
+	return bo;
+}
+
+void BranchObj::removeBranchHere(BranchObj* borem)
+{
+	// This removes the branch bo from list, but 
+	// inserts its childs at the place of bo
+	BranchObj *bo;
+	bo=borem->getLastBranch();
+	int pos=borem->getNum();
+	while (bo)
+	{
+		bo->linkTo (this,pos+1);
+		bo=borem->getLastBranch();
+	}	
+	removeBranch (borem);
+}
+
+void BranchObj::removeChilds()
+{
+	clear();
+}
+
 void BranchObj::removeBranch(BranchObj* bo)
 {
     // if bo is not in branch remove returns false, we
     // don't care...
-    branch.remove (bo);
+	
+	int i=branch.indexOf(bo);
+    if (i>=0)
+	{
+		delete (bo);
+		branch.removeAt (i);
+	} else
+		qWarning ("BranchObj::removeBranch tried to remove non existing branch?!\n");
+	requestReposition();
+}
+
+void BranchObj::removeBranchPtr(BranchObj* bo)
+{
+	int i=branch.indexOf(bo);
+	
+	if (i>=0)
+		branch.removeAt (i);
+	else	
+		qWarning ("BranchObj::removeBranchPtr tried to remove non existing branch?!\n");
 	requestReposition();
 }
 
 void BranchObj::setLastSelectedBranch (BranchObj* bo)
 {
-    lastSelectedBranch=branch.find(bo);
+    lastSelectedBranch=branch.indexOf(bo);
 }
 
 BranchObj* BranchObj::getLastSelectedBranch ()
 {
-    if (lastSelectedBranch>=0) 
+    if (lastSelectedBranch>=0)
 	{
-		BranchObj* bo=branch.at(lastSelectedBranch);
-		if (bo) return bo;
-    }	
-    return branch.first();
+		if ( branch.size()>lastSelectedBranch) 
+			return branch.at(lastSelectedBranch);
+		if (branch.size()>0)
+			return branch.last();
+	}	
+    return NULL;
 }
 
 BranchObj* BranchObj::getFirstBranch ()
 {
-    return branch.first();
+	if (branch.size()>0)
+		return branch.first();
+	else
+		return NULL;
 }
 
 BranchObj* BranchObj::getLastBranch ()
 {
-    return branch.last();
+	if (branch.size()>0)
+		return branch.last();
+	else
+		return NULL;
 }
 
-BranchObj* BranchObj::getBranchNum (const uint &i)
+BranchObj* BranchObj::getBranchNum (int i)
 {
-    return branch.at(i);
+	if (i>=0 && i<branch.size())
+		return branch.at(i);
+	else	
+		return	NULL;
 }
 
+bool BranchObj::canMoveBranchUp() 
+{
+	if (!parObj || depth==1) return false;
+	BranchObj* par=(BranchObj*)parObj;
+	if (this==par->getFirstBranch())
+		return false;
+	else
+		return true;
+}
 
-BranchObj* BranchObj::moveBranchUp(BranchObj* bo1) // move a branch up (modify myself)
+BranchObj* BranchObj::moveBranchUp(BranchObj* bo1) // modify my childlist
 {
 	savePosInAngle();
-    int i=branch.find(bo1);
+    int i=branch.indexOf(bo1);
     if (i>0) 
 	{	// -1 if bo1 not found 
 		branch.at(i)->angle--;
 		branch.at(i-1)->angle++;
-		branch.sort();
-		return branch.at(i-1);
+		qSort (branch.begin(),branch.end(), isAbove);
+		return branch.at(i);
 	} else
-		return branch.at(i);
+		return NULL;
 }
 
-BranchObj* BranchObj::moveBranchDown(BranchObj* bo1)
+bool BranchObj::canMoveBranchDown() 
+{
+	if (!parObj|| depth==1) return false;
+	BranchObj* par=(BranchObj*)parObj;
+	if (this==par->getLastBranch())
+		return false;
+	else
+		return true;
+}
+
+BranchObj* BranchObj::moveBranchDown(BranchObj* bo1)// modify my childlist
 {
 	savePosInAngle();
-    int i=branch.find(bo1);
+    int i=branch.indexOf(bo1);
 	int j;
-	if (branch.next())
+	if (i <branch.size())
 	{
-		j = branch.at();
+		j = i+1;
 		branch.at(i)->angle++;
 		branch.at(j)->angle--;
-		branch.sort();
-		return branch.at(j);
+		qSort (branch.begin(),branch.end(), isAbove);
+		return branch.at(i);
 	} else
-		return branch.at(i);
+		return NULL;
 }
 
-void BranchObj::alignRelativeTo (QPoint ref)
+void BranchObj::sortChildren()
 {
-/* FIXME testing
-	if (!getHeading().isEmpty())
-		cout << "BO::alignRelTo "<<getHeading()<<endl;
-	else	
-		cout << "BO::alignRelTo  ???"<<endl;
-	cout << "  d="<<depth<<endl;
-*/	
-	int th = bboxTotal.height();	
+	int childCount=branch.count();
+	int curChildIndex;
+	bool madeChanges=false;
+	do
+	{
+		madeChanges=false;
+		for(curChildIndex=1;curChildIndex<childCount;curChildIndex++){
+			BranchObj* curChild=(BranchObj*)branch.at(curChildIndex);
+			BranchObj* prevChild=(BranchObj*)branch.at(curChildIndex-1);
+			if(prevChild->heading->text().compare(curChild->heading->text())>0)
+			{
+				this->moveBranchUp(curChild);
+				madeChanges=true;
+			}
+		}
+	}while(madeChanges);
+}
 
-	// If I am the mapcenter or a mainbranch, reposition heading
+
+BranchObj* BranchObj::linkTo (BranchObj* dst, int pos)
+{
+	// Find current parent and 
+	// remove pointer to myself there
+	if (!dst) return NULL;
+	BranchObj *par=(BranchObj*)parObj;
+	if (par)
+		par->removeBranchPtr (this);
+	else
+		return NULL;
+
+	// Create new pointer to myself at dst
+	if (pos<0||dst->getDepth()==0)
+	{	
+		// links myself as last branch at dst
+		dst->addBranchPtr (this);
+		updateLink();
+		return this;
+	} else
+	{
+		// inserts me at pos in parent of dst
+		if (par)
+		{
+			BranchObj *bo=dst->insertBranchPtr (this,pos);
+			bo->setDefAttr(MovedBranch);
+			updateLink();
+			return bo;
+
+		} else
+			return NULL;
+	}	
+}
+
+void BranchObj::alignRelativeTo (QPointF ref)
+{
+	qreal th = bboxTotal.height();	
+// TODO testing
+/*
+	QPointF pp; if (parObj) pp=parObj->getChildPos();
+	cout << "BO::alignRelTo "<<qPrintable (getHeading());
+	cout << "    d="<<depth<<
+		"  ref="<<ref<<
+//		"  bbox.topLeft="<<bboxTotal.topLeft()<<
+		"  absPos="<<absPos<<
+		"  relPos="<<relPos<<
+		"  parPos="<<pp<<
+		"  orient="<<orientation<<
+//		"  pad="<<topPad<<","<<botPad<<","<<leftPad<<","<<rightPad<<
+//		"  hidden="<<hidden<<
+//		"  th="<<th<<
+		endl;
+*/
+
+	setOrientation();
+	//updateLink();
+
 	if (depth<2)
 	{
-		move (absPos.x(),absPos.y());
 		if (depth==1)
 		{
+			// Position relatively, if needed
+			//if (useRelPos) move2RelPos (relPos.x(), relPos.y());
+
 			// Calc angle to mapCenter if I am a mainbranch
 			// needed for reordering the mainbranches clockwise 
 			// around mapcenter 
-			angle=getAngle (QPoint ((int)(x() - parObj->getChildPos().x() ), 
+			angle=getAngle (QPointF ((int)(x() - parObj->getChildPos().x() ), 
 									(int)(y() - parObj->getChildPos().y() ) ) );
-		}	
+		}							
 	} 
 	else
     {
 		// Align myself depending on orientation and parent, but
-		// only if I am not the mainbranch or mapcenter itself
-		switch (orientation) 
+		// only if I am not a mainbranch or mapcenter itself
+
+		if (anim.isAnimated())
 		{
-			case OrientLeftOfCenter:
-				move (ref.x()-bbox.width(), ref.y() + (th-bbox.height())/2 );
-			break;
-			case OrientRightOfCenter:	
-				move (ref.x(), ref.y() + (th-bbox.height())/2 );
-			break;
-			default:
-				cout <<"LMO::alignRelativeTo: oops, no orientation given...\n";
-			break;
-		}		
+			move2RelPos(anim);
+		} else
+		{
+			LinkableMapObj::Orientation o;
+			o=parObj->getOrientation();
+			switch (orientation) 
+			{
+				case LinkableMapObj::LeftOfCenter:
+					move (ref.x() - bbox.width(), ref.y() + (th-bbox.height())/2 );
+				break;
+				case LinkableMapObj::RightOfCenter:	
+					move (ref.x() , ref.y() + (th-bbox.height())/2  );
+				break;
+				default:
+					qWarning ("LMO::alignRelativeTo: oops, no orientation given...");
+				break;
+			}	
+		}
     }		
 
-	FloatImageObj *fio;
-    for (fio=floatimage.first(); fio; fio=floatimage.next() )
-		fio->reposition();
-
 	if (scrolled) return;
 
     // Set reference point for alignment of childs
-    QPoint ref2;
-    if (orientation==OrientLeftOfCenter)
-		ref2.setX(childPos.x() - linkwidth);
+    QPointF ref2;
+    if (orientation==LinkableMapObj::LeftOfCenter)
+		ref2.setX(bbox.topLeft().x() - linkwidth);
     else	
-		ref2.setX(childPos.x() + linkwidth);
+		ref2.setX(bbox.topRight().x() + linkwidth);
 
 	if (depth==1)
 		ref2.setY(absPos.y()-(bboxTotal.height()-bbox.height())/2);
@@ -1000,73 +1389,111 @@
 		ref2.setY(ref.y() );	
 
     // Align the childs depending on reference point 
-    BranchObj *b;
-    for (b=branch.first(); b; b=branch.next() )
+	for (int i=0; i<branch.size(); ++i)
     {	
-		b->alignRelativeTo (ref2);
-		ref2.setY(ref2.y() + b->getBBoxSizeWithChilds().height() );
+		if (!branch.at(i)->isHidden())
+		{
+			branch.at(i)->alignRelativeTo (ref2);
+			ref2.setY(ref2.y() + branch.at(i)->getBBoxSizeWithChilds().height() );
+		}
     }
 }
 
 
 void BranchObj::reposition()
 {	
-/* FIXME testing
+/* TODO testing only
 	if (!getHeading().isEmpty())
-		cout << "BO::reposition  "<<getHeading()<<endl;
+		cout << "BO::reposition  "<<qPrintable(getHeading())<<endl;
 	else	
 		cout << "BO::reposition  ???"<<endl;
+
+	cout << "  orient="<<orientation<<endl;
 */		
+
 	if (depth==0)
 	{
 		// only calculate the sizes once. If the deepest LMO 
 		// changes its height,
 		// all upper LMOs have to change, too.
 		calcBBoxSizeWithChilds();
-	    alignRelativeTo ( QPoint (absPos.x(),
+		updateLink();	// This update is needed if the scene is resized 
+						// due to excessive moving of a FIO
+
+	    alignRelativeTo ( QPointF (absPos.x(),
 			absPos.y()-(bboxTotal.height()-bbox.height())/2) );
-		branch.sort();	
+		qSort (branch.begin(),branch.end(), isAbove);
+		positionBBox();	// Reposition bbox and contents
 	} else
 	{
 		// This is only important for moving branches:
 		// For editing a branch it isn't called...
-	    alignRelativeTo ( QPoint (absPos.x(),
+	    alignRelativeTo ( QPointF (absPos.x(),
 							absPos.y()-(bboxTotal.height()-bbox.height())/2) );
 	}
 }
 
+void BranchObj::unsetAllRepositionRequests()
+{
+	repositionRequest=false;
+	for (int i=0; i<branch.size(); ++i)
+		branch.at(i)->unsetAllRepositionRequests();
+}
 
-QRect BranchObj::getTotalBBox()
+
+QPolygonF BranchObj::shape()
 {
-	QRect r=bbox;
+	QPolygonF p;
+
+	QRectF r=getTotalBBox();
+	if (orientation==LinkableMapObj::LeftOfCenter)
+		p   <<r.bottomLeft()
+			<<r.topLeft()
+			<<QPointF (bbox.topLeft().x(), r.topLeft().y() )
+			<<bbox.topRight()
+			<<bbox.bottomRight()
+			<<QPointF (bbox.bottomLeft().x(), r.bottomLeft().y() ) ;
+	else		
+		p   <<r.bottomRight()
+			<<r.topRight()
+			<<QPointF (bbox.topRight().x(), r.topRight().y() )
+			<<bbox.topLeft()
+			<<bbox.bottomLeft()
+			<<QPointF (bbox.bottomRight().x(), r.bottomRight().y() ) ;
+	return p;
+}
+
+QRectF BranchObj::getTotalBBox()
+{
+	QRectF r=bbox;
 
 	if (scrolled) return r;
 
-	BranchObj* b;
-	for (b=branch.first();b ;b=branch.next() )
-		r=addBBox(b->getTotalBBox(),r);
+	for (int i=0; i<branch.size(); ++i)
+		if (!branch.at(i)->isHidden())
+			r=addBBox(branch.at(i)->getTotalBBox(),r);
 
-	FloatImageObj* fio;
-	for (fio=floatimage.first();fio ;fio=floatimage.next() )
-		r=addBBox(fio->getTotalBBox(),r);
+	for (int i=0; i<floatimage.size(); ++i)
+		if (!floatimage.at(i)->isHidden())
+			r=addBBox(floatimage.at(i)->getTotalBBox(),r);
 		
 	return r;
 }
 
-QRect BranchObj::getBBoxSizeWithChilds()
+QRectF BranchObj::getBBoxSizeWithChilds()
 {
 	return bboxTotal;
 }
 
 void BranchObj::calcBBoxSizeWithChilds()
-{
-	// This is called only from reposition and
+{	
+	// This is initially called only from reposition and
 	// and only for mapcenter. So it won't be
 	// called more than once for a single user 
 	// action
 	
+
 	// Calculate size of LMO including all childs (to align them later)
-
 	bboxTotal.setX(bbox.x() );
 	bboxTotal.setY(bbox.y() );
 
@@ -1078,20 +1505,38 @@
 		return;
 	}
 	
-	QRect r(0,0,0,0);
-	QRect br;
+	if (hidden)
+	{
+		bboxTotal.setWidth (0);
+		bboxTotal.setHeight(0);
+		if (parObj)
+		{
+			bboxTotal.setX (parObj->x());
+			bboxTotal.setY (parObj->y());
+		} else
+		{
+			bboxTotal.setX (bbox.x());
+			bboxTotal.setY (bbox.y());
+		}
+		return;
+	}
+	
+	QRectF r(0,0,0,0);
+	QRectF br;
 	// Now calculate recursivly
 	// sum of heights 
 	// maximum of widths 
 	// minimum of y
-	BranchObj* b;
-	for (b=branch.first();b ;b=branch.next() )
+	for (int i=0; i<branch.size(); ++i)
 	{
-		b->calcBBoxSizeWithChilds();
-		br=b->getBBoxSizeWithChilds();
-		r.setWidth( max (br.width(), r.width() ));
-		r.setHeight(br.height() + r.height() );
-		if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
+		if (!branch.at(i)->isHidden())
+		{
+			branch.at(i)->calcBBoxSizeWithChilds();
+			br=branch.at(i)->getBBoxSizeWithChilds();
+			r.setWidth( max (br.width(), r.width() ));
+			r.setHeight(br.height() + r.height() );
+			if (br.y()<bboxTotal.y()) bboxTotal.setY(br.y());
+		}
 	}
 	// Add myself and also
 	// add width of link to sum if necessary
@@ -1099,13 +1544,25 @@
 		bboxTotal.setWidth (bbox.width() + r.width() );
 	else	
 		bboxTotal.setWidth (bbox.width() + r.width() + linkwidth);
-	bboxTotal.setHeight(max (r.height(),  bbox.height() ) );
-//	frame->setRect(QRect(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
+	
+	bboxTotal.setHeight(max (r.height(),  bbox.height()));
 }
 
 void BranchObj::select()
 {
+	// update NoteEditor
+	textEditor->setText(note.getNote() );
+	QString fnh=note.getFilenameHint();
+	if (fnh!="")
+		textEditor->setFilenameHint(note.getFilenameHint() );
+	else	
+		textEditor->setFilenameHint(getHeading() );
+	textEditor->setFontHint (note.getFontHint() );
+	isNoteInEditor=true;
+
+	// set selected and visible
     LinkableMapObj::select();
+
 	// Tell parent that I am selected now:
 	BranchObj* po=(BranchObj*)(parObj);
     if (po)	// TODO	    Try to get rid of this cast...
@@ -1114,13 +1571,6 @@
 	// temporary unscroll, if we have scrolled parents somewhere
 	if (parObj) ((BranchObj*)(parObj))->tmpUnscroll();
 
-	// set Text in Editor	
-	textEditor->setText(note.getNote() );
-	textEditor->setFilename(note.getFilenameHint() );
-	textEditor->setFontHint (note.getFontHint() );
-	connect (textEditor, SIGNAL (textHasChanged() ), this, SLOT (updateNoteFlag() ) ); 
-	connect (textEditor, SIGNAL (fontSizeHasChanged() ), this, SLOT (updateNoteFlag() ) ); 
-
 	// Show URL and link in statusbar
 	QString status;
 	if (!url.isEmpty()) status+="URL: "+url+"  ";
@@ -1128,15 +1578,9 @@
 	if (!status.isEmpty()) mainWindow->statusMessage (status);
 
 	// Update Toolbar
-	standardFlags->updateToolBar();
+	updateFlagsToolbar();
 
-	// Update Browserbutton
-	if (!url.isEmpty())
-		actionEditOpenURL->setEnabled (true);
-	else	
-		actionEditOpenURL->setEnabled (false);
-
-	// Update actions in mapeditor
+	// Update actions
 	mapEditor->updateActions();
 }
 
@@ -1146,39 +1590,38 @@
 	// Delete any messages like vymLink in StatusBar
 	mainWindow->statusMessage ("");
 
-	// save note from editor and set flag
-	// text is done by updateNoteFlag(), just save
-	// filename here
-	note.setFilenameHint (textEditor->getFilename());
+	// Save current note
+	if (isNoteInEditor) getNoteFromTextEditor();
+	isNoteInEditor=false;
 
 	// reset temporary unscroll, if we have scrolled parents somewhere
 	if (parObj) ((BranchObj*)(parObj))->resetTmpUnscroll();
 
-	// Disconnect textEditor from this LMO
-	disconnect( textEditor, SIGNAL(textHasChanged()), 0, 0 );
-	disconnect( textEditor, SIGNAL (fontSizeHasChanged()),0,0 ); 
-
 	// Erase content of editor 
 	textEditor->setInactive();
 
 	// unselect all buttons in toolbar
-	standardFlagsDefault->updateToolBar();
+	standardFlagsDefault->updateToolbar();
 }
 
 QString BranchObj::getSelectString()
 {
-	QString s;
-	if (parObj)
-	{
-		if (parObj->getDepth()==0)
-			s= "bo:" + QString("%1").arg(getNum());
-		else	
-			s= ((BranchObj*)(parObj))->getSelectString() + ",bo:" + QString("%1").arg(getNum());
-	} else
-	{
-		s="mc:";
-	}
-	
-	return s;
+	return mapEditor->getModel()->getSelectString (this);
 }
 
+void BranchObj::setAnimation(const AnimPoint &ap)
+{
+	anim=ap;
+}
+
+bool BranchObj::animate()
+{
+	anim.animate ();
+	if ( anim.isAnimated() )
+	{
+		setRelPos (anim);
+		return true;
+	}
+	return false;
+}
+
diff -r e37153bea487 -r 394b2f297e1d tex/vym.changelog
--- a/tex/vym.changelog	Thu Jul 17 09:27:20 2008 +0000
+++ b/tex/vym.changelog	Thu Jul 17 11:11:55 2008 +0000
@@ -1,6 +1,7 @@
 -------------------------------------------------------------------
-Thu Jul 17 11:25:39 CEST 2008 - uwedr@suse.de
+Thu Jul 17 13:11:39 CEST 2008 - uwedr@suse.de
 
+- Bugfix: Deleting an animated part no longer segfaults
 - Bugfix: smaller image for export to elliminate pixel jitter on right
           side 
 
diff -r e37153bea487 -r 394b2f297e1d vymmodel.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vymmodel.cpp	Thu Jul 17 11:11:55 2008 +0000
@@ -0,0 +1,395 @@
+#include <QApplication>
+#include <typeinfo>
+
+#include "geometry.h"		// for addBBox
+#include "vymmodel.h"
+
+
+extern Settings settings;
+
+VymModel::VymModel() 
+{
+//    cout << "Const VymModel\n";
+}
+
+
+VymModel::~VymModel() 
+{
+//    cout << "Destr VymModel\n";
+}	
+
+void VymModel::clear() 
+{
+	while (!mapCenters.isEmpty())
+		delete mapCenters.takeFirst();
+}
+
+void VymModel::init () 
+{
+	addMapCenter();
+
+	// animations
+	animationUse=settings.readBoolEntry("/animation/use",false);
+	animationTicks=settings.readNumEntry("/animation/ticks",10);
+	animationInterval=settings.readNumEntry("/animation/interval",50);
+	animObjList.clear();
+	animationTimer=new QTimer (this);
+	connect(animationTimer, SIGNAL(timeout()), this, SLOT(animate()));
+
+}
+
+void VymModel::setMapEditor(MapEditor *me)
+{
+	mapEditor=me;
+	for (int i=0; i<mapCenters.count(); i++)
+		mapCenters.at(i)->setMapEditor(mapEditor);
+}
+
+MapEditor* VymModel::getMapEditor()
+{
+	return mapEditor;
+}
+
+void VymModel::setVersion (const QString &s)
+{
+	version=s;
+}
+
+void VymModel::setAuthor (const QString &s)
+{
+	author=s;
+}
+
+QString VymModel::getAuthor()
+{
+	return author;
+}
+
+void VymModel::setComment (const QString &s)
+{
+	comment=s;
+}
+
+QString VymModel::getComment ()
+{
+	return comment;
+}
+
+QString VymModel::getDate ()
+{
+	return QDate::currentDate().toString ("yyyy-MM-dd");
+}
+
+void VymModel::setScene (QGraphicsScene *s)
+{
+	mapScene=s;
+    init();	// Here we have a mapScene set, 
+			// which is (still) needed to create MapCenters
+}
+
+QGraphicsScene* VymModel::getScene ()
+{
+	return mapScene;
+}
+
+MapCenterObj* VymModel::addMapCenter()
+{
+	return addMapCenter (QPointF(0,0));
+}
+
+MapCenterObj* VymModel::addMapCenter(QPointF absPos)
+{
+	MapCenterObj *mapCenter = new MapCenterObj(mapScene);
+	mapCenter->move (absPos);
+    mapCenter->setVisibility (true);
+	mapCenter->setHeading (QApplication::translate("Heading of mapcenter in new map", "New map"));
+	mapCenter->setMapEditor(mapEditor);		//FIXME needed to get defLinkStyle, mapLinkColorHint ... for later added objects
+	mapCenters.append(mapCenter);
+	return mapCenter;
+}
+
+MapCenterObj *VymModel::removeMapCenter(MapCenterObj* mco)
+{
+	int i=mapCenters.indexOf (mco);
+	if (i>=0)
+	{
+		mapCenters.removeAt (i);
+		delete (mco);
+		if (i>0) return mapCenters.at(i-1);	// Return previous MCO
+	}
+	return NULL;
+}
+
+BranchObj* VymModel::first()
+{
+	if (mapCenters.count()>0) 
+		return mapCenters.first();
+	else	
+		return NULL;
+}
+	
+BranchObj* VymModel::next(BranchObj *bo_start)
+{
+	BranchObj *rbo;
+	BranchObj *bo=bo_start;
+	if (bo)
+	{
+		// Try to find next branch in current MapCenter
+		rbo=bo->next();
+		if (rbo) return rbo;
+
+		// Try to find MapCenter of bo
+		while (bo->getDepth()>0) bo=(BranchObj*)bo->getParObj();
+
+		// Try to find next MapCenter
+		int i=mapCenters.indexOf ((MapCenterObj*)bo);
+		if (i+2 > mapCenters.count() || i<0) return NULL;
+		if (mapCenters.at(i+1)!=bo_start)
+			return mapCenters.at(i+1);
+	} 
+	return NULL;
+}
+
+LinkableMapObj* VymModel::findMapObj(QPointF p, LinkableMapObj *excludeLMO)
+{
+	LinkableMapObj *lmo;
+
+	for (int i=0;i<mapCenters.count(); i++)
+	{
+		lmo=mapCenters.at(i)->findMapObj (p,excludeLMO);
+		if (lmo) return lmo;
+	}
+	return NULL;
+}
+
+LinkableMapObj* VymModel::findObjBySelect(const QString &s)
+{
+	LinkableMapObj *lmo;
+	if (!s.isEmpty() )
+	{
+		QString part;
+		QString typ;
+		QString num;
+		part=s.section(",",0,0);
+		typ=part.left (2);
+		num=part.right(part.length() - 3);
+		if (typ=="mc" && num.toInt()>=0 && num.toInt() <mapCenters.count() )
+			return mapCenters.at(num.toInt() );
+	}		
+
+	for (int i=0; i<mapCenters.count(); i++)
+	{
+		lmo=mapCenters.at(i)->findObjBySelect(s);
+		if (lmo) return lmo;
+	}	
+	return NULL;
+}
+
+LinkableMapObj* VymModel::findID (const QString &s)
+{
+	LinkableMapObj *lmo;
+	for (int i=0; i<mapCenters.count(); i++)
+	{
+		lmo=mapCenters.at(i)->findID (s);
+		if (lmo) return lmo;
+	}	
+	return NULL;
+}
+
+QString VymModel::saveToDir (const QString &tmpdir,const QString &prefix, int verbose, const QPointF &offset)
+{
+    QString s;
+
+	for (int i=0; i<mapCenters.count(); i++)
+		s+=mapCenters.at(i)->saveToDir (tmpdir,prefix,verbose,offset);
+    return s;
+}
+
+
+//////////////////////////////////////////////
+// View related
+//////////////////////////////////////////////
+
+void VymModel::updateRelPositions()
+{
+	for (int i=0; i<mapCenters.count(); i++)
+		mapCenters.at(i)->updateRelPositions();
+}
+
+void VymModel::reposition()
+{
+	for (int i=0;i<mapCenters.count(); i++)
+		mapCenters.at(i)->reposition();	//	for positioning heading
+}
+
+QPolygonF VymModel::shape(BranchObj *bo)
+{
+	// Creating (arbitrary) shapes
+
+	QPolygonF p;
+	QRectF rb=bo->getBBox();
+	if (bo->getDepth()==0)
+	{
+		// Just take BBox of this mapCenter
+		p<<rb.topLeft()<<rb.topRight()<<rb.bottomRight()<<rb.bottomLeft();
+		return p;
+	}
+
+	// Take union of BBox and TotalBBox 
+
+	QRectF ra=bo->getTotalBBox();
+	if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
+		p   <<ra.bottomLeft()
+			<<ra.topLeft()
+			<<QPointF (rb.topLeft().x(), ra.topLeft().y() )
+			<<rb.topRight()
+			<<rb.bottomRight()
+			<<QPointF (rb.bottomLeft().x(), ra.bottomLeft().y() ) ;
+	else		
+		p   <<ra.bottomRight()
+			<<ra.topRight()
+			<<QPointF (rb.topRight().x(), ra.topRight().y() )
+			<<rb.topLeft()
+			<<rb.bottomLeft()
+			<<QPointF (rb.bottomRight().x(), ra.bottomRight().y() ) ;
+	return p;		
+
+}
+
+void VymModel::moveAway(LinkableMapObj *lmo)
+{
+	// Autolayout:
+	//
+	// Move all branches and MapCenters away from lmo 
+	// to avoid collisions 
+
+	QPolygonF pA;
+	QPolygonF pB;
+
+	BranchObj *boA=(BranchObj*)lmo;
+	BranchObj *boB;
+	for (int i=0; i<mapCenters.count(); i++)
+	{
+		boB=mapCenters.at(i);
+		pA=shape (boA);
+		pB=shape (boB);
+		PolygonCollisionResult r = PolygonCollision(pA, pB, QPoint(0,0));
+		cout <<"------->"
+			<<"="<<r.intersect
+			<<"  ("<<qPrintable(boA->getHeading() )<<")"
+			<<"  with ("<< qPrintable (boB->getHeading() )
+			<<")  willIntersect"
+			<<r.willIntersect 
+			<<"  minT="<<r.minTranslation<<endl<<endl;
+	}
+}
+
+void VymModel::animate()
+{
+	animationTimer->stop();
+	BranchObj *bo;
+	int i=0;
+	while (i<animObjList.size() )
+	{
+		bo=(BranchObj*)animObjList.at(i);
+		if (!bo->animate())
+		{
+			if (i>=0) animObjList.removeAt(i);
+			i--;
+		}
+		bo->reposition();
+		i++;
+	} 
+	mapEditor->updateSelection();
+	mapScene->update();
+	animationTimer->start();
+}
+
+
+void VymModel::startAnimation(const QPointF &start, const QPointF &dest)
+{
+	BranchObj *bo=getSelectedBranch();
+	if (bo && bo->getDepth()>0) 
+	{
+		AnimPoint ap;
+		ap.setStart (start);
+		ap.setDest  (dest);
+		ap.setTicks (animationTicks);
+		ap.setAnimated (true);
+		bo->setAnimation (ap);
+		animObjList.append( bo );
+		animationTimer->setSingleShot (true);
+		animationTimer->start(animationInterval);
+	}
+}
+
+void VymModel::stopAnimation(MapObj *mo)
+{
+	int i=animObjList.indexOf(mo);
+    if (i>=0)
+		animObjList.removeAt (i);
+}
+
+//////////////////////////////////////////////
+// Selection related
+//////////////////////////////////////////////
+
+
+// Only as long as we dont have Model/View yet
+LinkableMapObj* VymModel::getSelection()
+{
+	return mapEditor->getSelection();
+}
+BranchObj* VymModel::getSelectedBranch()
+{
+	return mapEditor->getSelectedBranch();
+}
+
+
+bool VymModel::select (const QString &s)
+{
+	return mapEditor->select (s);
+}
+
+QString VymModel::getSelectString (LinkableMapObj *lmo)
+{
+	QString s;
+	if (!lmo) return s;
+	if (typeid(*lmo)==typeid(BranchObj) ||
+		typeid(*lmo)==typeid(MapCenterObj) )
+	{	
+		LinkableMapObj *par=lmo->getParObj();
+		if (par)
+		{
+			if (lmo->getDepth() ==1)
+				// Mainbranch, return 
+				s= "bo:" + QString("%1").arg(((BranchObj*)lmo)->getNum());
+			else	
+				// Branch, call myself recursively
+				s= getSelectString(par) + ",bo:" + QString("%1").arg(((BranchObj*)lmo)->getNum());
+		} else
+		{
+			// MapCenter
+			int i=mapCenters.indexOf ((MapCenterObj*)lmo);
+			if (i>=0) s=QString("mc:%1").arg(i);
+		}	
+	}	
+	return s;
+
+}
+
+	
+void VymModel::setHideTmp (HideTmpMode mode)
+{
+	for (int i=0;i<mapCenters.count(); i++)
+		mapCenters.at(i)->setHideTmp (mode);	
+}
+
+QRectF VymModel::getTotalBBox()
+{
+	QRectF r;
+	for (int i=0;i<mapCenters.count(); i++)
+		r=addBBox (mapCenters.at(i)->getTotalBBox(), r);
+	return r;	
+}
+
diff -r e37153bea487 -r 394b2f297e1d vymmodel.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vymmodel.h	Thu Jul 17 11:11:55 2008 +0000
@@ -0,0 +1,86 @@
+#ifndef VYMMODEL_H
+#define VYMMODEL_H
+
+#include <QGraphicsScene>
+
+#include "mapcenterobj.h"
+#include "mapeditor.h"
+
+
+/*! \brief This will later be divided into Model/View
+*/
+
+class VymModel : public QObject{
+	Q_OBJECT
+
+public:
+	VymModel();
+	~VymModel ();
+    void clear();
+    void init();
+	void setMapEditor(MapEditor *me);	// FIXME should not be necessary in Model/View
+	MapEditor* getMapEditor();
+	void setVersion(const  QString &);
+	void setAuthor  (const QString &);
+	QString getAuthor ();
+	void setComment (const QString &);
+	QString getComment ();
+	QString getDate();
+	void setScene(QGraphicsScene *s);
+	QGraphicsScene *getScene();
+	MapCenterObj* addMapCenter();
+	MapCenterObj* addMapCenter(QPointF absPos);
+	MapCenterObj* removeMapCenter(MapCenterObj *mco);
+
+	BranchObj* first();					// FIXME replaced by ModelIndex later
+	BranchObj* next(BranchObj *bo);		// FIXME replaced by ModelIndex later
+
+    LinkableMapObj* findMapObj(QPointF,LinkableMapObj*);	// find MapObj 
+    LinkableMapObj* findObjBySelect (const QString &s);		// find MapObj by select string
+    LinkableMapObj* findID (const QString &s);				// find MapObj by previously set ID
+	QString saveToDir (const QString&,const QString&,int, const QPointF&);// Save data recursivly to tempdir
+
+
+////////////////////////////////////////// View related
+    // void updateLink();  FIXME needed?
+    void updateRelPositions();
+
+	QRectF getTotalBBox();
+	void reposition();					//!< Call reposition for all MCOs
+	void setHideTmp (HideTmpMode mode);	
+	QPolygonF shape(BranchObj *bo);		//!< Returns arbitrary shape of subtree
+	void moveAway (LinkableMapObj *lmo);//!< Autolayout: Move all out of the way
+
+	// Animation  **experimental**
+private slots:
+	void animate();						//!< Called by timer to animate stuff
+public:
+	void startAnimation (const QPointF &start, const QPointF &dest);
+	void stopAnimation  (MapObj *mo);
+private:	
+	QTimer *animationTimer;
+	bool animationUse;
+	uint animationTicks;
+	uint animationInterval;
+	int timerId;				// animation timer
+	QList <MapObj*> animObjList;// list with animated objects
+
+////////////////////////////////////////// Selection related 
+public:
+	LinkableMapObj* getSelection();
+	BranchObj* getSelectedBranch();
+	bool select (const QString &s);
+	QString getSelectString (LinkableMapObj *lmo);
+
+private:
+	QGraphicsScene *mapScene;
+	MapEditor *mapEditor;
+	QList <MapCenterObj*> mapCenters;
+	QString version;	//!< version string saved in vym file
+	QString author;
+	QString comment;
+	QDate date;
+};
+
+
+#endif