mapeditor.cpp
branchqt4-port
changeset 2 608f976aa7bb
parent 0 7a96bd401351
child 3 6a0342b3c519
     1.1 --- a/mapeditor.cpp	Sun Jan 30 12:58:47 2005 +0000
     1.2 +++ b/mapeditor.cpp	Tue Jun 06 14:58:11 2006 +0000
     1.3 @@ -4,61 +4,63 @@
     1.4  #include <qmessagebox.h>
     1.5  #include <qapplication.h>
     1.6  #include <qpainter.h>
     1.7 -#include <qpopupmenu.h>
     1.8 +#include <q3popupmenu.h>
     1.9  #include <qprinter.h>
    1.10 -#include <qpaintdevicemetrics.h>
    1.11 +#include <q3paintdevicemetrics.h>
    1.12  #include <qfile.h>
    1.13 -#include <qfiledialog.h>
    1.14 +#include <q3filedialog.h>
    1.15  #include <qdir.h>
    1.16  #include <qcolor.h>
    1.17  #include <qcolordialog.h>
    1.18  #include <qbitmap.h>
    1.19 -#include <qprocess.h>
    1.20 +#include <q3process.h>
    1.21  #include <qinputdialog.h>
    1.22 +#include <q3dragobject.h>
    1.23 +#include <q3urloperator.h>
    1.24 +#include <q3networkprotocol.h>
    1.25 +#include <qregexp.h>
    1.26 +//Added by qt3to4:
    1.27 +#include <QResizeEvent>
    1.28 +#include <QContextMenuEvent>
    1.29 +#include <Q3StrList>
    1.30 +#include <QPixmap>
    1.31 +#include <QMouseEvent>
    1.32 +#include <QDragEnterEvent>
    1.33 +#include <QTextStream>
    1.34 +#include <QDropEvent>
    1.35 +#include <Q3ActionGroup>
    1.36 +#include <Q3PtrList>
    1.37  
    1.38  #include <iostream>
    1.39 -#include <stdlib.h>
    1.40 +#include <cstdlib>
    1.41  #include <typeinfo>
    1.42  
    1.43  #include "version.h"
    1.44  
    1.45 +#include "api.h"
    1.46 +#include "editxlinkdialog.h"
    1.47 +#include "exports.h"
    1.48 +#include "extrainfodialog.h"
    1.49 +#include "file.h"
    1.50 +#include "linkablemapobj.h"
    1.51 +#include "mainwindow.h"
    1.52 +#include "misc.h"
    1.53 +#include "settings.h"
    1.54 +#include "texteditor.h"
    1.55 +#include "warningdialog.h"
    1.56  #include "xml.h"
    1.57 -#include "texteditor.h"
    1.58 -#include "linkablemapobj.h"
    1.59 -#include "exports.h"
    1.60 -#include "misc.h"
    1.61 -#include "mainwindow.h"
    1.62 -#include "extrainfodialog.h"
    1.63 -#include "settings.h"
    1.64 -
    1.65 -#include "icons/flag-note.xpm"
    1.66 -#include "icons/flag-url.xpm"
    1.67 -#include "icons/flag-vymlink.xpm"	
    1.68 -#include "icons/flag-scrolled-right.xpm"
    1.69 -#include "icons/flag-tmpUnscrolled-right.xpm"
    1.70 -#include "icons/flag-questionmark.xpm"
    1.71 -#include "icons/flag-exclamationmark.xpm"
    1.72 -#include "icons/flag-hook-green.xpm"
    1.73 -#include "icons/flag-cross-red.xpm"
    1.74 -#include "icons/flag-stopsign.xpm"
    1.75 -#include "icons/flag-smiley-good.xpm"
    1.76 -#include "icons/flag-smiley-sad.xpm"
    1.77 -#include "icons/flag-clock.xpm"
    1.78 -#include "icons/flag-lamp.xpm"
    1.79 -#include "icons/flag-arrow-up.xpm"
    1.80 -#include "icons/flag-arrow-down.xpm"
    1.81 -#include "icons/flag-thumb-up.xpm"
    1.82 -#include "icons/flag-thumb-down.xpm"
    1.83 -#include "icons/flag-heart.xpm"
    1.84 -#include "icons/flag-flash.xpm"
    1.85 -#include "icons/flag-lifebelt.xpm"
    1.86 +
    1.87  
    1.88  extern TextEditor *textEditor;
    1.89  extern int statusbarTime;
    1.90  extern Main *mainWindow;
    1.91 +extern QString tmpVymDir;
    1.92 +extern QString clipboardDir;
    1.93 +extern bool clipboardEmpty;
    1.94  extern FlagRowObj *systemFlagsDefault;
    1.95  extern FlagRowObj *standardFlagsDefault;
    1.96 -extern MapEditor *clipboardME;
    1.97 +
    1.98 +extern Q3PtrList <QAction> actionListBranches;
    1.99  
   1.100  extern QAction *actionFileSave;
   1.101  extern QAction *actionEditUndo;
   1.102 @@ -69,24 +71,28 @@
   1.103  extern QAction *actionEditMoveDown;
   1.104  extern QAction *actionEditToggleScroll;
   1.105  extern QAction *actionEditOpenURL;
   1.106 +extern QAction *actionEditOpenURLTab;
   1.107  extern QAction *actionEditURL;
   1.108  extern QAction *actionEditHeading2URL;
   1.109  extern QAction *actionEditBugzilla2URL;
   1.110 +extern QAction *actionEditFATE2URL;
   1.111  extern QAction *actionEditOpenVymLink;
   1.112  extern QAction *actionEditVymLink;
   1.113  extern QAction *actionEditDeleteVymLink;
   1.114 +extern QAction *actionEditToggleHideExport;
   1.115  extern QAction *actionEditHeading;
   1.116  extern QAction *actionEditDelete;
   1.117  extern QAction *actionEditAddBranch;
   1.118  extern QAction *actionEditAddBranchAbove;
   1.119  extern QAction *actionEditAddBranchBelow;
   1.120 +extern QAction *actionEditRemoveBranchHere;
   1.121 +extern QAction *actionEditRemoveChilds;
   1.122  extern QAction *actionEditImportAdd;
   1.123  extern QAction *actionEditImportReplace;
   1.124  extern QAction *actionEditSaveBranch;
   1.125  extern QAction *actionEditSelectFirst;
   1.126  extern QAction *actionEditSelectLast;
   1.127  extern QAction *actionEditLoadImage;
   1.128 -extern QAction *actionEditToggleFloatExport;
   1.129  
   1.130  extern QAction* actionFormatPickColor;
   1.131  extern QAction* actionFormatColorBranch;
   1.132 @@ -95,11 +101,19 @@
   1.133  extern QAction *actionFormatBackColor;
   1.134  extern QAction *actionFormatLinkColor;
   1.135  
   1.136 -extern QActionGroup *actionGroupFormatFrameTypes;
   1.137 +extern Q3ActionGroup* actionGroupModModes;
   1.138 +extern QAction* actionModModeColor;
   1.139 +extern QAction* actionModModeLink;
   1.140 +extern QAction* actionModModeCopy;
   1.141 +
   1.142 +extern Q3ActionGroup *actionGroupFormatFrameTypes;
   1.143  extern QAction *actionFormatFrameNone;
   1.144  extern QAction *actionFormatFrameRectangle;
   1.145  
   1.146 -extern QActionGroup *actionGroupFormatLinkStyles;
   1.147 +extern Q3ActionGroup *actionGroupFormatLinkStyles;
   1.148 +extern QAction *actionFormatIncludeImagesVer;
   1.149 +extern QAction *actionFormatIncludeImagesHor;
   1.150 +extern QAction *actionFormatHideLinkUnselected;
   1.151  extern QAction *actionFormatLinkStyleLine;
   1.152  extern QAction *actionFormatLinkStyleParabel;
   1.153  extern QAction *actionFormatLinkStylePolyLine;
   1.154 @@ -111,213 +125,98 @@
   1.155  extern QAction *actionSettingsAutoselectHeading;
   1.156  extern QAction *actionSettingsAutoselectText;
   1.157  extern QAction *actionSettingsPasteNewHeading;
   1.158 -
   1.159 -extern QPopupMenu *branchContextMenu;
   1.160 -extern QPopupMenu *floatimageContextMenu;
   1.161 -extern QPopupMenu *saveImageFormatMenu;
   1.162 -extern QPopupMenu *exportImageFormatMenu;
   1.163 -extern QPopupMenu *canvasContextMenu;
   1.164 +extern QAction *actionSettingsUseFlagGroups;
   1.165 +
   1.166 +extern Q3PopupMenu *branchContextMenu;
   1.167 +extern Q3PopupMenu *branchLinksContextMenu;
   1.168 +extern Q3PopupMenu *branchLinksContextMenuDup;
   1.169 +extern Q3PopupMenu *floatimageContextMenu;
   1.170 +extern Q3PopupMenu *saveImageFormatMenu;
   1.171 +extern Q3PopupMenu *exportImageFormatMenu;
   1.172 +extern Q3PopupMenu *canvasContextMenu;
   1.173  
   1.174  extern Settings settings;
   1.175  
   1.176 +extern QString iconPath;
   1.177 +extern QDir vymBaseDir;
   1.178 +
   1.179 +int MapEditor::mapNum=0;	// make instance
   1.180  
   1.181  ///////////////////////////////////////////////////////////////////////
   1.182  ///////////////////////////////////////////////////////////////////////
   1.183  MapEditor::MapEditor(
   1.184 -	QWidget* parent, bool interactive, const char* name, WFlags f) :
   1.185 -    QCanvasView(parent,name,f)
   1.186 +	QWidget* parent, bool interactive, const char* name, Qt::WFlags f) :
   1.187 +  Q3CanvasView(parent,name,f), urlOperator(0), imageBuffer(0)
   1.188  {
   1.189  	//cout << "Constructor ME "<<this<<endl;
   1.190 -
   1.191 -    mapCanvas = new QCanvas(1000,800);
   1.192 +	mapNum++;
   1.193 +
   1.194 +    viewport()->setAcceptDrops(true);
   1.195 +
   1.196 +    mapCanvas = new Q3Canvas(1000,800);
   1.197  	mapCanvas->setAdvancePeriod(30);
   1.198 +	mapCanvas->setBackgroundColor (Qt::white);
   1.199  
   1.200      setCanvas (mapCanvas);
   1.201  	
   1.202 -	setVScrollBarMode ( QScrollView::AlwaysOn );
   1.203 -	setHScrollBarMode ( QScrollView::AlwaysOn );
   1.204 -
   1.205 -	// Now create the _global_ system flags _once_:
   1.206 -	// (Later all OrnamentedObj copy from this 
   1.207 -	// and set their own canvas)
   1.208 -	if (!systemFlagsDefault)
   1.209 -	{
   1.210 -		systemFlagsDefault = new FlagRowObj (mapCanvas);
   1.211 -		systemFlagsDefault->setVisibility (false);
   1.212 -		systemFlagsDefault->setName ("systemFlagsDef");
   1.213 -
   1.214 -		FlagObj *fo = new FlagObj (mapCanvas);
   1.215 -		fo->load(QPixmap(flag_note_xpm));
   1.216 -		fo->setName("note");
   1.217 -		fo->setToolTip(tr("Note"));
   1.218 -		systemFlagsDefault->addFlag (fo);	// makes deep copy
   1.219 -
   1.220 -		fo->load(QPixmap(flag_url_xpm));
   1.221 -		fo->setName("url");
   1.222 -		fo->setToolTip(tr("WWW Document (external)"));
   1.223 -		systemFlagsDefault->addFlag (fo);
   1.224 -		
   1.225 -		fo->load(QPixmap(flag_vymlink_xpm));
   1.226 -		fo->setName("vymLink");
   1.227 -		fo->setToolTip(tr("Link to another vym map"));
   1.228 -		systemFlagsDefault->addFlag (fo);	
   1.229 -
   1.230 -		fo->load(QPixmap(flag_scrolled_right_xpm));
   1.231 -		fo->setName("scrolledright");
   1.232 -		fo->setToolTip(tr("subtree is scrolled"));
   1.233 -		systemFlagsDefault->addFlag (fo);
   1.234 -		
   1.235 -		fo->load(QPixmap(flag_tmpUnscrolled_right_xpm));
   1.236 -		fo->setName("tmpUnscrolledright");
   1.237 -		fo->setToolTip(tr("subtree is temporary scrolled"));
   1.238 -		systemFlagsDefault->addFlag (fo);
   1.239 -		delete (fo);
   1.240 -	}
   1.241 -	if (!standardFlagsDefault)
   1.242 -	{
   1.243 -		standardFlagsDefault = new FlagRowObj (mapCanvas);
   1.244 -		standardFlagsDefault->setVisibility (false);
   1.245 -		standardFlagsDefault->setName ("standardFlagsDef");
   1.246 -
   1.247 -		FlagObj *fo = new FlagObj (mapCanvas);
   1.248 -		fo->load(QPixmap(flag_exclamationmark_xpm));
   1.249 -		fo->setName("exclamationmark");
   1.250 -		fo->setToolTip(tr("Take care!"));
   1.251 -		standardFlagsDefault->addFlag (fo);	// makes deep copy
   1.252 -		
   1.253 -		fo->load(QPixmap(flag_questionmark_xpm));
   1.254 -		fo->setName("questionmark");
   1.255 -		fo->setToolTip(tr("Really?"));
   1.256 -		standardFlagsDefault->addFlag (fo);	
   1.257 -
   1.258 -		fo->load(QPixmap(flag_hook_green_xpm));
   1.259 -		fo->setName("hook-green");
   1.260 -		fo->setToolTip(tr("ok!"));
   1.261 -		standardFlagsDefault->addFlag (fo);	
   1.262 -
   1.263 -		fo->load(QPixmap(flag_cross_red_xpm));
   1.264 -		fo->setName("cross-red");
   1.265 -		fo->setToolTip(tr("Not ok!"));
   1.266 -		standardFlagsDefault->addFlag (fo);	
   1.267 -
   1.268 -		fo->load(QPixmap(flag_stopsign_xpm));
   1.269 -		fo->setName("stopsign");
   1.270 -		fo->setToolTip(tr("This won't work!"));
   1.271 -		standardFlagsDefault->addFlag (fo);	
   1.272 -
   1.273 -		fo->load(QPixmap(flag_smiley_good_xpm));
   1.274 -		fo->setName("smiley-good");
   1.275 -		fo->setToolTip(tr("Good"));
   1.276 -		standardFlagsDefault->addFlag (fo);	
   1.277 -
   1.278 -		fo->load(QPixmap(flag_smiley_sad_xpm));
   1.279 -		fo->setName("smiley-sad");
   1.280 -		fo->setToolTip(tr("Bad"));
   1.281 -		standardFlagsDefault->addFlag (fo);	
   1.282 -
   1.283 -		fo->load(QPixmap(flag_clock_xpm));
   1.284 -		fo->setName("clock");
   1.285 -		fo->setToolTip(tr("Time critical"));
   1.286 -		standardFlagsDefault->addFlag (fo);	
   1.287 -
   1.288 -		fo->load(QPixmap(flag_lamp_xpm));
   1.289 -		fo->setName("lamp");
   1.290 -		fo->setToolTip(tr("Idea!"));
   1.291 -		standardFlagsDefault->addFlag (fo);	
   1.292 -
   1.293 -		fo->load(QPixmap(flag_arrow_up_xpm));
   1.294 -		fo->setName("arrow-up");
   1.295 -		fo->setToolTip(tr("Important"));
   1.296 -		standardFlagsDefault->addFlag (fo);	
   1.297 -
   1.298 -		fo->load(QPixmap(flag_arrow_down_xpm));
   1.299 -		fo->setName("arrow-down");
   1.300 -		fo->setToolTip(tr("Unimportant"));
   1.301 -		standardFlagsDefault->addFlag (fo);	
   1.302 -
   1.303 -		fo->load(QPixmap(flag_thumb_up_xpm));
   1.304 -		fo->setName("thumb-up");
   1.305 -		fo->setToolTip(tr("I like this"));
   1.306 -		standardFlagsDefault->addFlag (fo);	
   1.307 -
   1.308 -		fo->load(QPixmap(flag_thumb_down_xpm));
   1.309 -		fo->setName("thumb-down");
   1.310 -		fo->setToolTip(tr("I do not like this"));
   1.311 -		standardFlagsDefault->addFlag (fo);	
   1.312 -		
   1.313 -		fo->load(QPixmap(flag_heart_xpm));
   1.314 -		fo->setName("heart");
   1.315 -		fo->setToolTip(tr("I just love... "));
   1.316 -		standardFlagsDefault->addFlag (fo);	
   1.317 -
   1.318 -		fo->load(QPixmap(flag_flash_xpm));
   1.319 -		fo->setName("flash");
   1.320 -		fo->setToolTip(tr("Dangerous"));
   1.321 -		standardFlagsDefault->addFlag (fo);	
   1.322 -		
   1.323 -		fo->load(QPixmap(flag_lifebelt_xpm));
   1.324 -		fo->setName("lifebelt");
   1.325 -		fo->setToolTip(tr("This will help"));
   1.326 -		standardFlagsDefault->addFlag (fo);	
   1.327 -		delete (fo);
   1.328 -
   1.329 -	}
   1.330 -	
   1.331 +	// Always show scroll bars (automatic would flicker sometimes)
   1.332 +	setVScrollBarMode ( Q3ScrollView::AlwaysOn );
   1.333 +	setHScrollBarMode ( Q3ScrollView::AlwaysOn );
   1.334 +
   1.335      mapCenter = new MapCenterObj(mapCanvas);
   1.336      mapCenter->setVisibility (true);
   1.337  	mapCenter->setMapEditor (this);
   1.338 -	mapCenter->setHeading (tr("New Map"));
   1.339 +	mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
   1.340 +	mapCenter->move(mapCanvas->width()/2-mapCenter->width()/2,mapCanvas->height()/2-mapCenter->height()/2);
   1.341  
   1.342      printer=NULL;
   1.343  
   1.344      lineedit = new QLineEdit(this, "lineedit"  );
   1.345 -    connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEditNoSave() ) );
   1.346 +    connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEdit() ) );
   1.347      lineedit->hide();
   1.348  
   1.349 -    actColor=black; setColor (actColor);
   1.350 -	deflinkcolor=QColor (0,0,255);
   1.351 +    actColor=Qt::black; setColor (actColor);
   1.352 +	defLinkColor=QColor (0,0,255);
   1.353 +	defXLinkColor=QColor (180,180,180);
   1.354  	linkcolorhint=DefaultColor;
   1.355  	linkstyle=StylePolyParabel;
   1.356 -	mapCanvas->setBackgroundColor (white);
   1.357  
   1.358  	// Create bitmap cursors, patform dependant
   1.359  	#if defined(Q_OS_MACX)
   1.360 -		#include "icons/cursorhandopen16.xpm"
   1.361 -		#include "icons/cursorcolorpicker16.xpm"
   1.362 -		QBitmap cb( 16, 16, chandopen, TRUE );
   1.363 -		QBitmap cm( 16, 16, chandopenmask, TRUE );
   1.364 -		handOpenCursor=QCursor ( cb, cm );		
   1.365 +		handOpenCursor=QCursor ( QPixmap(iconPath+"cursorhandopen16.png") );		
   1.366  		// set hot spot to tip of picker			
   1.367 -		pickColorCursor=QCursor ( cursorcolorpicker_xpm, 1,15 ); 
   1.368 +		pickColorCursor=QCursor ( QPixmap (iconPath+"cursorcolorpicker16.png"), 1,15 ); 
   1.369  	#else
   1.370 -		#include "icons/cursorhandopen.xpm"
   1.371 -		#include "icons/cursorcolorpicker.xpm"
   1.372 -
   1.373 -		QBitmap cb( 32, 32, chandopen, TRUE );
   1.374 -		QBitmap cm( 32, 32, chandopenmask, TRUE );
   1.375 -		handOpenCursor=QCursor ( cb, cm );		
   1.376 +		handOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen16.png"));		
   1.377  		// set hot spot to tip of picker			
   1.378 -		pickColorCursor=QCursor ( cursorcolorpicker_xpm, 5,27 ); 
   1.379 +		pickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 ); 
   1.380  	#endif
   1.381  
   1.382 -
   1.383  	pickingColor=false;
   1.384 +	drawingLink=false;
   1.385 +	copyingObj=false;
   1.386  
   1.387      editingBO=NULL;
   1.388      selection=NULL;
   1.389      selectionLast=NULL;
   1.390      movingObj=NULL;
   1.391  
   1.392 +	defXLinkWidth=1;
   1.393 +	defXLinkColor=QColor (230,230,230);
   1.394 +
   1.395      mapChanged=false;
   1.396  	mapDefault=true;
   1.397  	mapUnsaved=false;
   1.398 -	undoSelection=NULL;
   1.399  	
   1.400  	zipped=true;
   1.401  	filePath="";
   1.402 -	fileName="unnamed";
   1.403 +	fileName=tr("unnamed");
   1.404  	mapName="";
   1.405  
   1.406 +	undosTotal=settings.readNumEntry("/vym/mapeditor/undoLevels",50);
   1.407 +	undosAvail=0;	
   1.408 +	undoNum=0;
   1.409 +	
   1.410  	// Initialize find routine
   1.411  	itFind=NULL;				
   1.412  	EOFind=false;
   1.413 @@ -325,7 +224,11 @@
   1.414  	printFrame=true;
   1.415  	printFooter=true;
   1.416  
   1.417 -	blockreposition=false;
   1.418 +	blockReposition=false;
   1.419 +	blockSaveState=false;
   1.420 +
   1.421 +	hidemode=HideNone;
   1.422 +
   1.423  	isInteractive=interactive;
   1.424  	if (isInteractive)
   1.425  		// Create temporary files
   1.426 @@ -334,13 +237,22 @@
   1.427  	// Initially set movingCentre
   1.428  	updateViewCenter();
   1.429  
   1.430 +	// For testing purposes create history window
   1.431 +	historyWindow = new ShowTextDialog (this);
   1.432 +	historyWindow->setCaption (fileName);
   1.433 +
   1.434  	mapCenter->reposition();	//	for positioning heading
   1.435  }
   1.436  
   1.437  MapEditor::~MapEditor()
   1.438  {
   1.439 +  if (imageBuffer) delete imageBuffer;
   1.440 +  if (urlOperator) {
   1.441 +    urlOperator->stop();
   1.442 +    delete urlOperator;
   1.443 +  }
   1.444 +
   1.445  	//cout <<"Destructor MapEditor\n";
   1.446 -	if (isInteractive) delTmpDirs();
   1.447  
   1.448  	// Save Settings
   1.449  	//settings.writeEntry( "/vym/mapeditor/editmode/autoselect",  );
   1.450 @@ -362,7 +274,7 @@
   1.451      return mapCenter;
   1.452  }
   1.453  
   1.454 -QCanvas* MapEditor::getCanvas()
   1.455 +Q3Canvas* MapEditor::getCanvas()
   1.456  {
   1.457      return mapCanvas;
   1.458  }
   1.459 @@ -420,6 +332,7 @@
   1.460  		{
   1.461  			mapCenter->moveAllBy(dx,dy);
   1.462  			mapCenter->reposition();
   1.463 +//			mapCenter->positionBBox();	// To move float
   1.464  
   1.465  			// scroll the view (in order to not move map on screen)
   1.466  			scrollBy (dx,dy);
   1.467 @@ -427,45 +340,44 @@
   1.468  	}
   1.469  }
   1.470  
   1.471 -bool MapEditor::blockReposition()
   1.472 +bool MapEditor::isRepositionBlocked()
   1.473  {
   1.474 -	return blockreposition;
   1.475 +	return blockReposition;
   1.476 +}
   1.477 +
   1.478 +QString MapEditor::getName (LinkableMapObj *lmo)
   1.479 +{
   1.480 +	QString s;
   1.481 +	if (!lmo) return QString("Error: NULL has no name!");
   1.482 +
   1.483 +	if ((typeid(*lmo) == typeid(BranchObj) ||
   1.484 +				      typeid(*lmo) == typeid(MapCenterObj))) 
   1.485 +	{
   1.486 +		
   1.487 +		s=(((BranchObj*)lmo)->getHeading());
   1.488 +		if (s=="") s="unnamed";
   1.489 +		return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
   1.490 +	}	
   1.491 +	if ((typeid(*lmo) == typeid(FloatImageObj) ))
   1.492 +		return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
   1.493 +	return QString("Unknown type has no name!");
   1.494  }
   1.495  
   1.496  void MapEditor::makeTmpDirs()
   1.497  {
   1.498  	// Create unique temporary directories
   1.499 -	char tmpdir[]="/tmp/vym-XXXXXX";	
   1.500 -	bakMapDir=mkdtemp(tmpdir);
   1.501 -	makeSubDirs(bakMapDir);
   1.502 -	// FIXME set permissions
   1.503 -	// and maybe use QT method for portability
   1.504 +	tmpMapDir=tmpVymDir+QString("/mapeditor-%1").arg(mapNum);
   1.505 +	QDir d;
   1.506 +	d.mkdir (tmpMapDir,true);
   1.507  }
   1.508  
   1.509 -void MapEditor::delTmpDirs()
   1.510 +QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, LinkableMapObj *saveSelection)
   1.511  {
   1.512 -	//FIXME delete tmp directory, better use QT methods here:
   1.513 -	system ( "rm -rf "+ bakMapDir );
   1.514 -}
   1.515 -
   1.516 -
   1.517 -void MapEditor::makeSubDirs(const QString &s)
   1.518 -{
   1.519 -	QDir d(s);
   1.520 -	d.mkdir ("images");	
   1.521 -	d.mkdir ("flags");	
   1.522 -}
   1.523 -
   1.524 -
   1.525 -QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, SaveMode savemode)
   1.526 -{
   1.527 -	// tmpdir		temporary directory to which data will be writte
   1.528 +	// tmpdir		temporary directory to which data will be written
   1.529  	// prefix		mapname, which will be appended to images etc.
   1.530  	// writeflags	Only write flags for "real" save of map, not undo
   1.531  	// offset		offset of bbox of whole map in canvas. 
   1.532  	//				Needed for XML export
   1.533 -	// completeMap	if false, only vympart will be written, without
   1.534 -	//				mapcenter
   1.535  	
   1.536  	// Save Header
   1.537  	QString ls;
   1.538 @@ -490,14 +402,16 @@
   1.539  	if (linkcolorhint==HeadingColor) 
   1.540  		colhint=attribut("linkColorHint","HeadingColor");
   1.541  
   1.542 -	QString mapAttr=attribut("version",__VYM_VERSION__);
   1.543 -	if (savemode==CompleteMap)
   1.544 +	QString mapAttr=attribut("version",__VYM_VERSION);
   1.545 +	if (!saveSelection)
   1.546  		mapAttr+= attribut("author",mapCenter->getAuthor()) +
   1.547  				  attribut("comment",mapCenter->getComment()) +
   1.548  			      attribut("date",mapCenter->getDate()) +
   1.549  		          attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
   1.550  		          attribut("linkStyle", ls ) +
   1.551 -		          attribut("linkColor", deflinkcolor.name() ) +
   1.552 +		          attribut("linkColor", defLinkColor.name() ) +
   1.553 +		          attribut("defXLinkColor", defXLinkColor.name() ) +
   1.554 +		          attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
   1.555  		          colhint; 
   1.556  	s+=beginElement("vymmap",mapAttr);
   1.557  	incIndent();
   1.558 @@ -505,21 +419,29 @@
   1.559  	// Find the used flags while traversing the tree
   1.560  	standardFlagsDefault->resetUsedCounter();
   1.561  	
   1.562 +	// Reset the counters before saving
   1.563 +	FloatImageObj (mapCanvas).resetSaveCounter();
   1.564 +
   1.565  	// Build xml recursivly
   1.566 -	if (savemode==CompleteMap)
   1.567 +	if (!saveSelection)
   1.568  		s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
   1.569  	else
   1.570  	{
   1.571 -		if ( undoSelection &&
   1.572 -			typeid(*undoSelection) == typeid(BranchObj) )
   1.573 -			s+=((BranchObj*)(undoSelection))->saveToDir(tmpdir,prefix,offset);
   1.574 +		if ( typeid(*saveSelection) == typeid(BranchObj) )
   1.575 +			s+=((BranchObj*)(saveSelection))->saveToDir(tmpdir,prefix,offset);
   1.576 +		else if ( typeid(*saveSelection) == typeid(FloatImageObj) )
   1.577 +			s+=((FloatImageObj*)(saveSelection))->saveToDir(tmpdir,prefix,offset);
   1.578 +			
   1.579 +		else if (selection && typeid(*selection)==typeid(BranchObj))
   1.580 +				// This is used if selected branch is saved from mainwindow
   1.581 +				s+=((BranchObj*)selection)->saveToDir(tmpdir,prefix,offset);
   1.582  	}
   1.583  
   1.584  	// Save local settings
   1.585  	s+=settings.getXMLData (destPath);
   1.586  
   1.587  	// Save selection
   1.588 -	if (selection) 
   1.589 +	if (selection && !saveSelection ) 
   1.590  		s+=valueElement("select",selection->getSelectString());
   1.591  
   1.592  	decIndent();
   1.593 @@ -527,37 +449,240 @@
   1.594  
   1.595  	if (writeflags)
   1.596  		standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
   1.597 -	
   1.598  	return s;
   1.599  }
   1.600  
   1.601 -void MapEditor::saveState()
   1.602 +void MapEditor::saveState(const QString &comment)
   1.603  {
   1.604 -	saveState (CompleteMap,NULL);
   1.605 +	// Save complete map
   1.606 +	saveState (CompleteMap,"",NULL,"",NULL, comment);
   1.607  }
   1.608  
   1.609 -void MapEditor::saveState(const SaveMode &mode, LinkableMapObj *part)
   1.610 +void MapEditor::saveState(LinkableMapObj *undoSel, const QString &comment)
   1.611  {
   1.612 -	// all binary data is saved in bakMapDir (created in Constructor)
   1.613 -	// the xml data itself is kept in memory in backupXML
   1.614 -	// 
   1.615 -	// For faster write/read of data, a part of the map can be
   1.616 -	// written. Then the undoSelection will mark, which part of the
   1.617 -	// map should be replaced if an undo is wanted later.
   1.618 -
   1.619 -	if (mode==PartOfMap && part && (typeid(*part) == typeid (BranchObj) ) ) 
   1.620 +	// save the given part of the map 
   1.621 +	saveState (PartOfMap,"",undoSel,"",NULL, comment);
   1.622 +}
   1.623 +
   1.624 +void MapEditor::saveState(const QString &uc, const QString &rc, const QString &comment)
   1.625 +{
   1.626 +	// selection does not change during action,
   1.627 +	// so just save commands for undo and redo
   1.628 +	LinkableMapObj *unsel;
   1.629 +	if (selection)
   1.630 +		unsel=selection;
   1.631 +	else
   1.632 +		unsel=NULL;
   1.633 +	saveState (UndoCommand,uc,unsel,rc,unsel, comment);
   1.634 +}
   1.635 +
   1.636 +void MapEditor::saveState(const QString & uncom, LinkableMapObj *unsel, const QString &comment) 
   1.637 +{
   1.638 +	saveState (UndoCommand,uncom,unsel,"FIXME-redoCom",NULL, comment);
   1.639 +}
   1.640 +
   1.641 +void MapEditor::saveState(const SaveMode &savemode, const QString &undoCom, LinkableMapObj *undoSel, const QString &redoCom, LinkableMapObj *redoSel, const QString &comment)
   1.642 +{
   1.643 +	// Main saveState
   1.644 +
   1.645 +	if (blockSaveState) return;
   1.646 +
   1.647 +	/* TODO remove after testing
   1.648 +	cout << "ME::saveState()  begin\n"<<endl;
   1.649 +	cout << "    undosTotal="<<undosTotal<<endl;
   1.650 +	cout << "    undosAvail="<<undosAvail<<endl;
   1.651 +	cout << "       undoNum="<<undoNum<<endl;
   1.652 +	cout << "    ---------------------------"<<endl;
   1.653 +	*/
   1.654 +
   1.655 +	historyWindow->append (comment);
   1.656 +	
   1.657 +	setChanged();
   1.658 +
   1.659 +	// Find out current undo directory
   1.660 +	if (undosAvail<undosTotal) undosAvail++;
   1.661 +	undoNum++;
   1.662 +	if (undoNum>undosTotal) undoNum=1;
   1.663 +	
   1.664 +	QString backupXML;
   1.665 +	QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(undoNum));
   1.666 +	QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
   1.667 +
   1.668 +	// Create bakMapDir if not available
   1.669 +	QDir d(bakMapDir);
   1.670 +	if (!d.exists()) 
   1.671 +		makeSubDirs (bakMapDir);
   1.672 +
   1.673 +	// Save current selection 
   1.674 +	QString redoSelection="";
   1.675 +	if (redoSel)
   1.676 +		redoSelection=redoSel->getSelectString();
   1.677 +
   1.678 +	// Save the object, which should be undone
   1.679 +	QString undoSelection="";
   1.680 +	if (undoSel)
   1.681 +		undoSelection=undoSel->getSelectString();
   1.682 +		
   1.683 +	// Save depending on how much needs to be saved	
   1.684 +	QString undoCommand="";
   1.685 +	if (savemode==UndoCommand)
   1.686  	{
   1.687 -		// Writing a vympart only is useful for BranchObj
   1.688 -		undoSelection=part;
   1.689 -		backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),PartOfMap);
   1.690 -	} else	
   1.691 +		undoCommand=undoCom;
   1.692 +		backupXML="";
   1.693 +	}	
   1.694 +	else if (savemode==PartOfMap && undoSel)
   1.695  	{
   1.696 -		undoSelection=NULL;
   1.697 -		backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),CompleteMap);
   1.698 +		undoCommand="undoPart (\""+ undoSelection+"\",\""+bakMapPath+"\")";
   1.699 +		backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),undoSel);
   1.700 +	} else
   1.701 +	{
   1.702 +		undoCommand="undoMap (\""+bakMapPath+"\")";
   1.703 +		backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),NULL);
   1.704 +		undoSelection="";
   1.705 +	}
   1.706 +	if (!backupXML.isEmpty())
   1.707 +		// Write XML Data to disk
   1.708 +		saveStringToDisk (QString(bakMapPath),backupXML);
   1.709 +
   1.710 +	SimpleSettings set;
   1.711 +	set.setEntry (QString("undoCommand"),undoCommand);
   1.712 +	set.setEntry (QString("undoSelection"),undoSelection);
   1.713 +	set.setEntry (QString("redoCommand"),redoCom);
   1.714 +	set.setEntry (QString("redoSelection"),redoSelection);
   1.715 +	set.setEntry (QString("comment"),comment);
   1.716 +	set.writeSettings(QString(bakMapDir+"/commands"));
   1.717 +
   1.718 +	/* TODO remove after testing
   1.719 +	cout << "          into="<< bakMapDir<<endl;
   1.720 +	cout << "    undosAvail="<<undosAvail<<endl;
   1.721 +	cout << "       undoNum="<<undoNum<<endl;
   1.722 +	cout << "    ---------------------------"<<endl;
   1.723 +	cout << "    comment="<<comment<<endl;
   1.724 +	cout << "    ---------------------------"<<endl;
   1.725 +	cout << "    undoCom="<<undoCommand<<endl;
   1.726 +	cout << "    undoSel="<<undoSelection<<endl;
   1.727 +	cout << "    ---------------------------"<<endl;
   1.728 +	cout << "    redoCom="<<redoCom<<endl;
   1.729 +	cout << "    redoSel="<<redoSelection<<endl;
   1.730 +	cout << "    ---------------------------"<<endl<<endl;
   1.731 +	*/
   1.732 +}
   1.733 +
   1.734 +void MapEditor::parseAtom(const QString &atom)
   1.735 +{
   1.736 +	API api;
   1.737 +	QString s,t;
   1.738 +	int x,y;
   1.739 +	bool ok;
   1.740 +
   1.741 +	// Split string s into command and parameters
   1.742 +	api.parseCommand (atom);
   1.743 +	QString com=api.command();
   1.744 +	
   1.745 +	// External commands
   1.746 +	if (com=="moveBranchUp")
   1.747 +		moveBranchUp();
   1.748 +	else if (com=="moveBranchDown")
   1.749 +		moveBranchDown();
   1.750 +	else if (com=="move")
   1.751 +	{
   1.752 +		if (api.checkParamCount(2) && selection )
   1.753 +		{	
   1.754 +			x=api.parInt (ok,0);
   1.755 +			if (ok)
   1.756 +			{
   1.757 +				y=api.parInt (ok,1);
   1.758 +				if (ok) move (x,y);
   1.759 +			}
   1.760 +		}	
   1.761 +	}
   1.762 +	else if (com=="linkBranchToPos")
   1.763 +	{
   1.764 +		if (selection && typeid(*selection) == typeid(BranchObj) ) 
   1.765 +		{
   1.766 +			if (api.checkParamCount(4))
   1.767 +			{
   1.768 +				s=api.parString(ok,0);
   1.769 +				LinkableMapObj *dst=mapCenter->findObjBySelect (s);
   1.770 +				if (dst)
   1.771 +				{	
   1.772 +					if (typeid(*dst) == typeid(BranchObj) ) 
   1.773 +					{
   1.774 +						// Get number in parent
   1.775 +						x=api.parInt (ok,1);
   1.776 +						if (ok)
   1.777 +							((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),x);
   1.778 +					} else if (typeid(*dst) == typeid(MapCenterObj) ) 
   1.779 +					{
   1.780 +						((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),-1);
   1.781 +						// Get coordinates of mainbranch
   1.782 +						x=api.parInt (ok,2);
   1.783 +						if (ok)
   1.784 +						{
   1.785 +							y=api.parInt (ok,3);
   1.786 +							if (ok) ((BranchObj*)selection)->move (x,y);
   1.787 +						}
   1.788 +					}	
   1.789 +				}	
   1.790 +			}
   1.791 +		}
   1.792 +	} else if (com=="setHeading")
   1.793 +	{
   1.794 +		if (api.checkParamCount(1))
   1.795 +		{
   1.796 +			s=api.parString (ok,0);
   1.797 +			if (ok) setHeading (s);
   1.798 +		}	
   1.799 +	} else if (com=="setURL")
   1.800 +	{
   1.801 +		if (api.checkParamCount(1))
   1.802 +		{
   1.803 +			s=api.parString (ok,0);
   1.804 +			if (ok) setURL(s);
   1.805 +		}	
   1.806 +	} else if (com=="setVymLink")
   1.807 +	{
   1.808 +		if (api.checkParamCount(1))
   1.809 +		{
   1.810 +			s=api.parString (ok,0);
   1.811 +			if (ok) setVymLink(s);
   1.812 +		}	
   1.813 +	}
   1.814 +	// Internal commands, used for undo etc.	
   1.815 +	else if (com==QString("undoMap"))
   1.816 +	{
   1.817 +		if (api.checkParamCount(1))
   1.818 +			undoXML("",api.parString (ok,0));
   1.819 +	} else if (com==QString("undoPart"))
   1.820 +	{
   1.821 +		if (api.checkParamCount(2))
   1.822 +		{
   1.823 +			s=api.parString (ok,0);
   1.824 +			t=api.parString (ok,1);
   1.825 +			undoXML(s,t);	
   1.826 +		}
   1.827 +	} else if (com=="select")
   1.828 +		if (api.checkParamCount(1))
   1.829 +		{
   1.830 +			s=api.parString(ok,0);
   1.831 +			if (ok) select (s);
   1.832 +		}	
   1.833 +	else
   1.834 +	{
   1.835 +		api.setError ("Unknown command in: "+atom);
   1.836 +		cout << "ME::parse   api should have error now...\n";
   1.837 +	}
   1.838 +
   1.839 +	// Any errors?
   1.840 +	if (api.error())
   1.841 +	{
   1.842 +		qWarning("MapEditor::parseAtom: Error!");
   1.843 +		qWarning(api.errorDesc());
   1.844  	}	
   1.845  }
   1.846  
   1.847 -void MapEditor::finishedLineEditNoSave()
   1.848 +
   1.849 +void MapEditor::finishedLineEdit()
   1.850  {
   1.851  	// This is called by finishedLineEdit or any MapEditor method,
   1.852  	// which wants to assure, that lineedits finish, before e.g. a branch is 
   1.853 @@ -569,6 +694,7 @@
   1.854  
   1.855      if (editingBO!=NULL) 
   1.856  	{
   1.857 +		saveState("setHeading (\""+editingBO->getHeading()+"\")",editingBO, QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(lineedit->text()) );
   1.858  		editingBO->setHeading(lineedit->text() );
   1.859  		editingBO=NULL;
   1.860  		lineedit->releaseKeyboard();
   1.861 @@ -580,6 +706,14 @@
   1.862      }		
   1.863  }
   1.864  
   1.865 +void MapEditor::toggleHistoryWindow()
   1.866 +{
   1.867 +	if (historyWindow->isVisible())
   1.868 +		historyWindow->hide();
   1.869 +	else	
   1.870 +		historyWindow->show();
   1.871 +}
   1.872 +
   1.873  
   1.874  bool MapEditor::isDefault()
   1.875  {
   1.876 @@ -609,7 +743,7 @@
   1.877  void MapEditor::closeMap()
   1.878  {
   1.879  	// Finish open lineEdits
   1.880 -	if (lineedit) finishedLineEditNoSave();
   1.881 +	if (lineedit) finishedLineEdit();
   1.882  
   1.883  	// Unselect before disabling the toolbar actions
   1.884  	if (selection) selection->unselect();
   1.885 @@ -627,20 +761,31 @@
   1.886  
   1.887  void MapEditor::setFilePath(QString fname, QString destname)
   1.888  {
   1.889 -	filePath=fname;
   1.890 -	fileName=fname;
   1.891 -	destPath=destname;
   1.892 -
   1.893 -	// If fname is not an absolute path, complete it
   1.894 -	filePath=QDir(fname).absPath();
   1.895 -	fileDir=filePath.left (1+filePath.findRev ("/"));
   1.896 -
   1.897 -	// Set short name, too. Search from behind:
   1.898 -	int i=fileName.findRev("/");
   1.899 -	if (i>=0) fileName=fileName.remove (0,i+1);
   1.900 -
   1.901 -	// Forget the .vym (or .xml) for name of map
   1.902 -	mapName=fileName.left(fileName.findRev(".",-1,true) );
   1.903 +	if (fname.isEmpty() || fname=="")
   1.904 +	{
   1.905 +		filePath="";
   1.906 +		fileName="";
   1.907 +		destPath="";
   1.908 +	} else
   1.909 +	{
   1.910 +		filePath=fname;		// becomes absolute path
   1.911 +		fileName=fname;		// gets stripped of path
   1.912 +		destPath=destname;	// needed for vymlinks
   1.913 +
   1.914 +		// If fname is not an absolute path, complete it
   1.915 +		filePath=QDir(fname).absPath();
   1.916 +		fileDir=filePath.left (1+filePath.findRev ("/"));
   1.917 +
   1.918 +		// Set short name, too. Search from behind:
   1.919 +		int i=fileName.findRev("/");
   1.920 +		if (i>=0) fileName=fileName.remove (0,i+1);
   1.921 +
   1.922 +		// Forget the .vym (or .xml) for name of map
   1.923 +		mapName=fileName.left(fileName.findRev(".",-1,true) );
   1.924 +
   1.925 +		// Adjust history window
   1.926 +		historyWindow->setCaption (fileName);
   1.927 +	}
   1.928  }
   1.929  
   1.930  QString MapEditor::getFilePath()
   1.931 @@ -663,12 +808,12 @@
   1.932  	return destPath;
   1.933  }
   1.934  
   1.935 -int MapEditor::load (QString &fname, const LoadMode &lmode)
   1.936 +ErrorCode MapEditor::load (QString fname, LoadMode lmode)
   1.937  {
   1.938  	// Finish open lineEdits
   1.939 -	if (lineedit) finishedLineEditNoSave();
   1.940 -
   1.941 -	int returnCode=0;
   1.942 +	if (lineedit) finishedLineEdit();
   1.943 +
   1.944 +	ErrorCode err=success;
   1.945  
   1.946  	if (lmode==NewMap)
   1.947  	{
   1.948 @@ -679,8 +824,7 @@
   1.949  		// (map state is set later at end of load...)
   1.950  	} else
   1.951  	{
   1.952 -		setChanged();
   1.953 -		saveState(PartOfMap,selection);
   1.954 +		saveState(selection,"Load map");
   1.955  	}	
   1.956  	
   1.957      
   1.958 @@ -693,19 +837,22 @@
   1.959  	{
   1.960  		QMessageBox::critical( 0, tr( "Critical Parse Error" ),
   1.961  				   tr("Couldn't open map " +fname)+".");
   1.962 -		returnCode=1;	
   1.963 +		err=aborted;	
   1.964  	} else
   1.965  	{
   1.966 -		blockreposition=true;
   1.967 +		blockReposition=true;
   1.968  		QXmlInputSource source( file);
   1.969  		QXmlSimpleReader reader;
   1.970  		reader.setContentHandler( &handler );
   1.971  		reader.setErrorHandler( &handler );
   1.972  		handler.setMapEditor( this );
   1.973  		handler.setTmpDir (filePath.left(filePath.findRev("/",-1)));	// needed to load files with rel. path
   1.974 +		handler.setInputFile (file.name());
   1.975  		handler.setLoadMode (lmode);
   1.976 +		blockSaveState=true;
   1.977  		bool ok = reader.parse( source );
   1.978 -		blockreposition=false;
   1.979 +		blockReposition=false;
   1.980 +		blockSaveState=false;
   1.981  		file.close();
   1.982  		if ( ok ) 
   1.983  		{
   1.984 @@ -727,16 +874,19 @@
   1.985  		}	
   1.986  	}	
   1.987  	updateActions();
   1.988 -	return returnCode;
   1.989 +	return err;
   1.990  }
   1.991  
   1.992  int MapEditor::save (const SaveMode &savemode)
   1.993  {
   1.994  	// Finish open lineEdits
   1.995 -	if (lineedit) finishedLineEditNoSave();
   1.996 +	if (lineedit) finishedLineEdit();
   1.997  
   1.998  	int returnCode=0;
   1.999  
  1.1000 +	// The SaveMode UndoCommand is not supported here
  1.1001 +	if (savemode==UndoCommand) return 1;
  1.1002 +
  1.1003  	// Create mapName and fileDir
  1.1004  	makeSubDirs (fileDir);
  1.1005  	QString fname;
  1.1006 @@ -748,32 +898,14 @@
  1.1007  		fname=fileName;
  1.1008  
  1.1009  
  1.1010 -	// Check if fname is writeable
  1.1011 -	QFile file( fileDir+fname);
  1.1012 -	if (!file.open( IO_WriteOnly ) ) 
  1.1013 -	{
  1.1014 -		QMessageBox::critical( 0, tr( "Critical Save Error" ),
  1.1015 -					   tr("Couldn't write to ") +fileDir+fname);
  1.1016 +	QString saveFile;
  1.1017 +	if (savemode==CompleteMap || selection==NULL)
  1.1018 +		saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),NULL);
  1.1019 +	else	
  1.1020 +		saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),selection);
  1.1021 +
  1.1022 +	if (!saveStringToDisk(fileDir+fname,saveFile))
  1.1023  		return 1;
  1.1024 -	}	
  1.1025 -	file.close();
  1.1026 -
  1.1027 -	QString saveFile;
  1.1028 -	saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),savemode);
  1.1029 -
  1.1030 -	file.setName ( fileDir  + fname);
  1.1031 -	if ( !file.open( IO_WriteOnly ) )
  1.1032 -	{
  1.1033 -		// This should neverever happen
  1.1034 -		QMessageBox::critical(0, tr("Critcal save error"),"MapEditor::save() Couldn't open "+file.name());
  1.1035 -		return 1;
  1.1036 -	}	
  1.1037 -
  1.1038 -	// Write it finally, and write in UTF8, no matter what 
  1.1039 -	QTextStream ts( &file );
  1.1040 -	ts.setEncoding (QTextStream::UnicodeUTF8);
  1.1041 -	ts << saveFile;
  1.1042 -	file.close();
  1.1043  
  1.1044  	if (returnCode==0)
  1.1045  	{
  1.1046 @@ -798,12 +930,13 @@
  1.1047  void MapEditor::print()
  1.1048  {
  1.1049  	// Finish open lineEdits
  1.1050 -	if (lineedit) finishedLineEditNoSave();
  1.1051 +	if (lineedit) finishedLineEdit();
  1.1052  
  1.1053  	if ( !printer ) 
  1.1054  	{
  1.1055  		printer = new QPrinter;
  1.1056  		printer->setColorMode (QPrinter::Color);
  1.1057 +		printer->setPrinterName (settings.readEntry("/vym/mainwindow/printerName",printer->printerName()));
  1.1058  	}
  1.1059  
  1.1060  	QRect totalBBox=mapCenter->getTotalBBox();
  1.1061 @@ -840,50 +973,56 @@
  1.1062  		// e.g. (0,50,700,700) is upper part on A4
  1.1063  		// see also /usr/lib/qt3/doc/html/coordsys.html
  1.1064  
  1.1065 -		QPaintDeviceMetrics metrics (printer);
  1.1066 +		Q3PaintDeviceMetrics metrics (printer);
  1.1067  
  1.1068  		double paperAspect = (double)metrics.width()   / (double)metrics.height();
  1.1069  		double   mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
  1.1070  
  1.1071 -		QRect mapRect=mapCenter->getTotalBBox();
  1.1072 -		QCanvasRectangle *frame=NULL;
  1.1073 -		QCanvasText *footerFN=NULL;
  1.1074 -		QCanvasText *footerDate=NULL;
  1.1075 +		QRect mapRect=totalBBox;
  1.1076 +		Q3CanvasRectangle *frame=NULL;
  1.1077 +		Q3CanvasText *footerFN=NULL;
  1.1078 +		Q3CanvasText *footerDate=NULL;
  1.1079  		if (printFrame || printFooter)
  1.1080  		{
  1.1081  			
  1.1082  			if (printFrame) 
  1.1083  			{
  1.1084  				// Print frame around map
  1.1085 -				mapRect.setRect (mapRect.x()-10, mapRect.y()-10, 
  1.1086 -					mapRect.width()+20, mapRect.height()+20);
  1.1087 -				frame=new QCanvasRectangle (mapRect,mapCanvas);
  1.1088 -				frame->setBrush (QColor(white));
  1.1089 -				frame->setPen (QColor(black));
  1.1090 +				mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10, 
  1.1091 +					totalBBox.width()+20, totalBBox.height()+20);
  1.1092 +				frame=new Q3CanvasRectangle (mapRect,mapCanvas);
  1.1093 +				frame->setBrush (QColor(Qt::white));
  1.1094 +				frame->setPen (QColor(Qt::black));
  1.1095  				frame->setZ(0);
  1.1096  				frame->show();    
  1.1097  			}		
  1.1098 +			/* TODO remove after testing 
  1.1099 +			QCanvasLine *l=new QCanvasLine (mapCanvas);
  1.1100 +			l->setPoints (0,0,mapRect.width(),mapRect.height());
  1.1101 +			l->setPen (QPen(QColor(black), 1));
  1.1102 +			l->setZ (200);
  1.1103 +			l->show();
  1.1104 +			*/
  1.1105 +
  1.1106  			if (printFooter) 
  1.1107  			{
  1.1108  				// Print footer below map
  1.1109  				QFont font;		
  1.1110  				font.setPointSize(10);
  1.1111 -				footerFN=new QCanvasText (mapCanvas);
  1.1112 +				footerFN=new Q3CanvasText (mapCanvas);
  1.1113  				footerFN->setText ("VYM - " + fileName);
  1.1114  				footerFN->setFont(font);
  1.1115  				footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
  1.1116  				footerFN->setZ(Z_TEXT);
  1.1117  				footerFN->show();    
  1.1118 -				footerDate=new QCanvasText (mapCanvas);
  1.1119 +				footerDate=new Q3CanvasText (mapCanvas);
  1.1120  				footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
  1.1121  				footerDate->setFont(font);
  1.1122  				footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
  1.1123  				footerDate->setZ(Z_TEXT);
  1.1124  				footerDate->show();    
  1.1125 -				mapRect.setRect (mapRect.x(), mapRect.y(), 
  1.1126 -					mapRect.width(), mapRect.height()+20);
  1.1127  			}
  1.1128 -			pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height());
  1.1129 +			pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()+20);
  1.1130  		}	else	
  1.1131  		{
  1.1132  			pp.setWindow (mapRect);
  1.1133 @@ -915,6 +1054,9 @@
  1.1134  			selection=oldselection;
  1.1135  			selection->select();
  1.1136  		}	
  1.1137 +
  1.1138 +		// Save settings in vymrc
  1.1139 +		settings.writeEntry("/vym/mainwindow/printerName",printer->printerName());
  1.1140  	}
  1.1141  }
  1.1142  
  1.1143 @@ -947,86 +1089,84 @@
  1.1144  	return pix;
  1.1145  }
  1.1146  
  1.1147 +void MapEditor::setHideTmpMode (HideTmpMode mode)
  1.1148 +{
  1.1149 +	hidemode=mode;
  1.1150 +	mapCenter->setHideTmp (hidemode);
  1.1151 +	mapCenter->reposition();
  1.1152 +	adjustCanvasSize();
  1.1153 +	canvas()->update();
  1.1154 +}
  1.1155 +
  1.1156 +HideTmpMode MapEditor::getHideTmpMode()
  1.1157 +{
  1.1158 +	return hidemode;
  1.1159 +}
  1.1160 +
  1.1161  void MapEditor::exportImage(QString fn)
  1.1162  {
  1.1163  	// Finish open lineEdits
  1.1164 -	if (lineedit) finishedLineEditNoSave();
  1.1165 -
  1.1166 +	if (lineedit) finishedLineEdit();
  1.1167 +
  1.1168 +	setExportMode (true);
  1.1169  	QPixmap pix (getPixmap());
  1.1170  	pix.save(fn, "PNG");
  1.1171 +	setExportMode (false);
  1.1172 +}
  1.1173 +
  1.1174 +void MapEditor::setExportMode (bool b)
  1.1175 +{
  1.1176 +	// should be called before and after exports
  1.1177 +	// depending on the settings
  1.1178 +	if (b && settings.value("/vym/export/useHideExport","yes")=="yes")
  1.1179 +		setHideTmpMode (HideExport);
  1.1180 +	else	
  1.1181 +		setHideTmpMode (HideNone);
  1.1182  }
  1.1183  
  1.1184  void MapEditor::exportImage(QString fn, int item)
  1.1185  {
  1.1186  	// Finish open lineEdits
  1.1187 -	if (lineedit) finishedLineEditNoSave();
  1.1188 -
  1.1189 +	if (lineedit) finishedLineEdit();
  1.1190 +
  1.1191 +	setExportMode (true);
  1.1192  	QPixmap pix (getPixmap());
  1.1193  	pix.save(fn, exportImageFormatMenu->text(item) );
  1.1194 +	setExportMode (false);
  1.1195  }
  1.1196  
  1.1197 -void MapEditor::exportASCII()
  1.1198 +void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
  1.1199  {
  1.1200 -	// FIXME still experimental
  1.1201 -	QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (ASCII)"));
  1.1202 -	fd->addFilter ("TXT (*.txt)");
  1.1203 -	fd->setCaption("VYM - Export (ASCII) (still experimental)");
  1.1204 -	fd->setMode( QFileDialog::AnyFile );
  1.1205 -	fd->show();
  1.1206 -
  1.1207 -	if ( fd->exec() == QDialog::Accepted )
  1.1208 +	ExportOO ex;
  1.1209 +	ex.setFile (fn);
  1.1210 +	ex.setMapCenter(mapCenter);
  1.1211 +	if (ex.setConfigFile(cf)) 
  1.1212  	{
  1.1213 -		if (QFile (fd->selectedFile()).exists() )
  1.1214 -		{
  1.1215 -			QMessageBox mb( "VYM",
  1.1216 -				tr("The file ") + fd->selectedFile() + 
  1.1217 -				tr(" exists already. Do you want to overwrite it?"),
  1.1218 -			QMessageBox::Warning,
  1.1219 -			QMessageBox::Yes | QMessageBox::Default,
  1.1220 -			QMessageBox::Cancel | QMessageBox::Escape,
  1.1221 -			QMessageBox::NoButton );
  1.1222 -
  1.1223 -			mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
  1.1224 -			mb.setButtonText( QMessageBox::No, tr("Cancel"));
  1.1225 -			Export ex;
  1.1226 -			switch( mb.exec() ) 
  1.1227 -			{
  1.1228 -				case QMessageBox::Yes:
  1.1229 -					// save 
  1.1230 -					if (!ex.setOutputDir ("out"))
  1.1231 -					{
  1.1232 -						QMessageBox::critical (0,tr("Critical Export Error "),tr("Couldn't create directory ") + "out");
  1.1233 -						return;
  1.1234 -					}
  1.1235 -					break;;
  1.1236 -				case QMessageBox::Cancel:
  1.1237 -					// do nothing
  1.1238 -					return;
  1.1239 -					break;
  1.1240 -			}
  1.1241 -		}
  1.1242 -		Export ex;
  1.1243 -		ex.setPath (fd->selectedFile() );
  1.1244 -		ex.setMapCenter(mapCenter);
  1.1245 -		ex.exportMap();
  1.1246 +		setExportMode (true);
  1.1247 +		ex.exportPresentation();
  1.1248 +		setExportMode (false);
  1.1249  	}
  1.1250  }
  1.1251  
  1.1252  
  1.1253 +
  1.1254  void MapEditor::exportXML(const QString &dir)
  1.1255  {
  1.1256 +	// Hide stuff during export, if settings want this
  1.1257 +	setExportMode (true);
  1.1258 +
  1.1259  	// Create subdirectories
  1.1260  	makeSubDirs (dir);
  1.1261  
  1.1262  	// write to directory
  1.1263 -	QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,CompleteMap);
  1.1264 +	QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
  1.1265  	QFile file;
  1.1266  
  1.1267  	file.setName ( dir + "/"+mapName+".xml");
  1.1268 -	if ( !file.open( IO_WriteOnly ) )
  1.1269 +	if ( !file.open( QIODevice::WriteOnly ) )
  1.1270  	{
  1.1271  		// This should neverever happen
  1.1272 -		QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open ")+file.name());
  1.1273 +		QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
  1.1274  		return;
  1.1275  	}	
  1.1276  
  1.1277 @@ -1038,6 +1178,8 @@
  1.1278  
  1.1279  	// Now write image, too
  1.1280  	exportImage (dir+"/images/"+mapName+".png");
  1.1281 +
  1.1282 +	setExportMode (false);
  1.1283  }
  1.1284  
  1.1285  void MapEditor::clear()
  1.1286 @@ -1051,240 +1193,264 @@
  1.1287  	mapCenter->clear();
  1.1288  }
  1.1289  
  1.1290 +void MapEditor::copy()
  1.1291 +{
  1.1292 +	// Finish open lineEdits
  1.1293 +	if (lineedit) finishedLineEdit();
  1.1294 +
  1.1295 +	if (selection) 
  1.1296 +	{
  1.1297 +		// write to directory
  1.1298 +		QString clipfile="part";
  1.1299 +		QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPoint(),selection);
  1.1300 +		QFile file;
  1.1301 +
  1.1302 +		file.setName ( clipboardDir + "/"+clipfile+".xml");
  1.1303 +		if ( !file.open( QIODevice::WriteOnly ) )
  1.1304 +		{
  1.1305 +			// This should neverever happen
  1.1306 +			QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
  1.1307 +			return;
  1.1308 +		}	
  1.1309 +
  1.1310 +		// Write it finally, and write in UTF8, no matter what 
  1.1311 +		QTextStream ts( &file );
  1.1312 +		ts.setEncoding (QTextStream::UnicodeUTF8);
  1.1313 +		ts << saveFile;
  1.1314 +		file.close();
  1.1315 +
  1.1316 +		clipboardEmpty=false;
  1.1317 +		updateActions();
  1.1318 +	}	    
  1.1319 +}
  1.1320 +
  1.1321 +void MapEditor::redo()
  1.1322 +{
  1.1323 +	// Finish open lineEdits
  1.1324 +	if (lineedit) finishedLineEdit();
  1.1325 +
  1.1326 +	blockSaveState=true;
  1.1327 +	
  1.1328 +	// Find out current undo directory
  1.1329 +	QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(undoNum));
  1.1330 +
  1.1331 +	// Restore variables
  1.1332 +	QString undoCommand;
  1.1333 +	QString undoSelection;
  1.1334 +	QString redoCommand;
  1.1335 +	QString redoSelection;
  1.1336 +	SimpleSettings set;
  1.1337 +	set.readSettings(QString(bakMapDir+"/commands"));
  1.1338 +	undoCommand=set.readEntry ("undoCommand");
  1.1339 +	undoSelection=set.readEntry ("undoSelection");
  1.1340 +	redoCommand=set.readEntry ("redoCommand");
  1.1341 +	redoSelection=set.readEntry ("redoSelection");
  1.1342 +
  1.1343 +	// select  object before redo
  1.1344 +	if (!redoSelection.isEmpty())
  1.1345 +		select (redoSelection);
  1.1346 +
  1.1347 +/* TODO remove testing
  1.1348 +	cout << "ME::redo() begin\n";
  1.1349 +	cout << "    undosTotal="<<undosTotal<<endl;
  1.1350 +	cout << "    undosAvail="<<undosAvail<<endl;
  1.1351 +	cout << "       undoNum="<<undoNum<<endl;
  1.1352 +	cout << "    ---------------------------"<<endl;
  1.1353 +	cout << "    undoCom="<<undoCommand<<endl;
  1.1354 +	cout << "    undoSel="<<undoSelection<<endl;
  1.1355 +	cout << "    ---------------------------"<<endl;
  1.1356 +	cout << "    redoCom="<<redoCommand<<endl;
  1.1357 +	cout << "    redoSel="<<redoSelection<<endl;
  1.1358 +	cout << "    ---------------------------"<<endl;
  1.1359 +*/
  1.1360 +	parseAtom (undoCommand);
  1.1361 +	mapCenter->reposition();
  1.1362 +
  1.1363 +	//if (!redoSelection.isEmpty())
  1.1364 +	//	select (redoSelection);
  1.1365 +
  1.1366 +	undosAvail--;
  1.1367 +	if (undosAvail<1)
  1.1368 +		// Undo not longer available now
  1.1369 +		actionEditUndo->setEnabled (false);
  1.1370 +	else	
  1.1371 +		undoNum--; if (undoNum<1) undoNum=undosTotal;
  1.1372 +
  1.1373 +	blockSaveState=false;
  1.1374 +/* TODO remove testing
  1.1375 +	cout << "ME::redo() end\n";
  1.1376 +	cout << "    undosAvail="<<undosAvail<<endl;
  1.1377 +	cout << "       undoNum="<<undoNum<<endl;
  1.1378 +	cout << "    ---------------------------"<<endl<<endl;
  1.1379 +*/	
  1.1380 +}
  1.1381 +
  1.1382  void MapEditor::undo()
  1.1383  {
  1.1384 -	QDir d;
  1.1385 -	d.setPath(bakMapDir);
  1.1386 +	// Finish open lineEdits
  1.1387 +	if (lineedit) finishedLineEdit();
  1.1388 +
  1.1389 +	blockSaveState=true;
  1.1390 +	
  1.1391 +	// Find out current undo directory
  1.1392 +	QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(undoNum));
  1.1393 +
  1.1394 +	// Restore variables
  1.1395 +	QString undoCommand;
  1.1396 +	QString undoSelection;
  1.1397 +	QString redoCommand;
  1.1398 +	QString redoSelection;
  1.1399 +	SimpleSettings set;
  1.1400 +	set.readSettings(QString(bakMapDir+"/commands"));
  1.1401 +	undoCommand=  set.readEntry ("undoCommand");
  1.1402 +	undoSelection=set.readEntry ("undoSelection");
  1.1403 +	redoCommand=  set.readEntry ("redoCommand");
  1.1404 +	redoSelection=set.readEntry ("redoSelection");
  1.1405 +
  1.1406 +	// select  object before undo
  1.1407 +	if (!undoSelection.isEmpty())
  1.1408 +		select (undoSelection);
  1.1409 +
  1.1410 +/* TODO testing
  1.1411 +	cout << "ME::undo() begin\n";
  1.1412 +	cout << "    undosTotal="<<undosTotal<<endl;
  1.1413 +	cout << "    undosAvail="<<undosAvail<<endl;
  1.1414 +	cout << "       undoNum="<<undoNum<<endl;
  1.1415 +	cout << "    ---------------------------"<<endl;
  1.1416 +	cout << "    undoCom="<<undoCommand<<endl;
  1.1417 +	cout << "    undoSel="<<undoSelection<<endl;
  1.1418 +	cout << "    ---------------------------"<<endl;
  1.1419 +	cout << "    redoCom="<<redoCommand<<endl;
  1.1420 +	cout << "    redoSel="<<redoSelection<<endl;
  1.1421 +	cout << "    ---------------------------"<<endl;
  1.1422 +*/	
  1.1423 +	parseAtom (undoCommand);
  1.1424 +	mapCenter->reposition();
  1.1425 +
  1.1426 +	//if (!redoSelection.isEmpty())
  1.1427 +	//	select (redoSelection);
  1.1428 +
  1.1429 +	undosAvail--;
  1.1430 +	if (undosAvail<1)
  1.1431 +		// Undo not longer available now
  1.1432 +		actionEditUndo->setEnabled (false);
  1.1433 +	else	
  1.1434 +		undoNum--; if (undoNum<1) undoNum=undosTotal;
  1.1435 +
  1.1436 +	blockSaveState=false;
  1.1437 +/* TODO remove testing
  1.1438 +	cout << "ME::undo() end\n";
  1.1439 +	cout << "    undosAvail="<<undosAvail<<endl;
  1.1440 +	cout << "       undoNum="<<undoNum<<endl;
  1.1441 +	cout << "    ---------------------------"<<endl<<endl;
  1.1442 +*/
  1.1443 +}
  1.1444 +
  1.1445 +void MapEditor::undoXML(const QString &undoSel, const QString &bakMapPath)
  1.1446 +{
  1.1447 +	QString bakMapDir=bakMapPath.left(bakMapPath.findRev("/"));
  1.1448 +	QDir d(bakMapDir);
  1.1449 +	QFile file (bakMapPath);
  1.1450 +
  1.1451  	if (d.exists() )
  1.1452  	{
  1.1453 -		// Finish open lineEdits
  1.1454 -		if (lineedit) finishedLineEditNoSave();
  1.1455 -
  1.1456 -		if (selection) 
  1.1457 -		{
  1.1458 -			selection->unselect();
  1.1459 -			selection=NULL;
  1.1460 -		}	
  1.1461 -		
  1.1462 +		// We need to parse saved XML data
  1.1463  		mapBuilderHandler handler;
  1.1464 -		QXmlInputSource source;
  1.1465 -		source.setData(backupXML);
  1.1466 +		QXmlInputSource source( file);
  1.1467  		QXmlSimpleReader reader;
  1.1468  		reader.setContentHandler( &handler );
  1.1469  		reader.setErrorHandler( &handler );
  1.1470  		handler.setMapEditor( this );
  1.1471  		handler.setTmpDir ( bakMapDir );	// needed to load files with rel. path
  1.1472 -		if (undoSelection)
  1.1473 +		if (undoSel.isEmpty())
  1.1474  		{
  1.1475 -			selection=undoSelection;
  1.1476 -			selection->select();
  1.1477 -			handler.setLoadMode (ImportReplace);
  1.1478 -
  1.1479 +			unselect();
  1.1480 +			mapCenter->clear();
  1.1481 +			handler.setLoadMode (NewMap);
  1.1482  		} else	
  1.1483  		{
  1.1484 -			mapCenter->clear();
  1.1485 -			handler.setLoadMode (NewMap);
  1.1486 +			select (undoSel);
  1.1487 +			handler.setLoadMode (ImportReplace);
  1.1488  		}	
  1.1489 -		blockreposition=true;
  1.1490 +		blockReposition=true;
  1.1491  		bool ok = reader.parse( source );
  1.1492 -		blockreposition=false;
  1.1493 -		if ( ok ) 
  1.1494 -			mapCenter->reposition();
  1.1495 -			
  1.1496 -		else 
  1.1497 +		blockReposition=false;
  1.1498 +		if (! ok ) 
  1.1499  		{	
  1.1500  			// This should never ever happen
  1.1501  			QMessageBox::critical( 0, tr( "Critical Parse Error by reading backupFile" ),
  1.1502 -								   tr( handler.errorProtocol() )+" in "+backupXML );
  1.1503 +								   tr( handler.errorProtocol() )+" in "+bakMapDir );
  1.1504  		}
  1.1505 -		// Undo not longer available now
  1.1506 -		actionEditUndo->setEnabled (false);
  1.1507 -		undoSelection=false;
  1.1508 -		mapChanged=false;
  1.1509 -		return;
  1.1510  	} else	
  1.1511  	{
  1.1512  		QMessageBox::critical( 0, tr( "Critical Error" ),
  1.1513 -			"Temporary directory " +bakMapDir + 
  1.1514 -			tr (" used for undo is gone. \n"
  1.1515 +			tr("Temporary directory %1 used for undo is gone. \n"
  1.1516  			"I will create a new one, but at the moment no undo is available.\n"
  1.1517  			"Maybe you want to reload your original data.\n\n"
  1.1518 -			"Sorry for any inconveniences.") );
  1.1519 +			"Sorry for any inconveniences.").arg(bakMapDir) );
  1.1520  		makeTmpDirs();	
  1.1521  	}							
  1.1522  }
  1.1523  
  1.1524 -void MapEditor::copy()
  1.1525 +void MapEditor::pasteNoSave()
  1.1526  {
  1.1527  	// Finish open lineEdits
  1.1528 -	if (lineedit) finishedLineEditNoSave();
  1.1529 -
  1.1530 -	if (selection) 
  1.1531 -	{
  1.1532 -		if (typeid(*selection) == typeid(BranchObj) ) 
  1.1533 -		{
  1.1534 -			BranchObj* to;
  1.1535 -			BranchObj* from;
  1.1536 -			clipboardME->clear();
  1.1537 -			clipboardME->getMapCenter()->addBranch();
  1.1538 -			to=clipboardME->getMapCenter()->getLastBranch();
  1.1539 -			if (to) 
  1.1540 -			{
  1.1541 -				from=(BranchObj*)(selection);
  1.1542 -				to->copy(from);
  1.1543 -
  1.1544 -				// keep position relative to parent
  1.1545 -				to->move2RelPos ( from->getRelPos());
  1.1546 -
  1.1547 -				// select data in clipboard
  1.1548 -				clipboardME->select ("bo:0");
  1.1549 -
  1.1550 -				// repositioning makes testing nicer,
  1.1551 -				// but is not needed usually:
  1.1552 -				if (clipboardME->isVisible())
  1.1553 -				{
  1.1554 -					clipboardME->getMapCenter()->reposition();  
  1.1555 -				}	
  1.1556 -				else
  1.1557 -					clipboardME->hide();
  1.1558 -			}
  1.1559 -		}    
  1.1560 -		if (typeid(*selection) == typeid(FloatImageObj) ) 
  1.1561 -		{
  1.1562 -			FloatImageObj* to;
  1.1563 -			FloatImageObj* from;
  1.1564 -			clipboardME->clear();
  1.1565 -			clipboardME->getMapCenter()->addFloatImage();
  1.1566 -			to=clipboardME->getMapCenter()->getLastFloatImage();
  1.1567 -			if (to) 
  1.1568 -			{
  1.1569 -				from=(FloatImageObj*)(selection);
  1.1570 -				to->copy(from);
  1.1571 -
  1.1572 -				// select data in clipboard
  1.1573 -				clipboardME->select ("fi:0");
  1.1574 -
  1.1575 -				// repositioning makes testing nicer,
  1.1576 -				// but is not needed usually:
  1.1577 -				if (clipboardME->isVisible())
  1.1578 -				{
  1.1579 -					clipboardME->getMapCenter()->reposition();  
  1.1580 -				}	
  1.1581 -				else
  1.1582 -					clipboardME->hide();
  1.1583 -			}
  1.1584 -		}    
  1.1585 -	}	    
  1.1586 -}
  1.1587 -
  1.1588 -LinkableMapObj* MapEditor::pasteNoSave()
  1.1589 -{
  1.1590 -	return pasteAtNoSave (-1);
  1.1591 -}
  1.1592 -
  1.1593 -LinkableMapObj* MapEditor::pasteAtNoSave(int pos)
  1.1594 -{
  1.1595 -	// Finish open lineEdits
  1.1596 -	if (lineedit) finishedLineEditNoSave();
  1.1597 -
  1.1598 -	LinkableMapObj *fromLMO=clipboardME->getSelection();
  1.1599 -	LinkableMapObj *returnLMO=NULL;
  1.1600 -
  1.1601 -	if (selection && fromLMO) 
  1.1602 -	{
  1.1603 -
  1.1604 -		if (typeid(*fromLMO) == typeid(BranchObj) ) 
  1.1605 -		{
  1.1606 -			if (typeid(*selection) == typeid(MapCenterObj)) 
  1.1607 -			{
  1.1608 -				returnLMO=mapCenter->addBranch( (BranchObj*)(fromLMO) );
  1.1609 -				((BranchObj*)(returnLMO))->move2RelPos(normalise(fromLMO->getRelPos() ) );
  1.1610 -			}     
  1.1611 -			if (typeid(*selection) == typeid(BranchObj)) 
  1.1612 -				if (pos<0)
  1.1613 -					returnLMO=((BranchObj*)(selection))->addBranch((BranchObj*)(fromLMO) );
  1.1614 -				else
  1.1615 -				{
  1.1616 -					BranchObj *par=(BranchObj*)(selection->getParObj());
  1.1617 -					if (par) returnLMO=par->insertBranch((BranchObj*)(fromLMO),pos );
  1.1618 -				}	
  1.1619 -		}
  1.1620 -		
  1.1621 -		if (typeid(*fromLMO) == typeid(FloatImageObj) &&
  1.1622 -			(typeid(*selection) == typeid (BranchObj) || 
  1.1623 -			 typeid(*selection)==typeid(MapCenterObj)) )
  1.1624 -			returnLMO=((BranchObj*) (selection))->addFloatImage ((FloatImageObj*)(fromLMO));
  1.1625 -		
  1.1626 -	}	    
  1.1627 -	return returnLMO;
  1.1628 +	if (lineedit) finishedLineEdit();
  1.1629 +
  1.1630 +	load (clipboardDir+"/part.xml",ImportAdd);
  1.1631  }
  1.1632  
  1.1633  void MapEditor::cutNoSave()
  1.1634  {
  1.1635 -	// Finish open lineEdits
  1.1636 -	if (lineedit) finishedLineEditNoSave();
  1.1637 -
  1.1638 -	BranchObj* bo;
  1.1639 -	BranchObj* par; 
  1.1640 -	if (selection != NULL) {
  1.1641 -		if (typeid(*selection) == typeid(BranchObj) ) 
  1.1642 -		{
  1.1643 -			bo=(BranchObj*)(selection);
  1.1644 -			par=(BranchObj*)(bo->getParObj());
  1.1645 -			bo->unselect();
  1.1646 -			selection=NULL;
  1.1647 -			par->removeBranch(bo);
  1.1648 -			selection=par;
  1.1649 -			selection->select();
  1.1650 -		}
  1.1651 -		if (typeid(*selection) == typeid(FloatImageObj) ) 
  1.1652 -		{
  1.1653 -			FloatImageObj* fio=(FloatImageObj*)(selection);
  1.1654 -			par=(BranchObj*)(fio->getParObj());
  1.1655 -			fio->unselect();
  1.1656 -			selection=NULL;
  1.1657 -			par->removeFloatImage(fio);
  1.1658 -			selection=par;
  1.1659 -			selection->select();
  1.1660 -		}
  1.1661 -	}	    
  1.1662 +	copy();
  1.1663 +	deleteSelection();
  1.1664  }
  1.1665  
  1.1666  void MapEditor::paste()
  1.1667  {   
  1.1668 -	setChanged();
  1.1669 -	saveState(PartOfMap,selection);
  1.1670 -	pasteNoSave();
  1.1671 -	mapCenter->reposition();
  1.1672 -	adjustCanvasSize();
  1.1673 +	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.1674 +				      typeid(*selection) == typeid(MapCenterObj))) 
  1.1675 +	{
  1.1676 +		saveState(selection,QString("Paste to %1").arg( getName(selection)));
  1.1677 +		pasteNoSave();
  1.1678 +		mapCenter->reposition();
  1.1679 +		adjustCanvasSize();
  1.1680 +	}
  1.1681  }
  1.1682  
  1.1683  void MapEditor::cut()
  1.1684  {
  1.1685 -	setChanged();
  1.1686 -	saveState(PartOfMap,selection->getParObj());
  1.1687 +	saveState(selection->getParObj(),QString("Cut %1").arg(getName(selection)));
  1.1688  	copy();
  1.1689  	cutNoSave();
  1.1690  	mapCenter->reposition();
  1.1691  	adjustCanvasSize();
  1.1692  }
  1.1693  
  1.1694 +void MapEditor::move(const int &x, const int &y)
  1.1695 +{
  1.1696 +	// TODO no saveState, because this is only internal at undo so far
  1.1697 +	if (selection) selection->move(x,y);
  1.1698 +	if (typeid(*selection) == typeid(FloatImageObj))
  1.1699 +		((FloatImageObj*)selection)->setRelPos();
  1.1700 +}
  1.1701 +
  1.1702  void MapEditor::moveBranchUp()
  1.1703  {
  1.1704  	// Finish open lineEdits
  1.1705 -	if (lineedit) finishedLineEditNoSave();
  1.1706 +	if (lineedit) finishedLineEdit();
  1.1707  
  1.1708  	BranchObj* bo;
  1.1709  	BranchObj* par;
  1.1710  	if (typeid(*selection) == typeid(BranchObj)  ) 
  1.1711  	{
  1.1712 -		setChanged();
  1.1713 -		saveState(PartOfMap,selection->getParObj());
  1.1714 -		bo=(BranchObj*)(selection);
  1.1715 +		bo=(BranchObj*)selection;
  1.1716 +		if (!bo->canMoveBranchUp()) return;
  1.1717  		par=(BranchObj*)(bo->getParObj());
  1.1718  		selection->unselect();
  1.1719  		selection=par->moveBranchUp (bo);
  1.1720  		selection->select();
  1.1721 +		saveState("moveBranchDown ()",bo,QString("Move up %1").arg(getName(bo)));
  1.1722  		mapCenter->reposition();
  1.1723  		ensureSelectionVisible();
  1.1724  	}
  1.1725 @@ -1293,19 +1459,19 @@
  1.1726  void MapEditor::moveBranchDown()
  1.1727  {
  1.1728  	// Finish open lineEdits
  1.1729 -	if (lineedit) finishedLineEditNoSave();
  1.1730 +	if (lineedit) finishedLineEdit();
  1.1731  
  1.1732  	BranchObj* bo;
  1.1733  	BranchObj* par;
  1.1734  	if (typeid(*selection) == typeid(BranchObj)  ) 
  1.1735  	{
  1.1736 -		setChanged();
  1.1737 -		saveState(PartOfMap,selection->getParObj());
  1.1738 -		bo=(BranchObj*)(selection);
  1.1739 +		bo=(BranchObj*)selection;
  1.1740 +		if (!bo->canMoveBranchDown()) return;
  1.1741  		par=(BranchObj*)(bo->getParObj());
  1.1742  		selection->unselect(); 
  1.1743  		selection=par->moveBranchDown(bo);
  1.1744  		selection->select();
  1.1745 +		saveState("moveBranchUp ()",bo,QString("Move down %1").arg(getName(bo)));
  1.1746  		mapCenter->reposition();
  1.1747  		ensureSelectionVisible();
  1.1748  	}	
  1.1749 @@ -1314,46 +1480,82 @@
  1.1750  void MapEditor::editHeading()
  1.1751  {
  1.1752  	// Finish open lineEdits
  1.1753 -	if (lineedit) finishedLineEditNoSave();
  1.1754 +	if (lineedit) finishedLineEdit();
  1.1755  
  1.1756  	if (selection  &&  
  1.1757  		 (typeid(*selection) == typeid(BranchObj) || 
  1.1758  		  typeid(*selection) == typeid(MapCenterObj) ) ) 
  1.1759  	{
  1.1760 -		setChanged();
  1.1761 -		saveState(PartOfMap,selection);
  1.1762 +		editingBO=(BranchObj*)selection;
  1.1763  
  1.1764  		ensureSelectionVisible();
  1.1765 -		BranchObj *bo=(BranchObj*)(selection);
  1.1766 -		editingBO=(BranchObj*)(selection);
  1.1767 -		QPoint p = worldMatrix().map(QPoint (bo->x(),bo->y()));
  1.1768 +		QPoint p = worldMatrix().map(QPoint (editingBO->x(),editingBO->y()));
  1.1769  		lineedit->setGeometry(p.x()-contentsX(),p.y()-contentsY(),200,25);
  1.1770 -		QString s=bo->getHeading();
  1.1771 +		QString s=editingBO->getHeading();
  1.1772  		lineedit->setText(s);
  1.1773  		lineedit->setCursorPosition(1);
  1.1774  		if (actionSettingsAutoselectText->isOn() && !s.isEmpty() && actionSettingsPasteNewHeading->isOn() )
  1.1775  			lineedit->selectAll();
  1.1776  		lineedit->show();
  1.1777 -
  1.1778  		lineedit->grabKeyboard();
  1.1779  		lineedit->setFocus();
  1.1780  	}				
  1.1781  }
  1.1782  
  1.1783 -
  1.1784 -void MapEditor::addNewBranch(int pos)
  1.1785 +void MapEditor::setHeading(const QString &s)
  1.1786  {
  1.1787 -	// Finish open lineEdits
  1.1788 -	if (lineedit) finishedLineEditNoSave();
  1.1789 -
  1.1790 +	// Internal function, no saveState needed
  1.1791  	if (selection  &&  
  1.1792  		 (typeid(*selection) == typeid(BranchObj) || 
  1.1793  		  typeid(*selection) == typeid(MapCenterObj) ) ) 
  1.1794  	{
  1.1795 -		setChanged();
  1.1796 -		saveState(PartOfMap,selection);
  1.1797 -
  1.1798 -		BranchObj* bo1 = (BranchObj*) (selection);
  1.1799 +		((BranchObj*)selection)->setHeading(s);
  1.1800 +		mapCenter->reposition();
  1.1801 +		adjustCanvasSize();
  1.1802 +		ensureSelectionVisible();
  1.1803 +	}
  1.1804 +}
  1.1805 +
  1.1806 +void MapEditor::setURL (const QString &s)
  1.1807 +{
  1.1808 +	// Internal function, no saveState needed
  1.1809 +	if (selection  &&  
  1.1810 +		 (typeid(*selection) == typeid(BranchObj) || 
  1.1811 +		  typeid(*selection) == typeid(MapCenterObj) ) ) 
  1.1812 +	{
  1.1813 +		((BranchObj*)selection)->setURL(s);
  1.1814 +		mapCenter->reposition();
  1.1815 +		adjustCanvasSize();
  1.1816 +		ensureSelectionVisible();
  1.1817 +	}
  1.1818 +}
  1.1819 +
  1.1820 +void MapEditor::setVymLink (const QString &s)
  1.1821 +{
  1.1822 +	// Internal function, no saveState needed
  1.1823 +	if (selection  &&  
  1.1824 +		 (typeid(*selection) == typeid(BranchObj) || 
  1.1825 +		  typeid(*selection) == typeid(MapCenterObj) ) ) 
  1.1826 +	{
  1.1827 +		((BranchObj*)selection)->setVymLink(s);
  1.1828 +		mapCenter->reposition();
  1.1829 +		adjustCanvasSize();
  1.1830 +		ensureSelectionVisible();
  1.1831 +	}
  1.1832 +}
  1.1833 +
  1.1834 +void MapEditor::addNewBranch(int pos)
  1.1835 +{
  1.1836 +	// Finish open lineEdits
  1.1837 +	if (lineedit) finishedLineEdit();
  1.1838 +
  1.1839 +	if (selection  &&  
  1.1840 +		 (typeid(*selection) == typeid(BranchObj) || 
  1.1841 +		  typeid(*selection) == typeid(MapCenterObj) ) ) 
  1.1842 +	{
  1.1843 +		BranchObj* bo1 = (BranchObj*) selection;
  1.1844 +		saveState(selection, QString("Add new branch to %1").arg(getName(bo1)));	//TODO undoCommand
  1.1845 +
  1.1846  		bool wasScrolled=false;
  1.1847  		BranchObj *newbo=NULL;
  1.1848  		if (pos==0)
  1.1849 @@ -1391,7 +1593,7 @@
  1.1850  			selection->select();
  1.1851  			if (actionSettingsPasteNewHeading->isOn() )
  1.1852  			{
  1.1853 -				BranchObj *bo2= (BranchObj*)(selection);
  1.1854 +				BranchObj *bo2= (BranchObj*)selection;
  1.1855  				bo2->setHeading("");
  1.1856  			}	
  1.1857  			if (actionSettingsAutoedit->isOn() )
  1.1858 @@ -1407,18 +1609,74 @@
  1.1859  	}	
  1.1860  }
  1.1861  
  1.1862 +
  1.1863 +void MapEditor::addNewBranchHere()
  1.1864 +{
  1.1865 +	// Finish open lineEdits
  1.1866 +	if (lineedit) finishedLineEdit();
  1.1867 +
  1.1868 +	if (selection  &&  
  1.1869 +		 (typeid(*selection) == typeid(BranchObj) ) )
  1.1870 +	{
  1.1871 +		BranchObj* bo1 = (BranchObj*) selection;
  1.1872 +		saveState(selection, QString("Add new branch here").arg(getName(bo1)));
  1.1873 +
  1.1874 +		bool wasScrolled=false;
  1.1875 +		BranchObj *newbo=NULL;
  1.1876 +		BranchObj *parbo=(BranchObj*)(selection->getParObj());
  1.1877 +		if (parbo)
  1.1878 +		{
  1.1879 +			// add below selection
  1.1880 +			newbo=parbo->insertBranch(bo1->getNum()+1);
  1.1881 +		} 
  1.1882 +
  1.1883 +		LinkableMapObj *oldselection=selection;
  1.1884 +		((BranchObj*)selection)->moveBranchTo (newbo,-1);
  1.1885 +
  1.1886 +		mapCenter->reposition();
  1.1887 +		adjustCanvasSize();
  1.1888 +		if (actionSettingsAutoedit->isOn() ||
  1.1889 +			actionSettingsAutoselectHeading->isOn() )
  1.1890 +		{
  1.1891 +			selection->unselect();
  1.1892 +			selection=newbo;
  1.1893 +			selection->select();
  1.1894 +			if (actionSettingsPasteNewHeading->isOn() )
  1.1895 +			{
  1.1896 +				BranchObj *bo2= (BranchObj*)selection;
  1.1897 +				bo2->setHeading("");
  1.1898 +			}	
  1.1899 +			if (actionSettingsAutoedit->isOn() )
  1.1900 +				editHeading();
  1.1901 +			if (!actionSettingsAutoselectHeading->isOn()
  1.1902 +				&& !wasScrolled)
  1.1903 +			{
  1.1904 +				selection->unselect();
  1.1905 +				selection=oldselection;
  1.1906 +				selection->select();
  1.1907 +			}
  1.1908 +		}	
  1.1909 +	}	
  1.1910 +}
  1.1911 +
  1.1912  void MapEditor::deleteSelection()
  1.1913  {
  1.1914  	// Finish open lineEdits
  1.1915 -	if (lineedit) finishedLineEditNoSave();
  1.1916 +	if (lineedit) finishedLineEdit();
  1.1917  
  1.1918  	if (selection  && typeid(*selection) ==typeid(BranchObj) ) 
  1.1919  	{
  1.1920 -		setChanged();
  1.1921 -		saveState(PartOfMap,selection->getParObj());
  1.1922  		BranchObj* bo=dynamic_cast <BranchObj*> (selection);
  1.1923  		BranchObj* par=(BranchObj*)(bo->getParObj());
  1.1924  		bo->unselect();
  1.1925 +		if (selection->getDepth()>1)
  1.1926 +			// Normal branch, save parent with childs
  1.1927 +			saveState(par,QString("Delete %1").arg(getName(bo)));
  1.1928 +		else
  1.1929 +			// Mainbranch, save whole map
  1.1930 +			// TODO Better would be to insert mainbranch again at pos
  1.1931 +			// But undoCommand is missing right now
  1.1932 +			saveState(QString("Delete %1").arg(getName(bo)));
  1.1933  		selection=NULL;
  1.1934  		par->removeBranch(bo);
  1.1935  		selection=par;
  1.1936 @@ -1429,10 +1687,9 @@
  1.1937  	}
  1.1938  	if (selection  && typeid(*selection) ==typeid(FloatImageObj) ) 
  1.1939  	{
  1.1940 -		setChanged();
  1.1941 -		saveState(PartOfMap,selection->getParObj());
  1.1942  		FloatImageObj* fio=dynamic_cast <FloatImageObj*> (selection);
  1.1943  		BranchObj* par=(BranchObj*)(fio->getParObj());
  1.1944 +		saveState(par, QString("Delete %1").arg(getName(fio)));
  1.1945  		fio->unselect();
  1.1946  		selection=NULL;
  1.1947  		par->removeFloatImage(fio);
  1.1948 @@ -1449,56 +1706,6 @@
  1.1949  	return selection;
  1.1950  }
  1.1951  
  1.1952 -bool MapEditor::select (QString s)
  1.1953 -{
  1.1954 -	LinkableMapObj *lmo=mapCenter;
  1.1955 -	QString part;
  1.1956 -	QString typ;
  1.1957 -	QString num;
  1.1958 -	while (!s.isEmpty() )
  1.1959 -	{
  1.1960 -		part=s.section(",",0,0);
  1.1961 -		typ=part.left (3);
  1.1962 -		num=part.right(part.length() - 3);
  1.1963 -		
  1.1964 -		if (typ=="mc:")
  1.1965 -		{
  1.1966 -			if (num=="")
  1.1967 -				break;
  1.1968 -			else
  1.1969 -				lmo=mapCenter->getBranchNum (num.toUInt());
  1.1970 -		} else
  1.1971 -			if (typ=="bo:")
  1.1972 -				lmo=((BranchObj*)(lmo))->getBranchNum (num.toUInt());
  1.1973 -			else
  1.1974 -				if (typ=="fi:")
  1.1975 -					lmo=((BranchObj*)(lmo))->getFloatImageNum (num.toUInt());
  1.1976 -				
  1.1977 -		
  1.1978 -		
  1.1979 -		if (!lmo) break;
  1.1980 -		
  1.1981 -		if (s.contains(","))
  1.1982 -			s=s.right(s.length() - part.length() -1 );
  1.1983 -		else	
  1.1984 -			break;
  1.1985 -	}
  1.1986 -
  1.1987 -	// Finally select the found object
  1.1988 -	if (lmo)
  1.1989 -	{
  1.1990 -		if (selection) selection->unselect();
  1.1991 -		selection=lmo;
  1.1992 -		selection->select();
  1.1993 -		adjustCanvasSize();
  1.1994 -		ensureSelectionVisible();
  1.1995 -		return true;
  1.1996 -	} else
  1.1997 -		return false;
  1.1998 -	
  1.1999 -	
  1.2000 -}
  1.2001 -
  1.2002  void MapEditor::unselect()
  1.2003  {
  1.2004  	if (selection) 
  1.2005 @@ -1519,6 +1726,37 @@
  1.2006  	}
  1.2007  }	
  1.2008  
  1.2009 +bool MapEditor::select (const QString &s)
  1.2010 +{
  1.2011 +	LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
  1.2012 +
  1.2013 +	// Finally select the found object
  1.2014 +	if (lmo)
  1.2015 +	{
  1.2016 +		if (selection) unselect();
  1.2017 +		selection=lmo;
  1.2018 +		selection->select();
  1.2019 +		adjustCanvasSize();
  1.2020 +		ensureSelectionVisible();
  1.2021 +		return true;
  1.2022 +	} 
  1.2023 +	return false;
  1.2024 +}
  1.2025 +
  1.2026 +void MapEditor::select (LinkableMapObj *lmo)
  1.2027 +{
  1.2028 +	if (lmo && selection != lmo)
  1.2029 +	{
  1.2030 +		// select the MapObj
  1.2031 +		if (selection) selection->unselect();
  1.2032 +		selection=lmo;
  1.2033 +		selection->select();
  1.2034 +			
  1.2035 +		adjustCanvasSize();
  1.2036 +	}
  1.2037 +
  1.2038 +}
  1.2039 +
  1.2040  void MapEditor::selectNextBranch()
  1.2041  {
  1.2042  	// Increase number of branch
  1.2043 @@ -1583,7 +1821,7 @@
  1.2044  					b=select (s);
  1.2045  					if (b)
  1.2046  					{	
  1.2047 -						if ( ((BranchObj*)(selection))->countBranches()>0)
  1.2048 +						if ( ((BranchObj*)selection)->countBranches()>0)
  1.2049  							s+=",bo:0";
  1.2050  						else	
  1.2051  							break;
  1.2052 @@ -1662,8 +1900,8 @@
  1.2053  				{
  1.2054  					b=select (s);
  1.2055  					if (b)
  1.2056 -						if ( ((BranchObj*)(selection))->countBranches()>0)
  1.2057 -							s+=",bo:"+ QString ("%1").arg( ((BranchObj*)(selection))->countBranches()-1 );
  1.2058 +						if ( ((BranchObj*)selection)->countBranches()>0)
  1.2059 +							s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
  1.2060  						else	
  1.2061  							break;
  1.2062  					else
  1.2063 @@ -1681,7 +1919,7 @@
  1.2064  void MapEditor::selectUpperBranch()
  1.2065  {
  1.2066  	// Finish open lineEdits
  1.2067 -	if (lineedit) finishedLineEditNoSave();
  1.2068 +	if (lineedit) finishedLineEdit();
  1.2069  
  1.2070  	if (selection) 
  1.2071  	{
  1.2072 @@ -1701,7 +1939,7 @@
  1.2073  void MapEditor::selectLowerBranch()
  1.2074  {
  1.2075  	// Finish open lineEdits
  1.2076 -	if (lineedit) finishedLineEditNoSave();
  1.2077 +	if (lineedit) finishedLineEdit();
  1.2078  
  1.2079  	if (selection) 
  1.2080  	{
  1.2081 @@ -1722,7 +1960,7 @@
  1.2082  void MapEditor::selectLeftBranch()
  1.2083  {
  1.2084  	// Finish open lineEdits
  1.2085 -	if (lineedit) finishedLineEditNoSave();
  1.2086 +	if (lineedit) finishedLineEdit();
  1.2087  
  1.2088  	BranchObj* bo;
  1.2089  	BranchObj* par;
  1.2090 @@ -1730,7 +1968,7 @@
  1.2091  	{
  1.2092  		if (typeid(*selection) == typeid(MapCenterObj))
  1.2093  		{
  1.2094 -			par=  (BranchObj*) (selection);
  1.2095 +			par=  (BranchObj*) selection;
  1.2096  			bo=par->getLastSelectedBranch();
  1.2097  			if (bo)
  1.2098  			{
  1.2099 @@ -1766,7 +2004,7 @@
  1.2100  			{
  1.2101  				if (typeid(*selection) == typeid(BranchObj) )
  1.2102  				{
  1.2103 -					bo=((BranchObj*)(selection))->getLastSelectedBranch();
  1.2104 +					bo=((BranchObj*)selection)->getLastSelectedBranch();
  1.2105  					if (bo) 
  1.2106  					{
  1.2107  						selection->unselect();
  1.2108 @@ -1784,7 +2022,7 @@
  1.2109  void MapEditor::selectRightBranch()
  1.2110  {
  1.2111  	// Finish open lineEdits
  1.2112 -	if (lineedit) finishedLineEditNoSave();
  1.2113 +	if (lineedit) finishedLineEdit();
  1.2114  
  1.2115  	BranchObj* bo;
  1.2116  	BranchObj* par;
  1.2117 @@ -1793,7 +2031,7 @@
  1.2118  	{
  1.2119  		if (typeid(*selection) == typeid(MapCenterObj))
  1.2120  		{
  1.2121 -			par=  (BranchObj*) (selection);
  1.2122 +			par=  (BranchObj*) selection;
  1.2123  			bo=par->getLastSelectedBranch();
  1.2124  			if (bo)
  1.2125  			{
  1.2126 @@ -1826,7 +2064,7 @@
  1.2127  			{
  1.2128  				if (typeid(*selection) == typeid(BranchObj) )
  1.2129  				{
  1.2130 -					bo=((BranchObj*)(selection))->getLastSelectedBranch();
  1.2131 +					bo=((BranchObj*)selection)->getLastSelectedBranch();
  1.2132  					if (bo) 
  1.2133  					{
  1.2134  						selection->unselect();
  1.2135 @@ -1844,7 +2082,7 @@
  1.2136  void MapEditor::selectFirstBranch()
  1.2137  {
  1.2138  	// Finish open lineEdits
  1.2139 -	if (lineedit) finishedLineEditNoSave();
  1.2140 +	if (lineedit) finishedLineEdit();
  1.2141  
  1.2142  	BranchObj *bo1;
  1.2143  	BranchObj *bo2;
  1.2144 @@ -1852,7 +2090,7 @@
  1.2145  	if (selection) {
  1.2146  		if (typeid(*selection) == typeid(BranchObj))
  1.2147  		{
  1.2148 -			bo1=  (BranchObj*) (selection);
  1.2149 +			bo1=  (BranchObj*) selection;
  1.2150  			par=(BranchObj*)(bo1->getParObj());
  1.2151  			bo2=par->getFirstBranch();
  1.2152  			if (bo2) {
  1.2153 @@ -1869,7 +2107,7 @@
  1.2154  void MapEditor::selectLastBranch()
  1.2155  {
  1.2156  	// Finish open lineEdits
  1.2157 -	if (lineedit) finishedLineEditNoSave();
  1.2158 +	if (lineedit) finishedLineEdit();
  1.2159  
  1.2160  	BranchObj *bo1;
  1.2161  	BranchObj *bo2;
  1.2162 @@ -1877,7 +2115,7 @@
  1.2163  	if (selection) {
  1.2164  		if (typeid(*selection) == typeid(BranchObj))
  1.2165  		{
  1.2166 -			bo1=  (BranchObj*) (selection);
  1.2167 +			bo1=  (BranchObj*) selection;
  1.2168  			par=(BranchObj*)(bo1->getParObj());
  1.2169  			bo2=par->getLastBranch();
  1.2170  			if (bo2) {
  1.2171 @@ -1899,12 +2137,12 @@
  1.2172  void MapEditor::selectBackgroundColor()
  1.2173  {
  1.2174  	// Finish open lineEdits
  1.2175 -	if (lineedit) finishedLineEditNoSave();
  1.2176 +	if (lineedit) finishedLineEdit();
  1.2177  
  1.2178  	QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
  1.2179  	if ( !col.isValid() ) return;
  1.2180  	setBackgroundColor( col );
  1.2181 -	setChanged();
  1.2182 +	saveState(QString("Set background color of map to %1").arg(col.name()));
  1.2183  }
  1.2184  
  1.2185  void MapEditor::setBackgroundColor(QColor c)
  1.2186 @@ -1919,7 +2157,7 @@
  1.2187  		if (typeid(*selection) == typeid(BranchObj) ||
  1.2188  			typeid(*selection) == typeid(MapCenterObj))
  1.2189  		{
  1.2190 -			BranchObj *bo=(BranchObj*)(selection);
  1.2191 +			BranchObj *bo=(BranchObj*)selection;
  1.2192  			actColor=bo->getColor(); 
  1.2193  		}    
  1.2194  	}
  1.2195 @@ -1933,10 +2171,9 @@
  1.2196  		if (typeid(*selection) == typeid(BranchObj) ||
  1.2197  			typeid(*selection) == typeid(MapCenterObj))
  1.2198  		{
  1.2199 -			setChanged();
  1.2200 -			saveState(PartOfMap,selection);
  1.2201 -			BranchObj *bo=(BranchObj*)(selection);
  1.2202 -			bo->setColor(actColor, false); // color links, color childs
  1.2203 +			BranchObj *bo=(BranchObj*)selection;
  1.2204 +			saveState(selection, QString("Set color of %1 to %2").arg(getName(bo)).arg(actColor.name()));	//TODO undoCommand
  1.2205 +			bo->setColor(actColor); // color branch
  1.2206  		}    
  1.2207  	}
  1.2208  }
  1.2209 @@ -1948,10 +2185,9 @@
  1.2210  		if (typeid(*selection) == typeid(BranchObj) ||
  1.2211  			typeid(*selection) == typeid(MapCenterObj))
  1.2212  		{
  1.2213 -			setChanged();
  1.2214 -			saveState(PartOfMap,selection);
  1.2215 -			BranchObj *bo=(BranchObj*)(selection);
  1.2216 -			bo->setColor(actColor, true); // color links, color childs
  1.2217 +			BranchObj *bo=(BranchObj*)selection;
  1.2218 +			saveState(selection, QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(actColor.name()));	//TODO undoCommand
  1.2219 +			bo->setColorChilds(actColor); // color links, color childs
  1.2220  		}    
  1.2221  	}
  1.2222  }
  1.2223 @@ -1961,9 +2197,15 @@
  1.2224  {
  1.2225  	if (selection)
  1.2226  	{
  1.2227 -		setChanged();
  1.2228 -		saveState(PartOfMap,selection);	
  1.2229 -		((BranchObj*)(selection))->toggleStandardFlag (f);
  1.2230 +		BranchObj *bo=(BranchObj*)selection;
  1.2231 +		QString s;
  1.2232 +		if (bo->isSetStandardFlag(f))
  1.2233 +			s="Unset";
  1.2234 +		else
  1.2235 +			s="Set";
  1.2236 +		saveState(selection, QString("%1 standard flag \"%2\" of %3").arg(s).arg(f).arg(getName(bo)));// TODO undoCommand	
  1.2237 +		bo->toggleStandardFlag (f,actionSettingsUseFlagGroups->isOn());
  1.2238 +		adjustCanvasSize();
  1.2239  	}	
  1.2240  }
  1.2241  
  1.2242 @@ -1995,7 +2237,7 @@
  1.2243  			{
  1.2244  				if (selection!=itFind) 
  1.2245  				{
  1.2246 -					if (selection) ((BranchObj*)(selection))->unselect();
  1.2247 +					if (selection) ((BranchObj*)selection)->unselect();
  1.2248  					selection=itFind;
  1.2249  					selection->select();
  1.2250  					adjustCanvasSize();
  1.2251 @@ -2010,7 +2252,7 @@
  1.2252  			// Searching in Heading
  1.2253  			if (searching && itFind->getHeading().contains (s,cs) ) 
  1.2254  			{
  1.2255 -				if (selection) ((BranchObj*)(selection))->unselect();
  1.2256 +				if (selection) ((BranchObj*)selection)->unselect();
  1.2257  				selection=itFind;
  1.2258  				selection->select();
  1.2259  				adjustCanvasSize();
  1.2260 @@ -2027,7 +2269,7 @@
  1.2261  	if (!searching)
  1.2262  	{
  1.2263  		adjustCanvasSize();
  1.2264 -		return (BranchObj*)(selection);
  1.2265 +		return (BranchObj*)selection;
  1.2266  	}	else
  1.2267  		return NULL;
  1.2268  }
  1.2269 @@ -2038,62 +2280,44 @@
  1.2270  	EOFind=false;
  1.2271  }
  1.2272  
  1.2273 -void MapEditor::openURL()
  1.2274 -{
  1.2275 -	if (selection )
  1.2276 -	{
  1.2277 -		if (typeid(*selection) == typeid(BranchObj) ||
  1.2278 -			typeid(*selection) == typeid(MapCenterObj))
  1.2279 -		{
  1.2280 -			QString url=((BranchObj*)(selection))->getURL();
  1.2281 -
  1.2282 -			QProcess *proc = new QProcess( this );
  1.2283 -
  1.2284 -#if !defined(Q_OS_MACX)
  1.2285 -			proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL","konqueror" ));
  1.2286 -#else			
  1.2287 -			proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL",
  1.2288 -				"/Applications/Safari.app/Contents/MacOS/Safari" ));
  1.2289 -#endif			
  1.2290 -
  1.2291 -			proc->addArgument( url);
  1.2292 -
  1.2293 -			if ( !proc->start() ) 
  1.2294 -				// error handling
  1.2295 -				if (mainWindow->settingsURL() ) 
  1.2296 -					openURL();
  1.2297 -		}	
  1.2298 -	}	
  1.2299 -}
  1.2300 -
  1.2301  void MapEditor::editURL()
  1.2302  {
  1.2303  	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.2304  			typeid(*selection) == typeid(MapCenterObj)) )
  1.2305  	{		
  1.2306  		bool ok;
  1.2307 +		BranchObj *bo=(BranchObj*)selection;
  1.2308  		QString text = QInputDialog::getText(
  1.2309  				"VYM", tr("Enter URL:"), QLineEdit::Normal,
  1.2310 -				((BranchObj*)(selection))->getURL(), &ok, this );
  1.2311 +				bo->getURL(), &ok, this );
  1.2312  		if ( ok) 
  1.2313  		{
  1.2314  			// user entered something and pressed OK
  1.2315 -			((BranchObj*)(selection))->setURL (text);
  1.2316 +			saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+text+"\")", QString("Set URL of %1 to %21").arg(getName(bo)).arg(text));	
  1.2317 +			bo->setURL (text);
  1.2318  			updateActions();
  1.2319 -			setChanged();
  1.2320  		}	
  1.2321  	}
  1.2322  }
  1.2323  
  1.2324 +QString MapEditor::getURL()
  1.2325 +{
  1.2326 +	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.2327 +			typeid(*selection) == typeid(MapCenterObj)) )
  1.2328 +		return ((BranchObj*)selection)->getURL();
  1.2329 +	else
  1.2330 +		return "";
  1.2331 +}
  1.2332 +
  1.2333  void MapEditor::editHeading2URL()
  1.2334  {
  1.2335  	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.2336  			typeid(*selection) == typeid(MapCenterObj)) )
  1.2337  	{		
  1.2338 -		BranchObj *b=(BranchObj*)(selection);
  1.2339 -		b->setURL (b->getHeading());
  1.2340 +		BranchObj *bo=(BranchObj*)selection;
  1.2341 +		saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+bo->getHeading()+"\")",QString("Copy heading of %1 to URL").arg(getName(bo)));	
  1.2342 +		bo->setURL (bo->getHeading());
  1.2343  		updateActions();
  1.2344 -		setChanged();
  1.2345  	}
  1.2346  }	
  1.2347  
  1.2348 @@ -2102,10 +2326,24 @@
  1.2349  	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.2350  			typeid(*selection) == typeid(MapCenterObj)) )
  1.2351  	{		
  1.2352 -		BranchObj *b=(BranchObj*)(selection);
  1.2353 -		b->setURL ("http://bugzilla.suse.de/show_bug.cgi?id="+b->getHeading());
  1.2354 +		BranchObj *bo=(BranchObj*)selection;
  1.2355 +		QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
  1.2356 +		saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+url+"\")",QString("Use heading of %1 as link to Novell Bugzilla").arg(getName(bo)));	
  1.2357 +		bo->setURL (url);
  1.2358  		updateActions();
  1.2359 -		setChanged();
  1.2360 +	}
  1.2361 +}	
  1.2362 +
  1.2363 +void MapEditor::editFATE2URL()
  1.2364 +{
  1.2365 +	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.2366 +			typeid(*selection) == typeid(MapCenterObj)) )
  1.2367 +	{		
  1.2368 +		BranchObj *bo=(BranchObj*)selection;
  1.2369 +		QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
  1.2370 +		saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+url+"\")",QString("Use heading of %1 as link to FATE").arg(getName(bo)));	
  1.2371 +		bo->setURL (url);
  1.2372 +		updateActions();
  1.2373  	}
  1.2374  }	
  1.2375  
  1.2376 @@ -2114,21 +2352,24 @@
  1.2377  	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.2378  			typeid(*selection) == typeid(MapCenterObj)) )
  1.2379  	{		
  1.2380 -		QFileDialog *fd=new QFileDialog( this,tr("VYM - Link to another map"));
  1.2381 +		BranchObj *bo=(BranchObj*)selection;
  1.2382 +		Q3FileDialog *fd=new Q3FileDialog( this,__VYM " - " +tr("Link to another map"));
  1.2383  		fd->addFilter (QString (tr("vym map") + " (*.vym)"));
  1.2384 -		fd->setCaption(tr("VYM - Link to another map"));
  1.2385 -		if (! ((BranchObj*)(selection))->getVymLink().isEmpty() )
  1.2386 -			fd->setSelection( ((BranchObj*)(selection))->getVymLink() );
  1.2387 +		fd->setCaption(__VYM " - " +tr("Link to another map"));
  1.2388 +		if (! bo->getVymLink().isEmpty() )
  1.2389 +			fd->setSelection( bo->getVymLink() );
  1.2390  		fd->show();
  1.2391  
  1.2392  		QString fn;
  1.2393  		if ( fd->exec() == QDialog::Accepted )
  1.2394 -			((BranchObj*)(selection))->setVymLink (fd->selectedFile() );
  1.2395 -		updateActions();
  1.2396 -		mapCenter->reposition();
  1.2397 -		adjustCanvasSize();
  1.2398 -		canvas()->update();
  1.2399 -		setChanged();
  1.2400 +		{
  1.2401 +			saveState("setVymLink (\""+bo->getVymLink()+"\")","setVymLink (\""+fd->selectedFile()+"\")",QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile()));	
  1.2402 +			bo->setVymLink (fd->selectedFile() );
  1.2403 +			updateActions();
  1.2404 +			mapCenter->reposition();
  1.2405 +			adjustCanvasSize();
  1.2406 +			canvas()->update();
  1.2407 +		}
  1.2408  	}
  1.2409  }
  1.2410  
  1.2411 @@ -2137,12 +2378,41 @@
  1.2412  	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.2413  			typeid(*selection) == typeid(MapCenterObj)) )
  1.2414  	{		
  1.2415 -		((BranchObj*)(selection))->setVymLink ("" );
  1.2416 +		BranchObj *bo=(BranchObj*)selection;
  1.2417 +		saveState("setVymLink (\""+bo->getVymLink()+"\")","setVymLink (\"\")",QString("Unset vymlink of %1").arg(getName(bo)));	
  1.2418 +		bo->setVymLink ("" );
  1.2419  		updateActions();
  1.2420  		mapCenter->reposition();
  1.2421  		adjustCanvasSize();
  1.2422  		canvas()->update();
  1.2423 -		setChanged();
  1.2424 +	}
  1.2425 +}
  1.2426 +
  1.2427 +void MapEditor::toggleHideExport()
  1.2428 +{
  1.2429 +	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.2430 +			typeid(*selection) == typeid(MapCenterObj)) ||
  1.2431 +			(typeid(*selection)==typeid(FloatImageObj))
  1.2432 +			)
  1.2433 +	{		
  1.2434 +		OrnamentedObj *oo=(OrnamentedObj*)selection;
  1.2435 +		QString s;
  1.2436 +		if (oo->hideInExport())
  1.2437 +		{
  1.2438 +			oo->setHideInExport(false);
  1.2439 +			s="Unset";
  1.2440 +		}	
  1.2441 +		else	
  1.2442 +		{
  1.2443 +			oo->setHideInExport(true);
  1.2444 +			s="Set";
  1.2445 +		}	
  1.2446 +		saveState(QString ("%1 hide export flag of %2").arg(s).arg(getName(selection)));	//TODO undoCommand
  1.2447 +		actionEditToggleHideExport->setOn (oo->hideInExport());	
  1.2448 +		updateActions();
  1.2449 +		mapCenter->reposition();
  1.2450 +		adjustCanvasSize();
  1.2451 +		canvas()->update();
  1.2452  	}
  1.2453  }
  1.2454  
  1.2455 @@ -2151,12 +2421,41 @@
  1.2456  	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.2457  			typeid(*selection) == typeid(MapCenterObj)) )
  1.2458  	{		
  1.2459 -		return ((BranchObj*)(selection))->getVymLink();
  1.2460 +		return ((BranchObj*)selection)->getVymLink();
  1.2461  	}
  1.2462  	return "";
  1.2463  	
  1.2464  }
  1.2465  
  1.2466 +void MapEditor::removeBranchKeepChilds()
  1.2467 +{
  1.2468 +	if (selection && (typeid(*selection) == typeid(BranchObj) ))
  1.2469 +	{		
  1.2470 +		BranchObj* bo=(BranchObj*)selection;
  1.2471 +		BranchObj* par=(BranchObj*)(bo->getParObj());
  1.2472 +		QString s=QString("Remove %1 and keep its childs").arg(getName(bo));
  1.2473 +		if (bo->getDepth()==1)
  1.2474 +			saveState(s);
  1.2475 +		else	
  1.2476 +			saveState(selection->getParObj(),s);	// TODO undoCommand
  1.2477 +		QString sel=selection->getSelectString();
  1.2478 +		unselect();
  1.2479 +		par->removeBranchHere(bo);
  1.2480 +		mapCenter->reposition();
  1.2481 +		select (sel);
  1.2482 +	}	
  1.2483 +}
  1.2484 +
  1.2485 +void MapEditor::removeChilds()
  1.2486 +{
  1.2487 +	if (selection && (typeid(*selection) == typeid(BranchObj) ))
  1.2488 +	{		
  1.2489 +		saveState(selection->getParObj(), QString("Remove childs of branch %1").arg(getName(selection)));
  1.2490 +		((BranchObj*)selection)->removeChilds();
  1.2491 +		mapCenter->reposition();
  1.2492 +	}	
  1.2493 +}
  1.2494 +
  1.2495  void MapEditor::editMapInfo()
  1.2496  {
  1.2497  	ExtraInfoDialog dia;
  1.2498 @@ -2167,14 +2466,15 @@
  1.2499  	// Calc some stats
  1.2500  	QString stats;
  1.2501      int i=0;
  1.2502 -    QCanvasItemList l=canvas()->allItems();
  1.2503 -    for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) 
  1.2504 +    Q3CanvasItemList l=canvas()->allItems();
  1.2505 +    for (Q3CanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) 
  1.2506          i++;
  1.2507      stats+=QString ("%1 items on canvas\n").arg (i,6);
  1.2508  
  1.2509  	uint b=0;
  1.2510  	uint f=0;
  1.2511  	uint n=0;
  1.2512 +	uint xl=0;
  1.2513  	BranchObj *bo;
  1.2514  	bo=mapCenter->first();
  1.2515  	while (bo) 
  1.2516 @@ -2182,9 +2482,11 @@
  1.2517  		if (!bo->getNote().isEmpty() ) n++;
  1.2518  		f+= bo->countFloatImages();
  1.2519  		b++;
  1.2520 +		xl+=bo->countXLinks();
  1.2521  		bo=bo->next();
  1.2522  	}
  1.2523      stats+=QString ("%1 branches\n").arg (b-1,6);
  1.2524 +    stats+=QString ("%1 xLinks \n").arg (xl,6);
  1.2525      stats+=QString ("%1 notes\n").arg (n,6);
  1.2526      stats+=QString ("%1 images\n").arg (f,6);
  1.2527  	dia.setStats (stats);
  1.2528 @@ -2192,14 +2494,15 @@
  1.2529  	// Finally show dialog
  1.2530  	if (dia.exec() == QDialog::Accepted)
  1.2531  	{
  1.2532 +		saveState("Edit info about map");	//TODO undoCommand
  1.2533  		mapCenter->setAuthor (dia.getAuthor() );
  1.2534  		mapCenter->setComment (dia.getComment() );
  1.2535 -		setChanged();
  1.2536  	}
  1.2537  }
  1.2538  
  1.2539  void MapEditor::updateActions()
  1.2540  {
  1.2541 +	QAction *a;
  1.2542  	if (getLinkColorHint()==HeadingColor) 
  1.2543  		actionFormatLinkColorHint->setOn(true);
  1.2544  	else	
  1.2545 @@ -2226,7 +2529,7 @@
  1.2546  	QPixmap pix( 16, 16 );
  1.2547      pix.fill( mapCanvas->backgroundColor() );
  1.2548      actionFormatBackColor->setIconSet( pix );
  1.2549 -    pix.fill( deflinkcolor );
  1.2550 +    pix.fill( defLinkColor );
  1.2551      actionFormatLinkColor->setIconSet( pix );
  1.2552  
  1.2553  	actionEditUndo->setEnabled( mapChanged );
  1.2554 @@ -2237,17 +2540,54 @@
  1.2555  		if ( (typeid(*selection) == typeid(BranchObj)) || 
  1.2556  			(typeid(*selection) == typeid(MapCenterObj))  )
  1.2557  		{
  1.2558 +			BranchObj *bo=(BranchObj*)selection;
  1.2559 +			// Take care of links
  1.2560 +			if (bo->countXLinks()==0)
  1.2561 +			{
  1.2562 +				branchLinksContextMenu->clear();
  1.2563 +				branchLinksContextMenu->insertItem ("No xLink available");
  1.2564 +				branchLinksContextMenuDup->clear();
  1.2565 +				branchLinksContextMenuDup->insertItem ("No xLink available");
  1.2566 +				
  1.2567 +			} else
  1.2568 +			{
  1.2569 +				BranchObj *bot;
  1.2570 +				QString s;
  1.2571 +				branchLinksContextMenu->clear();
  1.2572 +				branchLinksContextMenuDup->clear();
  1.2573 +				for (int i=0; i<=bo->countXLinks();i++)
  1.2574 +				{
  1.2575 +					bot=bo->XLinkTargetAt(i);
  1.2576 +					if (bot)
  1.2577 +					{
  1.2578 +						s=bot->getHeading();
  1.2579 +						if (s.length()>25)
  1.2580 +							s=s.left(25)+"...";
  1.2581 +						branchLinksContextMenu->insertItem (s);
  1.2582 +						branchLinksContextMenuDup->insertItem (s);
  1.2583 +					}	
  1.2584 +				}
  1.2585 +			}
  1.2586 +
  1.2587  			standardFlagsDefault->setEnabled (true);
  1.2588  
  1.2589 -			if ( ((BranchObj*)(selection))->getURL().isEmpty() )
  1.2590 +			actionEditToggleScroll->setEnabled (true);
  1.2591 +			if ( bo->isScrolled() )
  1.2592 +				actionEditToggleScroll->setOn(true);
  1.2593 +			else	
  1.2594 +				actionEditToggleScroll->setOn(false);
  1.2595 +
  1.2596 +			if ( bo->getURL().isEmpty() )
  1.2597 +			{
  1.2598  				actionEditOpenURL->setEnabled (false);
  1.2599 +				actionEditOpenURLTab->setEnabled (false);
  1.2600 +			}	
  1.2601  			else	
  1.2602 +			{
  1.2603  				actionEditOpenURL->setEnabled (true);
  1.2604 -			actionEditURL->setEnabled (true);	
  1.2605 -			actionEditHeading2URL->setEnabled (true);	
  1.2606 -			actionEditBugzilla2URL->setEnabled (true);	
  1.2607 -
  1.2608 -			if ( ((BranchObj*)(selection))->getVymLink().isEmpty() )
  1.2609 +				actionEditOpenURLTab->setEnabled (true);
  1.2610 +			}
  1.2611 +			if ( bo->getVymLink().isEmpty() )
  1.2612  			{
  1.2613  				actionEditOpenVymLink->setEnabled (false);
  1.2614  				actionEditDeleteVymLink->setEnabled (false);
  1.2615 @@ -2256,28 +2596,29 @@
  1.2616  				actionEditOpenVymLink->setEnabled (true);
  1.2617  				actionEditDeleteVymLink->setEnabled (true);
  1.2618  			}	
  1.2619 -			actionEditVymLink->setEnabled (true);	
  1.2620 +
  1.2621 +			if (bo->canMoveBranchUp()) 
  1.2622 +				actionEditMoveUp->setEnabled (true);
  1.2623 +			else	
  1.2624 +				actionEditMoveUp->setEnabled (false);
  1.2625 +			if (bo->canMoveBranchDown()) 
  1.2626 +				actionEditMoveDown->setEnabled (true);
  1.2627 +			else	
  1.2628 +				actionEditMoveDown->setEnabled (false);
  1.2629 +
  1.2630 +
  1.2631 +			actionEditToggleHideExport->setEnabled (true);	
  1.2632 +			actionEditToggleHideExport->setOn (bo->hideInExport() );	
  1.2633  
  1.2634  			actionEditCopy->setEnabled (true);	
  1.2635  			actionEditCut->setEnabled (true);	
  1.2636 -			actionEditPaste->setEnabled (true);	
  1.2637 -			actionEditMoveUp->setEnabled (true);	
  1.2638 -			actionEditMoveDown->setEnabled (true);	
  1.2639 -			actionEditToggleScroll->setEnabled (true);	
  1.2640 -			actionEditHeading->setEnabled (true);
  1.2641 +			if (!clipboardEmpty)
  1.2642 +				actionEditPaste->setEnabled (true);	
  1.2643 +			else	
  1.2644 +				actionEditPaste->setEnabled (false);	
  1.2645 +			for (a=actionListBranches.first();a;a=actionListBranches.next())
  1.2646 +				a->setEnabled(true);
  1.2647  			actionEditDelete->setEnabled (true);
  1.2648 -			actionEditAddBranch->setEnabled (true);
  1.2649 -			actionEditAddBranchAbove->setEnabled (true);
  1.2650 -			actionEditAddBranchBelow->setEnabled (true);
  1.2651 -			actionEditImportAdd->setEnabled (true);
  1.2652 -			actionEditImportReplace->setEnabled (true);
  1.2653 -			actionEditSaveBranch->setEnabled (true);
  1.2654 -			actionEditSelectFirst->setEnabled (true);
  1.2655 -			actionEditSelectLast->setEnabled (true);
  1.2656 -			actionEditToggleFloatExport->setEnabled (false);
  1.2657 -			actionFormatPickColor->setEnabled (true);
  1.2658 -			actionFormatColorBranch->setEnabled (true);
  1.2659 -			actionFormatColorSubtree->setEnabled (true);
  1.2660  			switch (selection->getFrameType())
  1.2661  			{
  1.2662  				case NoFrame: 
  1.2663 @@ -2289,40 +2630,35 @@
  1.2664  				default:
  1.2665  					break;
  1.2666  			}	
  1.2667 +			actionFormatIncludeImagesVer->setOn
  1.2668 +				( ((BranchObj*)selection)->getIncludeImagesVer());
  1.2669 +			actionFormatIncludeImagesHor->setOn
  1.2670 +				( ((BranchObj*)selection)->getIncludeImagesHor());
  1.2671 +			actionFormatHideLinkUnselected->setOn
  1.2672 +				(selection->getHideLinkUnselected());
  1.2673  		}
  1.2674  		if ( (typeid(*selection) == typeid(FloatImageObj)) )
  1.2675  		{
  1.2676 +			FloatObj *fo=(FloatImageObj*)selection;
  1.2677  			standardFlagsDefault->setEnabled (false);
  1.2678  
  1.2679  			actionEditOpenURL->setEnabled (false);
  1.2680 -			actionEditURL->setEnabled (false);	
  1.2681 -			actionEditHeading2URL->setEnabled (false);	
  1.2682 -			actionEditBugzilla2URL->setEnabled (false);	
  1.2683  			actionEditOpenVymLink->setEnabled (false);
  1.2684 -			actionEditVymLink->setEnabled (false);	
  1.2685  			actionEditDeleteVymLink->setEnabled (false);	
  1.2686 +			actionEditToggleHideExport->setEnabled (true);	
  1.2687 +			actionEditToggleHideExport->setOn (fo->hideInExport() );	
  1.2688 +
  1.2689  
  1.2690  			actionEditCopy->setEnabled (true);
  1.2691  			actionEditCut->setEnabled (true);	
  1.2692 -			actionEditPaste->setEnabled (false);	//FIXME
  1.2693 -			actionEditMoveUp->setEnabled (false);	
  1.2694 -			actionEditMoveDown->setEnabled (false);	
  1.2695 -			actionEditToggleScroll->setEnabled (false);	
  1.2696 -			actionEditHeading->setEnabled (false);
  1.2697 +			actionEditPaste->setEnabled (false);
  1.2698 +			for (a=actionListBranches.first();a;a=actionListBranches.next())
  1.2699 +				a->setEnabled(false);
  1.2700  			actionEditDelete->setEnabled (true);
  1.2701 -			actionEditAddBranch->setEnabled (false);
  1.2702 -			actionEditAddBranchAbove->setEnabled (false);
  1.2703 -			actionEditAddBranchBelow->setEnabled (false);
  1.2704 -			actionEditImportAdd->setEnabled (false);
  1.2705 -			actionEditSaveBranch->setEnabled (false);
  1.2706 -			actionEditImportReplace->setEnabled (false);
  1.2707 -			actionEditSelectFirst->setEnabled (false);
  1.2708 -			actionEditSelectLast->setEnabled (false);
  1.2709 -			actionEditToggleFloatExport->setOn
  1.2710 -				( ((FloatImageObj*)(selection))->getFloatExport() );
  1.2711 -			actionFormatPickColor->setEnabled (false);
  1.2712 -			actionFormatColorBranch->setEnabled (false);
  1.2713 -			actionFormatColorSubtree->setEnabled (false);
  1.2714 +			actionFormatHideLinkUnselected->setOn
  1.2715 +				( selection->getHideLinkUnselected());
  1.2716 +			actionEditMoveUp->setEnabled (false);
  1.2717 +			actionEditMoveDown->setEnabled (false);
  1.2718  		}
  1.2719  
  1.2720  	} else
  1.2721 @@ -2332,36 +2668,34 @@
  1.2722  		actionEditCopy->setEnabled (false);	
  1.2723  		actionEditCut->setEnabled (false);	
  1.2724  		actionEditPaste->setEnabled (false);	
  1.2725 -		actionEditMoveUp->setEnabled (false);	
  1.2726 -		actionEditMoveDown->setEnabled (false);	
  1.2727 -		actionEditToggleScroll->setEnabled (false);	
  1.2728 +		for (a=actionListBranches.first();a;a=actionListBranches.next())
  1.2729 +			a->setEnabled(false);
  1.2730 +
  1.2731 +		actionEditToggleScroll->setEnabled (false);
  1.2732  		actionEditOpenURL->setEnabled (false);
  1.2733 -		actionEditURL->setEnabled (false);	
  1.2734  		actionEditOpenVymLink->setEnabled (false);
  1.2735 -		actionEditVymLink->setEnabled (false);	
  1.2736  		actionEditDeleteVymLink->setEnabled (false);	
  1.2737  		actionEditHeading2URL->setEnabled (false);	
  1.2738 -		actionEditBugzilla2URL->setEnabled (false);	
  1.2739 -		actionEditHeading->setEnabled (false);
  1.2740  		actionEditDelete->setEnabled (false);
  1.2741 -		actionEditAddBranch->setEnabled (false);
  1.2742 -		actionEditAddBranchAbove->setEnabled (false);
  1.2743 -		actionEditAddBranchBelow->setEnabled (false);
  1.2744 -		actionEditSaveBranch->setEnabled (false);
  1.2745 -		actionEditImportReplace->setEnabled (false);
  1.2746 -		actionEditSelectFirst->setEnabled (false);
  1.2747 -		actionEditSelectLast->setEnabled (false);
  1.2748 -		actionEditToggleFloatExport->setEnabled (false);
  1.2749 -		actionFormatPickColor->setEnabled (false);
  1.2750 -		actionFormatColorBranch->setEnabled (false);
  1.2751 -		actionFormatColorSubtree->setEnabled (false);
  1.2752 +		actionEditMoveUp->setEnabled (false);
  1.2753 +		actionEditMoveDown->setEnabled (false);
  1.2754 +		actionEditToggleHideExport->setEnabled (false);	
  1.2755  	}	
  1.2756  }
  1.2757  
  1.2758 +void MapEditor::updateNoteFlag()
  1.2759 +{
  1.2760 +	if (selection)
  1.2761 +		if ( (typeid(*selection) == typeid(BranchObj)) || 
  1.2762 +			(typeid(*selection) == typeid(MapCenterObj))  )
  1.2763 +			((BranchObj*)selection)->updateNoteFlag();
  1.2764 +}
  1.2765 +
  1.2766  void MapEditor::setLinkStyle (LinkStyle ls)
  1.2767  {
  1.2768  	linkstyle=ls;
  1.2769  
  1.2770 +	saveState("Set link style");	// TODO undoCommand
  1.2771  	BranchObj *bo;
  1.2772  	bo=mapCenter->first();
  1.2773  	bo=bo->next();
  1.2774 @@ -2370,8 +2704,7 @@
  1.2775  		bo->setLinkStyle(bo->getDefLinkStyle());
  1.2776  		bo=bo->next();
  1.2777  	}
  1.2778 -	//setChanged();
  1.2779 -	//saveState();
  1.2780 +	mapCenter->reposition();
  1.2781  }
  1.2782  
  1.2783  LinkStyle MapEditor::getLinkStyle ()
  1.2784 @@ -2381,7 +2714,7 @@
  1.2785  
  1.2786  void MapEditor::setLinkColor(QColor c)
  1.2787  {
  1.2788 -	deflinkcolor=c;
  1.2789 +	defLinkColor=c;
  1.2790  	updateActions();
  1.2791  }
  1.2792  
  1.2793 @@ -2425,29 +2758,54 @@
  1.2794  
  1.2795  QColor MapEditor::getDefLinkColor()
  1.2796  {
  1.2797 -	return deflinkcolor;
  1.2798 +	return defLinkColor;
  1.2799 +}
  1.2800 +
  1.2801 +void MapEditor::setDefXLinkColor(QColor col)
  1.2802 +{
  1.2803 +	defXLinkColor=col;
  1.2804 +}
  1.2805 +
  1.2806 +QColor MapEditor::getDefXLinkColor()
  1.2807 +{
  1.2808 +	return defXLinkColor;
  1.2809 +}
  1.2810 +
  1.2811 +void MapEditor::setDefXLinkWidth (int w)
  1.2812 +{
  1.2813 +	defXLinkWidth=w;
  1.2814 +}
  1.2815 +
  1.2816 +int MapEditor::getDefXLinkWidth()
  1.2817 +{
  1.2818 +	return defXLinkWidth;
  1.2819  }
  1.2820  
  1.2821  void MapEditor::selectLinkColor()
  1.2822  {
  1.2823  	// Finish open lineEdits
  1.2824 -	if (lineedit) finishedLineEditNoSave();
  1.2825 -
  1.2826 -	QColor col = QColorDialog::getColor( deflinkcolor, this );
  1.2827 +	if (lineedit) finishedLineEdit();
  1.2828 +
  1.2829 +	QColor col = QColorDialog::getColor( defLinkColor, this );
  1.2830  	if ( !col.isValid() ) return;
  1.2831  	setLinkColor( col );
  1.2832 -	setChanged();
  1.2833 +	saveState(QString("Set link color to %1").arg(col.name()));	//TODO undoCommand
  1.2834 +
  1.2835  }
  1.2836  
  1.2837  void MapEditor::toggleScroll()
  1.2838  {
  1.2839  	if (selection && (typeid(*selection) == typeid(BranchObj)) )
  1.2840  	{
  1.2841 -		BranchObj *bo=((BranchObj*)(selection));
  1.2842 +		BranchObj *bo=((BranchObj*)selection);
  1.2843  		if (bo->countBranches()==0) return;
  1.2844  		if (bo->getDepth()==0) return;
  1.2845 -		setChanged();
  1.2846 -		saveState(PartOfMap,selection);
  1.2847 +		QString s;
  1.2848 +		if (bo->isScrolled())
  1.2849 +			s="Unscroll";
  1.2850 +		else	
  1.2851 +			s="Scroll";
  1.2852 +		saveState(selection, QString ("%1 %2").arg(s).arg(getName(bo)));
  1.2853  		bo->toggleScroll();
  1.2854  		adjustCanvasSize();
  1.2855  		canvas()->update();
  1.2856 @@ -2471,33 +2829,42 @@
  1.2857  		(typeid(*selection) == typeid(BranchObj)) || 
  1.2858  		(typeid(*selection) == typeid(MapCenterObj))  )
  1.2859  	{
  1.2860 -		BranchObj *bo=((BranchObj*)(selection));
  1.2861 -
  1.2862 -		QFileDialog *fd=new QFileDialog( this,tr("vym - load image"));
  1.2863 +		BranchObj *bo=((BranchObj*)selection);
  1.2864 +
  1.2865 +		Q3FileDialog *fd=new Q3FileDialog( this);
  1.2866 +		fd->setMode (Q3FileDialog::ExistingFiles);
  1.2867  		fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
  1.2868  		ImagePreview *p =new ImagePreview (fd);
  1.2869  		fd->setContentsPreviewEnabled( TRUE );
  1.2870  		fd->setContentsPreview( p, p );
  1.2871 -		fd->setPreviewMode( QFileDialog::Contents );
  1.2872 -		fd->setCaption(tr("vym - Load image"));
  1.2873 +		fd->setPreviewMode( Q3FileDialog::Contents );
  1.2874 +		fd->setCaption(__VYM " - " +tr("Load image"));
  1.2875  		fd->setDir (lastImageDir);
  1.2876  		fd->show();
  1.2877  
  1.2878  		QString fn;
  1.2879  		if ( fd->exec() == QDialog::Accepted )
  1.2880  		{
  1.2881 -			setChanged();
  1.2882 -			saveState(PartOfMap,selection);
  1.2883 -			QString fn=fd->selectedFile();
  1.2884 +			saveState(selection, QString("Add floatimage to %1").arg(getName(selection)));
  1.2885  			lastImageDir=fn.left(fn.findRev ("/"));
  1.2886 -			bo->addFloatImage();
  1.2887 -			// FIXME check if load was successful
  1.2888 -			bo->getLastFloatImage()->load(fn);
  1.2889 -			bo->getLastFloatImage()->setOriginalFilename(fn);
  1.2890 +			QStringList flist = fd->selectedFiles();
  1.2891 +			QStringList::Iterator it = flist.begin();
  1.2892 +			while( it != flist.end() ) 
  1.2893 +			{
  1.2894 +				fn = *it;
  1.2895 +				bo->addFloatImage();
  1.2896 +				// TODO check if load was successful
  1.2897 +				bo->getLastFloatImage()->load(*it);
  1.2898 +				bo->getLastFloatImage()->setOriginalFilename(fn);
  1.2899 +				++it;
  1.2900 +			}
  1.2901 +
  1.2902  			mapCenter->reposition();
  1.2903  			adjustCanvasSize();
  1.2904  			canvas()->update();
  1.2905  		}
  1.2906 +		delete (p);
  1.2907 +		delete (fd);
  1.2908  	}
  1.2909  }
  1.2910  
  1.2911 @@ -2506,10 +2873,10 @@
  1.2912  	if (selection && 
  1.2913  		(typeid(*selection) == typeid(FloatImageObj)) )
  1.2914  	{
  1.2915 -		FloatImageObj *fio=((FloatImageObj*)(selection));
  1.2916 +		FloatImageObj *fio=((FloatImageObj*)selection);
  1.2917  		const char* fmt = saveImageFormatMenu->text(item);
  1.2918  
  1.2919 -		QFileDialog *fd=new QFileDialog( this, tr("vym - save image as") + fmt);
  1.2920 +		Q3FileDialog *fd=new Q3FileDialog( this, tr("vym - save image as") + fmt);
  1.2921  		fd->addFilter ("PNG (*.png)");
  1.2922  		fd->addFilter ("BMP (*.bmp)");
  1.2923  		fd->addFilter ("XBM (*.xbm)");
  1.2924 @@ -2518,8 +2885,8 @@
  1.2925  		fd->addFilter ("GIF (*.gif)");
  1.2926  		fd->addFilter ("PNM (*.pnm)");
  1.2927  		fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
  1.2928 -		fd->setCaption(tr("vym - Save image as ") + fmt);
  1.2929 -		fd->setMode( QFileDialog::AnyFile );
  1.2930 +		fd->setCaption(__VYM " - " +tr("Save image as %1").arg(fmt));
  1.2931 +		fd->setMode( Q3FileDialog::AnyFile );
  1.2932  		fd->setSelection (fio->getOriginalFilename());
  1.2933  		fd->show();
  1.2934  
  1.2935 @@ -2528,10 +2895,9 @@
  1.2936  		{
  1.2937  			if (QFile (fd->selectedFile()).exists() )
  1.2938  			{
  1.2939 -				QMessageBox mb( "VYM",
  1.2940 -					tr("The file ") + fd->selectedFile() + 
  1.2941 -					tr(" exists already. "
  1.2942 -					"Do you want to overwrite it?"),
  1.2943 +				QMessageBox mb( __VYM,
  1.2944 +					tr("The file %1 exists already.\n"
  1.2945 +					"Do you want to overwrite it?").arg(fd->selectedFile()),
  1.2946  				QMessageBox::Warning,
  1.2947  				QMessageBox::Yes | QMessageBox::Default,
  1.2948  				QMessageBox::Cancel | QMessageBox::Escape,
  1.2949 @@ -2555,17 +2921,6 @@
  1.2950  	}
  1.2951  }
  1.2952  
  1.2953 -void MapEditor::toggleFloatExport()
  1.2954 -{
  1.2955 -	if (selection && 
  1.2956 -		(typeid(*selection) == typeid(FloatImageObj))|| 
  1.2957 -		(typeid(*selection) == typeid(FloatObj)) )
  1.2958 -	{
  1.2959 -		FloatImageObj *fio=((FloatImageObj*)(selection));
  1.2960 -		fio->setFloatExport (actionEditToggleFloatExport->isOn() );
  1.2961 -	}
  1.2962 -}
  1.2963 -
  1.2964  void MapEditor::setFrame(const FrameType &t)
  1.2965  {
  1.2966  	if (selection && 
  1.2967 @@ -2578,6 +2933,33 @@
  1.2968  	}
  1.2969  }
  1.2970  
  1.2971 +void MapEditor::setIncludeImagesVer(bool b)
  1.2972 +{
  1.2973 +	if (selection && 
  1.2974 +		(typeid(*selection) == typeid(BranchObj)) || 
  1.2975 +		(typeid(*selection) == typeid(MapCenterObj))  )
  1.2976 +		((BranchObj*)selection)->setIncludeImagesVer(b);
  1.2977 +		mapCenter->reposition();
  1.2978 +}
  1.2979 +
  1.2980 +void MapEditor::setIncludeImagesHor(bool b)
  1.2981 +{
  1.2982 +	if (selection && 
  1.2983 +		(typeid(*selection) == typeid(BranchObj)) || 
  1.2984 +		(typeid(*selection) == typeid(MapCenterObj))  )
  1.2985 +		((BranchObj*)selection)->setIncludeImagesHor(b);
  1.2986 +		mapCenter->reposition();
  1.2987 +}
  1.2988 +
  1.2989 +void MapEditor::setHideLinkUnselected (bool b)
  1.2990 +{
  1.2991 +	if (selection && 
  1.2992 +		(typeid(*selection) == typeid(BranchObj)) || 
  1.2993 +		(typeid(*selection) == typeid(MapCenterObj))  ||
  1.2994 +		(typeid(*selection) == typeid(FloatImageObj)) )
  1.2995 +		selection->setHideLinkUnselected(b);
  1.2996 +}
  1.2997 +
  1.2998  void MapEditor::importDir(BranchObj *dst, QDir d)
  1.2999  {
  1.3000  	if (selection && 
  1.3001 @@ -2588,41 +2970,42 @@
  1.3002  		
  1.3003  		// Traverse directories
  1.3004  		d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
  1.3005 -		const QFileInfoList *dirlist = d.entryInfoList();
  1.3006 -		QFileInfoListIterator itdir( *dirlist );
  1.3007 -		QFileInfo *fi;
  1.3008 -
  1.3009 -		while ( (fi = itdir.current()) != 0 ) 
  1.3010 +		QFileInfoList list = d.entryInfoList();
  1.3011 +		QFileInfo fi;
  1.3012 +
  1.3013 +		for (int i = 0; i < list.size(); ++i) 
  1.3014  		{
  1.3015 -			if (fi->fileName() != "." && fi->fileName() != ".." )
  1.3016 +			fi=list.at(i);
  1.3017 +			if (fi.fileName() != "." && fi.fileName() != ".." )
  1.3018  			{
  1.3019  				dst->addBranch();
  1.3020  				bo=dst->getLastBranch();
  1.3021 -				bo->setHeading (fi->fileName() );
  1.3022 -				bo->setColor (QColor("blue"),false);
  1.3023 +				bo->setHeading (fi.fileName() );
  1.3024 +				bo->setColor (QColor("blue"));
  1.3025  				bo->toggleScroll();
  1.3026 -				if ( !d.cd(fi->fileName()) ) 
  1.3027 -					QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory"));
  1.3028 +				if ( !d.cd(fi.fileName()) ) 
  1.3029 +					QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
  1.3030  				else 
  1.3031  				{
  1.3032 +					// Recursively add subdirs
  1.3033  					importDir (bo,d);
  1.3034  					d.cdUp();
  1.3035  				}
  1.3036  			}	
  1.3037 -			++itdir;
  1.3038  		}		
  1.3039  		// Traverse files
  1.3040  		d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
  1.3041 -		const QFileInfoList *filelist = d.entryInfoList();
  1.3042 -		QFileInfoListIterator itfile( *filelist );
  1.3043 -
  1.3044 -		while ( (fi = itfile.current()) != 0 ) 
  1.3045 +		list = d.entryInfoList();
  1.3046 +
  1.3047 +		for (int i = 0; i < list.size(); ++i) 
  1.3048  		{
  1.3049 +			fi=list.at(i);
  1.3050  			dst->addBranch();
  1.3051  			bo=dst->getLastBranch();
  1.3052 -			bo->setHeading (fi->fileName() );
  1.3053 -			bo->setColor (QColor("black"),false);
  1.3054 -			++itfile;
  1.3055 +			bo->setHeading (fi.fileName() );
  1.3056 +			bo->setColor (QColor("black"));
  1.3057 +			if (fi.fileName().right(4) == ".vym" )
  1.3058 +				bo->setVymLink (fi.filePath());
  1.3059  		}	
  1.3060  	}		
  1.3061  }
  1.3062 @@ -2633,16 +3016,16 @@
  1.3063  		(typeid(*selection) == typeid(BranchObj)) || 
  1.3064  		(typeid(*selection) == typeid(MapCenterObj))  )
  1.3065  	{
  1.3066 -		QFileDialog *fd=new QFileDialog( this,tr("VYM - Choose directory structur to import"));
  1.3067 -		fd->setMode (QFileDialog::DirectoryOnly);
  1.3068 +		Q3FileDialog *fd=new Q3FileDialog( this,__VYM " - " +tr("Choose directory structure to import"));
  1.3069 +		fd->setMode (Q3FileDialog::DirectoryOnly);
  1.3070  		fd->addFilter (QString (tr("vym map") + " (*.vym)"));
  1.3071 -		fd->setCaption(tr("VYM - Choose directory structur to import"));
  1.3072 +		fd->setCaption(__VYM " - " +tr("Choose directory structure to import"));
  1.3073  		fd->show();
  1.3074  
  1.3075  		QString fn;
  1.3076  		if ( fd->exec() == QDialog::Accepted )
  1.3077  		{
  1.3078 -			BranchObj *bo=((BranchObj*)(selection));
  1.3079 +			BranchObj *bo=((BranchObj*)selection);
  1.3080  			importDir (bo,QDir(fd->selectedFile()) );
  1.3081  			mapCenter->reposition();
  1.3082  			adjustCanvasSize();
  1.3083 @@ -2651,20 +3034,119 @@
  1.3084  	}	
  1.3085  }
  1.3086  
  1.3087 +void MapEditor::followXLink(int i)
  1.3088 +{
  1.3089 +	if (selection && 
  1.3090 +		(typeid(*selection) == typeid(BranchObj)) || 
  1.3091 +		(typeid(*selection) == typeid(MapCenterObj))  )
  1.3092 +	{
  1.3093 +		BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
  1.3094 +		if (bo) 
  1.3095 +		{
  1.3096 +			selection->unselect();
  1.3097 +			selection=bo;
  1.3098 +			selection->select();
  1.3099 +			ensureSelectionVisible();
  1.3100 +		}
  1.3101 +	}
  1.3102 +}
  1.3103 +
  1.3104 +void MapEditor::editXLink(int i)
  1.3105 +{
  1.3106 +	if (selection && 
  1.3107 +		(typeid(*selection) == typeid(BranchObj)) || 
  1.3108 +		(typeid(*selection) == typeid(MapCenterObj))  )
  1.3109 +	{
  1.3110 +		XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
  1.3111 +		if (xlo) 
  1.3112 +		{
  1.3113 +			EditXLinkDialog dia;
  1.3114 +			dia.setXLink (xlo);
  1.3115 +			dia.setSelection(selection);
  1.3116 +			if (dia.exec() == QDialog::Accepted)
  1.3117 +			{
  1.3118 +				if (dia.useSettingsGlobal() )
  1.3119 +				{
  1.3120 +					setDefXLinkColor (xlo->getColor() );
  1.3121 +					setDefXLinkWidth (xlo->getWidth() );
  1.3122 +				}
  1.3123 +				if (dia.deleteXLink())
  1.3124 +					((BranchObj*)selection)->deleteXLinkAt(i);
  1.3125 +				saveState("Edit xLink");	//TODO undoCommand
  1.3126 +			}
  1.3127 +		}	
  1.3128 +	}
  1.3129 +}
  1.3130 +
  1.3131  void MapEditor::testFunction()
  1.3132  {
  1.3133  	cout << "MapEditor::testFunction() called\n";
  1.3134 +
  1.3135 +	mapCenter->positionBBox();
  1.3136 +	return;
  1.3137 +
  1.3138 +	WarningDialog dia;
  1.3139 +	dia.setCancelButton (true);
  1.3140 +	dia.setText("This is a longer \nWarning");
  1.3141 +	dia.setCaption("Warning: Flux problem");
  1.3142 +	dia.setShowAgainName("/vym/warnings/mapeditor");
  1.3143 +	if (dia.exec()==QDialog::Accepted)
  1.3144 +		cout << "accepted!\n";
  1.3145 +	else	
  1.3146 +		cout << "canceled!\n";
  1.3147 +	return;
  1.3148 +
  1.3149 +	QString ub=vymBaseDir.path()+"/scripts/update-bookmarks";
  1.3150 +	Q3Process *proc = new Q3Process( this );
  1.3151 +	proc->addArgument(ub);
  1.3152 +
  1.3153 +	if ( !proc->start() ) 
  1.3154 +	{
  1.3155 +		QMessageBox::warning(0, 
  1.3156 +			tr("Warning"),
  1.3157 +			tr("Couldn't find script %1\nto notifiy Browsers of changed bookmarks.").arg(ub));
  1.3158 +	}	
  1.3159 +
  1.3160 +	
  1.3161 +/*
  1.3162 +	if (hidemode==HideNone)
  1.3163 +	{
  1.3164 +		setHideTmpMode (HideExport);
  1.3165 +		mapCenter->calcBBoxSizeWithChilds();
  1.3166 +		QRect totalBBox=mapCenter->getTotalBBox();
  1.3167 +		QRect mapRect=totalBBox;
  1.3168 +		QCanvasRectangle *frame=NULL;
  1.3169 +
  1.3170 +		cout << "  map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
  1.3171 +	
  1.3172 +		mapRect.setRect (totalBBox.x(), totalBBox.y(), 
  1.3173 +			totalBBox.width(), totalBBox.height());
  1.3174 +		frame=new QCanvasRectangle (mapRect,mapCanvas);
  1.3175 +		frame->setBrush (QColor(white));
  1.3176 +		frame->setPen (QColor(black));
  1.3177 +		frame->setZ(0);
  1.3178 +		frame->show();    
  1.3179 +	}	
  1.3180 +	else	
  1.3181 +	{
  1.3182 +		setHideTmpMode (HideNone);
  1.3183 +	}	
  1.3184 +	cout <<"  hidemode="<<hidemode<<endl;
  1.3185 +	*/
  1.3186  }
  1.3187  
  1.3188  void MapEditor::ensureSelectionVisible()
  1.3189  {
  1.3190 -	LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
  1.3191 -	QPoint p;
  1.3192 -	if (selection->getOrientation() == OrientLeftOfCenter)
  1.3193 -		p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
  1.3194 -	else	
  1.3195 -		p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
  1.3196 -	ensureVisible (p.x(), p.y() );
  1.3197 +	if (selection)
  1.3198 +	{
  1.3199 +		LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
  1.3200 +		QPoint p;
  1.3201 +		if (selection->getOrientation() == OrientLeftOfCenter)
  1.3202 +			p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
  1.3203 +		else	
  1.3204 +			p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
  1.3205 +		ensureVisible (p.x(), p.y() );
  1.3206 +	}
  1.3207  
  1.3208  }
  1.3209  
  1.3210 @@ -2719,78 +3201,129 @@
  1.3211  		updateActions();
  1.3212  		canvasContextMenu->popup(e->globalPos() );
  1.3213      } 
  1.3214 +	e->accept();
  1.3215  }
  1.3216  
  1.3217  void MapEditor::contentsMousePressEvent(QMouseEvent* e)
  1.3218  {
  1.3219 +	// Ignore right clicks, these will go to context menus
  1.3220 +	if (e->button() == Qt::RightButton )
  1.3221 +	{
  1.3222 +		e->ignore();
  1.3223 +		return;
  1.3224 +	}
  1.3225 +
  1.3226  	// Finish open lineEdits
  1.3227 -	if (lineedit) finishedLineEditNoSave();
  1.3228 +	if (lineedit) finishedLineEdit();
  1.3229  	
  1.3230      QPoint p = inverseWorldMatrix().map(e->pos());
  1.3231      LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
  1.3232  	
  1.3233 -	// Special case: CTRL is pressed, don't select anything
  1.3234 -	if (e->state() & QMouseEvent::ControlButton)
  1.3235 +	e->accept();
  1.3236 +
  1.3237 +	//Take care of clickdesystem flags _or_ modifier modes
  1.3238 +	//
  1.3239 +	if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
  1.3240 +		typeid(*lmo)==typeid(MapCenterObj) ))
  1.3241  	{
  1.3242 -		pickingColor=true;
  1.3243 -		setCursor (pickColorCursor);
  1.3244 -		return;
  1.3245 +		QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
  1.3246 +		if (!foname.isEmpty())
  1.3247 +		{
  1.3248 +			// systemFlag clicked
  1.3249 +			select (lmo);
  1.3250 +			if (foname=="url") 
  1.3251 +			{
  1.3252 +				if (e->state() & Qt::ControlModifier)
  1.3253 +					mainWindow->editOpenURLTab();
  1.3254 +				else	
  1.3255 +					mainWindow->editOpenURL();
  1.3256 +			}	
  1.3257 +			else if (foname=="vymLink")
  1.3258 +			{
  1.3259 +				mainWindow->editOpenVymLink();
  1.3260 +				// tabWidget may change, better return now
  1.3261 +				// before segfaulting...
  1.3262 +			} else if (foname=="note")
  1.3263 +				mainWindow->windowToggleNoteEditor();
  1.3264 +			else if (foname=="hideInExport")		
  1.3265 +				toggleHideExport();
  1.3266 +			return;	
  1.3267 +		} 
  1.3268 +	} 
  1.3269 +	// No system flag clicked, take care of modmodes
  1.3270 +
  1.3271 +	// Special case: CTRL is pressed
  1.3272 +	if (e->state() & Qt::ControlModifier)
  1.3273 +	{
  1.3274 +		if (actionModModeColor->isOn())
  1.3275 +		{
  1.3276 +				pickingColor=true;
  1.3277 +				setCursor (pickColorCursor);
  1.3278 +				return;
  1.3279 +		} 
  1.3280 +		if (actionModModeLink->isOn())
  1.3281 +		{	
  1.3282 +			BranchObj *bo_begin=NULL;
  1.3283 +			if (lmo)
  1.3284 +				bo_begin=(BranchObj*)(lmo);
  1.3285 +			else	
  1.3286 +				if (selection && 
  1.3287 +					((typeid(*selection) == typeid(BranchObj)) || 
  1.3288 +					(typeid(*selection) == typeid(MapCenterObj)))  )
  1.3289 +				bo_begin=(BranchObj*)selection;
  1.3290 +			if (bo_begin)	
  1.3291 +			{
  1.3292 +				drawingLink=true;
  1.3293 +				linkingObj_src=bo_begin;
  1.3294 +				tmpXLink=new XLinkObj (mapCanvas);
  1.3295 +				tmpXLink->setBegin (bo_begin);
  1.3296 +				tmpXLink->setEnd   (p);
  1.3297 +				tmpXLink->setColor(defXLinkColor);
  1.3298 +				tmpXLink->setWidth(defXLinkWidth);
  1.3299 +				tmpXLink->updateXLink();
  1.3300 +				tmpXLink->setVisibility (true);
  1.3301 +				return;
  1.3302 +			} 
  1.3303 +		}
  1.3304  	}
  1.3305 -
  1.3306      if (lmo) 
  1.3307 -	{	// MapObj was found
  1.3308 -		if (selection != lmo)
  1.3309 +	{	
  1.3310 +		select (lmo);
  1.3311 +		// Left Button	    Move Branches
  1.3312 +		if (e->button() == Qt::LeftButton )
  1.3313  		{
  1.3314 -			// select the MapObj
  1.3315 -			if (selection) selection->unselect();
  1.3316 -			selection=lmo;
  1.3317 -			selection->select();
  1.3318 -				
  1.3319 -			adjustCanvasSize();
  1.3320 -		}
  1.3321 -
  1.3322 -		// Check, if systemFlag clicked
  1.3323 -		if (typeid(*selection)==typeid(BranchObj) ||
  1.3324 -			typeid(*selection)==typeid(MapCenterObj) )
  1.3325 -		{
  1.3326 -			QString foname=((BranchObj*)(selection))->getSystemFlagName(p);
  1.3327 -			if (!foname.isEmpty())
  1.3328 -			{
  1.3329 -				// Do not move, if systemFlag clicked
  1.3330 -				if (foname=="url") 
  1.3331 -					openURL();
  1.3332 -				else
  1.3333 -					if (foname=="vymLink")
  1.3334 -					{
  1.3335 -						mainWindow->editOpenVymLink();
  1.3336 -						// tabWidget may change, better return now
  1.3337 -						// before segfaulting...
  1.3338 -						return;
  1.3339 -					} else
  1.3340 -						if (foname=="note")
  1.3341 -							mainWindow->windowToggleNoteEditor();
  1.3342 -			}			
  1.3343 -		}	
  1.3344 -			
  1.3345 -		// Left Button	    Move Branches
  1.3346 -		if (e->button() == QMouseEvent::LeftButton )
  1.3347 -		{
  1.3348 -			movingObj=selection;	
  1.3349  			movingObj_start.setX( p.x() - selection->x() );	
  1.3350  			movingObj_start.setY( p.y() - selection->y() );	
  1.3351 +			movingObj_orgPos.setX (lmo->x() );
  1.3352 +			movingObj_orgPos.setY (lmo->y() );
  1.3353 +
  1.3354 +			// If modMode==copy, then we want to "move" the _new_ object around
  1.3355 +			// then we need the offset from p to the _old_ selection, because of tmp
  1.3356 +			if (actionModModeCopy->isOn() &&
  1.3357 +				e->state() & Qt::ControlModifier)
  1.3358 +			{
  1.3359 +				if (typeid(*selection)==typeid(BranchObj) )
  1.3360 +				{
  1.3361 +					copyingObj=true;
  1.3362 +					mapCenter->addBranch ((BranchObj*)selection);
  1.3363 +					unselect();
  1.3364 +					selection=mapCenter->getLastBranch();
  1.3365 +					selection->select();
  1.3366 +					mapCenter->reposition();
  1.3367 +				}
  1.3368 +			}	
  1.3369 +			movingObj=selection;	
  1.3370  		} else
  1.3371  			// Middle Button    Toggle Scroll
  1.3372  			// (On Mac OS X this won't work, but we still have 
  1.3373  			// a button in the toolbar)
  1.3374 -			if (e->button() == QMouseEvent::MidButton )
  1.3375 -			{
  1.3376 +			if (e->button() == Qt::MidButton )
  1.3377  				toggleScroll();
  1.3378 -			} 
  1.3379  		updateActions();
  1.3380  	} else 
  1.3381  	{ // No MapObj found, we are on the Canvas itself
  1.3382  		// Left Button	    move Pos of CanvasView
  1.3383 -		if (e->button() == QMouseEvent::LeftButton )
  1.3384 +		if (e->button() == Qt::LeftButton )
  1.3385  		{
  1.3386  			movingObj=NULL;	// move Content not Obj
  1.3387  			movingObj_start=e->globalPos();
  1.3388 @@ -2803,14 +3336,19 @@
  1.3389  
  1.3390  void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
  1.3391  {
  1.3392 +	QPoint p = inverseWorldMatrix().map(e->pos());
  1.3393 +
  1.3394      // Move the selected MapObj
  1.3395      if ( selection && movingObj) 
  1.3396      {	
  1.3397 -		QPoint p = inverseWorldMatrix().map(e->pos());
  1.3398 +		// To avoid jumping of the CanvasView, only 
  1.3399 +		// ensureSelectionVisible, if not tmp linked
  1.3400 +		if (!selection->hasParObjTmp())
  1.3401 +			ensureSelectionVisible ();
  1.3402  		
  1.3403 -		// Now move the selection, but add relative position (movingObj_start) 
  1.3404 -		// where selection 
  1.3405 -		// was chosen with mousepointer. (This avoids flickering resp. jumping 
  1.3406 +		// Now move the selection, but add relative position 
  1.3407 +		// (movingObj_start) where selection was chosen with 
  1.3408 +		// mousepointer. (This avoids flickering resp. jumping 
  1.3409  		// of selection back to absPos)
  1.3410  		
  1.3411  		LinkableMapObj *lmosel;
  1.3412 @@ -2822,21 +3360,17 @@
  1.3413  
  1.3414  		if (typeid(*selection) == typeid(FloatImageObj))
  1.3415  		{
  1.3416 -			setChanged();
  1.3417 -			saveState();
  1.3418 -			FloatObj *fo=(FloatObj*)(selection);
  1.3419 -			if (fo->getLinkStyle()==StyleUndef) 
  1.3420 -			{
  1.3421 -				fo->setLinkStyle(fo->getDefLinkStyle());
  1.3422 -				fo->setLinkColor(fo->getParObj()->getLinkColor());
  1.3423 -			}	
  1.3424 +			FloatObj *fo=(FloatObj*)selection;
  1.3425 +			saveState(
  1.3426 +				"move "+qpointToString(movingObj_orgPos),fo->getSelectString() ,
  1.3427 +				QString("Move %1").arg(getName(selection)));
  1.3428  			fo->move   (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.3429  			fo->setRelPos();
  1.3430  			fo->reposition();
  1.3431  
  1.3432  			// Relink float to new mapcenter or branch, if shift is pressed	
  1.3433  			// Only relink, if selection really has a new parent
  1.3434 -			if ( (e->state() & QMouseEvent::ShiftButton) && lmo &&
  1.3435 +			if ( (e->state() & Qt::ShiftModifier) && lmo &&
  1.3436  				( (typeid(*lmo)==typeid(BranchObj)) ||
  1.3437  				  (typeid(*lmo)==typeid(MapCenterObj)) ) &&
  1.3438  				( lmo != fo->getParObj())  
  1.3439 @@ -2844,6 +3378,7 @@
  1.3440  			{
  1.3441  				if (typeid(*fo) == typeid(FloatImageObj)) 
  1.3442  				{
  1.3443 +					saveState(QString("Relink %1 to %2").arg(getName(fo)).arg(getName(lmo) ) );
  1.3444  					FloatImageObj *fio=(FloatImageObj*)(fo);
  1.3445  					((BranchObj*)(lmo))->addFloatImage (fio);
  1.3446  					fio->unselect();
  1.3447 @@ -2854,18 +3389,13 @@
  1.3448  					selection=(LinkableMapObj*)(fio);
  1.3449  					selection->select();
  1.3450  					movingObj=(MapObj*)(fio);
  1.3451 -					// setLinkStyle calls updateLink, only set it once
  1.3452 -					if (fio->getLinkStyle()!=fio->getDefLinkStyle() ) 
  1.3453 -						fio->setLinkStyle (fio->getDefLinkStyle());
  1.3454 -
  1.3455  				}	
  1.3456 -				// TODO if (typeid(*selection) == typeid(FloatTextObj))
  1.3457  			}
  1.3458  		} else	// selection != a FloatObj
  1.3459  		{
  1.3460  			if (lmosel->getDepth()==0)
  1.3461  			{
  1.3462 -				if (e->state() == (LeftButton | !ShiftButton)) 
  1.3463 +				if (e->state() == Qt::LeftButton && e->modifiers()==Qt::ShiftModifier) 
  1.3464  					// If mapCenter is moved, move all the rest by default, too.
  1.3465  					mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.3466  				else	
  1.3467 @@ -2875,8 +3405,6 @@
  1.3468  				if (lmosel->getDepth()==1)
  1.3469  				{
  1.3470  					// depth==1, mainbranch
  1.3471 -					setChanged();
  1.3472 -					saveState(PartOfMap,lmosel);
  1.3473  					lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.3474  				} else
  1.3475  				{
  1.3476 @@ -2884,36 +3412,31 @@
  1.3477  					if (lmosel->getOrientation() == OrientLeftOfCenter)
  1.3478  						// Add width of bbox here, otherwise alignRelTo will cause jumping around
  1.3479  						lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(), 
  1.3480 -							p.y()-movingObj_start.y() );		
  1.3481 +							p.y()-movingObj_start.y() +lmosel->getTopPad() );		
  1.3482  					else	
  1.3483 -						lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
  1.3484 +						lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
  1.3485  				} 
  1.3486  				// reposition subbranch
  1.3487  				lmosel->reposition();	
  1.3488 -				ensureSelectionVisible();
  1.3489 +				//ensureSelectionVisible();
  1.3490  
  1.3491  				if (lmo && (lmo!=selection) &&  
  1.3492  					(typeid(*lmo) == typeid(BranchObj) ||
  1.3493  					(typeid(*lmo) == typeid(MapCenterObj) )
  1.3494  					) )
  1.3495  				{
  1.3496 -					if (e->state() & QMouseEvent::ControlButton)
  1.3497 +					if (e->state() & Qt::ControlModifier)
  1.3498  					{
  1.3499  						// Special case: CTRL to link below lmo
  1.3500  						lmosel->setParObjTmp (lmo,p,+1);
  1.3501  					}
  1.3502 -					else if (e->state() & QMouseEvent::ShiftButton)
  1.3503 +					else if (e->state() & Qt::ShiftModifier)
  1.3504  						lmosel->setParObjTmp (lmo,p,-1);
  1.3505  					else
  1.3506  						lmosel->setParObjTmp (lmo,p,0);
  1.3507  				} else	
  1.3508  				{
  1.3509 -					if (lmo &&(lmo==selection))   
  1.3510 -						// Could link to myself (happens sometimes...)
  1.3511 -						lmosel->unsetParObjTmp();
  1.3512 -					if (!lmo)  
  1.3513 -						// no Obj under selection, go back to original Parent
  1.3514 -						lmosel->unsetParObjTmp();
  1.3515 +					lmosel->unsetParObjTmp();
  1.3516  				}		
  1.3517  			} // depth>0
  1.3518  
  1.3519 @@ -2923,8 +3446,15 @@
  1.3520  		return;
  1.3521  	} // selection && moving_obj
  1.3522  		
  1.3523 +	// Draw a link from one branch to another
  1.3524 +	if (drawingLink)
  1.3525 +	{
  1.3526 +		 tmpXLink->setEnd (p);
  1.3527 +		 tmpXLink->updateXLink();
  1.3528 +	}	 
  1.3529 +	
  1.3530      // Move CanvasView 
  1.3531 -    if (!movingObj && !pickingColor) 
  1.3532 +    if (!movingObj && !pickingColor &&!drawingLink) 
  1.3533  	{
  1.3534  		QPoint p=e->globalPos();
  1.3535  		movingVec.setX(-p.x() + movingObj_start.x() );
  1.3536 @@ -2944,37 +3474,62 @@
  1.3537  	if (pickingColor)
  1.3538  	{
  1.3539  		pickingColor=false;
  1.3540 -		setCursor (ArrowCursor);
  1.3541 +		setCursor (Qt::ArrowCursor);
  1.3542  		// Check if we are over another branch
  1.3543  		dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
  1.3544  		if (dst && selection) 
  1.3545  		{	
  1.3546 -			if (e->state() & QMouseEvent::ShiftButton)
  1.3547 +			if (e->state() & Qt::ShiftModifier)
  1.3548  			{
  1.3549 -				((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),false);
  1.3550 -				((BranchObj*)(selection))->setLinkColor ();
  1.3551 +				((BranchObj*)selection)->setColor (((BranchObj*)(dst))->getColor());
  1.3552 +				((BranchObj*)selection)->setLinkColor ();
  1.3553  			}	
  1.3554  			else	
  1.3555  			{
  1.3556 -				((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),true);
  1.3557 -				((BranchObj*)(selection))->setLinkColor ();
  1.3558 +				((BranchObj*)selection)->setColorChilds (((BranchObj*)(dst))->getColor());
  1.3559 +				((BranchObj*)selection)->setLinkColor ();
  1.3560  			}	
  1.3561  		} 
  1.3562  		return;
  1.3563  	}
  1.3564 +
  1.3565 +	// Have we been drawing a link?
  1.3566 +	if (drawingLink)
  1.3567 +	{
  1.3568 +		drawingLink=false;
  1.3569 +		// Check if we are over another branch
  1.3570 +		dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
  1.3571 +		if (dst && selection) 
  1.3572 +		{	
  1.3573 +			tmpXLink->setEnd ( ((BranchObj*)(dst)) );
  1.3574 +			tmpXLink->updateXLink();
  1.3575 +			tmpXLink->activate();
  1.3576 +			saveState(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );	//TODO undoCommand
  1.3577 +		} else
  1.3578 +		{
  1.3579 +			delete(tmpXLink);
  1.3580 +			tmpXLink=NULL;
  1.3581 +		}
  1.3582 +		return;
  1.3583 +	}
  1.3584 +	
  1.3585      // Have we been moving something?
  1.3586      if ( selection && movingObj ) 
  1.3587      {	
  1.3588 +		// Moved FloatObj? Maybe we need to reposition
  1.3589 +		if(typeid(*selection)==typeid (FloatImageObj))
  1.3590 +		{
  1.3591 +			selection->getParObj()->requestReposition();
  1.3592 +			mapCenter->reposition();
  1.3593 +		}	
  1.3594 +
  1.3595  		// Check if we are over another branch, but ignore 
  1.3596  		// any found LMOs, which are FloatObjs
  1.3597  		dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), 
  1.3598 -			((LinkableMapObj*)(selection)) );
  1.3599 -
  1.3600 -		if (dst &&
  1.3601 -		(typeid(*dst)!=typeid(BranchObj)&&typeid(*dst)!=typeid(MapCenterObj))) 
  1.3602 -		{
  1.3603 +			((LinkableMapObj*)selection) );
  1.3604 +
  1.3605 +		if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj))) 
  1.3606  			dst=NULL;
  1.3607 -		}	
  1.3608  		
  1.3609  		// Now check, if we have been moving a branch 
  1.3610  		if (typeid(*selection) == typeid(BranchObj)  )
  1.3611 @@ -2983,40 +3538,43 @@
  1.3612  			QPoint savePos=QPoint (selection->x(),selection->y() );
  1.3613  
  1.3614  			// Reset the temporary drawn link to the original one
  1.3615 -			((LinkableMapObj*)(selection))->unsetParObjTmp();
  1.3616 -
  1.3617 +			((LinkableMapObj*)selection)->unsetParObjTmp();
  1.3618 +
  1.3619 +
  1.3620 +			copyingObj=false;	
  1.3621  			if (dst ) 
  1.3622 -			{   
  1.3623 -				setChanged();
  1.3624 -				saveState();
  1.3625 +			{
  1.3626 +				BranchObj* bs=((BranchObj*)selection);
  1.3627 +				QString undoCom="linkBranchToPos (\""+ 
  1.3628 +					(bs->getParObj())->getSelectString()+
  1.3629 +					"\","+
  1.3630 +					QString("%1").arg(bs->getNum())+
  1.3631 +					","+
  1.3632 +					QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+
  1.3633 +					")";
  1.3634  				// TODO we also could check, if dest and src are on same branch,
  1.3635  				// then it would be sufficient to saveState of this branch
  1.3636  
  1.3637 -				// FIXME better introduce BO::move  to speed up and keep IDs
  1.3638 -				copy();			// copy selection to clipboard
  1.3639 -				cutNoSave();	// remove selection here
  1.3640 -
  1.3641 -				selection->unselect();	
  1.3642 -				selection=dst;
  1.3643  				// Modifiers allow to insert above/below dst
  1.3644 -				if (e->state() & QMouseEvent::ShiftButton)
  1.3645 +				if (e->state() & Qt::ShiftModifier)
  1.3646  				{
  1.3647 -					selection=pasteAtNoSave (((BranchObj*)(dst))->getNum());
  1.3648 -					if (selection) selection->select();
  1.3649 -				}	
  1.3650 -				else if (e->state() & QMouseEvent::ControlButton)
  1.3651 +					bs->moveBranchTo ( (BranchObj*)(dst->getParObj()), ((BranchObj*)(dst))->getNum());
  1.3652 +				} else 
  1.3653 +				if (e->state() & Qt::ControlModifier)
  1.3654 +			{
  1.3655 +					bs->moveBranchTo ( (BranchObj*)(dst->getParObj()), ((BranchObj*)(dst))->getNum()+1);
  1.3656 +				} else	
  1.3657  				{
  1.3658 -					selection=pasteAtNoSave (((BranchObj*)(dst))->getNum()+1);
  1.3659 -					if (selection) selection->select();
  1.3660 -				}	
  1.3661 -				else	
  1.3662 -				{
  1.3663 -					selection=pasteNoSave();
  1.3664 -					selection->select();
  1.3665 +					bs->moveBranchTo ((BranchObj*)(dst),-1);
  1.3666  					if (dst->getDepth()==0) 
  1.3667 -						((BranchObj*)(selection))->move (savePos);
  1.3668 -				}	
  1.3669 -			} 
  1.3670 +						bs->move (savePos);
  1.3671 +				} 
  1.3672 +				saveState (undoCom,bs->getSelectString(),QString("Relink %1 to %2").arg(getName(bs)).arg(getName(dst)) );
  1.3673 +			} else
  1.3674 +				if (selection->getDepth()==1)
  1.3675 +					// If we have moved mainbranch only save endposition
  1.3676 +					saveState("move "+qpointToString(movingObj_orgPos), selection->getSelectString(), QString("Move %1 to %2").arg(getName(selection)).arg(qpointToString(movingObj_orgPos)));
  1.3677 +			
  1.3678  			// Draw the original link, before selection was moved around
  1.3679  			mapCenter->reposition();
  1.3680  		}
  1.3681 @@ -3025,17 +3583,17 @@
  1.3682  		canvas()->update();
  1.3683  		movingObj=NULL;		
  1.3684  	} else 
  1.3685 -	{	// maybe we moved View: set old cursor
  1.3686 -		setCursor (ArrowCursor);
  1.3687 -    }
  1.3688 +		// maybe we moved View: set old cursor
  1.3689 +		setCursor (Qt::ArrowCursor);
  1.3690 +    
  1.3691  }
  1.3692  
  1.3693  void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
  1.3694  {
  1.3695  	// Finish open lineEdits
  1.3696 -	if (lineedit) finishedLineEditNoSave();
  1.3697 +	if (lineedit) finishedLineEdit();
  1.3698  	
  1.3699 -	if (e->button() == QMouseEvent::LeftButton )
  1.3700 +	if (e->button() == Qt::LeftButton )
  1.3701  	{
  1.3702  		QPoint p = inverseWorldMatrix().map(e->pos());
  1.3703  		LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
  1.3704 @@ -3044,8 +3602,6 @@
  1.3705  			if (selection) selection->unselect();
  1.3706  			selection=lmo;
  1.3707  			selection->select();
  1.3708 -			setChanged();
  1.3709 -			saveState(PartOfMap,selection);
  1.3710  			editHeading();
  1.3711  		}
  1.3712  	}
  1.3713 @@ -3053,10 +3609,239 @@
  1.3714  
  1.3715  void MapEditor::resizeEvent (QResizeEvent* e)
  1.3716  {
  1.3717 -	QCanvasView::resizeEvent( e );
  1.3718 -	
  1.3719 -	QString s="";
  1.3720 -	if (!fileName.isEmpty()) s=fileName;
  1.3721 +	Q3CanvasView::resizeEvent( e );
  1.3722  	adjustCanvasSize();
  1.3723  }
  1.3724  
  1.3725 +void MapEditor::contentsDragEnterEvent(QDragEnterEvent *event) 
  1.3726 +{
  1.3727 +
  1.3728 +//  for (unsigned int i=0;event->format(i);i++) // Debug mime type
  1.3729 +//    cerr << event->format(i) << endl;
  1.3730 +
  1.3731 +  if (selection && 
  1.3732 +      (typeid(*selection) == typeid(BranchObj)) || 
  1.3733 +      (typeid(*selection) == typeid(MapCenterObj))) {
  1.3734 +    
  1.3735 +    // If QImageDrag can decode mime type 
  1.3736 +    if (Q3ImageDrag::canDecode(event)) {
  1.3737 +      event->accept();
  1.3738 +      return;
  1.3739 +    }
  1.3740 +    
  1.3741 +    // If image are dragged from firefox 
  1.3742 +    if (event->provides("application/x-moz-file-promise-url") && 
  1.3743 +	event->provides("application/x-moz-nativeimage")) {
  1.3744 +      event->accept(true);
  1.3745 +      return;
  1.3746 +    }
  1.3747 +
  1.3748 +    // If QUriDrag can decode mime type 
  1.3749 +    if (Q3UriDrag::canDecode(event)) {
  1.3750 +      event->accept();
  1.3751 +      return;
  1.3752 +    }
  1.3753 +    
  1.3754 +	// If Uri are dragged from firefox 
  1.3755 +    if (event->provides("_NETSCAPE_URL")){
  1.3756 +      event->accept();
  1.3757 +      return;
  1.3758 +    }
  1.3759 +
  1.3760 +    // If QTextDrag can decode mime type
  1.3761 +    if (Q3TextDrag::canDecode(event)) {
  1.3762 +      event->accept();
  1.3763 +      return;
  1.3764 +    }
  1.3765 +
  1.3766 +  }
  1.3767 +  event->ignore();
  1.3768 +}
  1.3769 +
  1.3770 +bool isUnicode16(const QByteArray &d) 
  1.3771 +{
  1.3772 +  // TODO: make more precise check for unicode 16.
  1.3773 +  // Guess unicode16 if any of second bytes are zero
  1.3774 +  unsigned int length = max(0,d.size()-2)/2;
  1.3775 +  for (unsigned int i = 0; i<length ; i++)
  1.3776 +    if (d.at(i*2+1)==0) return true;
  1.3777 +  return false;
  1.3778 +}
  1.3779 +      
  1.3780 +void MapEditor::contentsDropEvent(QDropEvent *event) 
  1.3781 +{
  1.3782 +	if (selection && 
  1.3783 +      (typeid(*selection) == typeid(BranchObj)) || 
  1.3784 +      (typeid(*selection) == typeid(MapCenterObj))) 
  1.3785 +	{
  1.3786 +		bool update=false;
  1.3787 +		Q3StrList uris;
  1.3788 +		QString heading;
  1.3789 +		if (event->provides("image/png")) 
  1.3790 +		{
  1.3791 +			QPixmap pix;
  1.3792 +			if (Q3ImageDrag::decode(event, pix)) 
  1.3793 +			{
  1.3794 +				addFloatImage(pix);
  1.3795 +				event->accept();
  1.3796 +				update=true;
  1.3797 +			} else
  1.3798 +				event->ignore();
  1.3799 +
  1.3800 +		} else if (event->provides("application/x-moz-file-promise-url") && 
  1.3801 +			 event->provides("application/x-moz-nativeimage")) 
  1.3802 +		{
  1.3803 +			// Contains url to the img src in unicode16
  1.3804 +			QByteArray d = event->encodedData("application/x-moz-file-promise-url");
  1.3805 +			QString url = QString((const QChar*)d.data(),d.size()/2);
  1.3806 +			fetchImage(url);
  1.3807 +			event->accept();
  1.3808 +			update=true;
  1.3809 +		} else if (event->provides ("text/uri-list"))
  1.3810 +		{	// Uris provided e.g. by konqueror
  1.3811 +			Q3UriDrag::decode (event,uris);
  1.3812 +		} else if (event->provides ("_NETSCAPE_URL"))
  1.3813 +		{	// Uris provided by Mozilla
  1.3814 +		  QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
  1.3815 +		  uris.append(l[0]);
  1.3816 +		  heading = l[1];
  1.3817 +		} else if (event->provides("text/html")) {
  1.3818 +
  1.3819 +		  // Handels text mime types
  1.3820 +		  // Look like firefox allways handle text as unicode16 (2 bytes per char.)
  1.3821 +		  QByteArray d = event->encodedData("text/html");
  1.3822 +		  QString text;
  1.3823 +		  if (isUnicode16(d)) 
  1.3824 +		    text = QString((const QChar*)d.data(),d.size()/2);
  1.3825 +		  else 
  1.3826 +		    text = QString(d);
  1.3827 +
  1.3828 +		  textEditor->setText(text);
  1.3829 +
  1.3830 +		  event->accept();
  1.3831 +		  update=true;
  1.3832 +		} else if (event->provides("text/plain")) {
  1.3833 +		  QByteArray d = event->encodedData("text/plain");
  1.3834 +		  QString text;
  1.3835 +		  if (isUnicode16(d))
  1.3836 +		    text = QString((const QChar*)d.data(),d.size()/2);
  1.3837 +		  else 
  1.3838 +		    text = QString(d);
  1.3839 +
  1.3840 +		  textEditor->setText(text);
  1.3841 +		  
  1.3842 +		  event->accept();
  1.3843 +		  update= true;
  1.3844 +		}
  1.3845 +
  1.3846 +		if (uris.count()>0)
  1.3847 +		{
  1.3848 +			QStringList files;
  1.3849 +			QStringList urls;
  1.3850 +			QString s;
  1.3851 +			BranchObj *bo;
  1.3852 +			for (const char* u=uris.first(); u; u=uris.next())
  1.3853 +			{
  1.3854 +				bo=((BranchObj*)selection)->addBranch();
  1.3855 +				if (bo)
  1.3856 +				{
  1.3857 +					s=Q3UriDrag::uriToLocalFile(u);
  1.3858 +					if (!s.isEmpty()) 
  1.3859 +					{
  1.3860 +                       QString file = QDir::convertSeparators(s);
  1.3861 +                       heading = QFileInfo(file).baseName();
  1.3862 +                       files.append(file);
  1.3863 +                       if (file.endsWith(".vym", false))
  1.3864 +                           bo->setVymLink(file);
  1.3865 +                       else
  1.3866 +                           bo->setURL(u);
  1.3867 +                   } else 
  1.3868 +				   {
  1.3869 +                       urls.append (u);
  1.3870 +                       bo->setURL(u);
  1.3871 +                   }
  1.3872 +
  1.3873 +                   if (!heading.isEmpty())
  1.3874 +                       bo->setHeading(heading);
  1.3875 +                   else
  1.3876 +                       bo->setHeading(u);
  1.3877 +				}
  1.3878 +			}
  1.3879 +			update=true;
  1.3880 +		}
  1.3881 +
  1.3882 +		if (update) 
  1.3883 +		{
  1.3884 +			//FIXME saveState has to be called earlier for each of the drops...
  1.3885 +			saveState("Drop Event");	//TODO undo Command
  1.3886 +			mapCenter->reposition();
  1.3887 +			adjustCanvasSize();
  1.3888 +			canvas()->update();
  1.3889 +		}	
  1.3890 +	}	
  1.3891 +}
  1.3892 +
  1.3893 +void MapEditor::addFloatImage(const QPixmap &img) 
  1.3894 +{
  1.3895 +  if (selection && 
  1.3896 +      (typeid(*selection) == typeid(BranchObj)) || 
  1.3897 +      (typeid(*selection) == typeid(MapCenterObj))  )
  1.3898 +  {
  1.3899 +    BranchObj *bo=((BranchObj*)selection);
  1.3900 +    saveState(selection,QString("Add floatimage to %1").arg(getName(bo)));
  1.3901 +    //QString fn=fd->selectedFile();
  1.3902 +    //lastImageDir=fn.left(fn.findRev ("/"));
  1.3903 +    bo->addFloatImage();
  1.3904 +    // FIXME check if load was successful
  1.3905 +    bo->getLastFloatImage()->load(img);
  1.3906 +    //bo->getLastFloatImage()->setOriginalFilename(fn);
  1.3907 +    mapCenter->reposition();
  1.3908 +    adjustCanvasSize();
  1.3909 +    canvas()->update();
  1.3910 +  }
  1.3911 +}
  1.3912 +
  1.3913 +
  1.3914 +void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation */*nop*/) 
  1.3915 +{
  1.3916 +  if (!imageBuffer) imageBuffer = new QBuffer();
  1.3917 +  if (!imageBuffer->isOpen()) {
  1.3918 +    imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
  1.3919 +  }
  1.3920 +  imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
  1.3921 +}
  1.3922 +
  1.3923 +
  1.3924 +void MapEditor::imageDataFinished(Q3NetworkOperation *nop) 
  1.3925 +{
  1.3926 +	if (nop->state()==Q3NetworkProtocol::StDone) {
  1.3927 +		QPixmap img(imageBuffer->buffer());
  1.3928 +		addFloatImage(img);
  1.3929 +	}
  1.3930 +
  1.3931 +	if (imageBuffer) {
  1.3932 +		imageBuffer->close();
  1.3933 +		if (imageBuffer) {
  1.3934 +			imageBuffer->close();
  1.3935 +			delete imageBuffer;
  1.3936 +			imageBuffer = 0;
  1.3937 +		}
  1.3938 +	}
  1.3939 +}
  1.3940 +
  1.3941 +void MapEditor::fetchImage(const QString &url) 
  1.3942 +{
  1.3943 +  if (urlOperator) {
  1.3944 +    urlOperator->stop();
  1.3945 +    disconnect(urlOperator);
  1.3946 +    delete urlOperator;
  1.3947 +  }
  1.3948 +  
  1.3949 +  urlOperator = new Q3UrlOperator(url);
  1.3950 +  connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)), 
  1.3951 +	  this, SLOT(imageDataFinished(Q3NetworkOperation*)));
  1.3952 +
  1.3953 +  connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
  1.3954 +	  this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));
  1.3955 +  urlOperator->get();
  1.3956 +}