# HG changeset patch
# User insilmaril
# Date 1253180469 0
# Node ID 6b0a5f4923d336b5690a39db2f841578f1b821c2
# Parent  d922fb6ea482a7c13fb9e6ba9c5f5082a7432e1e
Fixed sort children and addMapReplaceInt

diff -r d922fb6ea482 -r 6b0a5f4923d3 attributeitem.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/attributeitem.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -0,0 +1,156 @@
+
+#include "attributeitem.h"
+
+#include <iostream>
+using namespace std;
+
+extern bool debug;
+
+AttributeItem::AttributeItem(const QList<QVariant> &data, TreeItem *parent):TreeItem (data,parent)
+{
+	TreeItem::setType (Attribute);
+	//table=NULL;
+	//definition=NULL;
+	type=Attribute;
+
+	internal=false;
+}
+
+AttributeItem::~AttributeItem()
+{
+}
+
+void AttributeItem::setKey (const QString &k, const Type &t)
+{
+/*
+	if (!table)
+	{
+		qWarning (QString("AttributeItem::setKey (%1)  No table defined!\n").arg(k).ascii());
+		return;	
+	}
+	
+	if (!definition)
+	{
+		definition=table->getDef(k);
+		if (!definition)
+		{
+			table->addKey (k,t);
+			return;	
+		}
+	}	
+	qWarning (QString("AttributeItem::setKey (%1)  attribute already defined!\n").arg(k).ascii());
+	*/
+}
+
+QString AttributeItem::getKey ()
+{
+/*
+	if (!table)
+	{
+		qWarning ("AttributeItem::getKey ()  No table defined!");
+		return QString();	
+	}
+	if (!definition)
+	{
+		qWarning ("AttributeItem::getKey ()  No attribute defined!");
+		return QString ();	
+	}	
+	return definition->getKey();
+	*/
+}
+
+void AttributeItem::setValue(const QString &v)
+{
+/*
+	if (!table)
+	{
+		qWarning (QString ("AttributeItem::setValue (%1)  No table defined!").arg(v));
+		return;	
+	}
+	if (!definition)
+	{
+		qWarning (QString ("AttributeItem::setValue (%1)  No attribute defined!").arg(v));
+		return;	
+	}	
+	definition->setValue (v);
+*/
+}
+
+QVariant AttributeItem::getValue()
+{
+/*
+	if (!table)
+	{
+		qWarning ("AttributeItem::getValue  No table defined!");
+		return QString();	
+	}
+	if (!definition)
+	{
+		qWarning ("AttributeItem::getValue  No attribute defined!");
+		return QString();	
+	}	
+	QVariant v= definition->getValue();
+	return v;
+	*/
+}
+
+void AttributeItem::setType (const Type &t)
+{
+/*
+	if (!table)
+	{
+		qWarning ("AttributeItem::setType  No table defined!");
+		return;
+	}
+	if (!definition)
+	{
+		qWarning ("Attribute::setType  No attribute defined!");
+		return; 
+	}	
+	definition->setType (t);
+*/
+}
+
+AttributeItem::Type AttributeItem::getAttributeType()
+{
+/*
+	if (!table)
+	{
+		qWarning ("AttributeItem::getType  No table defined!");
+		return Undefined;	
+	}
+	if (!definition)
+	{
+		qWarning ("AttributeItem::getType  No attribute defined!");
+		return Undefined;	
+	}	
+	return definition->getType();
+*/
+}
+
+QString AttributeItem::getTypeString()
+{
+/*
+	if (!table)
+	{
+		qWarning ("AttributeItem::getTypeString  No table defined!");
+		return "Undefined";	
+	}
+	if (!definition)
+	{
+		qWarning ("Attribute::getTypeString  No AttributeItem defined!");
+		return "Undefined";	
+	}	
+	return definition->getTypeString();
+*/	
+}
+
+QString AttributeItem::getDataXML()
+{
+	QString a=beginElement ("attribute");
+	a+=attribut ("key",getKey());
+	a+=attribut ("value",getValue().toString() );
+	a+=attribut ("type",getTypeString () );
+	return a;
+}
+
diff -r d922fb6ea482 -r 6b0a5f4923d3 attributeitem.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/attributeitem.h	Thu Sep 17 09:41:09 2009 +0000
@@ -0,0 +1,41 @@
+#ifndef ATTRIBUTEITEM_H
+#define ATTRIBUTEITEM_H
+
+#include <QStringList>
+#include <QVariant>
+
+#include "treeitem.h"
+
+/*! \brief A key and a value 
+    The data itself is stored in Attribute Definitions (AttributeDef). 
+	A list of these tables AttributeTable is maintained for every MapEditor.
+*/
+class AttributeItem:public TreeItem {
+
+enum Type {
+	Undefined,	//!< Undefined type
+	IntList,	//!< Free integer
+	FreeInt,	//!< Free integer
+	StringList, //!< List of strings, one can be attribute value
+	FreeString,	//!< Any string can be attribute value, not unique
+	UniqueString//!< UniqueString, e.g. for IDs
+};
+
+public:
+	AttributeItem(const QList<QVariant> &data, TreeItem *parent = 0);
+	virtual ~AttributeItem();
+	void setKey (const QString &k, const Type &t);
+	QString getKey ();
+	void setValue (const QString &v);
+	QVariant getValue ();
+	void setType (const Type &t);
+	AttributeItem::Type getAttributeType ();
+	QString getTypeString ();
+	QString getDataXML();
+protected:
+	QString freeString;		//!< String value for type FreeString
+	bool internal;			//!< Internal attributes cannot be edited by user
+};
+
+#endif
+
diff -r d922fb6ea482 -r 6b0a5f4923d3 branchitem.cpp
--- a/branchitem.cpp	Fri Sep 11 12:56:15 2009 +0000
+++ b/branchitem.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -45,6 +45,11 @@
 	tmpUnscrolled=other->tmpUnscrolled;
 }
 
+BranchItem* BranchItem::parentBranch ()
+{
+	return (BranchItem*) parentItem;
+}
+
 void BranchItem::insertBranch (int pos, BranchItem *branch)
 {
 	if (pos<0) pos=0;
@@ -216,7 +221,7 @@
 			}
 		}
 	}
-	model->reposition();	// FIXME-3 we don't really want to update view from here...
+	//model->reposition();	// FIXME-3 we don't really want to update view from here...
 	return true;
 }
 
@@ -273,10 +278,30 @@
 	}	
 }
 
+void BranchItem::sortChildren()
+{
+	int childCount=branchCounter; 
+	int curChildIndex;
+	bool madeChanges=false;
+	do
+	{
+		madeChanges=false;
+		for(curChildIndex=1;curChildIndex<childCount;curChildIndex++){
+			BranchItem* curChild =getBranchNum(curChildIndex);
+			BranchItem* prevChild=getBranchNum(curChildIndex-1);
+			if(prevChild->getHeading().compare(curChild->getHeading())>0)
+			{
+				model->moveUp(curChild);
+				madeChanges=true;
+			}
+		}
+	}while(madeChanges);
+}
+
 void BranchItem::setIncludeImagesVer(bool b)
 {
 	includeImagesVer=b;
-	/* calcBBoxSize(); FIXME-2
+	/* calcBBoxSize(); FIXME-3
 	positionBBox();
 	requestReposition();
 	*/
@@ -290,7 +315,7 @@
 void BranchItem::setIncludeImagesHor(bool b)
 {
 	includeImagesHor=b;
-	/* calcBBoxSize(); FIXME-2
+	/* calcBBoxSize(); FIXME-3
 	positionBBox();
 	requestReposition();
 	*/
@@ -377,7 +402,7 @@
 	}
 	return NULL;
 }
-
+/*
 TreeItem* BranchItem::findID (QString sid)	//FIXME-3 move to TreeItem	//FIXME-4 search images
 {
 	// Search branches
@@ -392,7 +417,6 @@
 	if (sid==objID) return this;
 
 
-/*
 	// Search float images 
     for (int i=0; i<floatimage.size(); ++i )
 		if (floatimage.at(i)->inBox(p) && 
@@ -400,10 +424,9 @@
 			floatimage.at(i)->getParObj()!= excludeLMO &&
 			floatimage.at(i)->isVisibleObj() 
 		) return floatimage.at(i);
-*/
     return NULL;
 }
-
+*/
 void BranchItem::updateStyles()
 {
 	// FIXME-5 compare also MapItem::initLMO...
diff -r d922fb6ea482 -r 6b0a5f4923d3 branchitem.h
--- a/branchitem.h	Fri Sep 11 12:56:15 2009 +0000
+++ b/branchitem.h	Thu Sep 17 09:41:09 2009 +0000
@@ -15,6 +15,7 @@
     BranchItem(const QList<QVariant> &data, TreeItem *parent = 0);
     virtual ~BranchItem();
 	virtual void copy (BranchItem *item);
+	virtual BranchItem* parentBranch();
 
 	virtual void insertBranch (int pos,BranchItem *branch);
 
@@ -34,7 +35,7 @@
 	virtual bool hasScrolledParent(BranchItem*);	// true, if any of the parents is scrolled
 	virtual void tmpUnscroll();				// unscroll scrolled parents temporary e.g. during "find" process
 	virtual void resetTmpUnscroll();		// scroll all tmp scrolled parents again e.g. when unselecting
-
+	virtual void sortChildren();		//! Sort children 
 
 protected:
 	bool includeImagesVer;			//! include floatimages in bbox vertically
@@ -57,7 +58,7 @@
 
 public:
 	TreeItem* findMapItem (QPointF p,TreeItem* excludeTI);	//! search map for branches or images. Ignore excludeTI, where search is started 
-	virtual TreeItem* findID (QString sid);	//! search map for object with ID string
+//	virtual TreeItem* findID (QString sid);	//! search map for object with ID string
 
 	virtual void updateStyles ();			//! update related fonts, parObjects, links, ...
 	virtual BranchObj* getBranchObj();	
diff -r d922fb6ea482 -r 6b0a5f4923d3 branchobj.cpp
--- a/branchobj.cpp	Fri Sep 11 12:56:15 2009 +0000
+++ b/branchobj.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -505,28 +505,6 @@
 	calcBBoxSize();
 }
 
-void BranchObj::sortChildren() //FIXME-3 not moved to model yet 
-{
-/*
-	int childCount=branch.count(); 
-	int curChildIndex;
-	bool madeChanges=false;
-	do
-	{
-		madeChanges=false;
-		for(curChildIndex=1;curChildIndex<childCount;curChildIndex++){
-			BranchObj* curChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex);
-			BranchObj* prevChild=(BranchObj*)treeItem->getBranchObjNum(curChildIndex-1);
-			if(prevChild->heading->text().compare(curChild->heading->text())>0)
-			{
-				this->moveBranchUp(curChild);
-				madeChanges=true;
-			}
-		}
-	}while(madeChanges);
-*/
-}
-
 void BranchObj::alignRelativeTo (QPointF ref,bool alignSelf)
 {
 	qreal th = bboxTotal.height();	
@@ -545,10 +523,10 @@
 //cout<<  "  ref="<<ref<<
       	"  bbox.tL="<<bboxTotal.topLeft()<<
 		"  absPos="<<absPos<<
-//		"  relPos="<<relPos<<
+		"  relPos="<<relPos<<
 //		"  parPos="<<pp<<
-		"  w="<<bbox.width()<<
-		"  h="<<bbox.height()<<
+//		"  w="<<bbox.width()<<
+//		"  h="<<bbox.height()<<
 //		"  orient="<<orientation<<
 //		"  alignSelf="<<alignSelf<<
 //		"  scrolled="<<((BranchItem*)treeItem)->isScrolled()<<
diff -r d922fb6ea482 -r 6b0a5f4923d3 branchobj.h
--- a/branchobj.h	Fri Sep 11 12:56:15 2009 +0000
+++ b/branchobj.h	Thu Sep 17 09:41:09 2009 +0000
@@ -48,7 +48,6 @@
 public:	
 	virtual void setDefAttr (BranchModification);	// set default attributes (font, size, ...)
 
-    virtual void sortChildren();
     virtual void alignRelativeTo(const QPointF, bool alignSelf=false );
 	virtual void reposition();
 	virtual void unsetAllRepositionRequests();
diff -r d922fb6ea482 -r 6b0a5f4923d3 mainwindow.cpp
--- a/mainwindow.cpp	Fri Sep 11 12:56:15 2009 +0000
+++ b/mainwindow.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -23,7 +23,7 @@
 #include "warningdialog.h"
 #include "xlinkitem.h"
 
-#include <modeltest.h>	// FIXME-3
+//#include <modeltest.h>	// FIXME-3
 
 #if defined(Q_OS_WIN32)
 // Define only this structure as opposed to
@@ -665,6 +665,13 @@
 	editMenu->addAction (a);
 	actionMoveDown=a;
 	
+    a = new QAction(QPixmap(), tr( "&Detach","Context menu" ),this);
+	a->setStatusTip ( tr( "Detach branch and use as mapcenter","Context menu" ) );
+	a->setShortcut ( Qt::Key_D );					// Detach branch
+	editMenu->addAction (a);
+    connect( a, SIGNAL( triggered() ), this, SLOT( editDetach() ) );
+	actionDetach=a;
+	
 	a = new QAction( QPixmap(iconPath+"editsort.png" ), tr( "Sort children","Edit menu" ), this );
 	connect( a, SIGNAL( activated() ), this, SLOT( editSortChildren() ) );
 	a->setEnabled (true);
@@ -1547,6 +1554,7 @@
 
 	actionSaveBranch->addTo( branchContextMenu );
 	actionFileNewCopy->addTo (branchContextMenu );
+	actionDetach->addTo (branchContextMenu );
 
 	branchContextMenu->addSeparator();	
 	branchContextMenu->addAction ( actionLoadImage);
@@ -1710,7 +1718,7 @@
 {
 	VymModel *vm=new VymModel;
 
-new ModelTest(vm, this);	//FIXME-3
+//new ModelTest(vm, this);	//FIXME-3
 
 
 	VymView *vv=new VymView (vm);
@@ -2699,6 +2707,7 @@
 void Main::editMapInfo()
 {
 	VymModel *m=currentModel();
+	if (!m) return;
 
 	ExtraInfoDialog dia;
 	dia.setMapName (m->getFileName() );
@@ -2707,27 +2716,27 @@
 
 	// Calc some stats
 	QString stats;
-/* FIXME-2 no stats at the moment (view dependent...)
-    stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
+    stats+=tr("%1 items on map\n","Info about map").arg (m->getScene()->items().size(),6);
 
 	uint b=0;
 	uint f=0;
 	uint n=0;
 	uint xl=0;
-	BranchObj *bo;
-	bo=m->first();
-	while (bo) 
+	BranchItem *cur=NULL;
+	BranchItem *prev=NULL;
+	m->next(cur,prev);
+	while (cur) 
 	{
-		if (!bo->getNote().isEmpty() ) n++;
-		f+= bo->countFloatImages();
+		if (!cur->getNote().isEmpty() ) n++;
+		f+= cur->imageCount();
 		b++;
-		xl+=bo->countXLinks();
-		bo=m->next(bo);
+		xl+=cur->xlinkCount();
+		m->next(cur,prev);
 	}
+
     stats+=QString ("%1 xLinks \n").arg (xl,6);
     stats+=QString ("%1 notes\n").arg (n,6);
     stats+=QString ("%1 images\n").arg (f,6);
-*/
     stats+=QString ("%1 branches\n").arg (m->branchCount(),6);
 	dia.setStats (stats);
 
@@ -2751,6 +2760,12 @@
 	if (m) m->moveDown();
 }
 
+void Main::editDetach()
+{
+	VymModel *m=currentModel();
+	if (m) m->detach();
+}
+
 void Main::editSortChildren()
 {
 	VymModel *m=currentModel();
@@ -3591,6 +3606,11 @@
 {
 	if (!currentMapEditor()) return;
 	currentMapEditor()->testFunction1();
+	/*
+	VymModel *m=currentModel();
+	if (!m) return;
+	m->clearItem (m->getSelectedItem());
+	*/
 }
 
 void Main::testFunction2()
diff -r d922fb6ea482 -r 6b0a5f4923d3 mainwindow.h
--- a/mainwindow.h	Fri Sep 11 12:56:15 2009 +0000
+++ b/mainwindow.h	Thu Sep 17 09:41:09 2009 +0000
@@ -144,6 +144,7 @@
 	void editMapInfo();
     void editMoveUp();	
     void editMoveDown();	
+    void editDetach();	
 	void editSortChildren();
     void editToggleScroll();
     void editExpandAll();
@@ -278,6 +279,7 @@
 	QAction *actionPaste;
 	QAction *actionMoveUp;
 	QAction *actionMoveDown;
+	QAction *actionDetach;
 	QAction *actionSortChildren;
 	QAction *actionToggleScroll;
 	QAction *actionExpandAll;
diff -r d922fb6ea482 -r 6b0a5f4923d3 mapeditor.cpp
--- a/mapeditor.cpp	Fri Sep 11 12:56:15 2009 +0000
+++ b/mapeditor.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -186,6 +186,8 @@
 
 void MapEditor::scrollTo (const QModelIndex &index)
 {
+	//cout <<"ME::scrollTo aborted\n";
+	//return;
 	if (index.isValid())
 	{
 		LinkableMapObj* lmo=NULL;
@@ -454,6 +456,7 @@
 
 void MapEditor::testFunction1()
 {
+	cout << "ME::test1  selected TI="<<model->getSelectedItem()<<endl;
 	/*
 	// Code copied from Qt sources
 	QRectF rect=model->getSelectedBranchObj()->getBBox();
diff -r d922fb6ea482 -r 6b0a5f4923d3 mysortfilterproxymodel.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mysortfilterproxymodel.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file.  Please review the following information
+** to ensure GNU General Public Licensing requirements will be met:
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
+** exception, Nokia gives you certain additional rights. These rights
+** are described in the Nokia Qt GPL Exception version 1.3, included in
+** the file GPL_EXCEPTION.txt in this package.
+**
+** Qt for Windows(R) Licensees
+** As a special exception, Nokia, as the sole copyright holder for Qt
+** Designer, grants users of the Qt/Eclipse Integration plug-in the
+** right for the Qt/Eclipse Integration to link to functionality
+** provided by Qt Designer and its related libraries.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+#include <QtGui>
+
+#include "mysortfilterproxymodel.h"
+
+MySortFilterProxyModel::MySortFilterProxyModel(QObject *parent)
+    : QSortFilterProxyModel(parent)
+{
+}
+/*
+void MySortFilterProxyModel::setFilterMinimumDate(const QDate &date)
+{
+    minDate = date;
+    invalidateFilter();
+}
+void MySortFilterProxyModel::setFilterMaximumDate(const QDate &date)
+{
+    maxDate = date;
+    invalidateFilter();
+}
+*/
+
+#include <iostream>
+using namespace std;
+bool MySortFilterProxyModel::filterAcceptsRow(int sourceRow,
+        const QModelIndex &sourceParent) const
+{
+	return true;
+cout << "MSFPM  sM="<<sourceModel()<<endl;
+    QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
+    QModelIndex index1 = sourceModel()->index(sourceRow, 1, sourceParent);
+
+    return (sourceModel()->data(index0).toString().contains(filterRegExp()) );
+}
+
+/*
+bool MySortFilterProxyModel::lessThan(const QModelIndex &left,
+                                      const QModelIndex &right) const
+{
+    QVariant leftData = sourceModel()->data(left);
+    QVariant rightData = sourceModel()->data(right);
+    if (leftData.type() == QVariant::DateTime) {
+        return leftData.toDateTime() < rightData.toDateTime();
+    } else {
+        QRegExp *emailPattern = new QRegExp("([\\w\\.]*@[\\w\\.]*)");
+
+        QString leftString = leftData.toString();
+        if(left.column() == 1 && emailPattern->indexIn(leftString) != -1)
+            leftString = emailPattern->cap(1);
+
+        QString rightString = rightData.toString();
+        if(right.column() == 1 && emailPattern->indexIn(rightString) != -1)
+            rightString = emailPattern->cap(1);
+
+        return QString::localeAwareCompare(leftString, rightString) < 0;
+    }
+}
+bool MySortFilterProxyModel::dateInRange(const QDate &date) const
+{
+    return (!minDate.isValid() || date > minDate)
+           && (!maxDate.isValid() || date < maxDate);
+}
+*/
diff -r d922fb6ea482 -r 6b0a5f4923d3 mysortfilterproxymodel.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mysortfilterproxymodel.h	Thu Sep 17 09:41:09 2009 +0000
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the example classes of the Qt Toolkit.
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file.  Please review the following information
+** to ensure GNU General Public Licensing requirements will be met:
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
+** exception, Nokia gives you certain additional rights. These rights
+** are described in the Nokia Qt GPL Exception version 1.3, included in
+** the file GPL_EXCEPTION.txt in this package.
+**
+** Qt for Windows(R) Licensees
+** As a special exception, Nokia, as the sole copyright holder for Qt
+** Designer, grants users of the Qt/Eclipse Integration plug-in the
+** right for the Qt/Eclipse Integration to link to functionality
+** provided by Qt Designer and its related libraries.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+#ifndef MYSORTFILTERPROXYMODEL_H
+#define MYSORTFILTERPROXYMODEL_H
+
+#include <QDate>
+#include <QSortFilterProxyModel>
+
+//! [0]
+class MySortFilterProxyModel : public QSortFilterProxyModel
+{
+    Q_OBJECT
+
+public:
+    MySortFilterProxyModel(QObject *parent = 0);
+
+ //   QDate filterMinimumDate() const { return minDate; }
+//    void setFilterMinimumDate(const QDate &date);
+
+//    QDate filterMaximumDate() const { return maxDate; }
+//    void setFilterMaximumDate(const QDate &date);
+
+protected:
+    bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+//    bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
+
+private:
+    bool dateInRange(const QDate &date) const;
+
+    QDate minDate;
+    QDate maxDate;
+};
+//! [0]
+
+#endif
diff -r d922fb6ea482 -r 6b0a5f4923d3 treeitem.cpp
--- a/treeitem.cpp	Fri Sep 11 12:56:15 2009 +0000
+++ b/treeitem.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -175,18 +175,6 @@
 	}
 }
 
-/*
-void TreeItem::clear()	// FIXME-2 used in vymmodel addMapInsert, but needs to be used via model and emit layout changes...
-{
-	cout << "TI::clear\n";
-	while ( childItems.size()>0)
-	{
-		branchCounter--;
-		childItems.removeAt (0);
-	}
-}
-*/
-
 TreeItem *TreeItem::child(int row)
 {
     return childItems.value(row);
diff -r d922fb6ea482 -r 6b0a5f4923d3 treeitem.h
--- a/treeitem.h	Fri Sep 11 12:56:15 2009 +0000
+++ b/treeitem.h	Thu Sep 17 09:41:09 2009 +0000
@@ -41,7 +41,6 @@
 
     virtual void appendChild (TreeItem *child);
 	virtual void removeChild (int row);
-//	virtual void clear();
 
     virtual TreeItem *child(int row);
     virtual int childCount() const;
diff -r d922fb6ea482 -r 6b0a5f4923d3 treemodel.cpp
--- a/treemodel.cpp	Fri Sep 11 12:56:15 2009 +0000
+++ b/treemodel.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -235,36 +235,12 @@
 		pi=rootItem;
 	TreeItem *ti;
 
-	cout << "TM::removeRows  pi="<<pi<<"  row="<<row<<"  count="<<count<<endl;
+	//cout << "TM::removeRows  pi="<<pi<<"  row="<<row<<"  count="<<count<<endl;
 	for (int i=row; i<=last; i++)
 	{
 		ti=pi->getChildNum (row);
-		cout << "   pi="<<pi<<"  ti="<<ti<<endl;
 		pi->removeChild (row);	// does not delete object!
 		delete ti;
-		/* FIXME-3
-		switch (ti->getType()) 
-		{
-			case TreeItem::MapCenter: 
-				delete (BranchItem*)ti; 
-				break;
-			case TreeItem::Branch:
-				delete (BranchItem*)ti; 
-				break;
-			case TreeItem::Image:
-				delete (ImageItem*)ti; 
-				break;
-			case TreeItem::Attribute:
-				delete (AttributeItem*)ti; 
-				break;
-			case TreeItem::XLink:
-				delete (XLinkItem*)ti; 
-				break;
-			default:
-				delete ti;
-				break;
-		}
-		*/
 	}
 	return true;
 }
diff -r d922fb6ea482 -r 6b0a5f4923d3 vymmodel.cpp
--- a/vymmodel.cpp	Fri Sep 11 12:56:15 2009 +0000
+++ b/vymmodel.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -640,7 +640,7 @@
 	return err;
 }
 
-void VymModel::addMapReplaceInt(const QString &undoSel, const QString &path)	// FIXME-1 test e.g. with undo color subtree
+void VymModel::addMapReplaceInt(const QString &undoSel, const QString &path)	
 {
 	QString pathDir=path.left(path.findRev("/"));
 	QDir d(pathDir);
@@ -1077,7 +1077,6 @@
 
 
 	parseAtom (redoCommand);
-	reposition();
 
 	blockSaveState=blockSaveStateOrg;
 
@@ -1156,7 +1155,6 @@
 		cout << "    ---------------------------"<<endl<<endl;
 	}	
 	parseAtom (undoCommand);
-	reposition();
 
 	undosAvail--;
 	curStep--; 
@@ -1180,7 +1178,7 @@
 
 	mainWindow->updateHistory (undoSet);
 	updateActions();
-	emitSelectionChanged();
+	//emitSelectionChanged();
 }
 
 bool VymModel::isUndoAvailable()
@@ -1439,7 +1437,7 @@
 	return  ti;
 }
 
-TreeItem* VymModel::findID (const QString &s)
+TreeItem* VymModel::findID (const QString &s)	//FIXME-4 Search also other types...
 {
 	BranchItem *cur=NULL;
 	BranchItem *prev=NULL;
@@ -1602,9 +1600,7 @@
 
 void VymModel::setScene (QGraphicsScene *s)
 {
-	mapScene=s;	// FIXME-2 VM should not be necessary anymore, move all occurences to MapEditor
-    //init();	// Here we have a mapScene set, 
-			// which is (still) needed to create MapCenters
+	mapScene=s;	
 }
 
 void VymModel::setURL(const QString &url) 
@@ -1918,47 +1914,80 @@
 	}
 }
 
-void VymModel::moveUp()	//FIXME-2 crashes if trying to move MCO
+bool VymModel::moveUp(BranchItem *bi)	//FIXME-2 crashes if trying to move MCO
+{
+	if (bi && bi->canMoveUp()) 
+		return relinkBranch (bi,(BranchItem*)bi->parent(),bi->num()-1);
+	else	
+		return false;
+}
+
+void VymModel::moveUp()	
 {
 	BranchItem *selbi=getSelectedBranch();
 	if (selbi)
 	{
-		if (!selbi->canMoveUp()) return;
 		QString oldsel=getSelectString();
-		if (relinkBranch (selbi,(BranchItem*)selbi->parent(),selbi->num()-1) )
-
-			saveState (getSelectString(),"moveDown ()",oldsel,"moveUp ()",QString("Move up %1").arg(getObjectName(selbi)));
+		if (moveUp (selbi))
+			saveState (
+				getSelectString(),"moveDown ()",
+				oldsel,"moveUp ()",
+				QString("Move up %1").arg(getObjectName(selbi)));
 	}
 }
 
+bool VymModel::moveDown(BranchItem *bi)	
+{
+	if (bi && bi->canMoveDown())
+		return relinkBranch (bi,(BranchItem*)bi->parent(),bi->num()+1);
+	else
+		return false;
+}
+
 void VymModel::moveDown()	
 {
 	BranchItem *selbi=getSelectedBranch();
 	if (selbi)
 	{
-		if (!selbi->canMoveDown()) return;
 		QString oldsel=getSelectString();
-		if ( relinkBranch (selbi,(BranchItem*)selbi->parent(),selbi->num()+1) )
-
-			saveState (getSelectString(),"moveUp ()",oldsel,"moveDown ()",QString("Move down %1").arg(getObjectName(selbi)));
+		if ( moveDown(selbi))
+			saveState (
+				getSelectString(),"moveUp ()",
+				oldsel,"moveDown ()",
+				QString("Move down %1").arg(getObjectName(selbi)));
 	}
 }
 
-void VymModel::sortChildren()	// FIXME-2 not implemented yet
-{
-/*
-	BranchObj* bo=getSelectedBranch();
-	if (bo)
+void VymModel::detach()	
+{
+	BranchItem *selbi=getSelectedBranch();
+	if (selbi && selbi->depth()>0)
 	{
-		if(treeItem->branchCount()>1)
+		//QString oldsel=getSelectString();
+		if ( relinkBranch (selbi,rootItem,-1) )
+			saveState (
+				selbi,QString("relink()"), //FIXME-1 add paramters
+				selbi,"detach ()",
+				QString("Detach %1").arg(getObjectName(selbi))
+			);
+	}
+}
+
+void VymModel::sortChildren()
+{
+	BranchItem* selbi=getSelectedBranch();
+	if (selbi)
+	{
+		if(selbi->branchCount()>1)
 		{
-			saveStateChangingPart(bo,bo, "sortChildren ()",QString("Sort children of %1").arg(getObjectName(bo)));
-			bo->sortChildren();
+			saveStateChangingPart(
+				selbi,selbi, "sortChildren ()",
+				QString("Sort children of %1").arg(getObjectName(selbi)));
+			selbi->sortChildren();
 			reposition();
 			emitShowSelection();
 		}
 	}
-*/
 }
 
 BranchItem* VymModel::createMapCenter()
@@ -2437,7 +2466,6 @@
 
 TreeItem* VymModel::deleteItem (TreeItem *ti)
 {
-	cout << "VM::deleteItem "<<ti<<"  "<<getSelectString(ti).toStdString()<<endl;
 	if (ti)
 	{
 		TreeItem *pi=ti->parent();
@@ -2457,6 +2485,29 @@
 	return NULL;
 }
 
+void VymModel::clearItem (TreeItem *ti)
+{
+	if (ti)
+	{
+		QModelIndex parentIndex=index(ti);
+		if (!parentIndex.isValid()) return;
+
+		int n=ti->childCount();
+		if (n==0) return;
+
+		emit (layoutAboutToBeChanged() );
+
+		beginRemoveRows (parentIndex,0,n-1);
+		removeRows (0,n,parentIndex);
+		endRemoveRows();
+		reposition();
+
+		emit (layoutChanged() );
+
+	}	
+	return ;
+}
+
 bool VymModel::scrollBranch(BranchItem *bi)
 {
 	if (bi)	
@@ -2478,7 +2529,7 @@
 			);
 			emitDataHasChanged(bi);
 			emitSelectionChanged();
-			mapScene->update(); //Needed for _quick_ update,  even in 1.13.x //FIXME-3 force update via signal...
+			mapScene->update(); //Needed for _quick_ update,  even in 1.13.x 
 			return true;
 		}
 	}	
@@ -2492,7 +2543,9 @@
 		if (!bi->isScrolled()) return false;
 		if (bi->branchCount()==0) return false;
 		if (bi->depth()==0) return false;
-
+		if (bi->toggleScroll())
+		{
+			reposition();
 		QString u,r;
 		u="scroll";
 		r="unscroll";
@@ -2503,13 +2556,12 @@
 			QString ("%1 ()").arg(r),
 			QString ("%1 %2").arg(r).arg(getObjectName(bi))
 		);
-		bi->toggleScroll();
 		emitDataHasChanged(bi);
 		emitSelectionChanged();
-
-		mapScene->update(); //Needed for _quick_ update,  even in 1.13.x //FIXME-3 force update via signal...
+			mapScene->update(); //Needed for _quick_ update,  even in 1.13.x 
 		return true;
 	}	
+	}	
 	return false;
 }
 
@@ -2523,24 +2575,34 @@
 		else
 			scrollBranch (bi);
 	}
-	// saveState is called in above functions
+	// saveState & reposition are called in above functions
 }
 
-void VymModel::unscrollChildren() 	// FIXME-2	first, next moved to vymmodel
-
-{
-/*
-	BranchObj *bo=getSelectedBranch();
-	if (bo)
+void VymModel::unscrollChildren() 	//FIXME-2 does not update flag yet, possible segfault
+{
+	BranchItem *selbi=getSelectedBranch();
+	BranchItem *prev=NULL;
+	BranchItem *cur=selbi;
+	if (selbi)
 	{
-		bo->first();
-		while (bo) 
+		saveStateChangingPart(
+			selbi,
+			selbi,
+			QString ("unscrollChildren ()"),
+			QString ("unscroll all children of %1").arg(getObjectName(selbi))
+		);	
+		while (cur) 
 		{
-			if (bo->isScrolled()) unscrollBranch (bo);
-			bo=bo->next();
+			if (cur->isScrolled())
+			{
+				cur->toggleScroll(); 
+				emitDataHasChanged (cur);
 		}
+			cur=next (cur,prev,selbi);
+		}	
+		updateActions();
+		reposition();
 	}	
-*/	
 }
 
 void VymModel::emitExpandAll()
@@ -2606,6 +2668,7 @@
 			QString("Set color of %1 to %2").arg(getObjectName(selbi)).arg(c.name())
 		);	
 		selbi->setHeadingColor(c); // color branch
+		mapScene->update();
 	}
 }
 
@@ -2627,7 +2690,7 @@
 			cur->setHeadingColor(c); // color links, color children
 			cur=next (cur,prev,selbi);
 		}	
-
+	mapScene->update();
 	}
 }
 
@@ -4057,82 +4120,16 @@
 	*/
 }
 
-void VymModel::reposition()	//FIXME-3 VM should have no need to reposition, this is done in views???
+void VymModel::reposition()	//FIXME-4 VM should have no need to reposition, but the views...
 {
 	//cout << "VM::reposition blocked="<<blockReposition<<endl;
 	if (blockReposition) return;
 
 	for (int i=0;i<rootItem->branchCount(); i++)
 		rootItem->getBranchObjNum(i)->reposition();	//	for positioning heading
-	emitSelectionChanged();	
+	//emitSelectionChanged();	
 }
 
-/*
-QPolygonF VymModel::shape(BranchObj *bo)	//FIXME-4
-{
-	return QPolygonF ();
-	// 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)	//FIXME-5
-{
-	// 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<rootItem->branchCount(); i++)
-	{
-		boB=rootItem->getBranchNum(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::setMapLinkStyle (const QString & s)
 {
@@ -4274,7 +4271,7 @@
 	}
 }	
 
-void VymModel::setMapBackgroundImage (const QString &fn)	//FIXME-2 missing savestate, move to ME
+void VymModel::setMapBackgroundImage (const QString &fn)	//FIXME-3 missing savestate, move to ME
 {
 	QColor oldcol=mapScene->backgroundBrush().color();
 	/*
@@ -4753,24 +4750,6 @@
 }
 
 
-//bool VymModel::selectInt (LinkableMapObj *lmo)	// FIXME-3 still needed?
-/*
-{
-	if (selection.select(lmo))
-	{
-		//emitSelectionChanged();
-	}
-}
-
-bool VymModel::selectInt (TreeItem *ti)	
-{
-	if (selection.select(lmo))
-	{
-		//emitSelectionChanged();
-	}
-}
-*/
-
 bool VymModel::selectFirstBranch()
 {
 	TreeItem *ti=getSelectedBranch();
diff -r d922fb6ea482 -r 6b0a5f4923d3 vymmodel.h
--- a/vymmodel.h	Fri Sep 11 12:56:15 2009 +0000
+++ b/vymmodel.h	Thu Sep 17 09:41:09 2009 +0000
@@ -190,12 +190,6 @@
 		const QString &comment, 
 		TreeItem *saveSelection);
 	/*! Overloaded for convenience */
-    void saveStateComplete(
-		TreeItem *undoSelection, 
-		TreeItem* redoSelection, 
-		const QString &redoCommand, 
-		const QString &comment);
-	/*! Overloaded for convenience */
     void saveStateChangingPart(
 		TreeItem *undoSelection, 
 		TreeItem* redoSelection, 
@@ -290,8 +284,11 @@
     void paste();			//!< Paste clipboard to branch and backup
     void cut();				//!< Cut to clipboard (and copy)
 
-    void moveUp();			//!< Move branch up
+    bool moveUp(BranchItem *bi);	//!< Move branch up without saving state
+    void moveUp();					//!< Move branch up with saving state
+    bool moveDown(BranchItem *bi);	//!< Move branch down without saving state
     void moveDown();		//!< Move branch down
+	void detach();					//!< Detach branch and use as new mapcenter
 	void sortChildren();	//!< Sort children lexically
 
 	// The create methods are used to quickly parse a XML file
@@ -347,6 +344,7 @@
 	void deleteChildren();				//!< keep branch, but remove children
 
 	TreeItem* deleteItem(TreeItem*);	//!< Delete item and return parent (if parent!= rootItem)
+	void clearItem (TreeItem* ti);		//!< Remove all children of TreeItem ti
 	bool scrollBranch(BranchItem *);
 	bool unscrollBranch(BranchItem *);
 public:	
@@ -441,9 +439,6 @@
 	void reposition();					//!< Call reposition for all MCOs
 	void setHideTmpMode (TreeItem::HideTmpMode mode);	
 
-	//FIXME-5 QPolygonF shape(BranchObj *bo);		//!< Returns arbitrary shape of subtree
-	//FIXME-5 void moveAway (LinkableMapObj *lmo);//!< Autolayout: Move all out of the way
-
 	void emitNoteHasChanged (TreeItem *ti);
 	void emitDataHasChanged (TreeItem *ti);
 
@@ -579,8 +574,6 @@
 signals:
 	void showSelection();
 
-//	bool selectInt(LinkableMapObj*);	//FIXME-4
-
 public:	
     bool selectFirstBranch();
     bool selectLastBranch();
diff -r d922fb6ea482 -r 6b0a5f4923d3 xlinkitem.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xlinkitem.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -0,0 +1,210 @@
+#include <QGraphicsScene>
+#include "xlinkitem.h"
+
+#include "branchitem.h"
+#include "linkablemapobj.h"
+#include "vymmodel.h"
+#include "xlinkobj.h"
+
+#include <iostream>
+using namespace std;
+
+/////////////////////////////////////////////////////////////////
+// XLinkItem
+/////////////////////////////////////////////////////////////////
+
+XLinkItem::XLinkItem (const QList<QVariant> &data, TreeItem *parent):MapItem (data,parent)
+
+{
+	//cout << "Const XLinkItem () "<<this<<endl;
+	init();
+}
+
+XLinkItem::~XLinkItem ()
+{
+	cout << "Destr XLinkItem "<<this<<"  lmo="<<lmo<<endl;
+	if (lmo){cout <<" calling delete\n"; delete (lmo);}
+	if (partnerXLink)
+	{
+		// Also delete partner 
+		cout << "  deleting partner="<<partnerXLink<<endl;
+		partnerXLink->partnerXLink=NULL;	// avoid endless recusion
+		model->deleteItem (partnerXLink);
+	}
+}
+
+
+void XLinkItem::init () 
+{
+	setType (XLink);
+	beginBranch=NULL;
+	endBranch=NULL;
+	partnerXLink=NULL;
+	isBeginXLink=true;
+	xLinkState=XLinkItem::undefinedXLink;
+
+	color=QColor (180,180,180);
+	width=1;
+}
+
+void XLinkItem::setBegin (BranchItem *bi)
+{
+	if (bi) 
+	{
+		xLinkState=initXLink;
+		beginBranch=bi;
+	}	
+}
+
+BranchItem* XLinkItem::getBegin ()
+{
+	return beginBranch;
+}
+
+void XLinkItem::setEnd (BranchItem *bi)
+{
+	if (bi) 
+	{
+		xLinkState=initXLink;
+		endBranch=bi;
+	}		
+}
+
+BranchItem* XLinkItem::getEnd()
+{
+	return endBranch;
+}
+
+void XLinkItem::setWidth (int w)
+{
+	if (isBeginXLink)
+	{
+		width=w;
+		if (lmo) ((XLinkObj*)lmo)->updateXLink();
+		return;
+	}
+	if (partnerXLink)
+		partnerXLink->setWidth (w);
+}
+
+int XLinkItem::getWidth()
+{
+	if (isBeginXLink) return width;
+	if (partnerXLink)
+		return partnerXLink->getWidth();
+	else
+		return -1;
+}
+
+void XLinkItem::setColor(QColor c)
+{
+	if (isBeginXLink)
+	{
+		color=c;
+		if (lmo) ((XLinkObj*)lmo)->updateXLink();
+		return;
+	}	
+	if (partnerXLink)
+		partnerXLink->setColor (c);
+}
+
+QColor XLinkItem::getColor()
+{
+	if (isBeginXLink) return color;
+	if (partnerXLink)
+		return partnerXLink->getColor();
+	else
+		return QColor();
+}
+
+void XLinkItem::setEnd (QPointF p)
+{
+	if (lmo) ((XLinkObj*)lmo)->setEnd (p);
+}
+
+bool XLinkItem::activate ()	
+{
+	if (beginBranch && endBranch)
+	{
+		if (beginBranch==endBranch) return false;
+
+		partnerXLink=model->createXLink (endBranch);
+		partnerXLink->setBegin (beginBranch);
+		partnerXLink->setEnd (endBranch);
+		partnerXLink->partnerXLink=this;
+		partnerXLink->isBeginXLink=false;
+
+		xLinkState=activeXLink;
+		partnerXLink->xLinkState=activeXLink;
+		partnerXLink->setHeading ("xLink to: "+beginBranch->getHeading());
+		setHeading ("xLink to: "+endBranch->getHeading());
+
+		model->updateActions();
+		return true;
+	} else
+		return false;
+}
+
+bool XLinkItem::isBegin()
+{
+	return isBeginXLink;
+}
+
+void XLinkItem::updateXLink()
+{
+	if(lmo && isBeginXLink) 
+		((XLinkObj*)lmo)->updateXLink();
+	else 
+		if (partnerXLink) partnerXLink->updateXLink();
+}
+
+void XLinkItem::updateVisibility()
+{
+	if (lmo) lmo->updateVisibility();
+}
+
+BranchItem* XLinkItem::getPartnerBranch()
+{
+	if (!beginBranch && !endBranch)
+		return NULL;
+	if (isBeginXLink)
+		return endBranch;
+	else	
+		return beginBranch;
+}
+
+
+XLinkItem* XLinkItem::getPartnerXLink()
+{
+	return partnerXLink;
+}
+
+
+QString XLinkItem::saveToDir ()
+{
+	QString s="";
+	if (beginBranch && endBranch && xLinkState==activeXLink)
+	{
+		if (beginBranch==endBranch )
+			qWarning ("XLI::saveToDir  beginBranch==endBranch"); //FIXME-3	s=""
+		else
+		{
+			QString colAttr=attribut ("color",color.name());
+			QString widAttr=attribut ("width",QString().setNum(width,10));
+			QString begSelAttr=attribut ("beginID",model->getSelectString(beginBranch));
+			QString endSelAttr=attribut ("endID",  model->getSelectString(endBranch));
+			s=beginElement ("xlink", colAttr +widAttr +begSelAttr +endSelAttr);
+
+			s+=endElement ("xlink");
+		}
+	}
+	return s;
+}
+
+XLinkObj* XLinkItem::createMapObj(QGraphicsScene *scene)  
+{
+	XLinkObj* xlo=new XLinkObj (scene,this);
+	lmo=(LinkableMapObj*)xlo;
+	return xlo;
+}
+
diff -r d922fb6ea482 -r 6b0a5f4923d3 xlinkitem.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xlinkitem.h	Thu Sep 17 09:41:09 2009 +0000
@@ -0,0 +1,48 @@
+#ifndef XLINKITEM_H
+#define XLINKITEM_H
+
+class BranchItem;
+class XLinkObj;
+class QGraphicsScene;
+
+#include "mapitem.h"
+
+/*! \brief xlinks are used to draw arbitrary connections between branches (BranchObj) in the map. */
+
+/////////////////////////////////////////////////////////////////////////////
+class XLinkItem:public MapItem {
+public:
+	enum XLinkState {undefinedXLink,initXLink,activeXLink,deleteXLink};	
+
+	XLinkItem (const QList<QVariant> &data, TreeItem *parent=NULL);
+    virtual ~XLinkItem ();
+    virtual void init ();
+	void setBegin (BranchItem*);
+	BranchItem* getBegin();
+	void setEnd   (BranchItem*);
+	void setEnd   (QPointF);
+	BranchItem* getEnd();
+	void setColor(QColor);
+	QColor getColor();
+	void setWidth (int);
+	int getWidth ();
+	bool activate ();			//! Creates a 2nd XLink (without a XLinkObj attached) 
+	bool isBegin();		//! true, if this is master xLink, which may have an XLinkObj attached
+	void updateXLink();
+	virtual void updateVisibility();	// FIXME-3 not really needed atm...
+	BranchItem* getPartnerBranch ();
+	XLinkItem *getPartnerXLink();	//! Partner XLink
+	QString saveToDir ();
+	virtual XLinkObj* createMapObj(QGraphicsScene *scene);
+
+private:
+	XLinkState xLinkState;	// init during drawing or active
+	QColor color;
+	int width;
+	BranchItem *beginBranch;
+	BranchItem *endBranch;
+	XLinkItem *partnerXLink;
+	bool isBeginXLink;
+};
+
+#endif
diff -r d922fb6ea482 -r 6b0a5f4923d3 xml-vym.cpp
--- a/xml-vym.cpp	Fri Sep 11 12:56:15 2009 +0000
+++ b/xml-vym.cpp	Thu Sep 17 09:41:09 2009 +0000
@@ -14,8 +14,6 @@
 #include "version.h"
 #include "xlinkitem.h"
 
-static ImageItem *lastImageItem;
-static MapItem *lastMI;
 
 extern Main *mainWindow;
 extern Settings settings;
@@ -145,7 +143,8 @@
 		{
 			// Treat the found mapcenter as a branch 
 			// in an existing map
-			BranchItem *bi=model->getSelectedBranch();	//FIXME-2 selection is no longer used here... 
+			BranchItem *bi=model->getSelectedBranch();	
+			cout << "xml-vym  bi="<<bi->getHeadingStd()<<"  loadMode="<<loadMode<<endl;
 			if (bi)
 			{
 				lastBranch=bi;
@@ -153,7 +152,7 @@
 				{
 					lastBranch=model->createBranch(lastBranch);
 				} //else
-					//lastBranch->clear(); //FIXME-2 clear not really defined!
+					model->clearItem(lastBranch); 
 			} else
 				// add mapCenter without parent
 				lastBranch=model->createMapCenter(); 
@@ -190,9 +189,9 @@
 		if (!readImageAttr(atts)) return false;
 	} else if ( (eName == "branch"||eName=="floatimage") && state == StateMap) 
 	{
-		// This is used in vymparts, which have no mapcenter!
+		// This is used in vymparts, which have no mapcenter or for undo
 		isVymPart=true;
-		TreeItem *ti=model->getSelectedItem();	//FIXME-3 selection is no longer used here...
+		TreeItem *ti=model->getSelectedItem();
 		if (!ti)
 		{
 			// If a vym part is _loaded_ (not imported), 
@@ -202,6 +201,7 @@
 			// FIXME-3 lmo=model->first()->getLMO();		
 			// Do we really have no MCO when loading?????
 			cout << "xml-vym aborted\n";
+			return false;
 		}	
 		if (ti && ti->isBranchLikeType() )
 		{
@@ -212,9 +212,8 @@
 				if (loadMode==ImportAdd)
 				{
 					lastBranch=model->createBranch(lastBranch);
-					
 				} else
-					//FIXME-2 lastBranch->clear();
+					model->clearItem (lastBranch);
 				readBranchAttr (atts);
 			} else if (eName=="floatimage")
 			{
diff -r d922fb6ea482 -r 6b0a5f4923d3 xml-vym.h
--- a/xml-vym.h	Fri Sep 11 12:56:15 2009 +0000
+++ b/xml-vym.h	Thu Sep 17 09:41:09 2009 +0000
@@ -55,5 +55,6 @@
 
 	BranchItem* lastBranch;
 	ImageItem* lastImage;
+	MapItem* lastMI;
 }; 
 #endif