# HG changeset patch
# User insilmaril
# Date 1248939605 0
# Node ID 98449ef9eccd0e0b57b8e449f9a260e57059b077
# Parent  41937601b3b81687745fd1529c2cc90ee116949e
Bugfix: no undo for deleted mapcenters

diff -r 41937601b3b8 -r 98449ef9eccd mapeditor.cpp
--- a/mapeditor.cpp	Mon Jul 27 12:53:19 2009 +0000
+++ b/mapeditor.cpp	Thu Jul 30 07:40:05 2009 +0000
@@ -249,7 +249,9 @@
 		
 		s=(((BranchObj*)lmo)->getHeading());
 		if (s=="") s="unnamed";
-		return QString("branch (%1)").arg(s);
+		if ((typeid(*lmo) == typeid(BranchObj) ) )
+			return QString("branch (%1)").arg(s);
+		return QString("mapcenter (%1)").arg(s);
 	}	
 	if ((typeid(*lmo) == typeid(FloatImageObj) ))
 		return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
@@ -321,12 +323,15 @@
 	FloatImageObj (mapScene).resetSaveCounter();
 
 	// Build xml recursivly
-	if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
+	if (!saveSel )
 		// Save complete map, if saveSel not set
 		s+=model->saveToDir(tmpdir,prefix,writeflags,offset);
 	else
 	{
-		if ( typeid(*saveSel) == typeid(BranchObj) )
+		if ( typeid (*saveSel) == typeid (MapCenterObj))
+			// Save Subtree
+			s+=((MapCenterObj*)saveSel)->saveToDir(tmpdir,prefix,0,offset);
+		else if ( typeid(*saveSel) == typeid(BranchObj) )
 			// Save Subtree
 			s+=((BranchObj*)saveSel)->saveToDir(tmpdir,prefix,offset);
 		else 
@@ -471,10 +476,12 @@
 		qWarning ("MapEditor::saveStateRemovingPart  no redoSel given!");
 		return;
 	}
-	QString undoSelection=model->getSelectString (redoSel->getParObj());
+	
+	QString undoSelection;
 	QString redoSelection=model->getSelectString(redoSel);
 	if (typeid(*redoSel) == typeid(BranchObj)  ) 
 	{
+		undoSelection=model->getSelectString (redoSel->getParObj());
 		// save the selected branch of the map, Undo will insert part of map 
 		saveState (PartOfMap,
 			undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
@@ -482,6 +489,16 @@
 			comment, 
 			redoSel);
 	}
+	if (typeid(*redoSel) == typeid(MapCenterObj)  ) 
+	{
+		undoSelection.clear();
+		// save the selected branch of the map, Undo will insert part of map 
+		saveState (PartOfMap,
+			undoSelection, QString("addMapInsert (\"PATH\")"),
+			redoSelection, "delete ()", 
+			comment, 
+			redoSel);
+	}
 }
 
 
@@ -611,21 +628,26 @@
 	/////////////////////////////////////////////////////////////////////
 	} else if (com==QString("addMapInsert"))
 	{
-		if (xelection.isEmpty())
+		if (parser.parCount()==2)
 		{
-			parser.setError (Aborted,"Nothing selected");
-		} else if (! selb )
-		{				  
-			parser.setError (Aborted,"Type of selection is not a branch");
-		} else 
-		{	
-			if (parser.checkParCount(2))
+			if (xelection.isEmpty())
+			{
+				parser.setError (Aborted,"Nothing selected");
+			} else if (! selb )
+			{				  
+				parser.setError (Aborted,"Type of selection is not a branch");
+			} else
 			{
 				t=parser.parString (ok,0);	// path to map
 				n=parser.parInt(ok,1);		// position
 				if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
-				addMapInsertInt(t,n);	
+				addMapInsertInt(t,n);
 			}
+		} else if (parser.parCount ()==1)
+		{
+			t=parser.parString (ok,0);	// path to map
+			if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
+			addMapInsertInt(t);	
 		}
 	/////////////////////////////////////////////////////////////////////
 	} else if (com=="clearFlags")
@@ -2312,8 +2334,7 @@
 	QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
 
 	// select  object before undo
-	if (!undoSelection.isEmpty())
-		select (undoSelection);
+	select (undoSelection);
 
 	if (debug)
 	{
@@ -2430,40 +2451,56 @@
 		QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
 }
 
-void MapEditor::addMapInsertInt (const QString &path, int pos)
+bool MapEditor::addMapInsertInt (const QString &path)
+{
+	QString pathDir=path.left(path.findRev("/"));
+	QDir d(pathDir);
+	QFile file (path);
+
+	if (d.exists() )
+	{
+		// We need to parse saved XML data
+		parseVYMHandler handler;
+		QXmlInputSource source( file);
+		QXmlSimpleReader reader;
+		reader.setContentHandler( &handler );
+		reader.setErrorHandler( &handler );
+		handler.setModel (model);
+		handler.setTmpDir ( pathDir );	// needed to load files with rel. path
+		handler.setLoadMode (ImportAdd);
+		blockReposition=true;
+		bool ok = reader.parse( source );
+		blockReposition=false;
+		if ( ok ) return true;	
+
+		// This should never ever happen
+		QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
+								handler.errorProtocol());
+	} else	
+		QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
+	return false;	
+}
+
+bool MapEditor::addMapInsertInt (const QString &path, int pos)
 {
 	BranchObj *sel=xelection.getBranch();
 	if (sel)
 	{
-		QString pathDir=path.left(path.findRev("/"));
-		QDir d(pathDir);
-		QFile file (path);
-
-		if (d.exists() )
+		if (addMapInsertInt (path))
 		{
-			// We need to parse saved XML data
-			parseVYMHandler handler;
-			QXmlInputSource source( file);
-			QXmlSimpleReader reader;
-			reader.setContentHandler( &handler );
-			reader.setErrorHandler( &handler );
-			handler.setModel (model);
-			handler.setTmpDir ( pathDir );	// needed to load files with rel. path
-			handler.setLoadMode (ImportAdd);
-			blockReposition=true;
-			bool ok = reader.parse( source );
-			blockReposition=false;
-			if (! ok ) 
-			{	
-				// This should never ever happen
-				QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
-										handler.errorProtocol());
+			{
+				if (sel->getDepth()>0)
+					sel->getLastBranch()->linkTo (sel,pos);
 			}
-			if (sel->getDepth()>0)
-				sel->getLastBranch()->linkTo (sel,pos);
+			return true;
 		} else	
+		{
 			QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
+			return false;
+		}	
 	}		
+	qWarning ("ME::addMapInsertInt nothing selected");
+	return false;
 }
 
 void MapEditor::pasteNoSave(const int &n)
@@ -2828,11 +2865,8 @@
 	BranchObj *bo = xelection.getBranch();
 	if (bo && xelection.type()==Selection::MapCenter)
 	{
-	//	BranchObj* par=(BranchObj*)(bo->getParObj());
 		xelection.unselect();
-	/* FIXME Note:  does saveStateRemovingPart work for MCO? (No parent!)
 		saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
-		*/
 		bo=model->removeMapCenter ((MapCenterObj*)bo);
 		if (bo) 
 		{
@@ -2852,7 +2886,6 @@
 		xelection.select (par);
 		ensureSelectionVisible();
 		model->reposition();
-//		xelection.update();
 		xelection.update();
 		return;
 	}
diff -r 41937601b3b8 -r 98449ef9eccd mapeditor.h
--- a/mapeditor.h	Mon Jul 27 12:53:19 2009 +0000
+++ b/mapeditor.h	Thu Jul 30 07:40:05 2009 +0000
@@ -1,88 +1,278 @@
 #ifndef MAPEDITOR_H
 #define MAPEDITOR_H
 
-#include <qcanvas.h>
-#include <qlineedit.h>
-#include <qcursor.h>
-#include <qfiledialog.h>
-#include <qevent.h>
-#include <qprocess.h>
+#include <QGraphicsView>
+#include <QtNetwork>
 
-#include "mapcenterobj.h"
+#include "attribute.h"
+#include "file.h"
 #include "misc.h"
+#include "parser.h"
+#include "ornamentedobj.h"
+#include "selection.h"
+#include "settings.h"
+#include "vymmodel.h"
 
-class MapEditor : public QCanvasView , public xmlObj {
+class VymModel;
+class Selection;
+
+/*! \brief Main widget in vym to display and edit a map */
+
+class MapEditor : public QGraphicsView, public XMLObj {
     Q_OBJECT
 
 public:
-    MapEditor(QWidget* parent=0, bool interactive=false, const char* name=0, WFlags f=0);
+    /*! \brief State of the mapeditor 
+		
+		While a heading is edited, the state has to change, so
+		that e.g. no other object might get selected. This is done
+		in Main by calling setStateEditHeading
+	*/
+	enum State {
+		Idle,			//!< Idle, waiting for user event
+		EditHeading		//!< Editing heading (dont't select another branch now)
+	};
+    /*! \brief Networking states
+		
+		In Network modus we want to switch of saveState, autosave, ...
+	*/
+	enum NetState {
+		Offline,			//!< Offline
+		Client,				//!< I am the client and connected to server
+		Server				//!< I am the server
+	};
+    MapEditor(QWidget* parent=0);
 	~MapEditor();
-    QColor color();
-    QColor backgroundColor();
-    MapCenterObj* getMapCenter();
-	QCanvas* getCanvas();
-	void adjustCanvasSize();// adjust canvas size to map and scrollview
-	bool blockReposition(); // block while load or undo
+	VymModel* getModel();
+	QGraphicsScene * getScene();
+	State getState();					//!< Return State of MapEditor
+	void setStateEditHeading (bool);	//!< If set to true, State will change to EditHeading
+	bool isRepositionBlocked(); //!< While load or undo there is no need to update graphicsview
+	bool isSaveStateBlocked();			//!< block while undo/redo or while running scripts
+	void setSaveStateBlocked(bool);		//!< block saving the undo/redo state
+	bool isSelectBlocked();		//!< true, if no change of selection is possible, e.g. while editing the heading of abranch
 	
+protected:
+	/*! \brief Get name of object
+	  
+	  Returns heading of a branch or name of an object for use in comment
+	  of undo/redo history
+	*/ 
+	QString getName(const LinkableMapObj*);	// Get e.g. heading or filename
+	void makeTmpDirs();		// create temporary directories
+
+	/*! This function saves all information of the map to disc.
+	    saveToDir also calls the functions for all BranchObj and other objects in the map.
+		The structure of the map itself is returned as QString and passed back to Main, 
+		where saveToDir is called initially
+	*/	
+    QString saveToDir (const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel);
+
+	/*! \brief Get directory, where current step in history is save
+
+		saveState creates a directory for each step in history. This function returns the
+		path of the current directory
+	*/
+	QString getHistoryDir();
+
+	/*! \brief Save the current changes in map 
+
+		Two commands and selections are saved:
+
+			- undocommand and undoselection to undo the change
+			- redocommand and redoselection to redo the action after an undo
+
+		Additionally a comment is logged. 
+
+	*/	
+    void saveState(
+		const SaveMode& savemode, 
+		const QString &undoSelection, 
+		const QString &undoCommand, 
+		const QString &redoSelection, 
+		const QString &redoCommand, 
+		const QString &comment, 
+		LinkableMapObj *saveSelection);
+	/*! Overloaded for convenience */
+    void saveStateChangingPart(
+		LinkableMapObj *undoSelection, 
+		LinkableMapObj* redoSelection, 
+		const QString &redoCommand, 
+		const QString &comment);
+	/*! Overloaded for convenience */
+    void saveStateRemovingPart(
+		LinkableMapObj *redoSelection, 
+		const QString &comment);
+	/*! Overloaded for convenience */
+    void saveState(
+		LinkableMapObj *undoSelection, 
+		const QString &undoCommand, 
+		LinkableMapObj *redoSelection, 
+		const QString &redoCommand, 
+		const QString &comment); 
+	/*! Overloaded for convenience */
+    void saveState(
+		const QString &undoSelection, 
+		const QString &undoCommand, 
+		const QString &redoSelection, 
+		const QString &redoCommand, 
+		const QString &comment) ;
+    void saveState(
+		const QString &undoCommand, 
+		const QString &redoCommand, 
+		const QString &comment) ;
+
+public:	
+
+	/* \brief Process one command and its parameters */
+    void parseAtom (const QString &atom);	
+
+	/* \brief Runs the script */
+	void runScript (QString script);
 private:
-	void makeTmpDirs();		// create temporary directories
-	void delTmpDirs();		// delete temporary directories
-	void makeSubDirs(const QString&);		
-							// create subdirs in dir
-    QString saveToDir(const QString&,const QString &,bool, const QPoint
-	&,SaveMode);
-    void saveState();		// save actual state to backup
-    void saveState(const SaveMode&, LinkableMapObj *);
-
-private slots:
-    void finishedLineEditNoSave();
+    void addFloatImageInt(const QPixmap &img);
 
 public:
-	bool isDefault();		// false, if map was changed once
-    bool isUnsaved();		// save necessary
-    bool hasChanged();		// undo possible
-	void setChanged();		// called from NoteEditor via LMO
-	void closeMap();
-	void setFilePath (QString);	
-	void setFilePath (QString,QString);	
-	QString getFilePath ();	// Full path e.g. "/home/tux/map.xml"
-	QString getFileName ();	// e.g. "map.xml"
-	QString getMapName ();	// e.g. "map"
-	QString getDestPath (); // e.g. "/home/tux/map.vym"
-    int load (QString&, const LoadMode &);	// newmap, import/replace selection
-    int save(const SaveMode &);	// Save map 
-	void setZipped(bool);		// save map zipped
-	bool saveZipped();			// 1 if file will be saved zipped
-    void print();				// print canvas
+	bool isDefault();		//!< true, if map is still the empty default map
+    bool hasChanged();		//!< true, if something has changed and is not saved yet
+	void setChanged();		//!< called from TextEditor via LinkableMapObj
+	void closeMap();		//!< Closes the map
+
+	/*! \brief Sets filepath, filename and mapname
+
+	     If the filepath is "/home/tux/map.xml", then the filename will be set
+		 to map.xml. The destname is needed for vymLinks, pointing to another map. 
+		 The destname holds the real name of the file, after it has been compressed, e.g. "map.vym"
+	*/	 
+
+	/*! \brief Set File path
+
+	     The destname is needed to construct the references between maps
+	*/	 
+	void setFilePath (QString filepath,QString destname);	
+	void setFilePath (QString);	//!< Overloaded for convenience
+	QString getFilePath ();	//!< Full path e.g. "/home/tux/map.xml"
+	QString getFileName ();	//!< e.g. "map.xml"
+	QString getMapName ();	//!< e.g. "map"
+	QString getDestPath (); //!< e.g. "/home/tux/map.vym"
+
+	/*! \brief Load map
+
+		The data is read from file. Depending on LoadMode the current
+		selection gets replaced by data or the data is appended.
+	*/	
+    ErrorCode load (QString, const LoadMode &, const FileType& );	// newmap, import/replace selection
+public:
+	/*! \brief Save the map to file */
+    ErrorCode save(const SaveMode &);	
+	/* FIXME no needed any longer
+	void setZipped(bool);		//!< Set or unset compression of map with zip save map zipped
+	bool saveZipped();			//!< True, if file will be saved zipped
+	*/
+    void print();				//!< Print the map
+	void setAntiAlias (bool);	//!< Set or unset antialiasing
+	void setSmoothPixmap(bool); //!< Set or unset smoothing of pixmaps
 private:
     QPixmap getPixmap();
+	void setHideTmpMode (HideTmpMode);	// temporary hide stuff
+	HideTmpMode getHideTmpMode();		// temporary hide stuff
 public:
-    void exportImage (QString fn);		// export as PNG	
-    void exportImage (QString fn, int);	// export in given format
-    void exportASCII();
-    void exportXML(const QString&);		// export to directory
-    void clear();		// clear map
-    void undo();		// undo last action
-    void copy();		// copy branch to clipboard
+	/*! Set or unset temporary hiding of objects during export  */
+	void setExportMode (bool);
+
+	/*! Export as ASCII text to file */
+	void exportASCII (QString fname="",bool askForName=true);  
+
+	/*! Save as image */
+    void exportImage (QString fname="",bool askForName=true,QString format="PNG");
+
+    /*! Export as OpenOfficeOrg presentation */
+    void exportOOPresentation(const QString &,const QString &);	
+
+	/*! Export as XHTML to directory */
+    void exportXHTML(const QString& dir="", bool askForName=true);	
+
+	/*! Export as XTML to directory */
+    void exportXML(QString dir="", bool askForName=true);
+
+    void clear();						//!< Clear map
+    void copy();						//!< Copy to clipboard
+    void redo();						//!< Redo last action
+	bool isRedoAvailable();				//!< True, if redo is available
+    void undo();						//!< Undo last action
+	bool isUndoAvailable();				//!< True, if undo is available
+	void gotoHistoryStep (int);			//!< Goto a specifig step in history
 private:	
-    LinkableMapObj* pasteNoSave();		// paste clipboard to branch
-    LinkableMapObj* pasteAtNoSave(int);	// paste clipboard to branch at position i
-    void cutNoSave();	// cut to clipboard
+    void addMapReplaceInt(const QString & undoSel, const QString & path);
+    bool addMapInsertInt (const QString & path);
+    bool addMapInsertInt (const QString & path, int pos);
+    void pasteNoSave(const int &n);		//!< paste clipboard to branch
 public:	
-    void paste();		// paste clipboard to branch and backup
-    void cut();			// cut to clipboard and backup
-    void moveBranchUp();
-    void moveBranchDown();
-    void editHeading();
-    void addNewBranch(int);			// pos allows to add above/below selection
-    void deleteSelection();
-	LinkableMapObj* getSelection();	// returns selection
-	bool select(QString );			// Select 
-	void unselect();				// before changing current noteedit
-	void reselect();				// after  changing current noteedit
+    void paste();		//!< Paste clipboard to branch and backup
+    void cut();			//!< Cut to clipboard (and copy)
+	/*! \brief Move absolutly
+
+		Move absolutly to (x,y).
+	*/	
+    void move    (const double &x, const double &y);
+	/*! \brief Move relativly
+
+		Move relativly to (x,y).
+	*/	
+    void moveRel (const double &x, const double &y);
+    void moveBranchUp();	//!< Move branch up
+    void moveBranchDown();	//!< Move branch down
+	void sortChildren();	//!< Sort children lexically
 private:	
-	void selectNextBranch();		// Increment number of branch
-	void selectPrevBranch();		// Decrement number of branch
+	void linkTo(const QString &);
+public:	
+	QString getHeading (bool &ok,QPoint &p); //!< Get heading, ok if selection is branch
+	void setHeading(const QString &);		//!< Set heading of branch	
+private:
+	void setHeadingInt(const QString &);
+	void setVymLinkInt(const QString &);	// Set vymLink for selection
+	/*! \brief Add new mapcenter
+
+	    Disclaimer: Still experimental, not fully supported.
+	*/	
+public:	
+    BranchObj* addMapCenter();		
+
+	/*! \brief Add new branch
+
+		Depending on num the new branch is created
+
+		-3 above selection as child of selections parent
+		-2 as child of selection
+		-1 below selection as child of selections parent
+		0..n	insert at a specific position in selections parent
+		(needed for free relinking)
+	*/	
+private:	
+    BranchObj* addNewBranchInt(int);		// pos allows to add above/below selection
+public:	
+	/*! \Add new branch
+		
+		Depending on num the new branch is created
+		-1 above selection
+		 0 as child of selection
+		 1 below selection
+	*/
+    BranchObj* addNewBranch(int pos);		
+    BranchObj* addNewBranchBefore();		//!< Insert branch between selection and its parent
+    void deleteSelection();					//!< Delete selection
+	LinkableMapObj* getSelection();			//!< Returns selection
+	BranchObj* getSelectedBranch();			// returns selected branch or NULL
+	FloatImageObj* getSelectedFloatImage();	// returns selected branch or NULL
+	void unselect();						// before changing current noteedit
+	void reselect();						// after  changing current noteedit
+	bool select(const QString &);			// Select by string
+	bool select(LinkableMapObj *lmo);		// Select by pointer
+	QString getSelectString();
+private:	
+	void selectInt(LinkableMapObj*);	
+	void selectNextBranchInt();		// Increment number of branch
+	void selectPrevBranchInt();		// Decrement number of branch
 public:	
     void selectUpperBranch();
     void selectLowerBranch();
@@ -90,108 +280,215 @@
     void selectRightBranch();
     void selectFirstBranch();
     void selectLastBranch();
-    void setColor(QColor);
-    void selectBackgroundColor();
-    void setBackgroundColor(QColor);
-    QColor pickColor();
-    void colorItem();
-    void colorBranch();
+    void selectMapBackgroundImage();
+    void setMapBackgroundImage(const QString &);
+    void selectMapBackgroundColor();
+    void setMapBackgroundColor(QColor);
+    QColor getMapBackgroundColor();
+    QColor getCurrentHeadingColor();
+    void colorBranch(QColor);
+    void colorSubtree(QColor);
 	void toggleStandardFlag(QString);
-	virtual void setViewCenter();			// needed for zooming
     BranchObj* findText(QString,bool);		// Find object
     void findReset();						// Reset Find 
-	void openURL();							// open URL in external browser
-	void editURL();							// edit the URL
+	void setURL(const QString &);			// set  URL
+	void editURL();							// edit URL
+	void editLocalURL();					// edit URL to local file
+	QString getURL();						// returns URL of selection or ""
+	QStringList getURLs();					// returns URLs of subtree
 	void editHeading2URL();					// copy heading to URL
 	void editBugzilla2URL();				// create URL to Bugzilla
+	void editFATE2URL();					// create URL to FATE
 	void editVymLink();						// edit link to another map
 	void deleteVymLink();					// delete link to another map
 	QString getVymLink();					// return path to map
+	QStringList getVymLinks();				// return paths in subtree
+	void setHideExport(bool);				// toggle the export flag
+	void toggleHideExport();				// toggle the export flag
+	void deleteKeepChilds();				// remove but keep childs
+	void deleteChilds();					// remove childs
 	void editMapInfo();						// dialog to enter author, ...
+	void ensureSelectionVisible();		
+	void updateSelection();					// update geometry of selection
 	void updateActions();					// update e.g. format buttons
-	void setLinkStyle (LinkStyle);			// Set style of link
-	LinkStyle getLinkStyle ();				// requested in LMO
-	void setLinkColor(QColor);				// default color of links
-	void setLinkColorHint();				// color of links
-	void setLinkColorHint(LinkColorHint);	// color of links
-	LinkColorHint getLinkColorHint();
-	QColor getDefLinkColor();
-	void toggleLinkColorHint();				// after changing linkStyles
-    void selectLinkColor();
+	void updateNoteFlag();					// when TextEditor changes
+	void setMapAuthor (const QString &);
+	void setMapComment(const QString &);
+	void setMapLinkStyle (const QString &);	// Set style of link
+	LinkableMapObj::Style getMapLinkStyle ();	// requested in LMO
+	void setMapDefLinkColor(QColor);		// default color of links
+	void setMapLinkColorHintInt();			// color of links
+	void setMapLinkColorHint(LinkableMapObj::ColorHint);// color of links
+	LinkableMapObj::ColorHint getMapLinkColorHint();
+	QColor getMapDefLinkColor();
+	void setMapDefXLinkColor(QColor);
+	QColor getMapDefXLinkColor();
+	void setMapDefXLinkWidth (int);
+	int getMapDefXLinkWidth();
+	void toggleMapLinkColorHint();			// after changing linkStyles
+    void selectMapLinkColor();
+    void selectMapSelectionColor();
+private:	
+    void setSelectionColorInt(QColor);
+public:	
+    void setSelectionColor(QColor);
+    QColor getSelectionColor();
+	bool scrollBranch(BranchObj*);
+	bool unscrollBranch(BranchObj*);
     void toggleScroll();
-    void unScrollAll();
+    void unscrollChilds();
+private:	
+	FloatImageObj* loadFloatImageInt (QString);
+public:	
 	void loadFloatImage ();
-	void saveFloatImage (int);
-	void toggleFloatExport();
-	void setFrame(const FrameType &);
 private:	
-    void importDir(BranchObj *,QDir);
+	void saveFloatImageInt (FloatImageObj*, const QString &, const QString &);
+public:	
+	void saveFloatImage ();
+	void setFrameType(const FrameObj::FrameType &);
+	void setFrameType(const QString &);
+	void setFramePenColor (const QColor &);
+	void setFrameBrushColor (const QColor &);
+	void setFramePadding (const int &);
+	void setFrameBorderWidth (const int &);
+	void setIncludeImagesVer(bool);
+	void setIncludeImagesHor(bool);
+	void setHideLinkUnselected (bool);
+	bool getHideLinkUnselected ();
+private:	
+    void importDirInt(BranchObj *,QDir);
+    void importDirInt(const QString&);
 public:	
     void importDir();
-    void testFunction();				// FIXME just testing
+	void followXLink (int);
+	void editXLink (int);
+	AttributeTable* attributeTable();
+    void testFunction1();					// just testing new stuff
+    void testFunction2();					// just testing new stuff
+											// set /mainwindo/showTestMenu=true...
 
 protected:
-	void ensureSelectionVisible();		
-	virtual void updateViewCenter();	// needed for zooming
-	virtual void contentsContextMenuEvent ( QContextMenuEvent *e );
-    virtual void contentsMousePressEvent(QMouseEvent*);
-    virtual void contentsMouseReleaseEvent(QMouseEvent*);
-    virtual void contentsMouseDoubleClickEvent(QMouseEvent*);
-    virtual void contentsMouseMoveEvent(QMouseEvent*);
+	virtual void contextMenuEvent ( QContextMenuEvent *e );
+    virtual void keyPressEvent(QKeyEvent*);
+    virtual void keyReleaseEvent(QKeyEvent*);
+    virtual void mousePressEvent(QMouseEvent*);
+    virtual void mouseMoveEvent(QMouseEvent*);
+    virtual void mouseReleaseEvent(QMouseEvent*);
+    virtual void mouseDoubleClickEvent(QMouseEvent*);
+    virtual void resizeEvent( QResizeEvent * );
+
+	void dragEnterEvent (QDragEnterEvent *);
+	void dragMoveEvent (QDragMoveEvent *);
+	void dragLeaveEvent (QDragLeaveEvent *);
+	void dropEvent (QDropEvent *);
+
+
+protected:
+	void sendSelection();
+
+public:
+	void newServer();
+	void connectToServer();
+
+private slots:	
+	void newClient();
+	void sendData(const QString &s);
+	void readData();
+	void displayNetworkError (QAbstractSocket::SocketError);
+
+	void autosave ();
+	void fileChanged();
 
 private:
-    QCanvas* mapCanvas;
-    MapCenterObj* mapCenter;
+	State state;				// State of MapEditor
+	QGraphicsScene *mapScene;
+	VymModel *model;					// Vym Map, includding several mapCenters
+	QTimer *autosaveTimer;
+	QTimer *fileChangedTimer;
+	QDateTime fileChangedTime;
 
 	bool adjustCanvasRequested;	// collect requests until end of user event
 	BranchObj *editingBO;		// entering Text into BO
-    QLineEdit* lineedit;
 
-    QColor actColor;			// actual color
-	QColor deflinkcolor;		// default color for links
-	LinkColorHint linkcolorhint;// use heading color or own color
-	LinkStyle linkstyle;		// default style for links
+	QColor defLinkColor;		// default color for links
+	QColor defXLinkColor;		// default color for xlinks
+	int defXLinkWidth;			// default width for xlinks
+	LinkableMapObj::ColorHint linkcolorhint;// use heading color or own color
+	LinkableMapObj::Style linkstyle;		// default style for links
 
-    QCursor handOpenCursor;		// cursor while moving canvas view
-	QCursor pickColorCursor;	// cursor while picking color 
-	bool pickingColor;			// true while picking Color CTRL-LeftButton
-	
-    LinkableMapObj* selection;		// select a LinkableMapObj
-    LinkableMapObj* selectionLast;	// last selection 
+    QCursor HandOpenCursor;		// cursor while moving canvas view
+	QCursor PickColorCursor;	// cursor while picking color 
+	QCursor CopyCursor;			// cursor while picking color 
+	QCursor XLinkCursor;		// cursor while picking color 
+	bool pickingColor;
+	bool drawingLink;			// true while creating a link
+	bool copyingObj;			// true while creating a link
+	XLinkObj* tmpXLink;
+
+	Selection xelection;	
+
+	QString latestSelection;		// select string of latest added object
+
     MapObj* movingObj;				// moving a MapObj
-    QPoint movingObj_start;			// rel. pos of mouse to absPos 
-    QPoint movingCont_start;		// inital pos of moving Content or
-    QPoint movingVec;				// how far has Content moved
-	QPoint movingCenter;			// used when zooming
+	MapObj* linkingObj_src;			// part of a link
+    QPointF movingObj_orgPos;		// org. pos of mouse before move
+    QPointF movingObj_orgRelPos;	// org. relative pos of mouse before move
+    QPointF movingObj_start;		// rel. pos of mouse to absPos 
+    QPointF movingCont_start;		// inital pos of moving Content or
+    QPointF movingVec;				// how far has Content moved
+
+	QPointF contextMenuPos;					// position where context event was triggered
+
     QPrinter* printer;				// Printing
 
     bool mapDefault;				// Flag if map is untouched
     bool mapChanged;				// Flag if undo is possible
 	bool mapUnsaved;				// Flag if map should be saved
-    QString backupXML;				// backup (XML) for undo
-	LinkableMapObj* undoSelection;	// replace this LMO with vympart from backup
-									// if != NULL
+
+	Parser parser;				// Parser stuff for scripting
+
+	AttributeTable *attrTable;
 
 	bool printFrame;			// Print frame around map
 	bool printFooter;			// Print footer below map
 
 	bool zipped;				// should map be zipped
+	static	int mapNum;			// unique number for Editor
+	FileType fileType;			// type of file, e.g. vym, freemind...
 	QString fileName;			// short name of file (for tab)
 	QString filePath;			// path to file which will be saved
 	QString fileDir;			// dir where file is saved
 	QString destPath;			// path to .vym file (needed for vymlinks)
 	QString mapName;			// fileName without ".vym"
-	QString lastImageDir;		// save dir for adding images
 
-	bool isInteractive;			// non interactive don't need tmpdirs
-	QString bakMapDir;			// tmp directory with data for undo
-	bool blockreposition;		// block while load or undo
+	QString tmpMapDir;			// tmp directory with undo history
+	QString histPath;			// Path to history file
+	SimpleSettings undoSet;		// undo/redo commands, saved in histPath
+	int stepsTotal;				// total number of steps (undos+redos) 
+	int curStep;				// Current step in history (ring buffer)
+	int curClipboard;			// number of history step, which is the current clipboard
+	int redosAvail;				// Available number of redo steps
+	int undosAvail;				// Available number of undo steps
+	bool blockReposition;		// block while load or undo
+	bool blockSaveState;		// block while load or undo
 
 	BranchObj* itFind;			// next object in find process
 	bool EOFind;				// true, if search failed
 
 	QPoint exportOffset;		// set before export, used in save
-    void resizeEvent( QResizeEvent * );
+	HideTmpMode hidemode;	// true while exporting to hide some stuff
+
+	// Network connections **Experimental**
+	NetState netstate;			// offline, client, server
+	QTcpServer *tcpServer;		// Act as server in conference mode (experimental)
+	QList <QTcpSocket*> clientList;		// List of connected clients
+	quint16 sendCounter;		// Increased with every sent command
+
+	QTcpSocket	*clientSocket;	// socket of this client
+	QString server;				// server address of this client
+	int port;					// server port of this client
+	void displayClientError(QAbstractSocket::SocketError socketError);
+
 };
 #endif
 
diff -r 41937601b3b8 -r 98449ef9eccd selection.cpp
--- a/selection.cpp	Mon Jul 27 12:53:19 2009 +0000
+++ b/selection.cpp	Thu Jul 30 07:40:05 2009 +0000
@@ -1,39 +1,129 @@
+#include <typeinfo>
+
 #include "selection.h"
 
+#include "mainwindow.h"
+#include "mapeditor.h"
+#include "vymmodel.h"
+
+
+
+extern Main *mainWindow;
 
 Selection::Selection()
 {
-}
-
-Selection::Selection(const Selection &other)
-{
+	color= QColor(255,255,0);
 }
 
 Selection::~Selection()
 {
 }
 
-void Selection::init()
+void Selection::setModel (VymModel *m)
 {
-	selectList.setAutoDelete(true);
+	model=m;
+	scene=model->getScene();
 }
 
 void Selection::copy(const Selection &other)
 {
+	selectList=other.selectList;
+	lastSelectList=other.lastSelectList;
 }
 
 void Selection::clear()
 {
-	selectList.clear();
+	unselect();
+	lastSelectList.clear();
 }
 
-bool Selection::select(LinkableMapObj *lmo)
+void Selection::update()
 {
-	return false;
+	QRectF bbox;
+	int w=0;
+	for (int i=0; i< selectList.count(); ++i) 
+	{
+		bbox=selectList.at(i)->getBBox();
+		selboxList.at(i)->setRect (
+			bbox.x()-w,bbox.y()-w, 
+			bbox.width()+2*w, bbox.height()+2*w);
+		selboxList.at(i)->setPen (color);	
+		selboxList.at(i)->setBrush (color);	
+	}	
 }
 
-void Selection::unselect(LinkableMapObj *lmo)
+void Selection::setColor (QColor col)
 {
+	color=col;
+	update();
+}
+
+QColor Selection::getColor ()
+{
+	return color;
+}
+
+bool Selection::select(LinkableMapObj *lmo)	// TODO no multiselections yet
+{
+	if (!selectList.isEmpty()) unselect();
+	selectList.append (lmo);
+	QGraphicsRectItem *sb = scene->addRect(
+		QRectF(0,0,0,0), 
+		QPen(color),
+		color);
+	sb->setZValue(Z_SELBOX);
+	sb->show();
+	selboxList.append (sb);
+	lmo->select();
+	update();
+	mainWindow->updateSatellites (model->getMapEditor() );	
+	return true;
+}
+
+bool Selection::select (const QString &s)	// TODO no multiselections yet
+{
+	if (s.isEmpty())
+	{
+		unselect();
+		return true;
+	}
+
+	LinkableMapObj *lmo=model->findObjBySelect(s);
+
+	// Finally select the found object
+	if (lmo)
+	{
+		unselect();
+		select (lmo);
+		return true;
+	} 
+	return false;
+
+}
+
+bool Selection::reselect ()	// TODO no multiselections yet
+{
+	if (!lastSelectList.isEmpty())
+	{
+		select (lastSelectList.first());
+		return true;
+	}
+	return false;
+
+}
+
+void Selection::unselect()
+{
+	if (!selectList.isEmpty() )
+	{
+		for (int i=0; i< selectList.count(); ++i) 
+			selectList.at(i)->unselect();
+		lastSelectList=selectList;
+		selectList.clear();
+		while (!selboxList.isEmpty() )
+			delete selboxList.takeFirst();
+
+	}	
 }
 
 bool Selection::isEmpty()
@@ -45,3 +135,66 @@
 {
 	return selectList.count();
 }
+
+Selection::Type Selection::type() // TODO no multiselections yet
+{
+	if (!selectList.isEmpty())
+	{
+		LinkableMapObj *sel=selectList.first();
+		if (typeid (*sel)==typeid (BranchObj)) return Branch;
+		if (typeid (*sel)==typeid (MapCenterObj)) return MapCenter;
+		if (typeid (*sel)==typeid (FloatImageObj)) return FloatImage;
+	}
+	return Undefined;
+}
+
+LinkableMapObj* Selection::first()
+{
+	if (!selectList.isEmpty())
+		return selectList.first();
+	else	
+		return NULL;
+}
+
+LinkableMapObj* Selection::single()
+{
+	if (selectList.count() == 1)
+		return selectList.first();
+	else	
+		return NULL;
+}
+
+BranchObj* Selection::getBranch()
+{
+	if (!selectList.isEmpty())
+	{
+		LinkableMapObj *sel=selectList.first();
+		if (typeid (*sel)==typeid (BranchObj) ||
+		    typeid (*sel)==typeid (MapCenterObj)) 
+			return (BranchObj*)sel;
+	}
+		return NULL;
+}
+
+FloatImageObj* Selection::getFloatImage()
+{
+	if (!selectList.isEmpty())
+	{
+		LinkableMapObj *sel=selectList.first();
+		if (typeid (*sel)==typeid (FloatImageObj)) 
+			return (FloatImageObj*)sel;
+	}
+		return NULL;
+}
+
+QString Selection::getSelectString()// TODO no multiselections yet
+{
+	if (selectList.count()==1)
+	{
+		return model->getSelectString (selectList.first() );
+	}
+	else
+		return"";
+}
+
+
diff -r 41937601b3b8 -r 98449ef9eccd tex/vym.changelog
--- a/tex/vym.changelog	Mon Jul 27 12:53:19 2009 +0000
+++ b/tex/vym.changelog	Thu Jul 30 07:40:05 2009 +0000
@@ -1,3 +1,9 @@
+-------------------------------------------------------------------
+Wed Jul 29 17:31:16 CEST 2009 - uwedr@suse.de
+
+- Version: 1.12.4
+- Bugfix: No undo for deleted mapCenters.
+
 -------------------------------------------------------------------
 Fri Jul 24 10:50:50 CEST 2009 - uwedr@suse.de
 
diff -r 41937601b3b8 -r 98449ef9eccd version.h
--- a/version.h	Mon Jul 27 12:53:19 2009 +0000
+++ b/version.h	Thu Jul 30 07:40:05 2009 +0000
@@ -7,7 +7,7 @@
 #define __VYM_VERSION "1.12.3"
 #define __VYM_CODENAME "Maintenance Update "
 //#define __VYM_CODENAME "Codename: development version"
-#define __VYM_BUILD_DATE "2009-07-24"
+#define __VYM_BUILD_DATE "2009-07-29"
 
 
 bool checkVersion(const QString &);
diff -r 41937601b3b8 -r 98449ef9eccd xml-vym.cpp
--- a/xml-vym.cpp	Mon Jul 27 12:53:19 2009 +0000
+++ b/xml-vym.cpp	Thu Jul 30 07:40:05 2009 +0000
@@ -60,7 +60,7 @@
 		<<">  state="<<state 
 		<<"  laststate="<<stateStack.last()
 		<<"   loadMode="<<loadMode
-		<<"       line="<<QXmlDefaultHandler::lineNumber()
+		//<<"       line="<<QXmlDefaultHandler::lineNumber()
 		<<endl;
 	*/	
 	stateStack.append (state);	
@@ -150,18 +150,23 @@
 			// Treat the found mapcenter as a branch 
 			// in an existing map
 			LinkableMapObj* lmo=model->getSelection();
-			if (lmo && ((typeid(*lmo) == typeid(BranchObj) ) 
-			        ||  typeid(*lmo) == typeid(MapCenterObj) ) )
+			if (lmo)
 			{
-				lastBranch=(BranchObj*)lmo;
-				if (loadMode==ImportAdd)
+				if ( (typeid(*lmo) == typeid(BranchObj) ) 
+						||  typeid(*lmo) == typeid(MapCenterObj) ) 
 				{
-					lastBranch->addBranch();
-					lastBranch=lastBranch->getLastBranch();
-				} else
-					lastBranch->clear();
+					lastBranch=(BranchObj*)lmo;
+					if (loadMode==ImportAdd)
+					{
+						lastBranch->addBranch();
+						lastBranch=lastBranch->getLastBranch();
+					} else
+						lastBranch->clear();
+				}	
 			} else
-				return false;
+				// Add mapCenter without parent
+				lastBranch=model->addMapCenter();
+			
 		}
 		readBranchAttr (atts);
 	} else if ( 
@@ -426,7 +431,7 @@
 					return false;   // Couldn't read relPos
 			}           
 		}           
-		if (!a.value( "absPosX").isEmpty() && loadMode==NewMap ) 
+		if (!a.value( "absPosX").isEmpty() ) 
 		{
 			if (!a.value( "absPosY").isEmpty() ) 
 			{