1.13.4 Various fixes
authorinsilmaril
Wed, 09 Jun 2010 13:14:08 +0000
changeset 84743268373032d
parent 846 f0fe7c36ec5c
child 848 e265f07f2173
1.13.4 Various fixes
adaptormodel.cpp
adaptormodel.h
animpoint.cpp
animpoint.h
branchitem.cpp
branchitem.h
branchobj.cpp
branchobj.h
editxlinkdialog.cpp
editxlinkdialog.h
exports.cpp
findresultitem.cpp
historywindow.cpp
linkablemapobj.cpp
main.cpp
mainwindow.cpp
mainwindow.h
mapeditor.cpp
mapeditor.h
noteobj.cpp
treeitem.cpp
treemodel.cpp
treemodel.h
version.h
vym.changelog
vym.pro
vymmodel.cpp
vymmodel.h
xlink.cpp
xlink.h
xlinkitem.cpp
xlinkitem.h
xlinkobj.cpp
xlinkobj.h
xml-base.cpp
xml-base.h
xml-vym.cpp
xml-vym.h
xmlobj.cpp
xmlobj.h
     1.1 --- a/adaptormodel.cpp	Fri Apr 09 14:24:04 2010 +0000
     1.2 +++ b/adaptormodel.cpp	Wed Jun 09 13:14:08 2010 +0000
     1.3 @@ -36,7 +36,7 @@
     1.4  	m_caption=newCaption;
     1.5  }
     1.6  
     1.7 -QDBusVariant AdaptorModel::query(const QString &query)
     1.8 +QDBusVariant AdaptorModel::query(const QString &)
     1.9  {
    1.10  	QString s;
    1.11  	if (model)
     2.1 --- a/adaptormodel.h	Fri Apr 09 14:24:04 2010 +0000
     2.2 +++ b/adaptormodel.h	Wed Jun 09 13:14:08 2010 +0000
     2.3 @@ -27,7 +27,7 @@
     2.4  	QString caption();
     2.5  	void setCaption(const QString &newCaption);
     2.6  public slots: // METHODS
     2.7 -   QDBusVariant query(const QString &query);
     2.8 +   QDBusVariant query(const QString &);
     2.9     QDBusVariant getCurrentModelID();
    2.10     QDBusVariant getHeading();
    2.11     void setHeading (const QString &s);
     3.1 --- a/animpoint.cpp	Fri Apr 09 14:24:04 2010 +0000
     3.2 +++ b/animpoint.cpp	Wed Jun 09 13:14:08 2010 +0000
     3.3 @@ -124,6 +124,13 @@
     3.4  	return animated;
     3.5  }
     3.6  
     3.7 +void AnimPoint::stop()
     3.8 +{
     3.9 +	animated=false;
    3.10 +	setX (destPos.x());
    3.11 +	setY (destPos.y());
    3.12 +}
    3.13 +
    3.14  void AnimPoint::initVector()
    3.15  {
    3.16  	vector.setX (destPos.x()-startPos.x() );
     4.1 --- a/animpoint.h	Fri Apr 09 14:24:04 2010 +0000
     4.2 +++ b/animpoint.h	Wed Jun 09 13:14:08 2010 +0000
     4.3 @@ -22,6 +22,7 @@
     4.4  	void setAnimated(bool);
     4.5  	bool isAnimated ();
     4.6  	bool animate();
     4.7 +	void stop();
     4.8  
     4.9  private:
    4.10  	void initVector();
     5.1 --- a/branchitem.cpp	Fri Apr 09 14:24:04 2010 +0000
     5.2 +++ b/branchitem.cpp	Wed Jun 09 13:14:08 2010 +0000
     5.3 @@ -1,13 +1,13 @@
     5.4 +#include "branchitem.h"
     5.5 +
     5.6  #include "attributeitem.h"
     5.7 -#include "branchitem.h"
     5.8  #include "branchobj.h"
     5.9  #include "vymmodel.h"
    5.10 +#include "xlink.h"
    5.11  #include "xlinkitem.h"
    5.12  
    5.13  #include <QDir>
    5.14  
    5.15 -using namespace std;
    5.16 -
    5.17  BranchItem::BranchItem(const QList<QVariant> &data, TreeItem *parent):MapItem (data,parent)
    5.18  {
    5.19  	//qDebug()<< "Constr. BranchItem";
    5.20 @@ -31,7 +31,7 @@
    5.21  
    5.22  BranchItem::~BranchItem()
    5.23  {
    5.24 -	qDebug()<< "Destr. BranchItem "<<getHeading();
    5.25 +	//qDebug()<< "Destr. BranchItem this="<<this<<"  "<<getHeading();
    5.26  	if (lmo) 
    5.27  	{
    5.28  		delete lmo;
    5.29 @@ -69,7 +69,7 @@
    5.30  	branchCounter++;
    5.31  }
    5.32  
    5.33 -QString BranchItem::saveToDir (const QString &tmpdir,const QString &prefix, const QPointF& offset) //FIXME-3 Check if everything is saved...
    5.34 +QString BranchItem::saveToDir (const QString &tmpdir,const QString &prefix, const QPointF& offset, QList <Link*> &tmpLinks ) //FIXME-3 Check if everything is saved...
    5.35  {
    5.36  	// Cloudy stuff can be hidden during exports
    5.37  	if (hidden) return QString();
    5.38 @@ -140,27 +140,15 @@
    5.39  	TreeItem *ti=getBranchNum(i);
    5.40  	while (ti)
    5.41  	{
    5.42 -		s+=getBranchNum(i)->saveToDir(tmpdir,prefix,offset);
    5.43 +		s+=getBranchNum(i)->saveToDir(tmpdir,prefix,offset,tmpLinks);
    5.44  		i++;
    5.45  		ti=getBranchNum(i);
    5.46  	}	
    5.47  
    5.48 -	// Save XLinks 
    5.49 -	QString ol;	// old link
    5.50 -	QString cl;	// current link
    5.51 +	// Mark Links for save
    5.52  	for (int i=0; i<xlinkCount(); ++i)
    5.53 -	{
    5.54 -		cl=getXLinkNum(i)->saveToDir();
    5.55 -		if (cl!=ol)
    5.56 -		{
    5.57 -			s+=cl;
    5.58 -			ol=cl;
    5.59 -		} else
    5.60 -		{
    5.61 -			qWarning (QString("BranchItem::saveToDir  Ignoring of duplicate xLink in %1").arg(getHeading()));
    5.62 -			qWarning ()<<"this="<<this<< " i="<<i<<" "<<getXLinkNum(i)<<"  "<<getXLinkNum(i-1);
    5.63 -		}
    5.64 -	}	
    5.65 +		if (!tmpLinks.contains (getXLinkNum (i)->getLink() )) 
    5.66 +			tmpLinks.append (getXLinkNum(i)->getLink() );
    5.67  
    5.68      decIndent();
    5.69      s+=endElement   (elementName);
     6.1 --- a/branchitem.h	Fri Apr 09 14:24:04 2010 +0000
     6.2 +++ b/branchitem.h	Wed Jun 09 13:14:08 2010 +0000
     6.3 @@ -2,11 +2,14 @@
     6.4  #define BRANCHITEM_H
     6.5  
     6.6  #include "mapitem.h"
     6.7 +//#include "xlink.h"
     6.8  
     6.9 +#include <QList>
    6.10  
    6.11  class QString;
    6.12  class QGraphicsScene;
    6.13  class BranchObj;
    6.14 +class Link;
    6.15  class XLinkItem;
    6.16  
    6.17  class BranchItem:public MapItem
    6.18 @@ -19,7 +22,7 @@
    6.19  
    6.20  	virtual void insertBranch (int pos,BranchItem *branch);
    6.21  
    6.22 -	virtual QString saveToDir (const QString &tmpdir,const QString &prefix, const QPointF& offset);
    6.23 +	virtual QString saveToDir (const QString &tmpdir,const QString &prefix, const QPointF& offset,QList <Link*> &tmpLinks);
    6.24  
    6.25  	virtual void updateVisibility();
    6.26  
     7.1 --- a/branchobj.cpp	Fri Apr 09 14:24:04 2010 +0000
     7.2 +++ b/branchobj.cpp	Wed Jun 09 13:14:08 2010 +0000
     7.3 @@ -29,7 +29,7 @@
     7.4  
     7.5  BranchObj::~BranchObj ()
     7.6  {
     7.7 -//	cout << "Destr BranchObj of "<<this<<" ("<<treeItem->getHeading().toStdString()<<")"<<endl;
     7.8 +	//qDebug()<< "Destr BranchObj of "<<this<<" ("<<treeItem->getHeading()<<")";
     7.9  
    7.10  	// If I'm animated, I need to un-animate myself first
    7.11  	if (anim.isAnimated() )
    7.12 @@ -63,9 +63,6 @@
    7.13  void BranchObj::clear() 
    7.14  {
    7.15  	//setVisibility (true); //FIXME-4 needed?
    7.16 -
    7.17 -	while (!xlink.isEmpty())
    7.18 -		delete xlink.takeFirst();
    7.19  }
    7.20  
    7.21  void BranchObj::setParObjTmp(LinkableMapObj* dst, QPointF m, int off)	
    7.22 @@ -251,7 +248,7 @@
    7.23  	// set the frame
    7.24  	frame->setRect(QRectF(bbox.x(),bbox.y(),bbox.width(),bbox.height() ) );
    7.25  
    7.26 -	//Update links to other branches
    7.27 +	//Update links to other branches	
    7.28  	XLinkObj *xlo;
    7.29  	for (int i=0; i<treeItem->xlinkCount(); ++i)	
    7.30  	{
    7.31 @@ -738,22 +735,24 @@
    7.32  	anim=ap;
    7.33  }
    7.34  
    7.35 +void BranchObj::stopAnimation()
    7.36 +{
    7.37 +	anim.stop();
    7.38 +	if (useRelPos)
    7.39 +		setRelPos (anim);
    7.40 +	else
    7.41 +		move (anim);
    7.42 +}
    7.43 +
    7.44  bool BranchObj::animate()
    7.45  {
    7.46  	anim.animate ();
    7.47  	if ( anim.isAnimated() )
    7.48  	{
    7.49 -		//if (((MapItem*)treeItem)->getPositionMode()==MapItem::Relative) 
    7.50  		if (useRelPos)
    7.51 -		{
    7.52  			setRelPos (anim);
    7.53 -			//cout<<"Animating rel "<<treeItem->getHeading().toStdString()<<" "<<anim<<" "<<anim.getStart()<<"->"<<anim.getDest()<<"  "<<relPos<<endl;
    7.54 -		}
    7.55  		else
    7.56 -		{
    7.57  			move (anim);
    7.58 -			//cout<<"Animating abs "<<treeItem->getHeading().toStdString()<<" "<<anim<<" "<<anim.getStart()<<"->"<<anim.getDest()<<"  "<<absPos<<endl;
    7.59 -		}
    7.60  		return true;
    7.61  	}
    7.62  	/*FIXME-3 reposition in BO:animate nearly never reached? needed?	
     8.1 --- a/branchobj.h	Fri Apr 09 14:24:04 2010 +0000
     8.2 +++ b/branchobj.h	Wed Jun 09 13:14:08 2010 +0000
     8.3 @@ -51,11 +51,10 @@
     8.4  	virtual void calcBBoxSizeWithChildren();	// calc size of  BBox including children recursivly
     8.5  
     8.6  	virtual void setAnimation(const AnimPoint &ap);
     8.7 +	virtual void stopAnimation();
     8.8  	virtual bool animate();
     8.9  
    8.10  protected:
    8.11 -	QList<XLinkObj*> xlink;			// xlinks to other branches
    8.12 -
    8.13  	AnimPoint anim;
    8.14  };
    8.15  
     9.1 --- a/editxlinkdialog.cpp	Fri Apr 09 14:24:04 2010 +0000
     9.2 +++ b/editxlinkdialog.cpp	Wed Jun 09 13:14:08 2010 +0000
     9.3 @@ -10,7 +10,7 @@
     9.4  	ui.setupUi (this);
     9.5  
     9.6  	delink=false;
     9.7 -	xli=NULL;
     9.8 +	link=NULL;
     9.9  	selbi=NULL;
    9.10  
    9.11  	connect ( ui.widthBox, SIGNAL (valueChanged( int)), this, SLOT (widthChanged (int)));
    9.12 @@ -33,14 +33,14 @@
    9.13  
    9.14  void EditXLinkDialog::widthChanged( int  w)
    9.15  {
    9.16 -	xli->setWidth(w);
    9.17 +	link->setWidth(w);
    9.18  }
    9.19  
    9.20 -void EditXLinkDialog::setXLink( XLinkItem * xi)
    9.21 +void EditXLinkDialog::setLink( Link * l)
    9.22  {
    9.23 -	xli=xi;
    9.24 -	ui.colorButton->setPaletteBackgroundColor (xli->getColor() );
    9.25 -	ui.widthBox->setValue(xli->getWidth());
    9.26 +	link=l;
    9.27 +	ui.colorButton->setPaletteBackgroundColor (link->getColor() );
    9.28 +	ui.widthBox->setValue(link->getWidth());
    9.29  }
    9.30  
    9.31  void EditXLinkDialog::setSelection(BranchItem *bi)
    9.32 @@ -50,23 +50,23 @@
    9.33  
    9.34  void EditXLinkDialog::colorButtonPressed()
    9.35  {
    9.36 -	if (xli)
    9.37 +	if (link)
    9.38  	{	
    9.39 -		QColor col = QColorDialog::getColor(xli->getColor(), this );
    9.40 +		QColor col = QColorDialog::getColor(link->getColor(), this );
    9.41  		if ( !col.isValid() ) return;
    9.42 -		xli->setColor( col );
    9.43 +		link->setColor( col );
    9.44  		ui.colorButton->setPaletteBackgroundColor (col);
    9.45  	}
    9.46  }
    9.47  
    9.48  void EditXLinkDialog::setColorHeadingButtonPressed()	
    9.49  {
    9.50 -	if (xli)
    9.51 +	if (link)
    9.52  	{	
    9.53  		if (selbi)
    9.54  		{
    9.55  			QColor col=selbi->getHeadingColor();
    9.56 -			xli->setColor(col);
    9.57 +			link->setColor(col);
    9.58  			ui.colorButton->setPaletteBackgroundColor (col);
    9.59  		}
    9.60  	}
    10.1 --- a/editxlinkdialog.h	Fri Apr 09 14:24:04 2010 +0000
    10.2 +++ b/editxlinkdialog.h	Wed Jun 09 13:14:08 2010 +0000
    10.3 @@ -17,7 +17,7 @@
    10.4  	Q_OBJECT
    10.5  public:
    10.6  	EditXLinkDialog (QWidget *parent=0);
    10.7 -	void setXLink (XLinkItem *);
    10.8 +	void setLink (Link *);
    10.9  	void setSelection (BranchItem*);
   10.10  	bool useSettingsGlobal();
   10.11  	bool deleteXLink();
   10.12 @@ -31,7 +31,7 @@
   10.13  private:
   10.14  	Ui::EditXLinkDialog ui;
   10.15  	bool delink;
   10.16 -	XLinkItem *xli;
   10.17 +	Link *link;
   10.18  	BranchItem *selbi;
   10.19  };
   10.20  
    11.1 --- a/exports.cpp	Fri Apr 09 14:24:04 2010 +0000
    11.2 +++ b/exports.cpp	Wed Jun 09 13:14:08 2010 +0000
    11.3 @@ -156,6 +156,8 @@
    11.4  	// Main loop over all branches
    11.5  	QString s;
    11.6  	QString curIndent;
    11.7 +	QString dashIndent;
    11.8 +
    11.9  	int i;
   11.10  	BranchItem *cur=NULL;
   11.11  	BranchItem *prev=NULL;
   11.12 @@ -183,6 +185,8 @@
   11.13  					colString="[G]";
   11.14  				else  	
   11.15  					colString="[?]";
   11.16 +
   11.17 +				dashIndent="";	
   11.18  				switch (cur->depth())
   11.19  				{
   11.20  					case 0:
   11.21 @@ -218,9 +222,14 @@
   11.22  					default:
   11.23  						ts << (curIndent + "- " + cur->getHeading());
   11.24  						ts << "\n";
   11.25 +						dashIndent="  ";
   11.26  						break;
   11.27  				}
   11.28  
   11.29 +				// If necessary, write URL
   11.30 +				if (!cur->getURL().isEmpty())
   11.31 +					ts << (curIndent + dashIndent + cur->getURL()) +"\n";
   11.32 +
   11.33  				// If necessary, write note
   11.34  				if (!cur->getNoteObj().isEmpty())
   11.35  				{
   11.36 @@ -263,6 +272,7 @@
   11.37  	// Main loop over all branches
   11.38  	QString s;
   11.39  	QString curIndent;
   11.40 +	QString dashIndent;
   11.41  	int i;
   11.42  	BranchItem *cur=NULL;
   11.43  	BranchItem *prev=NULL;
   11.44 @@ -279,6 +289,8 @@
   11.45  			if (!cur->hasHiddenExportParent() )
   11.46  			{
   11.47  				//std::cout << "ExportASCII::  "<<curIndent.toStdString()<<cur->getHeading().toStdString()<<std::endl;
   11.48 +
   11.49 +				dashIndent="";
   11.50  				switch (cur->depth())
   11.51  				{
   11.52  					case 0:
   11.53 @@ -294,17 +306,24 @@
   11.54  						ts << "\n";
   11.55  						ts << (curIndent + "* " + cur->getHeading());
   11.56  						ts << "\n";
   11.57 +						dashIndent="  ";
   11.58  						break;
   11.59  					case 3:
   11.60  						ts << (curIndent + "- " + cur->getHeading());
   11.61  						ts << "\n";
   11.62 +						dashIndent="  ";
   11.63  						break;
   11.64  					default:
   11.65  						ts << (curIndent + "- " + cur->getHeading());
   11.66  						ts << "\n";
   11.67 +						dashIndent="  ";
   11.68  						break;
   11.69  				}
   11.70  
   11.71 +				// If necessary, write URL
   11.72 +				if (!cur->getURL().isEmpty())
   11.73 +					ts << (curIndent + dashIndent + cur->getURL()) +"\n";
   11.74 +
   11.75  				// If necessary, write note
   11.76  				if (!cur->getNoteObj().isEmpty())
   11.77  				{
   11.78 @@ -512,10 +531,11 @@
   11.79  			.arg(col)
   11.80  			.arg(id);
   11.81  		QString url=current->getURL();	
   11.82 +		QString heading=quotemeta(current->getHeading());
   11.83  		if (!url.isEmpty())
   11.84  		{
   11.85  			s+=QString ("<a href=\"%1\">").arg(url);
   11.86 -			s+=QString ("<img src=\"flags/flag-url-16x16.png\">%1</a>").arg(quotemeta(current->getHeading()));
   11.87 +			s+=QString ("<img src=\"flags/flag-url-16x16.png\">%1</a>").arg(heading);
   11.88  			s+="</a>";
   11.89  			
   11.90  			QRectF fbox=current->getBBoxURLFlag ();
   11.91 @@ -664,7 +684,9 @@
   11.92  	model->setExportMode (true);
   11.93  
   11.94  	// Write header
   11.95 -	ts<<"<html><title>"+model->getMapName()<<"</title><body>";
   11.96 +	ts<<"<html>";
   11.97 +	ts<<"<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\"> ";
   11.98 +	ts<<"<title>"+model->getMapName()<<"</title><body>";
   11.99  	ts<<" <link rel='stylesheet' id='css.stylesheet' href='"<<cssFileName<<"' />\n";
  11.100  
  11.101  	// Include image
    12.1 --- a/findresultitem.cpp	Fri Apr 09 14:24:04 2010 +0000
    12.2 +++ b/findresultitem.cpp	Wed Jun 09 13:14:08 2010 +0000
    12.3 @@ -11,7 +11,7 @@
    12.4  	orgID=-1;
    12.5  	orgIndex=-1;
    12.6  	orgModel=NULL;
    12.7 -	itemData.append(QVariant("empty"));
    12.8 +	if (data.isEmpty()) itemData.append(QVariant("empty"));
    12.9  }
   12.10  
   12.11  FindResultItem::~FindResultItem()
    13.1 --- a/historywindow.cpp	Fri Apr 09 14:24:04 2010 +0000
    13.2 +++ b/historywindow.cpp	Wed Jun 09 13:14:08 2010 +0000
    13.3 @@ -155,6 +155,7 @@
    13.4  
    13.5  void HistoryWindow::closeEvent (QCloseEvent *)
    13.6  {
    13.7 +	hide();
    13.8  	emit (windowClosed() );
    13.9  }
   13.10  
    14.1 --- a/linkablemapobj.cpp	Fri Apr 09 14:24:04 2010 +0000
    14.2 +++ b/linkablemapobj.cpp	Wed Jun 09 13:14:08 2010 +0000
    14.3 @@ -32,8 +32,12 @@
    14.4  
    14.5  LinkableMapObj::~LinkableMapObj()
    14.6  {
    14.7 -	//cout << "Destructor LMO\n";
    14.8 -    delete (bottomline);
    14.9 +	//cout<< "Destructor LMO style="<<style<<" l="<<l<<"  p="<<p<<"  segment="<<segment.count()<<endl;
   14.10 +    if (bottomline)
   14.11 +	{
   14.12 +		delete (bottomline);
   14.13 +		bottomline=NULL;
   14.14 +	}	
   14.15  	delLink();
   14.16  }
   14.17  
    15.1 --- a/main.cpp	Fri Apr 09 14:24:04 2010 +0000
    15.2 +++ b/main.cpp	Wed Jun 09 13:14:08 2010 +0000
    15.3 @@ -79,7 +79,6 @@
    15.4  	options.add ("run", Option::String, "r", "run");
    15.5  	options.add ("shortcuts", Option::Switch, "s", "shortcuts");
    15.6  	options.add ("shortcutsLaTeX", Option::Switch, "sl", "shortcutsLaTeX");
    15.7 -	options.add ("test", Option::String, "t", "test");
    15.8  	options.add ("version", Option::Switch, "v","version");
    15.9  	options.setHelpText (
   15.10  		"VYM - View Your Mind\n"
   15.11 @@ -87,7 +86,19 @@
   15.12  		"Information about vym can be found in vym.pdf,\n"
   15.13  		"which should be part of the vym package.\n"
   15.14  		"It is also available at the project homepage:\n\n"
   15.15 -		"http://www.InSilmaril.de/vym\n");
   15.16 +		"http://www.InSilmaril.de/vym\n\n"
   15.17 +		"Usage: vym [OPTION]... [FILE]... \n"
   15.18 +		"Open FILEs with vym\n\n"
   15.19 +		"-d           debug       Show debugging output\n"
   15.20 +		"-h           help        Show this help text\n"
   15.21 +		"-l           local       Run with ressources in current directory\n"
   15.22 +		"-n  STRING   name        Set name of instance for DBus access\n"
   15.23 +		"-q           quit        Quit immediatly after start for benchmarking\n"
   15.24 +		"-r  FILE     run         Run script\n"
   15.25 +		"-s           shortcuts   Show Keyboard shortcuts on start\n"
   15.26 +		"-sl          LaTeX       Show Keyboard shortcuts in LaTeX format on start\n"
   15.27 +		"-v           version     Show vym version\n"
   15.28 +	);
   15.29  	if (options.parse())
   15.30  	{
   15.31  		cout << endl << qPrintable( options.getHelpText())<<endl;
   15.32 @@ -98,7 +109,7 @@
   15.33  
   15.34  	if (options.isOn ("version"))
   15.35  	{
   15.36 -		cout << "VYM - View Your Mind (c) 2004-2009 Uwe Drechsel "  << endl
   15.37 +		cout << "VYM - View Your Mind (c) 2004-2010 Uwe Drechsel "  << endl
   15.38  			<<"   Version: "<<__VYM_VERSION <<endl
   15.39  			<<"Build date: "<<__VYM_BUILD_DATE << endl
   15.40  			<<"  "<<__VYM_CODENAME<<endl;
    16.1 --- a/mainwindow.cpp	Fri Apr 09 14:24:04 2010 +0000
    16.2 +++ b/mainwindow.cpp	Wed Jun 09 13:14:08 2010 +0000
    16.3 @@ -720,7 +720,7 @@
    16.4  
    16.5  	a = new QAction(QPixmap(iconPath+"up.png" ), tr( "Move up","Edit menu" ), this);
    16.6  	a->setStatusTip ( tr( "Move branch up" ) );
    16.7 -	a->setShortcut (Qt::Key_PageUp );				// Move branch up	//FIXME-2 If already on top, GraphicsView scrolls up, probably because this action is disabled?!
    16.8 +	a->setShortcut (Qt::Key_PageUp );				// Move branch up	
    16.9  	a->setEnabled (false);
   16.10  	switchboard.addConnection(a,tr("Edit","Shortcut group"));
   16.11  	tb->addAction (a);
   16.12 @@ -2001,7 +2001,7 @@
   16.13  		fileNew();
   16.14  		VymModel *dstModel=vymViews.last()->getModel();
   16.15  		dstModel->select("mc:");
   16.16 -		dstModel->load (clipboardDir+"/"+clipboardFile,ImportReplace, VymMap);
   16.17 +		dstModel->loadMap (clipboardDir+"/"+clipboardFile,ImportReplace);
   16.18  	}
   16.19  }
   16.20  
   16.21 @@ -2116,7 +2116,7 @@
   16.22  
   16.23  			// Finally load map into mapEditor
   16.24  			vm->setFilePath (fn);
   16.25 -			err=vm->load(fn,lmode,ftype);
   16.26 +			err=vm->loadMap(fn,lmode,true,ftype);
   16.27  
   16.28  			// Restore old (maybe empty) filepath, if this is an import
   16.29  			if (lmode!=NewMap)
   16.30 @@ -2571,11 +2571,12 @@
   16.31  	}
   16.32  }
   16.33  
   16.34 -void Main::fileCloseMap()	
   16.35 +bool Main::fileCloseMap()	
   16.36  {
   16.37  	VymModel *m=currentModel();
   16.38  	if (m)
   16.39  	{
   16.40 +		//qDebug()<<"Main::fileCloseMap  currentIndex="<<tabWidget->currentIndex();
   16.41  		if (m->hasChanged())
   16.42  		{
   16.43  			QMessageBox mb( vymName,
   16.44 @@ -2586,6 +2587,9 @@
   16.45  				QMessageBox::Cancel | QMessageBox::Escape );
   16.46  			mb.setButtonText( QMessageBox::Yes, tr("Save modified map before closing it") );
   16.47  			mb.setButtonText( QMessageBox::No, tr("Discard changes"));
   16.48 +			mb.setModal (true);
   16.49 +			mb.show();
   16.50 +			mb.setActiveWindow();
   16.51  			switch( mb.exec() ) 
   16.52  			{
   16.53  				case QMessageBox::Yes:
   16.54 @@ -2597,7 +2601,7 @@
   16.55  					break;
   16.56  				case QMessageBox::Cancel:
   16.57  					// do nothing
   16.58 -				return;
   16.59 +					return true;
   16.60  			}
   16.61  		} 
   16.62  		// And here comes the segfault, because removeTab triggers 
   16.63 @@ -2609,7 +2613,9 @@
   16.64  		//delete (m->getMapEditor());
   16.65  
   16.66  		updateActions();
   16.67 +		return false;
   16.68  	}
   16.69 +	return true; // Better don't exit vym if there is no currentModel()...
   16.70  }
   16.71  
   16.72  void Main::filePrint()
   16.73 @@ -2618,41 +2624,16 @@
   16.74  		currentMapEditor()->print();
   16.75  }
   16.76  
   16.77 -void Main::fileExitVYM()
   16.78 +void Main::fileExitVYM()	
   16.79  {
   16.80  	// Check if one or more editors have changed
   16.81 -	int i;
   16.82 -	for (i=0;i<=vymViews.count() -1;i++)
   16.83 +	int i=0;
   16.84 +	while (vymViews.count()>0)
   16.85  	{
   16.86 -		// If something changed, ask what to do
   16.87 -		if (vymViews.at(i)->getModel()->hasChanged())
   16.88 -		{
   16.89 -			tabWidget->setCurrentPage(i);
   16.90 -			QMessageBox mb( vymName,
   16.91 -				tr("This map is not saved yet. Do you want to"),
   16.92 -				QMessageBox::Warning,
   16.93 -				QMessageBox::Yes | QMessageBox::Default,
   16.94 -				QMessageBox::No,
   16.95 -				QMessageBox::Cancel | QMessageBox::Escape );
   16.96 -			mb.setButtonText( QMessageBox::Yes, tr("Save map") );
   16.97 -			mb.setButtonText( QMessageBox::No, tr("Discard changes") );
   16.98 -			mb.setModal (true);
   16.99 -			mb.show();
  16.100 -			mb.setActiveWindow();
  16.101 -			switch( mb.exec() ) {
  16.102 -				case QMessageBox::Yes:
  16.103 -					// save (the changed editors) and exit
  16.104 -					fileSave(currentModel(), CompleteMap);
  16.105 -					break;
  16.106 -				case QMessageBox::No:
  16.107 -					// exit without saving
  16.108 -					break;
  16.109 -				case QMessageBox::Cancel:
  16.110 -					// don't save and don't exit
  16.111 -				return;
  16.112 -			}
  16.113 -		}
  16.114 -	} // loop over all MEs	
  16.115 +		//qDebug()<<"Main::fileExitVym  count="<<vymViews.count();
  16.116 +		tabWidget->setCurrentPage(i);
  16.117 +		if (fileCloseMap()) return;
  16.118 +	} 
  16.119      qApp->quit();
  16.120  }
  16.121  
  16.122 @@ -2784,12 +2765,6 @@
  16.123  				// Try to open new tab in existing konqueror started previously by vym
  16.124  				args.clear();
  16.125  
  16.126 -/*	On KDE3 use DCOP
  16.127 -				args<< QString("konqueror-%1").arg(procBrowser->pid())<<
  16.128 -					"konqueror-mainwindow#1"<<
  16.129 -					"newTab" <<
  16.130 -					urls.at(i);
  16.131 -*/					
  16.132  				args<< QString("org.kde.konqueror-%1").arg(*browserPID)<<
  16.133  					"/konqueror/MainWindow_1"<<
  16.134  					"newTab" <<
  16.135 @@ -2837,7 +2812,7 @@
  16.136  		QString browser=settings.value("/mainwindow/readerURL" ).toString();
  16.137  		args<<url;
  16.138  		QString workDir=QDir::currentDirPath();
  16.139 -		if (!procBrowser->startDetached(browser,args))
  16.140 +		if (!QProcess::startDetached(browser,args))
  16.141  		{
  16.142  			// try to set path to browser
  16.143  			QMessageBox::warning(0, 
  16.144 @@ -3049,7 +3024,7 @@
  16.145  		m->nextBranch(cur,prev);
  16.146  	}
  16.147  
  16.148 -    stats+=QString ("%1 xLinks \n").arg (xl,6);
  16.149 +    stats+=QString ("%1 xLinks \n").arg (xl/2,6);
  16.150      stats+=QString ("%1 notes\n").arg (n,6);
  16.151      stats+=QString ("%1 images\n").arg (f,6);
  16.152      stats+=QString ("%1 branches\n").arg (m->branchCount(),6);
  16.153 @@ -3671,7 +3646,7 @@
  16.154  
  16.155  void Main::updateActions()
  16.156  {
  16.157 -	// updateActions is also called when satellites are closed	//FIXME-2 doesn't update immediatly, e.g. historyWindow is still visible, when "close" is pressed
  16.158 +	// updateActions is also called when satellites are closed	
  16.159  	actionViewToggleNoteEditor->setChecked (textEditor->isVisible());
  16.160  	actionViewToggleHistoryWindow->setChecked (historyWindow->isVisible());
  16.161  	actionViewTogglePropertyWindow->setChecked (branchPropertyWindow->isVisible());
    17.1 --- a/mainwindow.h	Fri Apr 09 14:24:04 2010 +0000
    17.2 +++ b/mainwindow.h	Wed Jun 09 13:14:08 2010 +0000
    17.3 @@ -109,7 +109,7 @@
    17.4      void fileExportKDE4Bookmarks();
    17.5      void fileExportTaskjuggler();
    17.6      void fileExportOOPresentation();
    17.7 -    void fileCloseMap();
    17.8 +    bool fileCloseMap();
    17.9      void filePrint();
   17.10      void fileExitVYM();
   17.11  
   17.12 @@ -258,7 +258,6 @@
   17.13  
   17.14  private:
   17.15  	QTabWidget *tabWidget;
   17.16 -	QProcess *procBrowser;		//FIXME-2 remove this...
   17.17  	qint64 *browserPID;
   17.18  
   17.19  	QStringList imageTypes;
    18.1 --- a/mapeditor.cpp	Fri Apr 09 14:24:04 2010 +0000
    18.2 +++ b/mapeditor.cpp	Wed Jun 09 13:14:08 2010 +0000
    18.3 @@ -125,7 +125,7 @@
    18.4  	selectionColor =QColor (255,255,0);
    18.5  	
    18.6  
    18.7 -	// Attributes	//FIXME-2 testing only...
    18.8 +	// Attributes	//FIXME-3 testing only...
    18.9  	QString k;
   18.10  	AttributeDef *ad;
   18.11  	attrTable= new AttributeTable();
   18.12 @@ -160,8 +160,7 @@
   18.13  
   18.14  MapEditor::~MapEditor()
   18.15  {
   18.16 -	//qDebug() <<"Destructor MapEditor for "<<model->getMapName();
   18.17 -	//model->unregisterEditor(this);
   18.18 +	//qDebug ()<<"Destr MapEditor this="<<this;
   18.19  }
   18.20  
   18.21  VymModel* MapEditor::getModel()
   18.22 @@ -1070,28 +1069,20 @@
   18.23  				if ((lmo->getOrientation()!=LinkableMapObj::RightOfCenter && p.x() < lmo->getBBox().left()+20)  ||
   18.24  				    (lmo->getOrientation()!=LinkableMapObj::LeftOfCenter && p.x() > lmo->getBBox().right()-20) ) 
   18.25  				{
   18.26 -					// FIXME-4 if (ti->xlinkCount()>1)
   18.27 -					if (true)
   18.28 +					QMenu menu;
   18.29 +					QList <QAction*> alist;
   18.30 +					for (int i=0;i<ti->xlinkCount();i++)
   18.31 +						alist.append (new QAction(ti->getXLinkNum(i)->getPartnerBranch()->getHeading(),&menu));
   18.32 +					menu.addActions (alist);	
   18.33 +					QAction *ra=menu.exec (e->globalPos() );
   18.34 +					if (ra)
   18.35 +						model->select (ti->getXLinkNum(alist.indexOf(ra))->getPartnerBranch ());
   18.36 +					while (!alist.isEmpty())
   18.37  					{
   18.38 -						QMenu menu;
   18.39 -						QList <QAction*> alist;
   18.40 -						for (int i=0;i<ti->xlinkCount();i++)
   18.41 -							alist.append (new QAction(ti->getXLinkNum(i)->getOtherBranch(ti)->getHeading(),&menu));
   18.42 -						menu.addActions (alist);	
   18.43 -						QAction *ra=menu.exec (e->globalPos() );
   18.44 -						if (ra)
   18.45 -							model->select (ti->getXLinkNum(alist.indexOf(ra))->getOtherBranch (ti));
   18.46 -						while (!alist.isEmpty())
   18.47 -						{
   18.48 -							QAction *a=alist.takeFirst();
   18.49 -							delete a;
   18.50 -						}	
   18.51 -						return;
   18.52 -					} else
   18.53 -					{
   18.54 -						model->select (ti->getXLinkNum(0)->getOtherBranch (ti));
   18.55 -						return;
   18.56 -					}
   18.57 +						QAction *a=alist.takeFirst();
   18.58 +						delete a;
   18.59 +					}	
   18.60 +					return;
   18.61  				}	
   18.62  			}
   18.63  		}
   18.64 @@ -1112,11 +1103,13 @@
   18.65  			if (bi_begin)	
   18.66  			{
   18.67  				drawingLink=true;
   18.68 -				tmpXLink=model->createXLink(bi_begin,true);
   18.69 -				tmpXLink->setColor(model->getMapDefXLinkColor());
   18.70 -				tmpXLink->setWidth(model->getMapDefXLinkWidth());
   18.71 -				tmpXLink->setEnd   (p);
   18.72 -				tmpXLink->updateXLink();
   18.73 +				tmpLink=new Link (model);
   18.74 +				tmpLink->setBeginBranch (bi_begin);
   18.75 +				tmpLink->setColor(model->getMapDefXLinkColor());
   18.76 +				tmpLink->setWidth(model->getMapDefXLinkWidth());
   18.77 +				tmpLink->setEndPoint   (p);
   18.78 +				tmpLink->createMapObj(mapScene);
   18.79 +				tmpLink->updateLink();
   18.80  				return;
   18.81  			} 
   18.82  		}
   18.83 @@ -1141,8 +1134,11 @@
   18.84  			movingObj_start.setY( p.y() - lmo->y() );	
   18.85  			movingObj_orgPos.setX (lmo->x() );
   18.86  			movingObj_orgPos.setY (lmo->y() );
   18.87 -			lmo->setRelPos();
   18.88 -			movingObj_orgRelPos=lmo->getRelPos();
   18.89 +			if (ti->depth()>0)
   18.90 +			{
   18.91 +				lmo->setRelPos();	
   18.92 +				movingObj_orgRelPos=lmo->getRelPos();
   18.93 +			}
   18.94  
   18.95  			// If modMode==copy, then we want to "move" the _new_ object around
   18.96  			// then we need the offset from p to the _old_ selection, because of tmp
   18.97 @@ -1204,11 +1200,10 @@
   18.98  		if (mainWindow->getModMode()!=Main::ModModeCopy)
   18.99  			setCursor (Qt::ArrowCursor);
  18.100  
  18.101 +		// Scroll if needed
  18.102  		// To avoid jumping of the sceneView, only 
  18.103  		// show selection, if not tmp linked
  18.104 -		/* FIXME-2 if (!lmosel->hasParObjTmp())
  18.105 -			model->emitShowSelection();
  18.106 -			*/
  18.107 +		model->emitShowSelection();
  18.108  		
  18.109  		// Now move the selection, but add relative position 
  18.110  		// (movingObj_start) where selection was chosen with 
  18.111 @@ -1275,6 +1270,7 @@
  18.112  						seli->getBranchObjNum(i)->setOrientation();
  18.113  					}
  18.114  				}	
  18.115 +				lmosel->move   (p-movingObj_start);		
  18.116  			} else
  18.117  			{	
  18.118  				if (seli->depth()==1)
  18.119 @@ -1326,8 +1322,8 @@
  18.120  	// Draw a link from one branch to another
  18.121  	if (drawingLink)
  18.122  	{
  18.123 -		 tmpXLink->setEnd (p);
  18.124 -		 tmpXLink->updateXLink();
  18.125 +		 tmpLink->setEndPoint (p);
  18.126 +		 tmpLink->updateLink();
  18.127  	}	 
  18.128  	
  18.129      // Move sceneView 
  18.130 @@ -1380,18 +1376,20 @@
  18.131  		// Check if we are over another branch
  18.132  		if (dsti)
  18.133  		{	
  18.134 -			tmpXLink->setEnd ( ((BranchItem*)dsti) );
  18.135 -			tmpXLink->updateXLink();
  18.136 -			tmpXLink->activate(); 
  18.137 +			tmpLink->setEndBranch ( ((BranchItem*)dsti) );
  18.138 +			tmpLink->updateLink();
  18.139 +			model->createLink (tmpLink);
  18.140 +			/* FIXME-2 Link savestate missing, segfaulting on undo
  18.141  			model->saveState(
  18.142  				tmpXLink,QString("delete ()"),
  18.143  				dsti,QString("addXLink (\"%1\",\"%2\")").arg(model->getSelectString(tmpXLink->getBegin())).arg(model->getSelectString(dsti)),
  18.144  				QString("Add xLink from %1 to %2").arg(model->getObjectName(tmpXLink->getBegin())).arg(model->getObjectName(dsti)) 
  18.145  			);	
  18.146 +			*/
  18.147  		} else
  18.148  		{
  18.149 -			model->deleteItem(tmpXLink);
  18.150 -			tmpXLink=NULL;
  18.151 +			delete (tmpLink);
  18.152 +			tmpLink=NULL;
  18.153  		}
  18.154  		return;
  18.155  	}
  18.156 @@ -1576,6 +1574,13 @@
  18.157  	}
  18.158  }
  18.159  
  18.160 +void MapEditor::wheelEvent(QWheelEvent* e)
  18.161 +{
  18.162 +	//qDebug ()<<"ME::wheelEvent";	//FIXME-2 stop all animations in vymModel here
  18.163 +	//model->stopAllAnimation();
  18.164 +	QGraphicsView::wheelEvent (e);
  18.165 +}
  18.166 +
  18.167  void MapEditor::resizeEvent (QResizeEvent* e)
  18.168  {
  18.169  	QGraphicsView::resizeEvent( e );
    19.1 --- a/mapeditor.h	Fri Apr 09 14:24:04 2010 +0000
    19.2 +++ b/mapeditor.h	Wed Jun 09 13:14:08 2010 +0000
    19.3 @@ -7,6 +7,7 @@
    19.4  #include <QPropertyAnimation>	
    19.5  
    19.6  #include "attribute.h"
    19.7 +#include "xlink.h"
    19.8  #include "ornamentedobj.h"
    19.9  #include "settings.h"
   19.10  #include "vymmodel.h"
   19.11 @@ -93,6 +94,8 @@
   19.12      virtual void mouseMoveEvent(QMouseEvent*);
   19.13      virtual void mouseReleaseEvent(QMouseEvent*);
   19.14      virtual void mouseDoubleClickEvent(QMouseEvent*);
   19.15 +    virtual void wheelEvent(QWheelEvent*);
   19.16 +
   19.17      virtual void resizeEvent( QResizeEvent * );
   19.18  
   19.19  	void dragEnterEvent (QDragEnterEvent *);
   19.20 @@ -116,7 +119,7 @@
   19.21  	bool drawingLink;			// true while creating a link
   19.22  	bool copyingObj;			// true while modModeCopy
   19.23  	bool objectMoved;			// true if object was not clicked, but moved with mouse
   19.24 -	XLinkItem* tmpXLink;
   19.25 +	Link* tmpLink;
   19.26  
   19.27  	MapObj* movingObj;				// moving a MapObj
   19.28      QPointF movingObj_orgPos;		// org. pos of mouse before move
    20.1 --- a/noteobj.cpp	Fri Apr 09 14:24:04 2010 +0000
    20.2 +++ b/noteobj.cpp	Wed Jun 09 13:14:08 2010 +0000
    20.3 @@ -52,7 +52,7 @@
    20.4  	return getNoteASCII ("",80);
    20.5  }
    20.6  
    20.7 -QString NoteObj::getNoteASCII(QString indent, const int &width)
    20.8 +QString NoteObj::getNoteASCII(QString indent, const int &)	//FIXME-3 use width
    20.9  {
   20.10  	if (note.isEmpty()) return note;
   20.11  	QString r=note;
    21.1 --- a/treeitem.cpp	Fri Apr 09 14:24:04 2010 +0000
    21.2 +++ b/treeitem.cpp	Wed Jun 09 13:14:08 2010 +0000
    21.3 @@ -17,7 +17,7 @@
    21.4  
    21.5  TreeItem::TreeItem()
    21.6  {
    21.7 -	cout << "Constr. TI  this="<<this<<endl;
    21.8 +	//cout << "Constr. TI  this="<<this<<endl;
    21.9  	init();
   21.10  	itemData.clear();
   21.11  	rootItem=this;
   21.12 @@ -38,13 +38,30 @@
   21.13  
   21.14  TreeItem::~TreeItem()
   21.15  {
   21.16 -	//cout << "Destructor TreeItem "<<getHeadingStd()<<endl;
   21.17 +	//qDebug()<<"Destr TreeItem this="<<this<<"  childcount="<<childItems.count();
   21.18 +	/*
   21.19 +	qDeleteAll(childItems);	// Call delete	//FIXME-3 use this instead of below
   21.20 +	qDebug()<<"  ok1";
   21.21 +	childItems.clear();		// and clear list
   21.22 +	qDebug()<<"  ok2";use
   21.23 +	*/
   21.24 +
   21.25 +	/*
   21.26 +	if (this==rootItem)
   21.27 +	{
   21.28 +		qDebug()<<"  I'm rootItem, aborting";
   21.29 +		return;
   21.30 +	}
   21.31 +	*/
   21.32 +	//qDebug()<<"                   ="<<getHeading();
   21.33  	TreeItem *ti;
   21.34  	while (!childItems.isEmpty())
   21.35  	{
   21.36 +		//qDebug()<<"    ="<<ti->getHeading();
   21.37  		ti=childItems.takeFirst();
   21.38 +		//qDebug()<<"  ti="<<ti;
   21.39  		delete ti;
   21.40 -	}	
   21.41 +	}
   21.42  }
   21.43  
   21.44  
   21.45 @@ -316,6 +333,7 @@
   21.46  void TreeItem::setHeading (const QString s)
   21.47  {
   21.48  	itemData[0]=s;
   21.49 +	//qDebug()<<"TI::setHeading this="<<this<<"  "<<s;
   21.50  }
   21.51  
   21.52  QString TreeItem::getHeading () const
   21.53 @@ -591,9 +609,17 @@
   21.54  {
   21.55  	if (n>=0 && n<branchCounter)
   21.56  	{
   21.57 -		return (BranchObj*)(getBranchNum(n)->getLMO());
   21.58 -	} else
   21.59 -		return NULL;
   21.60 +		BranchItem *bi=getBranchNum(n);
   21.61 +		if (bi)
   21.62 +		{
   21.63 +			BranchObj *bo=(BranchObj*)(bi->getLMO());
   21.64 +			if (bo)
   21.65 +				return bo;
   21.66 +			else
   21.67 +				qDebug()<<"TI::getBONum bo=NULL";
   21.68 +		}
   21.69 +	} 
   21.70 +	return NULL;
   21.71  }
   21.72  
   21.73  ImageItem* TreeItem::getImageNum (const int &n)
   21.74 @@ -634,14 +660,10 @@
   21.75  	if (xlinkCounter>0 )
   21.76  	{
   21.77  		XLinkItem *xli=getXLinkNum (n);
   21.78 -		if (!xli) return NULL;
   21.79 -		if (xli->isBegin() )
   21.80 -			return (XLinkObj*)(xli->getLMO());
   21.81 -		else
   21.82 +		if (xli)
   21.83  		{
   21.84 -			xli=xli->getPartnerXLink();
   21.85 -			if (!xli) return NULL;
   21.86 -			return (XLinkObj*)(xli->getLMO());
   21.87 +			Link *l=xli->getLink();
   21.88 +			if (l) return l->getXLinkObj();
   21.89  		}
   21.90  	}
   21.91  	return NULL;
    22.1 --- a/treemodel.cpp	Fri Apr 09 14:24:04 2010 +0000
    22.2 +++ b/treemodel.cpp	Wed Jun 09 13:14:08 2010 +0000
    22.3 @@ -17,6 +17,7 @@
    22.4  
    22.5  TreeModel::~TreeModel()
    22.6  {
    22.7 +	//qDebug()<<"Destr TreeModel  this="<<this;
    22.8      delete rootItem;
    22.9  }
   22.10  
    23.1 --- a/treemodel.h	Fri Apr 09 14:24:04 2010 +0000
    23.2 +++ b/treemodel.h	Wed Jun 09 13:14:08 2010 +0000
    23.3 @@ -8,6 +8,7 @@
    23.4  
    23.5  class BranchItem;
    23.6  class TreeItem;
    23.7 +class Link;
    23.8  class LinkableMapObj;
    23.9  
   23.10  class TreeModel : public QAbstractItemModel
   23.11 @@ -40,6 +41,10 @@
   23.12  
   23.13  protected:
   23.14      BranchItem *rootItem;
   23.15 +
   23.16 +	QList <Link*> xlinks;
   23.17 +	QList <Link*> xlinks_obsolete;
   23.18 +
   23.19  };
   23.20  
   23.21  #endif
    24.1 --- a/version.h	Fri Apr 09 14:24:04 2010 +0000
    24.2 +++ b/version.h	Wed Jun 09 13:14:08 2010 +0000
    24.3 @@ -4,10 +4,10 @@
    24.4  #include <QString>
    24.5  
    24.6  #define __VYM_NAME "VYM"
    24.7 -#define __VYM_VERSION "1.13.3"
    24.8 +#define __VYM_VERSION "1.13.4"
    24.9  //#define __VYM_CODENAME "Codename: RC-1"
   24.10  #define __VYM_CODENAME "Codename: development version, not for production!"
   24.11 -#define __VYM_BUILD_DATE "2010-04-09"
   24.12 +#define __VYM_BUILD_DATE "2010-06-08"
   24.13  
   24.14  
   24.15  bool checkVersion(const QString &);
    25.1 --- a/vym.changelog	Fri Apr 09 14:24:04 2010 +0000
    25.2 +++ b/vym.changelog	Wed Jun 09 13:14:08 2010 +0000
    25.3 @@ -1,3 +1,43 @@
    25.4 +-------------------------------------------------------------------
    25.5 +Tue Jun  8 17:17:41 CEST 2010 - vym@insilmaril.de
    25.6 +
    25.7 +- Version: 1.13.4   
    25.8 +- Bugfix: ImportReplace of a map with multiple mapcenters 
    25.9 +- Bugfix: Toolbar icon updated immediatly when history window is closed
   25.10 +
   25.11 +-------------------------------------------------------------------
   25.12 +Mon Jun  7 10:40:15 CEST 2010 - vym@insilmaril.de
   25.13 +
   25.14 +- Bugfix: Umlauts in HTML export (set encoding to UTF-8)
   25.15 +- Bugfix: xLink handling while deleting/restoring xLinks
   25.16 +
   25.17 +-------------------------------------------------------------------
   25.18 +Tue Jun  1 15:50:44 CEST 2010 - vym@insilmaril.de
   25.19 +
   25.20 +- Version: 1.13.3   
   25.21 +- Bugfix: Rewrote xlink engine in large parts to address 
   25.22 +          several issues
   25.23 +
   25.24 +-------------------------------------------------------------------
   25.25 +Fri Apr 30 10:26:59 CEST 2010 - vym@insilmaril.de
   25.26 +
   25.27 +- Bugfix: Don't reset zoomFactor after load
   25.28 +
   25.29 +-------------------------------------------------------------------
   25.30 +Thu Apr 29 13:16:50 CEST 2010 - vym@insilmaril.de
   25.31 +
   25.32 +- Feature: Added some helptext about commandline options 
   25.33 +
   25.34 +-------------------------------------------------------------------
   25.35 +Wed Apr 28 17:43:10 CEST 2010 - vym@insilmaril.de
   25.36 +
   25.37 +- Feature: ASCII exports show URLs now
   25.38 +
   25.39 +-------------------------------------------------------------------
   25.40 +Thu Apr 22 16:07:44 CEST 2010 - vym@insilmaril.de
   25.41 +
   25.42 +- Bugfix: Removed empty field in findresults TreeView
   25.43 +
   25.44  -------------------------------------------------------------------
   25.45  Fri Apr  9 16:12:55 CEST 2010 - vym@insilmaril.de
   25.46  
    26.1 --- a/vym.pro	Fri Apr 09 14:24:04 2010 +0000
    26.2 +++ b/vym.pro	Wed Jun 09 13:14:08 2010 +0000
    26.3 @@ -91,6 +91,7 @@
    26.4  	vymmodel.h \
    26.5  	vymview.h \
    26.6  	warningdialog.h \
    26.7 +	xlink.h \
    26.8  	xlinkitem.h \
    26.9  	xlinkobj.h \
   26.10  	xml-base.h \
   26.11 @@ -161,6 +162,7 @@
   26.12  	vymmodel.cpp \
   26.13  	vymview.cpp \
   26.14  	warningdialog.cpp \
   26.15 +	xlink.cpp \
   26.16  	xlinkitem.cpp \
   26.17  	xlinkobj.cpp \
   26.18  	xml-base.cpp \
   26.19 @@ -225,4 +227,4 @@
   26.20  INSTALLS += doc
   26.21  DEFINES += VYM_DOCDIR=\\\"$${DOCDIR}\\\"
   26.22  
   26.23 -include(test/modeltest/modeltest.pri)
   26.24 +#include(test/modeltest/modeltest.pri)
    27.1 --- a/vymmodel.cpp	Fri Apr 09 14:24:04 2010 +0000
    27.2 +++ b/vymmodel.cpp	Wed Jun 09 13:14:08 2010 +0000
    27.3 @@ -12,14 +12,13 @@
    27.4  #include "exporthtmldialog.h"
    27.5  #include "file.h"
    27.6  #include "findresultmodel.h"
    27.7 -#include "geometry.h"		// for addBBox
    27.8  #include "mainwindow.h"
    27.9  #include "misc.h"
   27.10  #include "parser.h"
   27.11  #include "process.h"
   27.12  
   27.13 -#include "warningdialog.h"
   27.14  #include "xlinkitem.h"
   27.15 +#include "xlinkobj.h"
   27.16  #include "xml-freemind.h"
   27.17  #include "xmlobj.h"
   27.18  #include "xml-vym.h"
   27.19 @@ -54,7 +53,7 @@
   27.20  
   27.21  VymModel::VymModel()
   27.22  {
   27.23 -    //cout << "Const VymModel\n";
   27.24 +    //qDebug()<< "Const VymModel";
   27.25  	init();
   27.26  	rootItem->setModel (this);
   27.27  }
   27.28 @@ -62,18 +61,20 @@
   27.29  
   27.30  VymModel::~VymModel() 
   27.31  {
   27.32 -    //cout << "Destr VymModel\n";
   27.33 +    //qDebug() << "Destr VymModel begin this="<<this;
   27.34  	autosaveTimer->stop();
   27.35  	fileChangedTimer->stop();
   27.36 -	clear();
   27.37 -	if (mapEditor) delete (mapEditor);
   27.38 +	//qApp->processEvents();	// Update view (scene()->update() is not enough)
   27.39 +    //qDebug() << "Destr VymModel end   this="<<this;
   27.40  }	
   27.41  
   27.42  void VymModel::clear() 
   27.43  {
   27.44 -	unselect();
   27.45  	while (rootItem->childCount() >0)
   27.46 +	{
   27.47 +		//qDebug()<<"VM::clear  ri="<<rootItem<<"  ri->count()="<<rootItem->childCount();
   27.48  		deleteItem (rootItem->getChildNum(0) );
   27.49 +	}
   27.50  }
   27.51  
   27.52  void VymModel::init () 
   27.53 @@ -125,11 +126,11 @@
   27.54  	// find routine
   27.55  	findReset();
   27.56  
   27.57 -	// animations	// FIXME-3 switch to new animation system 
   27.58 -	animationUse=settings.readBoolEntry("/animation/use",false);	// FIXME-3 add options to control _what_ is animated
   27.59 +	// animations	// FIXME-4 switch to new animation system 
   27.60 +	animationUse=settings.readBoolEntry("/animation/use",false);	// FIXME-4 add options to control _what_ is animated
   27.61  	animationTicks=settings.readNumEntry("/animation/ticks",10);
   27.62  	animationInterval=settings.readNumEntry("/animation/interval",50);
   27.63 -	animObjList.clear();
   27.64 +	animObjList.clear();	
   27.65  	animationTimer=new QTimer (this);
   27.66  	connect(animationTimer, SIGNAL(timeout()), this, SLOT(animate()));
   27.67  
   27.68 @@ -144,6 +145,9 @@
   27.69  
   27.70  	hidemode=TreeItem::HideNone;
   27.71  
   27.72 +	// Avoid recursions later
   27.73 +	cleaningUpLinks=false;
   27.74 +
   27.75  	// Network
   27.76  	netstate=Offline;
   27.77  
   27.78 @@ -236,21 +240,34 @@
   27.79  	// Find the used flags while traversing the tree	// FIXME-3 this can be done local to vymmodel maybe...
   27.80  	standardFlagsMaster->resetUsedCounter();
   27.81  	
   27.82 +
   27.83 +	// Temporary list of links
   27.84 +	QList <Link*> tmpLinks;
   27.85 +
   27.86  	// Build xml recursivly
   27.87  	if (!saveSel)
   27.88 +	{
   27.89  		// Save all mapcenters as complete map, if saveSel not set
   27.90 -		s+=saveTreeToDir(tmpdir,prefix,offset);
   27.91 -	else
   27.92 +			s+=saveTreeToDir(tmpdir,prefix,offset,tmpLinks);
   27.93 +
   27.94 +		// Save local settings
   27.95 +		s+=settings.getDataXML (destPath);
   27.96 +
   27.97 +		// Save selection
   27.98 +		if (getSelectedItem() && !saveSel ) 
   27.99 +			s+=xml.valueElement("select",getSelectString());
  27.100 +
  27.101 +	} else
  27.102  	{
  27.103  		switch (saveSel->getType())
  27.104  		{
  27.105  			case TreeItem::Branch:
  27.106  				// Save Subtree
  27.107 -				s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset);
  27.108 +				s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset,tmpLinks);
  27.109  				break;
  27.110  			case TreeItem::MapCenter:
  27.111  				// Save Subtree
  27.112 -				s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset);
  27.113 +				s+=((BranchItem*)saveSel)->saveToDir(tmpdir,prefix,offset,tmpLinks);
  27.114  				break;
  27.115  			case TreeItem::Image:
  27.116  				// Save Image
  27.117 @@ -262,12 +279,11 @@
  27.118  		}
  27.119  	}
  27.120  
  27.121 -	// Save local settings
  27.122 -	s+=settings.getDataXML (destPath);
  27.123 -
  27.124 -	// Save selection
  27.125 -	if (getSelectedItem() && !saveSel ) 
  27.126 -		s+=xml.valueElement("select",getSelectString());
  27.127 +	// Save XLinks
  27.128 +	for (int i=0; i<tmpLinks.count();++i)
  27.129 +	{
  27.130 +		s+=tmpLinks.at(i)->saveToDir();
  27.131 +	}
  27.132  
  27.133  	xml.decIndent();
  27.134  	s+=xml.endElement("vymmap");
  27.135 @@ -278,12 +294,11 @@
  27.136  	return s;
  27.137  }
  27.138  
  27.139 -QString VymModel::saveTreeToDir (const QString &tmpdir,const QString &prefix, const QPointF &offset)
  27.140 +QString VymModel::saveTreeToDir (const QString &tmpdir,const QString &prefix, const QPointF &offset, QList <Link*> &tmpLinks)
  27.141  {
  27.142      QString s;
  27.143 -
  27.144  	for (int i=0; i<rootItem->branchCount(); i++)
  27.145 -		s+=rootItem->getBranchNum(i)->saveToDir (tmpdir,prefix,offset);
  27.146 +		s+=rootItem->getBranchNum(i)->saveToDir (tmpdir,prefix,offset,tmpLinks);
  27.147      return s;
  27.148  }
  27.149  
  27.150 @@ -338,10 +353,22 @@
  27.151  	return destPath;
  27.152  }
  27.153  
  27.154 -ErrorCode VymModel::load (QString fname, const LoadMode &lmode, const FileType &ftype)
  27.155 +ErrorCode VymModel::loadMap (
  27.156 +	QString fname, 
  27.157 +	const LoadMode &lmode, 
  27.158 +	bool saveStateFlag, 
  27.159 +	const FileType &ftype,
  27.160 +	int pos)
  27.161  {
  27.162  	ErrorCode err=success;
  27.163  
  27.164 +	// Get updated zoomFactor, before applying one read from file in the end
  27.165 +	if (mapEditor) zoomFactor=mapEditor->getZoomFactorTarget();
  27.166 +
  27.167 +	// For ImportReplace let's insert a new branch and replace that
  27.168 +	BranchItem *selbi=getSelectedBranch();
  27.169 +	BranchItem *newbi=NULL;
  27.170 +
  27.171  	parseBaseHandler *handler;
  27.172  	fileType=ftype;
  27.173  	switch (fileType)
  27.174 @@ -361,20 +388,23 @@
  27.175  		selModel->clearSelection();
  27.176  	} else
  27.177  	{
  27.178 -		BranchItem *bi=getSelectedBranch();
  27.179 -		if (!bi) return aborted;
  27.180 +		if (!selbi) return aborted;
  27.181  		if (lmode==ImportAdd)
  27.182 -			saveStateChangingPart(
  27.183 -				bi,
  27.184 -				bi,
  27.185 +			if (saveStateFlag) saveStateChangingPart(
  27.186 +				selbi,
  27.187 +				selbi,
  27.188  				QString("addMapInsert (%1)").arg(fname),
  27.189 -				QString("Add map %1 to %2").arg(fname).arg(getObjectName(bi)));
  27.190 -		else	
  27.191 -			saveStateChangingPart(
  27.192 -				bi,
  27.193 -				bi,
  27.194 +				QString("Add map %1 to %2").arg(fname).arg(getObjectName(selbi)));
  27.195 +		if (lmode==ImportReplace)
  27.196 +		{
  27.197 +			if (saveStateFlag) saveStateChangingPart(
  27.198 +				selbi,
  27.199 +				selbi,
  27.200  				QString("addMapReplace(%1)").arg(fname),
  27.201 -				QString("Add map %1 to %2").arg(fname).arg(getObjectName(bi)));
  27.202 +				QString("Add map %1 to %2").arg(fname).arg(getObjectName(selbi)));
  27.203 +			newbi=addNewBranchInt (selbi,-1);	// Add below selection	
  27.204 +			select (newbi);
  27.205 +		}
  27.206  	}	
  27.207      
  27.208  
  27.209 @@ -465,7 +495,11 @@
  27.210  			tmpdir=fname.left(fname.findRev("/",-1));	
  27.211  		handler->setTmpDir (tmpdir);
  27.212  		handler->setInputFile (file.name());
  27.213 -		handler->setLoadMode (lmode);
  27.214 +		if (lmode==ImportReplace)
  27.215 +			handler->setLoadMode (ImportAdd,pos);
  27.216 +		else	
  27.217 +			handler->setLoadMode (lmode,pos);
  27.218 +
  27.219  		bool ok = reader.parse( source );
  27.220  		blockReposition=false;
  27.221  		blockSaveState=blockSaveStateOrg;
  27.222 @@ -473,18 +507,27 @@
  27.223  		file.close();
  27.224  		if ( ok ) 
  27.225  		{
  27.226 -			reposition();	
  27.227 -			emitSelectionChanged();
  27.228  			if (lmode==NewMap)
  27.229  			{
  27.230  				mapDefault=false;
  27.231  				mapChanged=false;
  27.232  				mapUnsaved=false;
  27.233  				autosaveTimer->stop();
  27.234 +
  27.235 +				// Reset timestamp to check for later updates of file
  27.236 +				fileChangedTime=QFileInfo (destPath).lastModified();
  27.237  			}
  27.238  
  27.239 -			// Reset timestamp to check for later updates of file
  27.240 -			fileChangedTime=QFileInfo (destPath).lastModified();
  27.241 +	
  27.242 +
  27.243 +			if (lmode==ImportReplace)
  27.244 +			{
  27.245 +				deleteItem (selbi);
  27.246 +				select (newbi);
  27.247 +				deleteKeepChildren (false);
  27.248 +			}
  27.249 +			reposition();	
  27.250 +			emitSelectionChanged();
  27.251  		} else 
  27.252  		{
  27.253  			QMessageBox::critical( 0, tr( "Critical Parse Error" ),
  27.254 @@ -640,96 +683,6 @@
  27.255  	return err;
  27.256  }
  27.257  
  27.258 -void VymModel::addMapReplaceInt(const QString &undoSel, const QString &path)	
  27.259 -{
  27.260 -	QString pathDir=path.left(path.findRev("/"));
  27.261 -	QDir d(pathDir);
  27.262 -	QFile file (path);
  27.263 -
  27.264 -	if (d.exists() )
  27.265 -	{
  27.266 -		// We need to parse saved XML data
  27.267 -		parseVYMHandler handler;
  27.268 -		QXmlInputSource source( file);
  27.269 -		QXmlSimpleReader reader;
  27.270 -		reader.setContentHandler( &handler );
  27.271 -		reader.setErrorHandler( &handler );
  27.272 -		handler.setModel ( this);
  27.273 -		handler.setTmpDir ( pathDir );	// needed to load files with rel. path
  27.274 -		if (undoSel.isEmpty())
  27.275 -		{
  27.276 -			unselect();
  27.277 -			clear();
  27.278 -			handler.setLoadMode (NewMap);
  27.279 -		} else	
  27.280 -		{
  27.281 -			select (undoSel);
  27.282 -			handler.setLoadMode (ImportReplace);
  27.283 -		}	
  27.284 -		blockReposition=true;
  27.285 -		bool ok = reader.parse( source );
  27.286 -		blockReposition=false;
  27.287 -		if (! ok ) 
  27.288 -		{	
  27.289 -			// This should never ever happen
  27.290 -			QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
  27.291 -								    handler.errorProtocol());
  27.292 -		}
  27.293 -	} else	
  27.294 -		QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
  27.295 -}
  27.296 -
  27.297 -bool VymModel::addMapInsertInt (const QString &path)
  27.298 -{
  27.299 -	QString pathDir=path.left(path.findRev("/"));
  27.300 -	QDir d(pathDir);
  27.301 -	QFile file (path);
  27.302 -
  27.303 -	if (d.exists() )
  27.304 -	{
  27.305 -		// We need to parse saved XML data
  27.306 -		parseVYMHandler handler;
  27.307 -		QXmlInputSource source( file);
  27.308 -		QXmlSimpleReader reader;
  27.309 -		reader.setContentHandler( &handler );
  27.310 -		reader.setErrorHandler( &handler );
  27.311 -		handler.setModel (this);
  27.312 -		handler.setTmpDir ( pathDir );	// needed to load files with rel. path
  27.313 -		handler.setLoadMode (ImportAdd);
  27.314 -		blockReposition=true;
  27.315 -		bool ok = reader.parse( source );
  27.316 -		blockReposition=false;
  27.317 -		if ( ok ) return true;
  27.318 -		{	
  27.319 -			// This should never ever happen
  27.320 -			QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
  27.321 -									handler.errorProtocol());
  27.322 -		}
  27.323 -	} else	
  27.324 -		QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
  27.325 -	return false;
  27.326 -}
  27.327 -
  27.328 -bool VymModel::addMapInsertInt (const QString &path, int pos)
  27.329 -{
  27.330 -	BranchItem *selbi=getSelectedBranch();
  27.331 -	if (selbi)
  27.332 -	{
  27.333 -		if (addMapInsertInt (path))
  27.334 -		{
  27.335 -			if (selbi->depth()>0)
  27.336 -				relinkBranch (selbi->getLastBranch(), selbi,pos);
  27.337 -			return true;	
  27.338 -		} else
  27.339 -		{
  27.340 -			QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
  27.341 -			return false;
  27.342 -		}	
  27.343 -	}		
  27.344 -	qWarning ("ME::addMapInsertInt nothing selected");
  27.345 -	return false;
  27.346 -}
  27.347 -
  27.348  ImageItem* VymModel::loadFloatImageInt (BranchItem *dst,QString fn)
  27.349  {
  27.350  	ImageItem *ii=createImage(dst);
  27.351 @@ -975,7 +928,7 @@
  27.352  			{
  27.353  				case QMessageBox::Yes:
  27.354  					// Reload map
  27.355 -					load (filePath,NewMap,fileType);
  27.356 +					loadMap (filePath);
  27.357  		        case QMessageBox::Cancel:
  27.358  					fileChangedTime=tmod; // allow autosave to overwrite newer file!
  27.359  			}
  27.360 @@ -1109,7 +1062,7 @@
  27.361  		return false;
  27.362  }
  27.363  
  27.364 -void VymModel::undo()
  27.365 +void VymModel::undo()	//FIXME-1 segfault when trying to undo in a brandnew map
  27.366  {
  27.367  	// Can we undo at all?
  27.368  	if (undosAvail<1) return;
  27.369 @@ -1253,6 +1206,7 @@
  27.370  		makeSubDirs (histDir);
  27.371  
  27.372  	// Save depending on how much needs to be saved	
  27.373 +	QList <Link*> tmpLinks;
  27.374  	if (saveSel)
  27.375  		backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
  27.376  		
  27.377 @@ -1529,7 +1483,7 @@
  27.378  	return sortFilter;
  27.379  }
  27.380  
  27.381 -void VymModel::setHeading(const QString &s)
  27.382 +void VymModel::setHeading(const QString &s) 
  27.383  {
  27.384  	BranchItem *selbi=getSelectedBranch();
  27.385  	if (selbi)
  27.386 @@ -1541,7 +1495,7 @@
  27.387  			"setHeading (\""+s+"\")", 
  27.388  			QString("Set heading of %1 to \"%2\"").arg(getObjectName(selbi)).arg(s) );
  27.389  		selbi->setHeading(s );
  27.390 -		emitDataHasChanged ( selbi);	//FIXME-3 maybe emit signal from TreeItem? 
  27.391 +		emitDataHasChanged ( selbi);	//FIXME-4 maybe emit signal from TreeItem? 
  27.392  		reposition();
  27.393  		emitSelectionChanged();
  27.394  	}
  27.395 @@ -1655,7 +1609,7 @@
  27.396  {
  27.397  	rmodel->clear();
  27.398  	rmodel->setSearchString (s);
  27.399 -	rmodel->setSearchFlags (0);	//FIXME-2 translate cs to QTextDocument::FindFlag
  27.400 +	rmodel->setSearchFlags (0);	//FIXME-3 translate cs to QTextDocument::FindFlag
  27.401  	BranchItem *cur=NULL;
  27.402  	BranchItem *prev=NULL;
  27.403  	nextBranch(cur,prev);
  27.404 @@ -1671,7 +1625,7 @@
  27.405  		int j=0;
  27.406  		while ( i>=0)
  27.407  		{
  27.408 -			i=n.indexOf (s,i,cs); //FIXME-2 add subitems to rmodel
  27.409 +			i=n.indexOf (s,i,cs); 
  27.410  			if (i>=0) 
  27.411  			{
  27.412  				// If not there yet, add "parent" item
  27.413 @@ -2050,20 +2004,17 @@
  27.414  
  27.415  void VymModel::pasteNoSave(const int &n)
  27.416  {
  27.417 -	bool old=blockSaveState;
  27.418 -	blockSaveState=true;
  27.419  	bool zippedOrg=zipped;
  27.420  	if (redosAvail > 0 || n!=0)
  27.421  	{
  27.422  		// Use the "historical" buffer
  27.423  		QString bakMapName(QString("history-%1").arg(n));
  27.424  		QString bakMapDir(tmpMapDir +"/"+bakMapName);
  27.425 -		load (bakMapDir+"/"+clipboardFile,ImportAdd, VymMap);
  27.426 +		loadMap (bakMapDir+"/"+clipboardFile,ImportAdd, false);
  27.427  	} else
  27.428  		// Use the global buffer
  27.429 -		load (clipboardDir+"/"+clipboardFile,ImportAdd, VymMap);
  27.430 +		loadMap (clipboardDir+"/"+clipboardFile,ImportAdd, false);
  27.431  	zipped=zippedOrg;
  27.432 -	blockSaveState=old;
  27.433  }
  27.434  
  27.435  void VymModel::paste()	
  27.436 @@ -2231,39 +2182,61 @@
  27.437  	return NULL;
  27.438  }
  27.439  
  27.440 -XLinkItem* VymModel::createXLink(BranchItem *bi,bool createMO)
  27.441 -{
  27.442 -	if (bi)
  27.443 -	{
  27.444 +bool VymModel::createLink(Link *link, bool createMO)
  27.445 +{
  27.446 +		BranchItem *begin=link->getBeginBranch();
  27.447 +		BranchItem *end  =link->getEndBranch();
  27.448 +
  27.449 +		if (!begin || !end)
  27.450 +		{
  27.451 +			qWarning ()<<"VM::createXLinkNew part of XLink is NULL";
  27.452 +			return false;
  27.453 +		}
  27.454 +
  27.455 +
  27.456  		QModelIndex parix;
  27.457  		int n;
  27.458  
  27.459  		QList<QVariant> cData;
  27.460 -		cData << "new xLink"<<"undef";
  27.461 -
  27.462 -		XLinkItem *newxli=new XLinkItem(cData) ;	
  27.463 -		newxli->setBegin (bi);
  27.464 +
  27.465 +		cData << "new Link begin"<<"undef";
  27.466 +		XLinkItem *newli=new XLinkItem(cData) ;	
  27.467 +		newli->setLink (link);
  27.468 +		link->setBeginLinkItem (newli);
  27.469  
  27.470  		emit (layoutAboutToBeChanged() );
  27.471  
  27.472 -			parix=index(bi);
  27.473 -			n=bi->getRowNumAppend(newxli);
  27.474 +			parix=index(begin);
  27.475 +			n=begin->getRowNumAppend(newli);
  27.476  			beginInsertRows (parix,n,n);
  27.477 -			bi->appendChild (newxli);	
  27.478 +			begin->appendChild (newli);	
  27.479  			endInsertRows ();
  27.480  
  27.481 +		cData.clear();
  27.482 +		cData << "new Link end"<<"undef";
  27.483 +		newli=new XLinkItem(cData) ;	
  27.484 +		newli->setLink (link);
  27.485 +		link->setEndLinkItem (newli);
  27.486 +
  27.487 +			parix=index(end);
  27.488 +			n=end->getRowNumAppend(newli);
  27.489 +			beginInsertRows (parix,n,n);
  27.490 +			end->appendChild (newli);	
  27.491 +			endInsertRows ();
  27.492 +
  27.493  		emit (layoutChanged() );
  27.494  
  27.495 -		// save scroll state. If scrolled, automatically select
  27.496 -		// new branch in order to tmp unscroll parent...
  27.497 +		xlinks.append (link);
  27.498 +		link->activate();
  27.499 +
  27.500  		if (createMO) 
  27.501  		{
  27.502 -			newxli->createMapObj(mapScene);
  27.503 +			link->createMapObj(mapScene);
  27.504  			reposition();
  27.505  		}
  27.506 -		return newxli;
  27.507 -	} 
  27.508 -	return NULL;
  27.509 +//	} 
  27.510 +	//return newli;
  27.511 +	return true;
  27.512  }
  27.513  
  27.514  AttributeItem* VymModel::addAttribute()	
  27.515 @@ -2279,7 +2252,7 @@
  27.516  	return NULL;
  27.517  }
  27.518  
  27.519 -AttributeItem* VymModel::addAttribute(AttributeItem *ai)	// FIXME-2 savestate missing
  27.520 +AttributeItem* VymModel::addAttribute(AttributeItem *ai)	// FIXME-3 savestate missing
  27.521  {
  27.522  	BranchItem *selbi=getSelectedBranch();
  27.523  	if (selbi)
  27.524 @@ -2294,7 +2267,7 @@
  27.525  
  27.526  		emit (layoutChanged() );
  27.527  
  27.528 -		ai->createMapObj(mapScene);		//FIXME-2 check that...
  27.529 +		ai->createMapObj(mapScene);		//FIXME-3 check that...
  27.530  		reposition();
  27.531  		return ai;
  27.532  	}
  27.533 @@ -2564,7 +2537,30 @@
  27.534  	return false;
  27.535  }
  27.536  
  27.537 -void VymModel::deleteSelection()	//FIXME-2 xLinks in a deleted subtree are not restored on undo	
  27.538 +void VymModel::cleanupLinks()	
  27.539 +{
  27.540 +	// This probably could be done more elegant from destructor of a Link,
  27.541 +	// but somehow this resulted in strange segfaults deep in Qt and glibc...
  27.542 +	//qDebug ()<<"VM::cleanupLinks begin"<< "CUL="<<cleaningUpLinks;
  27.543 +	cleaningUpLinks=true;
  27.544 +	Link *l;
  27.545 +	XLinkItem *xli;
  27.546 +	while (!xlinks_obsolete.isEmpty())
  27.547 +	{
  27.548 +		l=xlinks_obsolete.takeFirst();
  27.549 +		xli=l->getBeginLinkItem();
  27.550 +		//qDebug()<<"VM::cleanupLinks  a)  l="<<l<<"  xli="<<xli;
  27.551 +		if (xli) deleteItem (xli);
  27.552 +		xli=l->getEndLinkItem();
  27.553 +		//qDebug()<<"VM::cleanupLinks  b)  l="<<l<<"  xli="<<xli;
  27.554 +		if (xli) deleteItem (xli);
  27.555 +		delete (l);
  27.556 +	}
  27.557 +	cleaningUpLinks=false;
  27.558 +	//qDebug ()<<"VM::cleanupLinks end";
  27.559 +}
  27.560 +
  27.561 +void VymModel::deleteSelection()	
  27.562  {
  27.563  	BranchItem *selbi=getSelectedBranch();
  27.564  
  27.565 @@ -2586,12 +2582,14 @@
  27.566  		}
  27.567  		return;
  27.568  	}
  27.569 +
  27.570  	TreeItem *ti=getSelectedItem();
  27.571 +
  27.572  	if (ti)
  27.573  	{	// Delete other item
  27.574  		TreeItem *pi=ti->parent();
  27.575  		if (!pi) return;
  27.576 -		if (ti->getType()==TreeItem::Image || ti->getType()==TreeItem::Attribute)
  27.577 +		if (ti->getType()==TreeItem::Image || ti->getType()==TreeItem::Attribute||ti->getType()==TreeItem::XLink)
  27.578  		{
  27.579  			saveStateChangingPart(
  27.580  				pi, 
  27.581 @@ -2605,16 +2603,12 @@
  27.582  			select (pi);
  27.583  			reposition();
  27.584  			emitShowSelection();
  27.585 -		} else if (ti->getType()==TreeItem::XLink)
  27.586 -		{
  27.587 -			//FIXME-2 savestate for deleting xlink missing
  27.588 -			deleteItem (ti);
  27.589  		} else
  27.590  			qWarning ("VymmModel::deleteSelection()  unknown type?!");
  27.591  	}
  27.592  }
  27.593  
  27.594 -void VymModel::deleteKeepChildren()	//FIXME-3 does not work yet for mapcenters
  27.595 +void VymModel::deleteKeepChildren(bool saveStateFlag)	//FIXME-3 does not work yet for mapcenters
  27.596  
  27.597  {
  27.598  	BranchItem *selbi=getSelectedBranch();
  27.599 @@ -2634,7 +2628,7 @@
  27.600  
  27.601  		QPointF p;
  27.602  		if (selbi->getLMO()) p=selbi->getLMO()->getRelPos();
  27.603 -		saveStateChangingPart(
  27.604 +		if (saveStateFlag) saveStateChangingPart(
  27.605  			pi,
  27.606  			selbi,
  27.607  			"deleteKeepChildren ()",
  27.608 @@ -2693,6 +2687,7 @@
  27.609  	if (ti)
  27.610  	{
  27.611  		TreeItem *pi=ti->parent();
  27.612 +		//qDebug()<<"VM::deleteItem  start ti="<<ti<<"  "<<ti->getHeading()<<"  pi="<<pi<<"="<<pi->getHeading();
  27.613  		QModelIndex parentIndex=index(pi);
  27.614  
  27.615  		emit (layoutAboutToBeChanged() );
  27.616 @@ -2704,11 +2699,19 @@
  27.617  		reposition();
  27.618  
  27.619  		emit (layoutChanged() );
  27.620 +		//qDebug()<<"VM::deleteItem  end   ti="<<ti;
  27.621 +		if (!cleaningUpLinks) cleanupLinks();
  27.622  		if (pi->depth()>=0) return pi;
  27.623  	}	
  27.624  	return NULL;
  27.625  }
  27.626  
  27.627 +void VymModel::deleteLink(Link* l)	
  27.628 +{
  27.629 +	int i=xlinks.indexOf(l);
  27.630 +	if (i>-1) xlinks_obsolete.append (xlinks.takeAt (i));
  27.631 +}
  27.632 +
  27.633  void VymModel::clearItem (TreeItem *ti)
  27.634  {
  27.635  	if (ti)
  27.636 @@ -3138,35 +3141,30 @@
  27.637  	}
  27.638  }
  27.639  
  27.640 -void VymModel::editXLink(int i)	
  27.641 -{
  27.642 -	i=0;
  27.643 +void VymModel::editXLink(int i)
  27.644 +{
  27.645  	BranchItem *selbi=getSelectedBranch();
  27.646  	if (selbi)
  27.647  	{
  27.648 -		XLinkItem *xli=selbi->getXLinkNum(i);
  27.649 -		if (xli) 
  27.650 +		Link *l=selbi->getXLinkNum(i)->getLink();
  27.651 +		if (l) 
  27.652  		{
  27.653  			EditXLinkDialog dia;
  27.654 -			dia.setXLink (xli);
  27.655 +			dia.setLink (l);
  27.656  			dia.setSelection(selbi);
  27.657  			if (dia.exec() == QDialog::Accepted)
  27.658  			{
  27.659  				if (dia.useSettingsGlobal() )
  27.660  				{
  27.661 -					setMapDefXLinkColor (xli->getColor() );
  27.662 -					setMapDefXLinkWidth (xli->getWidth() );
  27.663 +					setMapDefXLinkColor (l->getColor() );
  27.664 +					setMapDefXLinkWidth (l->getWidth() );
  27.665  				}
  27.666 -				if (dia.deleteXLink()) deleteItem (xli);
  27.667 +				if (dia.deleteXLink()) delete (l);
  27.668  			}
  27.669  		}	
  27.670  	}
  27.671  }
  27.672  
  27.673 -
  27.674 -
  27.675 -
  27.676 -
  27.677  //////////////////////////////////////////////
  27.678  // Scripting
  27.679  //////////////////////////////////////////////
  27.680 @@ -3252,7 +3250,7 @@
  27.681  			//s=parser.parString (ok,0);	// selection
  27.682  			t=parser.parString (ok,0);	// path to map
  27.683  			if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
  27.684 -			addMapReplaceInt(getSelectString(selbi),t);	
  27.685 +			loadMap (t,ImportReplace,false,VymMap,n);
  27.686  		}
  27.687  	/////////////////////////////////////////////////////////////////////
  27.688  	} else if (com==QString("addMapInsert"))
  27.689 @@ -3271,18 +3269,19 @@
  27.690  				t=parser.parString (ok,0);	// path to map
  27.691  				n=parser.parInt(ok,1);		// position
  27.692  				if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
  27.693 -				addMapInsertInt(t,n);	
  27.694 +				loadMap (t,ImportAdd,false,VymMap,n);
  27.695  			}
  27.696  		} else if (parser.parCount()==1)
  27.697  		{
  27.698  			t=parser.parString (ok,0);	// path to map
  27.699  			if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
  27.700 -			addMapInsertInt(t);	
  27.701 +			loadMap (t,ImportAdd,false);
  27.702  		} else
  27.703  			parser.setError (Aborted,"Wrong number of parameters");
  27.704  	/////////////////////////////////////////////////////////////////////
  27.705 -	} else if (com==QString("addXLink"))
  27.706 -	{
  27.707 +	} else if (com==QString("addXLink"))  //FIXME-2 not ported yet to Link
  27.708 +	{
  27.709 +	/*
  27.710  		if (parser.parCount()>1)
  27.711  		{
  27.712  			s=parser.parString (ok,0);	// begin
  27.713 @@ -3308,6 +3307,7 @@
  27.714  				parser.setError (Aborted,"Couldn't select begin or end of xLink");
  27.715  		} else
  27.716  			parser.setError (Aborted,"Need at least 2 parameters for begin and end");
  27.717 +	*/		
  27.718  	/////////////////////////////////////////////////////////////////////
  27.719  	} else if (com=="clearFlags")	
  27.720  	{
  27.721 @@ -4424,8 +4424,15 @@
  27.722  	//cout << "VM::reposition blocked="<<blockReposition<<endl;
  27.723  	if (blockReposition) return;
  27.724  
  27.725 +	BranchObj *bo;
  27.726  	for (int i=0;i<rootItem->branchCount(); i++)
  27.727 -		rootItem->getBranchObjNum(i)->reposition();	//	for positioning heading
  27.728 +	{
  27.729 +		bo=rootItem->getBranchObjNum(i);
  27.730 +		if (bo)
  27.731 +			bo->reposition();	//	for positioning heading
  27.732 +		else
  27.733 +			qDebug()<<"VM::reposition bo=0";
  27.734 +	}	
  27.735  	//emitSelectionChanged();	
  27.736  }
  27.737  
  27.738 @@ -4763,6 +4770,20 @@
  27.739  		animObjList.removeAt (i);
  27.740  }
  27.741  
  27.742 +void VymModel::stopAllAnimation ()
  27.743 +{
  27.744 +	BranchObj *bo;
  27.745 +	int i=0;
  27.746 +	while (i<animObjList.size() )
  27.747 +	{
  27.748 +		bo=(BranchObj*)animObjList.at(i);
  27.749 +		bo->stopAnimation();
  27.750 +		bo->requestReposition();
  27.751 +		i++;
  27.752 +	} 
  27.753 +	reposition();
  27.754 +}
  27.755 +
  27.756  void VymModel::sendSelection()
  27.757  {
  27.758  	if (netstate!=Server) return;
  27.759 @@ -5269,3 +5290,8 @@
  27.760  	return s;
  27.761  }
  27.762  
  27.763 +QString VymModel::getSelectString (BranchItem *bi) 
  27.764 +{
  27.765 +	return getSelectString ((TreeItem*)bi);
  27.766 +}
  27.767 +
    28.1 --- a/vymmodel.h	Fri Apr 09 14:24:04 2010 +0000
    28.2 +++ b/vymmodel.h	Wed Jun 09 13:14:08 2010 +0000
    28.3 @@ -21,6 +21,7 @@
    28.4  class BranchItem;
    28.5  class FindResultModel;
    28.6  class MapEditor;
    28.7 +class Link;
    28.8  class XLinkItem;
    28.9  
   28.10  class VymModel :  public TreeModel {		
   28.11 @@ -46,7 +47,7 @@
   28.12      void init();
   28.13  	void makeTmpDirectories();		//!< create temporary directories e.g. for history
   28.14  
   28.15 -	MapEditor* getMapEditor();			// FIXME-2 still necessary?
   28.16 +	MapEditor* getMapEditor();			
   28.17  	uint getID();						//! Return unique ID of model
   28.18  
   28.19  	bool isRepositionBlocked();		//!< While load or undo there is no need to update graphicsview
   28.20 @@ -83,7 +84,7 @@
   28.21      QString saveToDir (const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, TreeItem *saveSel);
   28.22  
   28.23  	/*! Save all data in tree*/
   28.24 -	QString saveTreeToDir (const QString&,const QString&,const QPointF&);// Save data recursivly to tempdir
   28.25 +	QString saveTreeToDir (const QString&,const QString&,const QPointF&,QList <Link*> &tmpLinks);// Save data recursivly to tempdir
   28.26  
   28.27  
   28.28  	/*! \brief Sets filepath, filename and mapname
   28.29 @@ -110,17 +111,19 @@
   28.30  		The data is read from file. Depending on LoadMode the current
   28.31  		selection gets replaced by data or the data is appended.
   28.32  	*/	
   28.33 -    ErrorCode load (QString, const LoadMode &, const FileType& );	// newmap, import/replace selection
   28.34 +    ErrorCode loadMap  (
   28.35 +		QString,						//!< Path
   28.36 +		const LoadMode &lmode=NewMap,	//!< New map, replace or add to selection
   28.37 +		bool saveStateFlag=true,		//!< If called internally for history, don't save
   28.38 +		const FileType &ftype=VymMap,	//!< VymMap or FreeMind
   28.39 +		int pos=-1						//!< Optionally tell position where to add data
   28.40 +	);	
   28.41  
   28.42  public:
   28.43  	/*! \brief Save the map to file */
   28.44      ErrorCode save(const SaveMode &);	
   28.45  
   28.46  private:
   28.47 -    void addMapReplaceInt(const QString & undoSel, const QString & path);
   28.48 -    bool addMapInsertInt (const QString & path);
   28.49 -    bool addMapInsertInt (const QString & path, int pos);
   28.50 -
   28.51  	ImageItem* loadFloatImageInt (BranchItem *dst,QString);
   28.52  	void saveFloatImageInt (ImageItem*, const QString &, const QString &);
   28.53  public:	
   28.54 @@ -321,7 +324,9 @@
   28.55  	BranchItem* createMapCenter();				//!< Create MapCenter 
   28.56  	BranchItem* createBranch(BranchItem *dst);	//!< Create Branch
   28.57  	ImageItem* createImage(BranchItem *dst);	//!< Create image
   28.58 -	XLinkItem* createXLink(BranchItem *dst,bool createMO=false);	//!< Create XLink starting at dst
   28.59 +
   28.60 +public:	
   28.61 +	bool createLink(Link *l, bool createMO=false);			//!< Create XLink 
   28.62  
   28.63  	AttributeItem* addAttribute();
   28.64  	AttributeItem* addAttribute(AttributeItem* );
   28.65 @@ -366,15 +371,20 @@
   28.66  	bool relinkBranch (BranchItem* branch, BranchItem* dst, int pos =-1);	
   28.67  	bool relinkImage  (ImageItem* image, BranchItem* dst);	
   28.68  
   28.69 +private:
   28.70 +	bool cleaningUpLinks;				//!< True while cleaning up to avoid recursion
   28.71 +public:	
   28.72 +	void cleanupLinks();				//!< Delete orphaned XLinkItems
   28.73      void deleteSelection();				//!< Delete selection
   28.74 -	void deleteKeepChildren();			//!< remove branch, but keep children
   28.75 +	void deleteKeepChildren(bool saveStateFlag=true);	//!< remove branch, but keep children
   28.76 +public:	
   28.77  	void deleteChildren();				//!< keep branch, but remove children
   28.78  
   28.79  	TreeItem* deleteItem(TreeItem*);	//!< Delete item and return parent (if parent!= rootItem)
   28.80 +	void deleteLink (Link*);			//!< Remove Link and related LinkItems in TreeModel
   28.81  	void clearItem (TreeItem* ti);		//!< Remove all children of TreeItem ti
   28.82  	bool scrollBranch(BranchItem *);
   28.83  	bool unscrollBranch(BranchItem *);
   28.84 -public:	
   28.85      void toggleScroll();
   28.86      void unscrollChildren();
   28.87  	void emitExpandAll();
   28.88 @@ -406,7 +416,7 @@
   28.89  	QString getVymLink();					// return path to map
   28.90  	QStringList getVymLinks();				// return paths in subtree
   28.91  	void followXLink (int);
   28.92 -	void editXLink (int);
   28.93 +	void editXLink (int i=0);
   28.94  
   28.95  
   28.96  
   28.97 @@ -536,6 +546,7 @@
   28.98  	void startAnimation(BranchObj *bo, const QPointF &v);
   28.99  	void startAnimation(BranchObj *bo, const QPointF &start, const QPointF &dest);
  28.100  	void stopAnimation(MapObj *mo);
  28.101 +	void stopAllAnimation();
  28.102  
  28.103  ////////////////////////////////////////////
  28.104  // Network related 
  28.105 @@ -631,6 +642,7 @@
  28.106  	QString getSelectString ();
  28.107  	QString getSelectString (LinkableMapObj *lmo);
  28.108  	QString getSelectString (TreeItem *item);
  28.109 +	QString getSelectString (BranchItem *item);
  28.110  	
  28.111  	
  28.112  signals:
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/xlink.cpp	Wed Jun 09 13:14:08 2010 +0000
    29.3 @@ -0,0 +1,192 @@
    29.4 +#include <QDebug>
    29.5 +
    29.6 +#include "xlink.h"
    29.7 +
    29.8 +#include "vymmodel.h"
    29.9 +#include "xlinkitem.h"
   29.10 +#include "xlinkobj.h"
   29.11 +
   29.12 +/////////////////////////////////////////////////////////////////
   29.13 +// Link
   29.14 +/////////////////////////////////////////////////////////////////
   29.15 +
   29.16 +Link::Link (VymModel *m)
   29.17 +{
   29.18 +	//qDebug() << "Const Link () this="<<this;
   29.19 +	init();
   29.20 +	model=m;
   29.21 +}
   29.22 +
   29.23 +Link::~Link ()
   29.24 +{
   29.25 +	//qDebug()<<"* Destr Link begin this="<<this<<"  bLI="<<beginLinkItem<<"  eLI="<<endLinkItem;
   29.26 +	//deactivate();
   29.27 +	//qDebug()<<"* Destr Link end   this="<<this;
   29.28 +}
   29.29 +
   29.30 +void Link::init () 
   29.31 +{
   29.32 +	xlo=NULL;
   29.33 +	beginBranch=NULL;
   29.34 +	endBranch=NULL;
   29.35 +	xLinkState=Link::undefinedXLink;
   29.36 +
   29.37 +	color=QColor (180,180,180);
   29.38 +	width=1;
   29.39 +}
   29.40 +
   29.41 +void Link::setBeginBranch (BranchItem *bi)
   29.42 +{
   29.43 +	if (bi) 
   29.44 +	{
   29.45 +		xLinkState=initXLink;
   29.46 +		beginBranch=bi;
   29.47 +	}	
   29.48 +}
   29.49 +
   29.50 +BranchItem* Link::getBeginBranch ()
   29.51 +{
   29.52 +	return beginBranch;
   29.53 +}
   29.54 +
   29.55 +void Link::setEndBranch (BranchItem *bi)
   29.56 +{
   29.57 +	if (bi) 
   29.58 +	{
   29.59 +		xLinkState=initXLink;
   29.60 +		endBranch=bi;
   29.61 +	}		
   29.62 +}
   29.63 +
   29.64 +BranchItem* Link::getEndBranch()
   29.65 +{
   29.66 +	return endBranch;
   29.67 +}
   29.68 +
   29.69 +void Link::setEndPoint (QPointF p)
   29.70 +{
   29.71 +	if (xlo) xlo->setEnd (p);
   29.72 +}
   29.73 +
   29.74 +void Link::setBeginLinkItem (XLinkItem *li)
   29.75 +{
   29.76 +	if (li) 
   29.77 +	{
   29.78 +		xLinkState=initXLink;
   29.79 +		beginLinkItem=li;
   29.80 +	}	
   29.81 +}
   29.82 +
   29.83 +XLinkItem* Link::getBeginLinkItem ()
   29.84 +{
   29.85 +	return beginLinkItem;
   29.86 +}
   29.87 +
   29.88 +void Link::setEndLinkItem (XLinkItem *li)
   29.89 +{
   29.90 +	if (li) 
   29.91 +	{
   29.92 +		xLinkState=initXLink;
   29.93 +		endLinkItem=li;
   29.94 +	}		
   29.95 +}
   29.96 +
   29.97 +XLinkItem* Link::getEndLinkItem()
   29.98 +{
   29.99 +	return endLinkItem;
  29.100 +}
  29.101 +
  29.102 +void Link::setWidth (int w)
  29.103 +{
  29.104 +	width=w;
  29.105 +	if (xlo) xlo->updateXLink();
  29.106 +}
  29.107 +
  29.108 +int Link::getWidth()
  29.109 +{
  29.110 +	return width;
  29.111 +}
  29.112 +
  29.113 +void Link::setColor(QColor c)
  29.114 +{
  29.115 +	color=c;
  29.116 +	if (xlo) xlo->updateXLink();
  29.117 +}
  29.118 +
  29.119 +QColor Link::getColor()
  29.120 +{
  29.121 +	return color;
  29.122 +}
  29.123 +
  29.124 +bool Link::activate ()	
  29.125 +{
  29.126 +	if (beginBranch && endBranch)
  29.127 +	{
  29.128 +		
  29.129 +		if (beginBranch==endBranch) return false;
  29.130 +		xLinkState=activeXLink;
  29.131 +
  29.132 +		model->updateActions();
  29.133 +		return true;
  29.134 +	} else
  29.135 +		return false;
  29.136 +}
  29.137 +
  29.138 +void Link::deactivate ()	
  29.139 +{
  29.140 +	// Remove pointers from XLinkItem to Link and
  29.141 +	// delete XLinkObj
  29.142 +
  29.143 +	xLinkState=deleteXLink;
  29.144 +	if (beginLinkItem) beginLinkItem->setLink (NULL);
  29.145 +	if (endLinkItem) endLinkItem->setLink (NULL);
  29.146 +	if (xlo)
  29.147 +	{
  29.148 +		delete (xlo);  
  29.149 +		xlo=NULL;
  29.150 +	}
  29.151 +}
  29.152 +
  29.153 +void Link::removeXLinkItem (XLinkItem *xli)
  29.154 +{
  29.155 +	if (xli==beginLinkItem) beginLinkItem=NULL;
  29.156 +	if (xli==endLinkItem) endLinkItem=NULL;
  29.157 +}
  29.158 +
  29.159 +void Link::updateLink()
  29.160 +{
  29.161 +	if(xlo ) xlo->updateXLink();
  29.162 +}
  29.163 +
  29.164 +QString Link::saveToDir ()
  29.165 +{
  29.166 +	QString s="";
  29.167 +	if (beginBranch && endBranch && xLinkState==activeXLink)
  29.168 +	{
  29.169 +		if (beginBranch==endBranch )
  29.170 +			qWarning ("Link::saveToDir  beginBranch==endBranch");
  29.171 +		else
  29.172 +		{
  29.173 +			QString colAttr=attribut ("color",color.name());
  29.174 +			QString widAttr=attribut ("width",QString().setNum(width,10));
  29.175 +			QString begSelAttr=attribut ("beginID",model->getSelectString(beginBranch));
  29.176 +			QString endSelAttr=attribut ("endID",  model->getSelectString(endBranch));
  29.177 +			s=singleElement ("xlink", colAttr +widAttr +begSelAttr +endSelAttr);
  29.178 +
  29.179 +		}
  29.180 +	}
  29.181 +	return s;
  29.182 +}
  29.183 +
  29.184 +XLinkObj* Link::getXLinkObj()
  29.185 +{
  29.186 +	return xlo;
  29.187 +}
  29.188 +
  29.189 +XLinkObj* Link::createMapObj(QGraphicsScene *scene)  
  29.190 +{
  29.191 +	if (!xlo) xlo=new XLinkObj (scene,this);  
  29.192 +	return xlo;
  29.193 +}
  29.194 +
  29.195 +
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/xlink.h	Wed Jun 09 13:14:08 2010 +0000
    30.3 @@ -0,0 +1,64 @@
    30.4 +#ifndef LINK_H
    30.5 +#define LINK_H
    30.6 +
    30.7 +#include <QColor>
    30.8 +
    30.9 +#include "xmlobj.h"
   30.10 +
   30.11 +class QPointF;
   30.12 +class QGraphicsScene;
   30.13 +class QString;
   30.14 +
   30.15 +class BranchItem;
   30.16 +class LinkableMapObj;
   30.17 +class VymModel;
   30.18 +class XLinkItem;
   30.19 +class XLinkObj;
   30.20 +
   30.21 +
   30.22 +class Link:public XMLObj
   30.23 +{
   30.24 +public:
   30.25 +	enum XLinkState {undefinedXLink,initXLink,activeXLink,deleteXLink};	
   30.26 +
   30.27 +	Link (VymModel *m);
   30.28 +    virtual ~Link();
   30.29 +    virtual void init ();
   30.30 +	void setBeginBranch (BranchItem*);
   30.31 +	BranchItem* getBeginBranch();
   30.32 +	void setEndBranch   (BranchItem*);
   30.33 +	void setEndPoint(QPointF);
   30.34 +	BranchItem* getEndBranch();
   30.35 +	void setBeginLinkItem (XLinkItem*);
   30.36 +	XLinkItem* getBeginLinkItem();
   30.37 +	void setEndLinkItem (XLinkItem*);
   30.38 +	XLinkItem* getEndLinkItem ();
   30.39 +	void setColor(QColor);
   30.40 +	QColor getColor();
   30.41 +	void setWidth (int);
   30.42 +	int getWidth ();
   30.43 +	bool activate ();			
   30.44 +	void deactivate ();			
   30.45 +	void removeXLinkItem (XLinkItem *xli);
   30.46 +	void updateLink();
   30.47 +	QString saveToDir ();
   30.48 +	XLinkObj* getXLinkObj();
   30.49 +	XLinkObj* createMapObj(QGraphicsScene *scene);
   30.50 +
   30.51 +private:
   30.52 +	XLinkState xLinkState;	// init during drawing or active
   30.53 +	QColor color;
   30.54 +	int width;
   30.55 +
   30.56 +	XLinkObj *xlo;
   30.57 +	VymModel *model;
   30.58 +
   30.59 +	BranchItem *beginBranch;
   30.60 +	BranchItem *endBranch;
   30.61 +	XLinkItem *beginLinkItem;
   30.62 +	XLinkItem *endLinkItem;
   30.63 +};
   30.64 +
   30.65 +
   30.66 +#endif
   30.67 +
    31.1 --- a/xlinkitem.cpp	Fri Apr 09 14:24:04 2010 +0000
    31.2 +++ b/xlinkitem.cpp	Wed Jun 09 13:14:08 2010 +0000
    31.3 @@ -19,205 +19,51 @@
    31.4  
    31.5  XLinkItem::~XLinkItem ()
    31.6  {
    31.7 -	qDebug() << "Destr XLinkItem "<<this<<"  lmo="<<lmo;
    31.8 -	if (lmo)
    31.9 +	//qDebug() << "Destr XLinkItem begin "<<this<<"  pI="<<parentItem<<"  link="<<link;
   31.10 +	if (link)
   31.11  	{
   31.12 -		qDebug() <<" calling delete (lmo)"; 
   31.13 -		delete (lmo);
   31.14 -	}
   31.15 -	if (partnerXLink)
   31.16 -	{
   31.17 -		// Also delete partner 
   31.18 -		qDebug() << "  deleting partner="<<partnerXLink;
   31.19 -		partnerXLink->partnerXLink=NULL;	// avoid endless recusion
   31.20 -		model->deleteItem (partnerXLink);
   31.21 -	}
   31.22 +		// tell the model to remove the link later
   31.23 +		// (and then remove partner link in VymModel::cleanupLinks)
   31.24 +		model->deleteLink (link);
   31.25 +		link->removeXLinkItem (this);
   31.26 +		link->deactivate();
   31.27 +	}	
   31.28 +	//qDebug() << "Destr XLinkItem end"<<this;
   31.29  }
   31.30  
   31.31  
   31.32  void XLinkItem::init () 
   31.33  {
   31.34  	setType (XLink);
   31.35 -	beginBranch=NULL;
   31.36 -	endBranch=NULL;
   31.37 -	partnerXLink=NULL;
   31.38 -	isBeginXLink=true;
   31.39 -	xLinkState=XLinkItem::undefinedXLink;
   31.40 -
   31.41 -	color=QColor (180,180,180);
   31.42 -	width=1;
   31.43 +	link=NULL;
   31.44  }
   31.45  
   31.46 -void XLinkItem::setBegin (BranchItem *bi)
   31.47 +void XLinkItem::setLink (Link *l)
   31.48  {
   31.49 -	if (bi) 
   31.50 -	{
   31.51 -		xLinkState=initXLink;
   31.52 -		beginBranch=bi;
   31.53 -	}	
   31.54 +	link=l;
   31.55  }
   31.56  
   31.57 -BranchItem* XLinkItem::getBegin ()
   31.58 +Link* XLinkItem::getLink ()
   31.59  {
   31.60 -	return beginBranch;
   31.61 -}
   31.62 -
   31.63 -void XLinkItem::setEnd (BranchItem *bi)
   31.64 -{
   31.65 -	if (bi) 
   31.66 -	{
   31.67 -		xLinkState=initXLink;
   31.68 -		endBranch=bi;
   31.69 -	}		
   31.70 -}
   31.71 -
   31.72 -BranchItem* XLinkItem::getEnd()
   31.73 -{
   31.74 -	return endBranch;
   31.75 -}
   31.76 -
   31.77 -void XLinkItem::setWidth (int w)
   31.78 -{
   31.79 -	if (isBeginXLink)
   31.80 -	{
   31.81 -		width=w;
   31.82 -		if (lmo) ((XLinkObj*)lmo)->updateXLink();
   31.83 -		return;
   31.84 -	}
   31.85 -	if (partnerXLink)
   31.86 -		partnerXLink->setWidth (w);
   31.87 -}
   31.88 -
   31.89 -int XLinkItem::getWidth()
   31.90 -{
   31.91 -	if (isBeginXLink) return width;
   31.92 -	if (partnerXLink)
   31.93 -		return partnerXLink->getWidth();
   31.94 -	else
   31.95 -		return -1;
   31.96 -}
   31.97 -
   31.98 -void XLinkItem::setColor(QColor c)
   31.99 -{
  31.100 -	if (isBeginXLink)
  31.101 -	{
  31.102 -		color=c;
  31.103 -		if (lmo) ((XLinkObj*)lmo)->updateXLink();
  31.104 -		return;
  31.105 -	}	
  31.106 -	if (partnerXLink)
  31.107 -		partnerXLink->setColor (c);
  31.108 -}
  31.109 -
  31.110 -QColor XLinkItem::getColor()
  31.111 -{
  31.112 -	if (isBeginXLink) return color;
  31.113 -	if (partnerXLink)
  31.114 -		return partnerXLink->getColor();
  31.115 -	else
  31.116 -		return QColor();
  31.117 -}
  31.118 -
  31.119 -void XLinkItem::setEnd (QPointF p)
  31.120 -{
  31.121 -	if (lmo) ((XLinkObj*)lmo)->setEnd (p);
  31.122 -}
  31.123 -
  31.124 -bool XLinkItem::activate ()	
  31.125 -{
  31.126 -	if (beginBranch && endBranch)
  31.127 -	{
  31.128 -		if (beginBranch==endBranch) return false;
  31.129 -
  31.130 -		partnerXLink=model->createXLink (endBranch);
  31.131 -		partnerXLink->setBegin (beginBranch);
  31.132 -		partnerXLink->setEnd (endBranch);
  31.133 -		partnerXLink->partnerXLink=this;
  31.134 -		partnerXLink->isBeginXLink=false;
  31.135 -
  31.136 -		xLinkState=activeXLink;
  31.137 -		partnerXLink->xLinkState=activeXLink;
  31.138 -		partnerXLink->setHeading ("xLink to: "+beginBranch->getHeading());
  31.139 -		setHeading ("xLink to: "+endBranch->getHeading());
  31.140 -
  31.141 -		model->updateActions();
  31.142 -		return true;
  31.143 -	} else
  31.144 -		return false;
  31.145 -}
  31.146 -
  31.147 -bool XLinkItem::isBegin()
  31.148 -{
  31.149 -	return isBeginXLink;
  31.150 +	return link;
  31.151  }
  31.152  
  31.153  void XLinkItem::updateXLink()
  31.154  {
  31.155 -	if(lmo && isBeginXLink) 
  31.156 -		((XLinkObj*)lmo)->updateXLink();
  31.157 -	else 
  31.158 -		if (partnerXLink) partnerXLink->updateXLink();
  31.159 -}
  31.160 -
  31.161 -void XLinkItem::updateVisibility()
  31.162 -{
  31.163 -	if (lmo) lmo->updateVisibility();
  31.164 +	qDebug()<<"XLI::updateXLink";
  31.165 +	if (link)
  31.166 +		link->updateLink();
  31.167  }
  31.168  
  31.169  BranchItem* XLinkItem::getPartnerBranch()
  31.170  {
  31.171 -	if (!beginBranch && !endBranch)
  31.172 -		return NULL;
  31.173 -	if (isBeginXLink)
  31.174 -		return endBranch;
  31.175 -	else	
  31.176 -		return beginBranch;
  31.177 +	if (link && link->getBeginBranch() && link->getEndBranch())
  31.178 +	{
  31.179 +		if (parentItem==link->getBeginBranch())
  31.180 +			return link->getEndBranch();
  31.181 +		else	
  31.182 +			return link->getBeginBranch();
  31.183 +	}
  31.184 +	return NULL;
  31.185  }
  31.186  
  31.187 -BranchItem* XLinkItem::getOtherBranch(TreeItem *ti)
  31.188 -{
  31.189 -	BranchItem *pb=getPartnerBranch();
  31.190 -	if (!pb) return NULL;
  31.191 -
  31.192 -	if (ti==beginBranch)
  31.193 -		return endBranch;
  31.194 -	else
  31.195 -		return beginBranch;
  31.196 -}
  31.197 -
  31.198 -
  31.199 -
  31.200 -XLinkItem* XLinkItem::getPartnerXLink()
  31.201 -{
  31.202 -	return partnerXLink;
  31.203 -}
  31.204 -
  31.205 -
  31.206 -QString XLinkItem::saveToDir ()
  31.207 -{
  31.208 -	QString s="";
  31.209 -	if (beginBranch && endBranch && xLinkState==activeXLink)
  31.210 -	{
  31.211 -		if (beginBranch==endBranch )
  31.212 -			qWarning ("XLI::saveToDir  beginBranch==endBranch"); //FIXME-3	s=""
  31.213 -		else
  31.214 -		{
  31.215 -			QString colAttr=attribut ("color",color.name());
  31.216 -			QString widAttr=attribut ("width",QString().setNum(width,10));
  31.217 -			QString begSelAttr=attribut ("beginID",model->getSelectString(beginBranch));
  31.218 -			QString endSelAttr=attribut ("endID",  model->getSelectString(endBranch));
  31.219 -			s=beginElement ("xlink", colAttr +widAttr +begSelAttr +endSelAttr);
  31.220 -
  31.221 -			s+=endElement ("xlink");
  31.222 -		}
  31.223 -	}
  31.224 -	return s;
  31.225 -}
  31.226 -
  31.227 -XLinkObj* XLinkItem::createMapObj(QGraphicsScene *scene)  
  31.228 -{
  31.229 -	XLinkObj* xlo=new XLinkObj (scene,this);
  31.230 -	lmo=(LinkableMapObj*)xlo;
  31.231 -	return xlo;
  31.232 -}
  31.233 -
    32.1 --- a/xlinkitem.h	Fri Apr 09 14:24:04 2010 +0000
    32.2 +++ b/xlinkitem.h	Wed Jun 09 13:14:08 2010 +0000
    32.3 @@ -2,14 +2,16 @@
    32.4  #define XLINKITEM_H
    32.5  
    32.6  class BranchItem;
    32.7 +class QGraphicsScene;
    32.8  class XLinkObj;
    32.9 -class QGraphicsScene;
   32.10  
   32.11  #include "mapitem.h"
   32.12 +#include "xlink.h"
   32.13  
   32.14  /*! \brief xlinks are used to draw arbitrary connections between branches (BranchObj) in the map. */
   32.15  
   32.16  /////////////////////////////////////////////////////////////////////////////
   32.17 +
   32.18  class XLinkItem:public MapItem {
   32.19  public:
   32.20  	enum XLinkState {undefinedXLink,initXLink,activeXLink,deleteXLink};	
   32.21 @@ -17,33 +19,13 @@
   32.22  	XLinkItem (const QList<QVariant> &data, TreeItem *parent=NULL);
   32.23      virtual ~XLinkItem ();
   32.24      virtual void init ();
   32.25 -	void setBegin (BranchItem*);
   32.26 -	BranchItem* getBegin();
   32.27 -	void setEnd   (BranchItem*);
   32.28 -	void setEnd   (QPointF);
   32.29 -	BranchItem* getEnd();
   32.30 -	void setColor(QColor);
   32.31 -	QColor getColor();
   32.32 -	void setWidth (int);
   32.33 -	int getWidth ();
   32.34 -	bool activate ();			//! Creates a 2nd XLink (without a XLinkObj attached) 
   32.35 -	bool isBegin();		//! true, if this is master xLink, which may have an XLinkObj attached
   32.36 +	void setLink (Link*);
   32.37 +	Link* getLink ();
   32.38  	void updateXLink();
   32.39 -	virtual void updateVisibility();	// FIXME-3 not really needed atm...
   32.40  	BranchItem* getPartnerBranch ();
   32.41 -	BranchItem* getOtherBranch (TreeItem *ti);
   32.42 -	XLinkItem *getPartnerXLink();	//! Partner XLink
   32.43 -	QString saveToDir ();
   32.44 -	virtual XLinkObj* createMapObj(QGraphicsScene *scene);
   32.45  
   32.46  private:
   32.47 -	XLinkState xLinkState;	// init during drawing or active
   32.48 -	QColor color;
   32.49 -	int width;
   32.50 -	BranchItem *beginBranch;
   32.51 -	BranchItem *endBranch;
   32.52 -	XLinkItem *partnerXLink;
   32.53 -	bool isBeginXLink;
   32.54 +	Link *link;
   32.55  };
   32.56  
   32.57  #endif
    33.1 --- a/xlinkobj.cpp	Fri Apr 09 14:24:04 2010 +0000
    33.2 +++ b/xlinkobj.cpp	Wed Jun 09 13:14:08 2010 +0000
    33.3 @@ -1,11 +1,9 @@
    33.4 +#include <QDebug>
    33.5 +
    33.6  #include "xlinkobj.h"
    33.7  
    33.8  #include "branchobj.h"
    33.9  #include "branchitem.h"
   33.10 -#include "xlinkitem.h"
   33.11 -
   33.12 -#include <iostream>
   33.13 -using namespace std;
   33.14  
   33.15  /////////////////////////////////////////////////////////////////
   33.16  // XLinkObj
   33.17 @@ -13,16 +11,18 @@
   33.18  
   33.19  int XLinkObj::arrowSize=10;					// make instances
   33.20  
   33.21 -XLinkObj::XLinkObj (QGraphicsScene* scene, TreeItem* ti):MapObj(scene,ti)
   33.22 +XLinkObj::XLinkObj (QGraphicsScene* scene,Link *l):MapObj(scene)
   33.23  {
   33.24 -	//cout << "Const XLinkObj (s)\n";
   33.25 +	//qDebug()<< "Const XLinkObj (s,Link)";
   33.26 +	link=l;
   33.27  	init();
   33.28  }
   33.29  
   33.30  
   33.31 +
   33.32  XLinkObj::~XLinkObj ()
   33.33  {
   33.34 -	//cout << "Destr XLinkObj\n";
   33.35 +	//qDebug() << "Destr XLinkObj";
   33.36  	delete (line);
   33.37  	delete (poly);
   33.38  }
   33.39 @@ -30,16 +30,15 @@
   33.40  
   33.41  void XLinkObj::init () 
   33.42  {
   33.43 -	XLinkItem *xli=(XLinkItem*)treeItem;
   33.44  	visBranch=NULL;
   33.45  
   33.46 -	pen.setColor ( xli->getColor() );
   33.47 -	pen.setWidth ( xli->getWidth() );
   33.48 +	pen.setColor ( link->getColor() );
   33.49 +	pen.setWidth ( link->getWidth() );
   33.50  	pen.setCapStyle (  Qt::RoundCap );
   33.51  	line=scene->addLine(QLineF(1,1,1,1),pen);
   33.52 -    line->setZValue (Z_XLINK);
   33.53 -	poly=scene->addPolygon(QPolygonF(),pen, xli->getColor());
   33.54 -    poly->setZValue (Z_XLINK);
   33.55 +	line->setZValue (Z_LINK);
   33.56 +	poly=scene->addPolygon(QPolygonF(),pen, link->getColor());
   33.57 +	poly->setZValue (Z_LINK);
   33.58  	setVisibility (true);
   33.59  }
   33.60  
   33.61 @@ -53,7 +52,7 @@
   33.62  {
   33.63  	QPointF a,b;
   33.64  	QPolygonF pa;
   33.65 -	if (visBranch)
   33.66 +	if (visBranch)   
   33.67  	{
   33.68  		// Only one of the linked branches is visible
   33.69  		BranchObj *bo=(BranchObj*)(visBranch->getLMO());
   33.70 @@ -81,7 +80,7 @@
   33.71  	} else
   33.72  	{
   33.73  		// Both linked branches are visible
   33.74 -		BranchItem *bi=((XLinkItem*)treeItem)->getBegin();
   33.75 +		BranchItem *bi=link->getBeginBranch();
   33.76  		if ( bi)
   33.77  		{
   33.78  			// If a link is just drawn in the editor,
   33.79 @@ -96,8 +95,7 @@
   33.80  			// This shouldn't be reached normally...
   33.81  			a=beginPos;
   33.82  
   33.83 -		// FIXME-3 try to get rid of xLinkstate if (xLinkState==activeXLink && endBranch)
   33.84 -		bi=((XLinkItem*)treeItem)->getEnd();
   33.85 +		bi=link->getEndBranch();
   33.86  		if (bi)
   33.87  		{
   33.88  			BranchObj *bo=(BranchObj*)(bi->getLMO());
   33.89 @@ -112,10 +110,9 @@
   33.90  
   33.91  	beginPos=a;
   33.92  	endPos=b;
   33.93 -	XLinkItem *xli=(XLinkItem*)treeItem;
   33.94 -	pen.setColor ( xli->getColor() );
   33.95 -	pen.setWidth ( xli->getWidth() );
   33.96 -	poly->setBrush (xli->getColor() );
   33.97 +	pen.setColor ( link->getColor() );
   33.98 +	pen.setWidth ( link->getWidth() );
   33.99 +	poly->setBrush (link->getColor() );
  33.100  	line->setPen (pen);
  33.101  	line->setLine(a.x(), a.y(), b.x(), b.y());
  33.102  }
  33.103 @@ -148,12 +145,12 @@
  33.104  
  33.105  void XLinkObj::setVisibility ()
  33.106  {
  33.107 -	BranchItem* beginBI=((XLinkItem*)treeItem)->getBegin();
  33.108 +	BranchItem* beginBI=link->getBeginBranch();
  33.109  	BranchObj* beginBO=NULL;
  33.110  	if (beginBI) beginBO=(BranchObj*)(beginBI->getLMO());
  33.111  
  33.112  	BranchObj* endBO=NULL;
  33.113 -	BranchItem* endBI=((XLinkItem*)treeItem)->getEnd();
  33.114 +	BranchItem* endBI=link->getEndBranch();
  33.115  	if (endBI) endBO=(BranchObj*)(endBI->getLMO());
  33.116  	if (beginBO && endBO)
  33.117  	{
    34.1 --- a/xlinkobj.h	Fri Apr 09 14:24:04 2010 +0000
    34.2 +++ b/xlinkobj.h	Wed Jun 09 13:14:08 2010 +0000
    34.3 @@ -2,6 +2,7 @@
    34.4  #define XLINKOBJ_H
    34.5  
    34.6  #include "mapobj.h"
    34.7 +#include "xlink.h"
    34.8  
    34.9  class BranchObj;
   34.10  class BranchItem;
   34.11 @@ -11,7 +12,7 @@
   34.12  /////////////////////////////////////////////////////////////////////////////
   34.13  class XLinkObj:public MapObj {
   34.14  public:
   34.15 -    XLinkObj (QGraphicsScene* scene, TreeItem* ti);
   34.16 +    XLinkObj (QGraphicsScene* scene, Link* l );
   34.17      virtual ~XLinkObj ();
   34.18      virtual void init ();
   34.19  	virtual void setEnd (QPointF);
   34.20 @@ -30,6 +31,7 @@
   34.21  	QPointF   endPos;
   34.22  
   34.23  	BranchItem *visBranch;	// the "visible" part of a partially scrolled li
   34.24 +	Link *link;
   34.25  };
   34.26  
   34.27  #endif
    35.1 --- a/xml-base.cpp	Fri Apr 09 14:24:04 2010 +0000
    35.2 +++ b/xml-base.cpp	Wed Jun 09 13:14:08 2010 +0000
    35.3 @@ -99,8 +99,9 @@
    35.4  	inputFile=f;
    35.5  }
    35.6  
    35.7 -void parseBaseHandler::setLoadMode (const LoadMode &lm)
    35.8 +void parseBaseHandler::setLoadMode (const LoadMode &lm, int p)
    35.9  {
   35.10  	loadMode=lm;
   35.11 +	insertPos=p;
   35.12  }
   35.13  
    36.1 --- a/xml-base.h	Fri Apr 09 14:24:04 2010 +0000
    36.2 +++ b/xml-base.h	Wed Jun 09 13:14:08 2010 +0000
    36.3 @@ -29,12 +29,14 @@
    36.4  	void setModel (VymModel *);
    36.5  	void setTmpDir (QString);
    36.6  	void setInputFile (QString);
    36.7 -	void setLoadMode (const LoadMode &);
    36.8 +	void setLoadMode (const LoadMode &,int p=-1);
    36.9  
   36.10  protected:
   36.11  	QString     errorProt;
   36.12  
   36.13  	LoadMode loadMode;
   36.14 +	int insertPos;
   36.15 +
   36.16  	bool isVymPart;
   36.17  //	State state;			 
   36.18  //	State laststate;
    37.1 --- a/xml-vym.cpp	Fri Apr 09 14:24:04 2010 +0000
    37.2 +++ b/xml-vym.cpp	Wed Jun 09 13:14:08 2010 +0000
    37.3 @@ -146,9 +146,15 @@
    37.4  				lastBranch=bi;
    37.5  				if (loadMode==ImportAdd)
    37.6  				{
    37.7 +					// Import Add
    37.8  					lastBranch=model->createBranch(lastBranch);
    37.9 -				} //else
   37.10 -					model->clearItem(lastBranch); 
   37.11 +				} else  
   37.12 +				{
   37.13 +					// Import Replace 
   37.14 +					// Parser should not be called with ImportReplace any longer,
   37.15 +					// that's done in VymModel now.
   37.16 +					qDebug()<<"xml-vym:  ImportReplace  ?!"; 
   37.17 +				}
   37.18  			} else
   37.19  				// add mapCenter without parent
   37.20  				lastBranch=model->createMapCenter(); 
   37.21 @@ -208,6 +214,8 @@
   37.22  				if (loadMode==ImportAdd)
   37.23  				{
   37.24  					lastBranch=model->createBranch(lastBranch);
   37.25 +					if (insertPos>=0)
   37.26 +						model->relinkBranch (lastBranch,(BranchItem*)ti,insertPos);
   37.27  				} else
   37.28  					model->clearItem (lastBranch);
   37.29  				readBranchAttr (atts);
   37.30 @@ -239,6 +247,10 @@
   37.31  	{
   37.32  		state=StateBranchXLink;
   37.33  		if (!readXLinkAttr (atts)) return false;
   37.34 +    } else if ( eName == "xlink" && state == StateMap) 
   37.35 +	{
   37.36 +		state=StateLink;
   37.37 +		if (!readLinkNewAttr (atts)) return false;
   37.38      } else if ( eName == "branch" && state == StateBranch ) 
   37.39  	{
   37.40  		lastBranch=model->createBranch(lastBranch);
   37.41 @@ -545,10 +557,17 @@
   37.42  	return true;
   37.43  }
   37.44  
   37.45 -bool parseVYMHandler::readXLinkAttr (const QXmlAttributes& a)	
   37.46 +bool parseVYMHandler::readXLinkAttr (const QXmlAttributes& a) 
   37.47  {
   37.48 +	// Format of links was changed several times:
   37.49 +	//
   37.50  	// object ID is used starting in version 1.8.76
   37.51  	// (before there was beginBranch and endBranch)
   37.52 +	//
   37.53 +	// Starting in 1.13.2 xlinks are no longer subitems of branches,
   37.54 +	// but listed at the end of the data in a map. This make handling 
   37.55 +	// of links much safer and easier
   37.56 +
   37.57  	if (!a.value( "beginID").isEmpty() ) 
   37.58  	{ 
   37.59  		if (!a.value( "endID").isEmpty() ) 
   37.60 @@ -557,28 +576,66 @@
   37.61  			TreeItem   *endBI=model->findBySelectString (a.value( "endID"));
   37.62  			if (beginBI && endBI && beginBI->isBranchLikeType() && endBI->isBranchLikeType() )
   37.63  			{
   37.64 -				XLinkItem *xli=model->createXLink (lastBranch,true);
   37.65 -				xli->setBegin ( (BranchItem*)beginBI );
   37.66 -				xli->setEnd ( (BranchItem*)endBI);
   37.67 -				xli->activate();
   37.68 +				Link *li=new Link (model);
   37.69 +				li->setBeginBranch ( (BranchItem*)beginBI );
   37.70 +				li->setEndBranch ( (BranchItem*)endBI);
   37.71  
   37.72  				if (!a.value( "color").isEmpty() ) 
   37.73  				{
   37.74  					QColor col;
   37.75  					col.setNamedColor(a.value("color"));
   37.76 -					xli->setColor (col);
   37.77 +					li->setColor (col);
   37.78  				}
   37.79  
   37.80  				if (!a.value( "width").isEmpty() ) 
   37.81  				{
   37.82  					bool okx;
   37.83 -					xli->setWidth(a.value ("width").toInt (&okx, 10));
   37.84 +					li->setWidth(a.value ("width").toInt (&okx, 10));
   37.85  				}
   37.86 -				xli->updateXLink();
   37.87 +				model->createLink (li,true);	// create MO by default
   37.88  			}
   37.89  		}           
   37.90  	}	
   37.91 -	return true;	// xLinks can only be established at the "end branch", return true
   37.92 +	return true;	
   37.93 +}
   37.94 +
   37.95 +bool parseVYMHandler::readLinkNewAttr (const QXmlAttributes& a)	
   37.96 +{
   37.97 +	// object ID is used starting in version 1.8.76
   37.98 +	// (before there was beginBranch and endBranch)
   37.99 +
  37.100 +	// Beginning in 1.13.2 xLinks are no longer parts of branches, but
  37.101 +	// a separate list after all the mapCenters within <vymmap> ... </vymmap>
  37.102 +
  37.103 +	if (!a.value( "beginID").isEmpty() ) 
  37.104 +	{ 
  37.105 +		if (!a.value( "endID").isEmpty() ) 
  37.106 +		{
  37.107 +			TreeItem *beginBI=model->findBySelectString (a.value( "beginID"));
  37.108 +			TreeItem   *endBI=model->findBySelectString (a.value( "endID"));
  37.109 +			if (beginBI && endBI && beginBI->isBranchLikeType() && endBI->isBranchLikeType() )
  37.110 +			{
  37.111 +				Link *li=new Link (model);
  37.112 +				li->setBeginBranch ( (BranchItem*)beginBI );
  37.113 +				li->setEndBranch ( (BranchItem*)endBI);
  37.114 +
  37.115 +				if (!a.value( "color").isEmpty() ) 
  37.116 +				{
  37.117 +					QColor col;
  37.118 +					col.setNamedColor(a.value("color"));
  37.119 +					li->setColor (col);
  37.120 +				}
  37.121 +
  37.122 +				if (!a.value( "width").isEmpty() ) 
  37.123 +				{
  37.124 +					bool okx;
  37.125 +					li->setWidth(a.value ("width").toInt (&okx, 10));
  37.126 +				}
  37.127 +				model->createLink (li,true);	// create MO by default
  37.128 +			}
  37.129 +		}           
  37.130 +	}	
  37.131 +	return true;	
  37.132  }
  37.133  
  37.134  bool parseVYMHandler::readHtmlAttr (const QXmlAttributes& a)
    38.1 --- a/xml-vym.h	Fri Apr 09 14:24:04 2010 +0000
    38.2 +++ b/xml-vym.h	Wed Jun 09 13:14:08 2010 +0000
    38.3 @@ -22,6 +22,7 @@
    38.4  	bool readNoteAttr (const QXmlAttributes&);
    38.5  	bool readImageAttr (const QXmlAttributes&);
    38.6  	bool readXLinkAttr (const QXmlAttributes&);
    38.7 +	bool readLinkNewAttr (const QXmlAttributes&);
    38.8  	bool readHtmlAttr (const QXmlAttributes&);
    38.9  	bool readSettingAttr (const QXmlAttributes&);
   38.10  
   38.11 @@ -41,7 +42,8 @@
   38.12  		StateStandardFlag,
   38.13  		StateNote,
   38.14  		StateImage,
   38.15 -		StateHeading
   38.16 +		StateHeading,
   38.17 +		StateLink,
   38.18  	 };
   38.19  
   38.20  	 int branchesCounter;
    39.1 --- a/xmlobj.cpp	Fri Apr 09 14:24:04 2010 +0000
    39.2 +++ b/xmlobj.cpp	Wed Jun 09 13:14:08 2010 +0000
    39.3 @@ -19,6 +19,29 @@
    39.4      return r;
    39.5  }
    39.6  
    39.7 +QString quoteUmlaut(const QString &s)
    39.8 +{
    39.9 +	QString r=s;
   39.10 +    QRegExp rx( "ü");
   39.11 +    r.replace ( rx,"&uuml;");
   39.12 +    rx.setPattern( "Ü");
   39.13 +    r.replace ( rx,"&Uuml;");
   39.14 +    rx.setPattern( "ö");
   39.15 +    r.replace ( rx,"&ouml;");
   39.16 +    rx.setPattern( "Ö");
   39.17 +    r.replace ( rx,"&Ouml;");
   39.18 +    rx.setPattern( "ä");
   39.19 +    r.replace ( rx,"&auml;");
   39.20 +    rx.setPattern( "Ö");
   39.21 +    r.replace ( rx,"&Auml;");
   39.22 +    rx.setPattern( "ß");
   39.23 +    r.replace ( rx,"&szlig;");
   39.24 +    rx.setPattern( "€");
   39.25 +    r.replace ( rx,"&euro;");
   39.26 +    return r;
   39.27 +}
   39.28 +
   39.29 +
   39.30  
   39.31  
   39.32  int XMLObj::actindent=0;		// make instance of actindent
    40.1 --- a/xmlobj.h	Fri Apr 09 14:24:04 2010 +0000
    40.2 +++ b/xmlobj.h	Wed Jun 09 13:14:08 2010 +0000
    40.3 @@ -4,6 +4,7 @@
    40.4  class QString;
    40.5  
    40.6  QString quotemeta(const QString&);	
    40.7 +QString quoteUmlaut(const QString&);	
    40.8  
    40.9  /////////////////////////////////////////////////////////////////////////////
   40.10  class XMLObj