removed pixel garbage on right side of exported images release-1-12-maintained
authorinsilmaril
Thu, 17 Jul 2008 09:27:20 +0000
branchrelease-1-12-maintained
changeset 39e37153bea487
parent 29 49a910838042
child 40 394b2f297e1d
removed pixel garbage on right side of exported images
mapeditor.cpp
tex/vym.changelog
version.h
     1.1 --- a/mapeditor.cpp	Sun Jan 30 12:59:03 2005 +0000
     1.2 +++ b/mapeditor.cpp	Thu Jul 17 09:27:20 2008 +0000
     1.3 @@ -1,323 +1,121 @@
     1.4  #include "mapeditor.h"
     1.5  
     1.6 -#include <qstatusbar.h>
     1.7 -#include <qmessagebox.h>
     1.8 -#include <qapplication.h>
     1.9 -#include <qpainter.h>
    1.10 -#include <qpopupmenu.h>
    1.11 -#include <qprinter.h>
    1.12 -#include <qpaintdevicemetrics.h>
    1.13 -#include <qfile.h>
    1.14 -#include <qfiledialog.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 <qinputdialog.h>
    1.21 +#include <q3filedialog.h>
    1.22  
    1.23  #include <iostream>
    1.24 -#include <stdlib.h>
    1.25 +#include <cstdlib>
    1.26  #include <typeinfo>
    1.27  
    1.28 -#include "version.h"
    1.29 -
    1.30 -#include "xml.h"
    1.31 +#include "parser.h"
    1.32 +#include "editxlinkdialog.h"
    1.33 +#include "exports.h"
    1.34 +#include "exportxhtmldialog.h"
    1.35 +#include "extrainfodialog.h"
    1.36 +#include "file.h"
    1.37 +#include "linkablemapobj.h"
    1.38 +#include "mainwindow.h"
    1.39 +#include "misc.h"
    1.40  #include "texteditor.h"
    1.41 -#include "linkablemapobj.h"
    1.42 -#include "exports.h"
    1.43 -#include "misc.h"
    1.44 -#include "mainwindow.h"
    1.45 -#include "extrainfodialog.h"
    1.46 -#include "settings.h"
    1.47 -
    1.48 -#include "icons/flag-note.xpm"
    1.49 -#include "icons/flag-url.xpm"
    1.50 -#include "icons/flag-vymlink.xpm"	
    1.51 -#include "icons/flag-scrolled-right.xpm"
    1.52 -#include "icons/flag-tmpUnscrolled-right.xpm"
    1.53 -#include "icons/flag-questionmark.xpm"
    1.54 -#include "icons/flag-exclamationmark.xpm"
    1.55 -#include "icons/flag-hook-green.xpm"
    1.56 -#include "icons/flag-cross-red.xpm"
    1.57 -#include "icons/flag-stopsign.xpm"
    1.58 -#include "icons/flag-smiley-good.xpm"
    1.59 -#include "icons/flag-smiley-sad.xpm"
    1.60 -#include "icons/flag-clock.xpm"
    1.61 -#include "icons/flag-lamp.xpm"
    1.62 -#include "icons/flag-arrow-up.xpm"
    1.63 -#include "icons/flag-arrow-down.xpm"
    1.64 -#include "icons/flag-thumb-up.xpm"
    1.65 -#include "icons/flag-thumb-down.xpm"
    1.66 -#include "icons/flag-heart.xpm"
    1.67 -#include "icons/flag-flash.xpm"
    1.68 -#include "icons/flag-lifebelt.xpm"
    1.69 +#include "warningdialog.h"
    1.70 +#include "xml-freemind.h"
    1.71 +#include "xml-vym.h"
    1.72 +
    1.73  
    1.74  extern TextEditor *textEditor;
    1.75  extern int statusbarTime;
    1.76  extern Main *mainWindow;
    1.77 -extern FlagRowObj *systemFlagsDefault;
    1.78 +extern QString tmpVymDir;
    1.79 +extern QString clipboardDir;
    1.80 +extern QString clipboardFile;
    1.81 +extern bool clipboardEmpty;
    1.82 +extern bool debug;
    1.83  extern FlagRowObj *standardFlagsDefault;
    1.84 -extern MapEditor *clipboardME;
    1.85 -
    1.86 -extern QAction *actionFileSave;
    1.87 -extern QAction *actionEditUndo;
    1.88 -extern QAction *actionEditCopy;
    1.89 -extern QAction *actionEditCut;
    1.90 -extern QAction *actionEditPaste;
    1.91 -extern QAction *actionEditMoveUp;
    1.92 -extern QAction *actionEditMoveDown;
    1.93 -extern QAction *actionEditToggleScroll;
    1.94 -extern QAction *actionEditOpenURL;
    1.95 -extern QAction *actionEditURL;
    1.96 -extern QAction *actionEditHeading2URL;
    1.97 -extern QAction *actionEditBugzilla2URL;
    1.98 -extern QAction *actionEditOpenVymLink;
    1.99 -extern QAction *actionEditVymLink;
   1.100 -extern QAction *actionEditDeleteVymLink;
   1.101 -extern QAction *actionEditHeading;
   1.102 -extern QAction *actionEditDelete;
   1.103 -extern QAction *actionEditAddBranch;
   1.104 -extern QAction *actionEditAddBranchAbove;
   1.105 -extern QAction *actionEditAddBranchBelow;
   1.106 -extern QAction *actionEditImportAdd;
   1.107 -extern QAction *actionEditImportReplace;
   1.108 -extern QAction *actionEditSaveBranch;
   1.109 -extern QAction *actionEditSelectFirst;
   1.110 -extern QAction *actionEditSelectLast;
   1.111 -extern QAction *actionEditLoadImage;
   1.112 -extern QAction *actionEditToggleFloatExport;
   1.113 -
   1.114 -extern QAction* actionFormatPickColor;
   1.115 -extern QAction* actionFormatColorBranch;
   1.116 -extern QAction* actionFormatColorSubtree;
   1.117 -extern QAction *actionFormatLinkColorHint;
   1.118 -extern QAction *actionFormatBackColor;
   1.119 -extern QAction *actionFormatLinkColor;
   1.120 -
   1.121 -extern QActionGroup *actionGroupFormatFrameTypes;
   1.122 -extern QAction *actionFormatFrameNone;
   1.123 -extern QAction *actionFormatFrameRectangle;
   1.124 -
   1.125 -extern QActionGroup *actionGroupFormatLinkStyles;
   1.126 -extern QAction *actionFormatLinkStyleLine;
   1.127 -extern QAction *actionFormatLinkStyleParabel;
   1.128 -extern QAction *actionFormatLinkStylePolyLine;
   1.129 -extern QAction *actionFormatLinkStylePolyParabel;
   1.130 -
   1.131 -extern QAction *actionViewToggleNoteEditor;
   1.132 -
   1.133 -extern QAction *actionSettingsAutoedit;
   1.134 -extern QAction *actionSettingsAutoselectHeading;
   1.135 -extern QAction *actionSettingsAutoselectText;
   1.136 -extern QAction *actionSettingsPasteNewHeading;
   1.137 -
   1.138 -extern QPopupMenu *branchContextMenu;
   1.139 -extern QPopupMenu *floatimageContextMenu;
   1.140 -extern QPopupMenu *saveImageFormatMenu;
   1.141 -extern QPopupMenu *exportImageFormatMenu;
   1.142 -extern QPopupMenu *canvasContextMenu;
   1.143 +
   1.144 +extern QMenu* branchContextMenu;
   1.145 +extern QMenu* branchAddContextMenu;
   1.146 +extern QMenu* branchRemoveContextMenu;
   1.147 +extern QMenu* branchLinksContextMenu;
   1.148 +extern QMenu* branchXLinksContextMenuEdit;
   1.149 +extern QMenu* branchXLinksContextMenuFollow;
   1.150 +extern QMenu* floatimageContextMenu;
   1.151 +extern QMenu* canvasContextMenu;
   1.152 +
   1.153  
   1.154  extern Settings settings;
   1.155 -
   1.156 +extern ImageIO imageIO;
   1.157 +
   1.158 +extern QString vymName;
   1.159 +extern QString vymVersion;
   1.160 +
   1.161 +extern QString iconPath;
   1.162 +extern QDir vymBaseDir;
   1.163 +extern QDir lastImageDir;
   1.164 +extern QDir lastFileDir;
   1.165 +
   1.166 +int MapEditor::mapNum=0;	// make instance
   1.167  
   1.168  ///////////////////////////////////////////////////////////////////////
   1.169  ///////////////////////////////////////////////////////////////////////
   1.170 -MapEditor::MapEditor(
   1.171 -	QWidget* parent, bool interactive, const char* name, WFlags f) :
   1.172 -    QCanvasView(parent,name,f)
   1.173 -{
   1.174 +MapEditor::MapEditor( QWidget* parent) :
   1.175 +  QGraphicsView(parent)  
   1.176 +{
   1.177 +	setObjectName ("MapEditor");
   1.178 +
   1.179  	//cout << "Constructor ME "<<this<<endl;
   1.180 -
   1.181 -    mapCanvas = new QCanvas(1000,800);
   1.182 -	mapCanvas->setAdvancePeriod(30);
   1.183 -
   1.184 -    setCanvas (mapCanvas);
   1.185 -	
   1.186 -	setVScrollBarMode ( QScrollView::AlwaysOn );
   1.187 -	setHScrollBarMode ( QScrollView::AlwaysOn );
   1.188 -
   1.189 -	// Now create the _global_ system flags _once_:
   1.190 -	// (Later all OrnamentedObj copy from this 
   1.191 -	// and set their own canvas)
   1.192 -	if (!systemFlagsDefault)
   1.193 -	{
   1.194 -		systemFlagsDefault = new FlagRowObj (mapCanvas);
   1.195 -		systemFlagsDefault->setVisibility (false);
   1.196 -		systemFlagsDefault->setName ("systemFlagsDef");
   1.197 -
   1.198 -		FlagObj *fo = new FlagObj (mapCanvas);
   1.199 -		fo->load(QPixmap(flag_note_xpm));
   1.200 -		fo->setName("note");
   1.201 -		fo->setToolTip(tr("Note"));
   1.202 -		systemFlagsDefault->addFlag (fo);	// makes deep copy
   1.203 -
   1.204 -		fo->load(QPixmap(flag_url_xpm));
   1.205 -		fo->setName("url");
   1.206 -		fo->setToolTip(tr("WWW Document (external)"));
   1.207 -		systemFlagsDefault->addFlag (fo);
   1.208 -		
   1.209 -		fo->load(QPixmap(flag_vymlink_xpm));
   1.210 -		fo->setName("vymLink");
   1.211 -		fo->setToolTip(tr("Link to another vym map"));
   1.212 -		systemFlagsDefault->addFlag (fo);	
   1.213 -
   1.214 -		fo->load(QPixmap(flag_scrolled_right_xpm));
   1.215 -		fo->setName("scrolledright");
   1.216 -		fo->setToolTip(tr("subtree is scrolled"));
   1.217 -		systemFlagsDefault->addFlag (fo);
   1.218 -		
   1.219 -		fo->load(QPixmap(flag_tmpUnscrolled_right_xpm));
   1.220 -		fo->setName("tmpUnscrolledright");
   1.221 -		fo->setToolTip(tr("subtree is temporary scrolled"));
   1.222 -		systemFlagsDefault->addFlag (fo);
   1.223 -		delete (fo);
   1.224 -	}
   1.225 -	if (!standardFlagsDefault)
   1.226 -	{
   1.227 -		standardFlagsDefault = new FlagRowObj (mapCanvas);
   1.228 -		standardFlagsDefault->setVisibility (false);
   1.229 -		standardFlagsDefault->setName ("standardFlagsDef");
   1.230 -
   1.231 -		FlagObj *fo = new FlagObj (mapCanvas);
   1.232 -		fo->load(QPixmap(flag_exclamationmark_xpm));
   1.233 -		fo->setName("exclamationmark");
   1.234 -		fo->setToolTip(tr("Take care!"));
   1.235 -		standardFlagsDefault->addFlag (fo);	// makes deep copy
   1.236 -		
   1.237 -		fo->load(QPixmap(flag_questionmark_xpm));
   1.238 -		fo->setName("questionmark");
   1.239 -		fo->setToolTip(tr("Really?"));
   1.240 -		standardFlagsDefault->addFlag (fo);	
   1.241 -
   1.242 -		fo->load(QPixmap(flag_hook_green_xpm));
   1.243 -		fo->setName("hook-green");
   1.244 -		fo->setToolTip(tr("ok!"));
   1.245 -		standardFlagsDefault->addFlag (fo);	
   1.246 -
   1.247 -		fo->load(QPixmap(flag_cross_red_xpm));
   1.248 -		fo->setName("cross-red");
   1.249 -		fo->setToolTip(tr("Not ok!"));
   1.250 -		standardFlagsDefault->addFlag (fo);	
   1.251 -
   1.252 -		fo->load(QPixmap(flag_stopsign_xpm));
   1.253 -		fo->setName("stopsign");
   1.254 -		fo->setToolTip(tr("This won't work!"));
   1.255 -		standardFlagsDefault->addFlag (fo);	
   1.256 -
   1.257 -		fo->load(QPixmap(flag_smiley_good_xpm));
   1.258 -		fo->setName("smiley-good");
   1.259 -		fo->setToolTip(tr("Good"));
   1.260 -		standardFlagsDefault->addFlag (fo);	
   1.261 -
   1.262 -		fo->load(QPixmap(flag_smiley_sad_xpm));
   1.263 -		fo->setName("smiley-sad");
   1.264 -		fo->setToolTip(tr("Bad"));
   1.265 -		standardFlagsDefault->addFlag (fo);	
   1.266 -
   1.267 -		fo->load(QPixmap(flag_clock_xpm));
   1.268 -		fo->setName("clock");
   1.269 -		fo->setToolTip(tr("Time critical"));
   1.270 -		standardFlagsDefault->addFlag (fo);	
   1.271 -
   1.272 -		fo->load(QPixmap(flag_lamp_xpm));
   1.273 -		fo->setName("lamp");
   1.274 -		fo->setToolTip(tr("Idea!"));
   1.275 -		standardFlagsDefault->addFlag (fo);	
   1.276 -
   1.277 -		fo->load(QPixmap(flag_arrow_up_xpm));
   1.278 -		fo->setName("arrow-up");
   1.279 -		fo->setToolTip(tr("Important"));
   1.280 -		standardFlagsDefault->addFlag (fo);	
   1.281 -
   1.282 -		fo->load(QPixmap(flag_arrow_down_xpm));
   1.283 -		fo->setName("arrow-down");
   1.284 -		fo->setToolTip(tr("Unimportant"));
   1.285 -		standardFlagsDefault->addFlag (fo);	
   1.286 -
   1.287 -		fo->load(QPixmap(flag_thumb_up_xpm));
   1.288 -		fo->setName("thumb-up");
   1.289 -		fo->setToolTip(tr("I like this"));
   1.290 -		standardFlagsDefault->addFlag (fo);	
   1.291 -
   1.292 -		fo->load(QPixmap(flag_thumb_down_xpm));
   1.293 -		fo->setName("thumb-down");
   1.294 -		fo->setToolTip(tr("I do not like this"));
   1.295 -		standardFlagsDefault->addFlag (fo);	
   1.296 -		
   1.297 -		fo->load(QPixmap(flag_heart_xpm));
   1.298 -		fo->setName("heart");
   1.299 -		fo->setToolTip(tr("I just love... "));
   1.300 -		standardFlagsDefault->addFlag (fo);	
   1.301 -
   1.302 -		fo->load(QPixmap(flag_flash_xpm));
   1.303 -		fo->setName("flash");
   1.304 -		fo->setToolTip(tr("Dangerous"));
   1.305 -		standardFlagsDefault->addFlag (fo);	
   1.306 -		
   1.307 -		fo->load(QPixmap(flag_lifebelt_xpm));
   1.308 -		fo->setName("lifebelt");
   1.309 -		fo->setToolTip(tr("This will help"));
   1.310 -		standardFlagsDefault->addFlag (fo);	
   1.311 -		delete (fo);
   1.312 -
   1.313 -	}
   1.314 -	
   1.315 -    mapCenter = new MapCenterObj(mapCanvas);
   1.316 -    mapCenter->setVisibility (true);
   1.317 -	mapCenter->setMapEditor (this);
   1.318 -	mapCenter->setHeading (tr("New Map"));
   1.319 +	mapNum++;
   1.320 +
   1.321 +
   1.322 +	mapScene= new QGraphicsScene(parent);
   1.323 +	//mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
   1.324 +	mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
   1.325 +
   1.326 +	model=new VymModel();
   1.327 +	model->setScene (mapScene);
   1.328 +	model->setMapEditor (this);
   1.329 +
   1.330 +    setScene (mapScene);
   1.331  
   1.332      printer=NULL;
   1.333  
   1.334 -    lineedit = new QLineEdit(this, "lineedit"  );
   1.335 -    connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEditNoSave() ) );
   1.336 -    lineedit->hide();
   1.337 -
   1.338 -    actColor=black; setColor (actColor);
   1.339 -	deflinkcolor=QColor (0,0,255);
   1.340 -	linkcolorhint=DefaultColor;
   1.341 -	linkstyle=StylePolyParabel;
   1.342 -	mapCanvas->setBackgroundColor (white);
   1.343 -
   1.344 -	// Create bitmap cursors, patform dependant
   1.345 -	#if defined(Q_OS_MACX)
   1.346 -		#include "icons/cursorhandopen16.xpm"
   1.347 -		#include "icons/cursorcolorpicker16.xpm"
   1.348 -		QBitmap cb( 16, 16, chandopen, TRUE );
   1.349 -		QBitmap cm( 16, 16, chandopenmask, TRUE );
   1.350 -		handOpenCursor=QCursor ( cb, cm );		
   1.351 -		// set hot spot to tip of picker			
   1.352 -		pickColorCursor=QCursor ( cursorcolorpicker_xpm, 1,15 ); 
   1.353 -	#else
   1.354 -		#include "icons/cursorhandopen.xpm"
   1.355 -		#include "icons/cursorcolorpicker.xpm"
   1.356 -
   1.357 -		QBitmap cb( 32, 32, chandopen, TRUE );
   1.358 -		QBitmap cm( 32, 32, chandopenmask, TRUE );
   1.359 -		handOpenCursor=QCursor ( cb, cm );		
   1.360 -		// set hot spot to tip of picker			
   1.361 -		pickColorCursor=QCursor ( cursorcolorpicker_xpm, 5,27 ); 
   1.362 -	#endif
   1.363 -
   1.364 +	defLinkColor=QColor (0,0,255);
   1.365 +	defXLinkColor=QColor (180,180,180);
   1.366 +	linkcolorhint=LinkableMapObj::DefaultColor;
   1.367 +	linkstyle=LinkableMapObj::PolyParabel;
   1.368 +
   1.369 +	// Create bitmap cursors, platform dependant
   1.370 +	HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);		
   1.371 +	PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 ); 
   1.372 +	CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 ); 
   1.373 +	XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 ); 
   1.374 +
   1.375 +	setFocusPolicy (Qt::StrongFocus);
   1.376  
   1.377  	pickingColor=false;
   1.378 +	drawingLink=false;
   1.379 +	copyingObj=false;
   1.380  
   1.381      editingBO=NULL;
   1.382 -    selection=NULL;
   1.383 -    selectionLast=NULL;
   1.384      movingObj=NULL;
   1.385  
   1.386 +	xelection.setModel (model);
   1.387 +	xelection.unselect();
   1.388 +
   1.389 +	defXLinkWidth=1;
   1.390 +	defXLinkColor=QColor (230,230,230);
   1.391 +
   1.392      mapChanged=false;
   1.393  	mapDefault=true;
   1.394  	mapUnsaved=false;
   1.395 -	undoSelection=NULL;
   1.396  	
   1.397  	zipped=true;
   1.398  	filePath="";
   1.399 -	fileName="unnamed";
   1.400 +	fileName=tr("unnamed");
   1.401  	mapName="";
   1.402  
   1.403 +	stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
   1.404 +	undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
   1.405 +	mainWindow->updateHistory (undoSet);
   1.406 +	
   1.407  	// Initialize find routine
   1.408  	itFind=NULL;				
   1.409  	EOFind=false;
   1.410 @@ -325,159 +123,167 @@
   1.411  	printFrame=true;
   1.412  	printFooter=true;
   1.413  
   1.414 -	blockreposition=false;
   1.415 -	isInteractive=interactive;
   1.416 -	if (isInteractive)
   1.417 -		// Create temporary files
   1.418 -		makeTmpDirs();
   1.419 -
   1.420 -	// Initially set movingCentre
   1.421 -	updateViewCenter();
   1.422 -
   1.423 -	mapCenter->reposition();	//	for positioning heading
   1.424 -}
   1.425 -
   1.426 -MapEditor::~MapEditor()
   1.427 -{
   1.428 -	//cout <<"Destructor MapEditor\n";
   1.429 -	if (isInteractive) delTmpDirs();
   1.430 -
   1.431 -	// Save Settings
   1.432 -	//settings.writeEntry( "/vym/mapeditor/editmode/autoselect",  );
   1.433 -
   1.434 -}
   1.435 -
   1.436 -QColor MapEditor::color()
   1.437 -{
   1.438 -    return actColor;
   1.439 -}
   1.440 -
   1.441 -QColor MapEditor::backgroundColor()
   1.442 -{
   1.443 -    return mapCanvas->backgroundColor();
   1.444 -}
   1.445 -
   1.446 -MapCenterObj* MapEditor::getMapCenter()
   1.447 -{
   1.448 -    return mapCenter;
   1.449 -}
   1.450 -
   1.451 -QCanvas* MapEditor::getCanvas()
   1.452 -{
   1.453 -    return mapCanvas;
   1.454 -}
   1.455 -
   1.456 -void MapEditor::adjustCanvasSize()
   1.457 -{
   1.458 -	// To adjust the canvas to map, viewport size and position, we have to
   1.459 -	// do some coordinate magic...
   1.460 -	//
   1.461 -	// Get rectangle of (scroll-)view. 
   1.462 -	// We want to be in canvas coords, so
   1.463 -	// we map. Important if view is zoomed...
   1.464 -	QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(),
   1.465 -												visibleWidth(), visibleHeight()) );	
   1.466 -												
   1.467 -	// Now we need the bounding box of view AND map to calc the correct canvas size.
   1.468 -	// Why? Because if the map itself is moved out of view, the view has to be enlarged
   1.469 -	// to avoid jumping aroung...
   1.470 -	QRect map=mapCenter->getTotalBBox();
   1.471 -
   1.472 -	// right edge - left edge
   1.473 -	int cw= max(map.x() + map.width(),  view.x() + view.width())  - min(map.x(), view.x());
   1.474 -	int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
   1.475 -
   1.476 -
   1.477 -	if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) ||
   1.478 -		!mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight())
   1.479 -	)	
   1.480 -	{	
   1.481 -		// move the map on canvas (in order to not move it on screen) this is neccessary
   1.482 -		// a) if topleft corner of canvas is left or above topleft corner of view and also left of
   1.483 -		//    above topleft corner of map. E.g. if map is completly inside view, but it would be possible 
   1.484 -		//    to scroll to an empty area of canvas to the left.
   1.485 -		// b) if topleft corner of map left of or above topleft of canvas
   1.486 -		int dx=0;
   1.487 -		int dy=0;
   1.488 -
   1.489 -		if (cw > mapCanvas->width() )
   1.490 -		{
   1.491 -			if (map.x()<0) dx=-map.x();	
   1.492 -		}
   1.493 -		if (cw <  mapCanvas->width() )
   1.494 -			dx=-min (view.x(),map.x());
   1.495 -		if (ch > mapCanvas->height() )
   1.496 -		{
   1.497 -			if (map.y()<0) dy=-map.y();	
   1.498 -		}
   1.499 -		if (ch <  mapCanvas->height() )
   1.500 -		{
   1.501 -			dy=-min (view.y(),map.y());
   1.502 -		}
   1.503 -		// We really have to resize now. Let's go...
   1.504 -		mapCanvas->resize (cw,ch);
   1.505 -		if ( (dx!=0) || (dy!=0) ) 
   1.506 -		{
   1.507 -			mapCenter->moveAllBy(dx,dy);
   1.508 -			mapCenter->reposition();
   1.509 -
   1.510 -			// scroll the view (in order to not move map on screen)
   1.511 -			scrollBy (dx,dy);
   1.512 -		}	
   1.513 +	blockReposition=false;
   1.514 +	blockSaveState=false;
   1.515 +
   1.516 +	hidemode=HideNone;
   1.517 +
   1.518 +	// Create temporary files
   1.519 +	makeTmpDirs();
   1.520 +
   1.521 +	curStep=0;
   1.522 +	redosAvail=0;
   1.523 +	undosAvail=0;
   1.524 +
   1.525 +	setAcceptDrops (true);	
   1.526 +
   1.527 +	model->reposition();
   1.528 +
   1.529 +	// autosave
   1.530 +	autosaveTimer=new QTimer (this);
   1.531 +	connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
   1.532 +
   1.533 +	fileChangedTimer=new QTimer (this);
   1.534 +	fileChangedTimer->start(3000);
   1.535 +	connect(fileChangedTimer, SIGNAL(timeout()), this, SLOT(fileChanged()));
   1.536 +
   1.537 +	// Network
   1.538 +	netstate=Offline;
   1.539 +
   1.540 +	// Attributes	//FIXME testing only...
   1.541 +	QString k;
   1.542 +	AttributeDef *ad;
   1.543 +	attrTable= new AttributeTable();
   1.544 +	k="A - StringList";
   1.545 +	ad=attrTable->addKey (k,StringList);
   1.546 +	if (ad)
   1.547 +	{
   1.548 +		QStringList sl;
   1.549 +		sl <<"val 1"<<"val 2"<< "val 3";
   1.550 +		ad->setValue (QVariant (sl));
   1.551 +	}
   1.552 +	//attrTable->addValue ("Key A","P 1");
   1.553 +	//attrTable->addValue ("Key A","P 2");
   1.554 +	//attrTable->addValue ("Key A","P 3");
   1.555 +	//attrTable->addValue ("Key A","P 4");
   1.556 +	k="B - FreeString";
   1.557 +	ad=attrTable->addKey (k,FreeString);
   1.558 +	if (ad)
   1.559 +	{
   1.560 +		//attrTable->addValue ("Key B","w1");
   1.561 +		//attrTable->addValue ("Key B","w2");
   1.562 +	}
   1.563 +	k="C - UniqueString";
   1.564 +	ad=attrTable->addKey (k,UniqueString);
   1.565 +	if (ad)
   1.566 +	{
   1.567 +	//attrTable->addKey ("Key Prio");
   1.568 +	//attrTable->addValue ("Key Prio","Prio 1");
   1.569 +	//attrTable->addValue ("Key Prio","Prio 2");
   1.570  	}
   1.571  }
   1.572  
   1.573 -bool MapEditor::blockReposition()
   1.574 -{
   1.575 -	return blockreposition;
   1.576 +MapEditor::~MapEditor()
   1.577 +{
   1.578 +	//cout <<"Destructor MapEditor\n";
   1.579 +	autosaveTimer->stop();
   1.580 +	fileChangedTimer->stop();
   1.581 +
   1.582 +	// tmpMapDir is in tmpVymDir, so it gets removed automagically when vym closes
   1.583 +	
   1.584 +	//removeDir(QDir(tmpMapDir));
   1.585 +	delete (model);
   1.586  }
   1.587  
   1.588 +VymModel* MapEditor::getModel()
   1.589 +{
   1.590 +    return model;
   1.591 +}
   1.592 +
   1.593 +QGraphicsScene * MapEditor::getScene()
   1.594 +{
   1.595 +    return mapScene;
   1.596 +}
   1.597 +
   1.598 +MapEditor::State MapEditor::getState()
   1.599 +{
   1.600 +    return state;
   1.601 +}
   1.602 +
   1.603 +void MapEditor::setStateEditHeading(bool s)
   1.604 +{
   1.605 +	if (s)
   1.606 +	{
   1.607 +		if (state==Idle) state=EditHeading;
   1.608 +	}
   1.609 +	else	
   1.610 +		state=Idle;
   1.611 +}
   1.612 +
   1.613 +bool MapEditor::isRepositionBlocked()
   1.614 +{
   1.615 +	return blockReposition;
   1.616 +}
   1.617 +
   1.618 +void MapEditor::setSaveStateBlocked(bool b)
   1.619 +{
   1.620 +	blockSaveState=b;
   1.621 +}
   1.622 +
   1.623 +bool MapEditor::isSelectBlocked()
   1.624 +{
   1.625 +	if (state==EditHeading)
   1.626 +		return true;
   1.627 +	else
   1.628 +		return false; 
   1.629 +}
   1.630 +
   1.631 +QString MapEditor::getName (const LinkableMapObj *lmo)
   1.632 +{
   1.633 +	QString s;
   1.634 +	if (!lmo) return QString("Error: NULL has no name!");
   1.635 +
   1.636 +	if ((typeid(*lmo) == typeid(BranchObj) ||
   1.637 +				      typeid(*lmo) == typeid(MapCenterObj))) 
   1.638 +	{
   1.639 +		
   1.640 +		s=(((BranchObj*)lmo)->getHeading());
   1.641 +		if (s=="") s="unnamed";
   1.642 +		return QString("branch (%1)").arg(s);
   1.643 +	}	
   1.644 +	if ((typeid(*lmo) == typeid(FloatImageObj) ))
   1.645 +		return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
   1.646 +	return QString("Unknown type has no name!");
   1.647 +}
   1.648 +
   1.649  void MapEditor::makeTmpDirs()
   1.650  {
   1.651  	// Create unique temporary directories
   1.652 -	char tmpdir[]="/tmp/vym-XXXXXX";	
   1.653 -	bakMapDir=mkdtemp(tmpdir);
   1.654 -	makeSubDirs(bakMapDir);
   1.655 -	// FIXME set permissions
   1.656 -	// and maybe use QT method for portability
   1.657 +	tmpMapDir = tmpVymDir+QString("/mapeditor-%1").arg(mapNum);
   1.658 +	histPath = tmpMapDir+"/history";
   1.659 +	QDir d;
   1.660 +	d.mkdir (tmpMapDir);
   1.661  }
   1.662  
   1.663 -void MapEditor::delTmpDirs()
   1.664 -{
   1.665 -	//FIXME delete tmp directory, better use QT methods here:
   1.666 -	system ( "rm -rf "+ bakMapDir );
   1.667 -}
   1.668 -
   1.669 -
   1.670 -void MapEditor::makeSubDirs(const QString &s)
   1.671 -{
   1.672 -	QDir d(s);
   1.673 -	d.mkdir ("images");	
   1.674 -	d.mkdir ("flags");	
   1.675 -}
   1.676 -
   1.677 -
   1.678 -QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, SaveMode savemode)
   1.679 -{
   1.680 -	// tmpdir		temporary directory to which data will be writte
   1.681 +QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
   1.682 +{
   1.683 +	// tmpdir		temporary directory to which data will be written
   1.684  	// prefix		mapname, which will be appended to images etc.
   1.685  	// writeflags	Only write flags for "real" save of map, not undo
   1.686 -	// offset		offset of bbox of whole map in canvas. 
   1.687 +	// offset		offset of bbox of whole map in scene. 
   1.688  	//				Needed for XML export
   1.689 -	// completeMap	if false, only vympart will be written, without
   1.690 -	//				mapcenter
   1.691  	
   1.692  	// Save Header
   1.693  	QString ls;
   1.694  	switch (linkstyle)
   1.695  	{
   1.696 -		case StyleLine: 
   1.697 +		case LinkableMapObj::Line: 
   1.698  			ls="StyleLine";
   1.699  			break;
   1.700 -		case StyleParabel:
   1.701 +		case LinkableMapObj::Parabel:
   1.702  			ls="StyleParabel";
   1.703  			break;
   1.704 -		case StylePolyLine:	
   1.705 +		case LinkableMapObj::PolyLine:	
   1.706  			ls="StylePolyLine";
   1.707  			break;
   1.708  		default:
   1.709 @@ -487,17 +293,20 @@
   1.710  
   1.711  	QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
   1.712  	QString colhint="";
   1.713 -	if (linkcolorhint==HeadingColor) 
   1.714 +	if (linkcolorhint==LinkableMapObj::HeadingColor) 
   1.715  		colhint=attribut("linkColorHint","HeadingColor");
   1.716  
   1.717 -	QString mapAttr=attribut("version",__VYM_VERSION__);
   1.718 -	if (savemode==CompleteMap)
   1.719 -		mapAttr+= attribut("author",mapCenter->getAuthor()) +
   1.720 -				  attribut("comment",mapCenter->getComment()) +
   1.721 -			      attribut("date",mapCenter->getDate()) +
   1.722 -		          attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
   1.723 +	QString mapAttr=attribut("version",vymVersion);
   1.724 +	if (!saveSel)
   1.725 +		mapAttr+= attribut("author",model->getAuthor()) +
   1.726 +				  attribut("comment",model->getComment()) +
   1.727 +			      attribut("date",model->getDate()) +
   1.728 +		          attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
   1.729 +		          attribut("selectionColor", xelection.getColor().name() ) +
   1.730  		          attribut("linkStyle", ls ) +
   1.731 -		          attribut("linkColor", deflinkcolor.name() ) +
   1.732 +		          attribut("linkColor", defLinkColor.name() ) +
   1.733 +		          attribut("defXLinkColor", defXLinkColor.name() ) +
   1.734 +		          attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
   1.735  		          colhint; 
   1.736  	s+=beginElement("vymmap",mapAttr);
   1.737  	incIndent();
   1.738 @@ -505,92 +314,1170 @@
   1.739  	// Find the used flags while traversing the tree
   1.740  	standardFlagsDefault->resetUsedCounter();
   1.741  	
   1.742 +	// Reset the counters before saving
   1.743 +	// TODO constr. of FIO creates lots of objects, better do this in some other way...
   1.744 +	FloatImageObj (mapScene).resetSaveCounter();
   1.745 +
   1.746  	// Build xml recursivly
   1.747 -	if (savemode==CompleteMap)
   1.748 -		s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
   1.749 +	if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
   1.750 +		// Save complete map, if saveSel not set
   1.751 +		s+=model->saveToDir(tmpdir,prefix,writeflags,offset);
   1.752  	else
   1.753  	{
   1.754 -		if ( undoSelection &&
   1.755 -			typeid(*undoSelection) == typeid(BranchObj) )
   1.756 -			s+=((BranchObj*)(undoSelection))->saveToDir(tmpdir,prefix,offset);
   1.757 +		if ( typeid(*saveSel) == typeid(BranchObj) )
   1.758 +			// Save Subtree
   1.759 +			s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
   1.760 +		else if ( typeid(*saveSel) == typeid(FloatImageObj) )
   1.761 +			// Save image
   1.762 +			s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
   1.763  	}
   1.764  
   1.765  	// Save local settings
   1.766 -	s+=settings.getXMLData (destPath);
   1.767 +	s+=settings.getDataXML (destPath);
   1.768  
   1.769  	// Save selection
   1.770 -	if (selection) 
   1.771 -		s+=valueElement("select",selection->getSelectString());
   1.772 +	if (!xelection.isEmpty() && !saveSel ) 
   1.773 +		s+=valueElement("select",xelection.getSelectString());
   1.774  
   1.775  	decIndent();
   1.776  	s+=endElement("vymmap");
   1.777  
   1.778  	if (writeflags)
   1.779  		standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
   1.780 -	
   1.781  	return s;
   1.782  }
   1.783  
   1.784 -void MapEditor::saveState()
   1.785 -{
   1.786 -	saveState (CompleteMap,NULL);
   1.787 +QString MapEditor::getHistoryDir()
   1.788 +{
   1.789 +	QString histName(QString("history-%1").arg(curStep));
   1.790 +	return (tmpMapDir+"/"+histName);
   1.791  }
   1.792  
   1.793 -void MapEditor::saveState(const SaveMode &mode, LinkableMapObj *part)
   1.794 -{
   1.795 -	// all binary data is saved in bakMapDir (created in Constructor)
   1.796 -	// the xml data itself is kept in memory in backupXML
   1.797 -	// 
   1.798 -	// For faster write/read of data, a part of the map can be
   1.799 -	// written. Then the undoSelection will mark, which part of the
   1.800 -	// map should be replaced if an undo is wanted later.
   1.801 -
   1.802 -	if (mode==PartOfMap && part && (typeid(*part) == typeid (BranchObj) ) ) 
   1.803 -	{
   1.804 -		// Writing a vympart only is useful for BranchObj
   1.805 -		undoSelection=part;
   1.806 -		backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),PartOfMap);
   1.807 -	} else	
   1.808 -	{
   1.809 -		undoSelection=NULL;
   1.810 -		backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),CompleteMap);
   1.811 +void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
   1.812 +{
   1.813 +	sendData(redoCom);	//FIXME testing
   1.814 +
   1.815 +	// Main saveState
   1.816 +
   1.817 +
   1.818 +	if (blockSaveState) return;
   1.819 +
   1.820 +	if (debug) cout << "ME::saveState() for  "<<qPrintable (mapName)<<endl;
   1.821 +	
   1.822 +	// Find out current undo directory
   1.823 +	if (undosAvail<stepsTotal) undosAvail++;
   1.824 +	curStep++;
   1.825 +	if (curStep>stepsTotal) curStep=1;
   1.826 +	
   1.827 +	QString backupXML="";
   1.828 +	QString histDir=getHistoryDir();
   1.829 +	QString bakMapPath=histDir+"/map.xml";
   1.830 +
   1.831 +	// Create histDir if not available
   1.832 +	QDir d(histDir);
   1.833 +	if (!d.exists()) 
   1.834 +		makeSubDirs (histDir);
   1.835 +
   1.836 +	// Save depending on how much needs to be saved	
   1.837 +	if (saveSel)
   1.838 +		backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
   1.839 +		
   1.840 +	QString undoCommand="";
   1.841 +	if (savemode==UndoCommand)
   1.842 +	{
   1.843 +		undoCommand=undoCom;
   1.844  	}	
   1.845 +	else if (savemode==PartOfMap )
   1.846 +	{
   1.847 +		undoCommand=undoCom;
   1.848 +		undoCommand.replace ("PATH",bakMapPath);
   1.849 +	}
   1.850 +
   1.851 +	if (!backupXML.isEmpty())
   1.852 +		// Write XML Data to disk
   1.853 +		saveStringToDisk (bakMapPath,backupXML);
   1.854 +
   1.855 +	// We would have to save all actions in a tree, to keep track of 
   1.856 +	// possible redos after a action. Possible, but we are too lazy: forget about redos.
   1.857 +	redosAvail=0;
   1.858 +
   1.859 +	// Write the current state to disk
   1.860 +	undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
   1.861 +	undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
   1.862 +	undoSet.setEntry ("/history/curStep",QString::number(curStep));
   1.863 +	undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
   1.864 +	undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
   1.865 +	undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
   1.866 +	undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
   1.867 +	undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
   1.868 +	undoSet.setEntry (QString("/history/version"),vymVersion);
   1.869 +	undoSet.writeSettings(histPath);
   1.870 +
   1.871 +	if (debug)
   1.872 +	{
   1.873 +		// TODO remove after testing
   1.874 +		//cout << "          into="<< histPath.toStdString()<<endl;
   1.875 +		cout << "    stepsTotal="<<stepsTotal<<
   1.876 +		", undosAvail="<<undosAvail<<
   1.877 +		", redosAvail="<<redosAvail<<
   1.878 +		", curStep="<<curStep<<endl;
   1.879 +		cout << "    ---------------------------"<<endl;
   1.880 +		cout << "    comment="<<comment.toStdString()<<endl;
   1.881 +		cout << "    undoCom="<<undoCommand.toStdString()<<endl;
   1.882 +		cout << "    undoSel="<<undoSelection.toStdString()<<endl;
   1.883 +		cout << "    redoCom="<<redoCom.toStdString()<<endl;
   1.884 +		cout << "    redoSel="<<redoSelection.toStdString()<<endl;
   1.885 +		if (saveSel) cout << "    saveSel="<<qPrintable (model->getSelectString(saveSel))<<endl;
   1.886 +		cout << "    ---------------------------"<<endl;
   1.887 +	}
   1.888 +
   1.889 +	mainWindow->updateHistory (undoSet);
   1.890 +	setChanged();
   1.891 +	updateActions();
   1.892  }
   1.893  
   1.894 -void MapEditor::finishedLineEditNoSave()
   1.895 -{
   1.896 -	// This is called by finishedLineEdit or any MapEditor method,
   1.897 -	// which wants to assure, that lineedits finish, before e.g. a branch is 
   1.898 -	// deleted
   1.899 -    
   1.900 -	// After calling LineEdit and using the clipboard, the 
   1.901 -    // focus is not any longer on the main widget, we
   1.902 -    // have to restore it using parentWidget()->setFocus()
   1.903 -
   1.904 -    if (editingBO!=NULL) 
   1.905 -	{
   1.906 -		editingBO->setHeading(lineedit->text() );
   1.907 -		editingBO=NULL;
   1.908 -		lineedit->releaseKeyboard();
   1.909 -		lineedit->hide();
   1.910 -		parentWidget()->setFocus();
   1.911 -		mapCenter->reposition();
   1.912 -		adjustCanvasSize();
   1.913 -		ensureSelectionVisible();
   1.914 -    }		
   1.915 +
   1.916 +void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
   1.917 +{
   1.918 +	// save the selected part of the map, Undo will replace part of map 
   1.919 +	QString undoSelection="";
   1.920 +	if (undoSel)
   1.921 +		undoSelection=model->getSelectString(undoSel);
   1.922 +	else
   1.923 +		qWarning ("MapEditor::saveStateChangingPart  no undoSel given!");
   1.924 +	QString redoSelection="";
   1.925 +	if (redoSel)
   1.926 +		redoSelection=model->getSelectString(undoSel);
   1.927 +	else
   1.928 +		qWarning ("MapEditor::saveStateChangingPart  no redoSel given!");
   1.929 +		
   1.930 +
   1.931 +	saveState (PartOfMap,
   1.932 +		undoSelection, "addMapReplace (\"PATH\")",
   1.933 +		redoSelection, rc, 
   1.934 +		comment, 
   1.935 +		undoSel);
   1.936  }
   1.937  
   1.938 +void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
   1.939 +{
   1.940 +	if (!redoSel)
   1.941 +	{
   1.942 +		qWarning ("MapEditor::saveStateRemovingPart  no redoSel given!");
   1.943 +		return;
   1.944 +	}
   1.945 +	QString undoSelection=model->getSelectString (redoSel->getParObj());
   1.946 +	QString redoSelection=model->getSelectString(redoSel);
   1.947 +	if (typeid(*redoSel) == typeid(BranchObj)  ) 
   1.948 +	{
   1.949 +		// save the selected branch of the map, Undo will insert part of map 
   1.950 +		saveState (PartOfMap,
   1.951 +			undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
   1.952 +			redoSelection, "delete ()", 
   1.953 +			comment, 
   1.954 +			redoSel);
   1.955 +	}
   1.956 +}
   1.957 +
   1.958 +
   1.959 +void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment) 
   1.960 +{
   1.961 +	// "Normal" savestate: save commands, selections and comment
   1.962 +	// so just save commands for undo and redo
   1.963 +	// and use current selection
   1.964 +
   1.965 +	QString redoSelection="";
   1.966 +	if (redoSel) redoSelection=model->getSelectString(redoSel);
   1.967 +	QString undoSelection="";
   1.968 +	if (undoSel) undoSelection=model->getSelectString(undoSel);
   1.969 +
   1.970 +	saveState (UndoCommand,
   1.971 +		undoSelection, uc,
   1.972 +		redoSelection, rc, 
   1.973 +		comment, 
   1.974 +		NULL);
   1.975 +}
   1.976 +
   1.977 +void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment) 
   1.978 +{
   1.979 +	// "Normal" savestate: save commands, selections and comment
   1.980 +	// so just save commands for undo and redo
   1.981 +	// and use current selection
   1.982 +	saveState (UndoCommand,
   1.983 +		undoSel, uc,
   1.984 +		redoSel, rc, 
   1.985 +		comment, 
   1.986 +		NULL);
   1.987 +}
   1.988 +
   1.989 +void MapEditor::saveState(const QString &uc, const QString &rc, const QString &comment) 
   1.990 +{
   1.991 +	// "Normal" savestate applied to model (no selection needed): 
   1.992 +	// save commands  and comment
   1.993 +	saveState (UndoCommand,
   1.994 +		NULL, uc,
   1.995 +		NULL, rc, 
   1.996 +		comment, 
   1.997 +		NULL);
   1.998 +}
   1.999 +
  1.1000 +		
  1.1001 +void MapEditor::parseAtom(const QString &atom)
  1.1002 +{
  1.1003 +	BranchObj *selb=xelection.getBranch();
  1.1004 +	QString s,t;
  1.1005 +	double x,y;
  1.1006 +	int n;
  1.1007 +	bool b,ok;
  1.1008 +
  1.1009 +	// Split string s into command and parameters
  1.1010 +	parser.parseAtom (atom);
  1.1011 +	QString com=parser.getCommand();
  1.1012 +	
  1.1013 +	// External commands
  1.1014 +	/////////////////////////////////////////////////////////////////////
  1.1015 +	if (com=="addBranch")
  1.1016 +	{
  1.1017 +		if (xelection.isEmpty())
  1.1018 +		{
  1.1019 +			parser.setError (Aborted,"Nothing selected");
  1.1020 +		} else if (! selb )
  1.1021 +		{				  
  1.1022 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1023 +		} else 
  1.1024 +		{	
  1.1025 +			QList <int> pl;
  1.1026 +			pl << 0 <<1;
  1.1027 +			if (parser.checkParCount(pl))
  1.1028 +			{
  1.1029 +				if (parser.parCount()==0)
  1.1030 +					addNewBranch (0);
  1.1031 +				else
  1.1032 +				{
  1.1033 +					n=parser.parInt (ok,0);
  1.1034 +					if (ok ) addNewBranch (n);
  1.1035 +				}
  1.1036 +			}
  1.1037 +		}
  1.1038 +	/////////////////////////////////////////////////////////////////////
  1.1039 +	} else if (com=="addBranchBefore")
  1.1040 +	{
  1.1041 +		if (xelection.isEmpty())
  1.1042 +		{
  1.1043 +			parser.setError (Aborted,"Nothing selected");
  1.1044 +		} else if (! selb )
  1.1045 +		{				  
  1.1046 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1047 +		} else 
  1.1048 +		{	
  1.1049 +			if (parser.parCount()==0)
  1.1050 +			{
  1.1051 +				addNewBranchBefore ();
  1.1052 +			}	
  1.1053 +		}
  1.1054 +	/////////////////////////////////////////////////////////////////////
  1.1055 +	} else if (com==QString("addMapCenter"))
  1.1056 +	{
  1.1057 +		if (parser.checkParCount(2))
  1.1058 +		{
  1.1059 +			x=parser.parDouble (ok,0);
  1.1060 +			if (ok)
  1.1061 +			{
  1.1062 +				y=parser.parDouble (ok,1);
  1.1063 +				if (ok) model->addMapCenter (QPointF(x,y));
  1.1064 +			}
  1.1065 +		}	
  1.1066 +	/////////////////////////////////////////////////////////////////////
  1.1067 +	} else if (com==QString("addMapReplace"))
  1.1068 +	{
  1.1069 +		if (xelection.isEmpty())
  1.1070 +		{
  1.1071 +			parser.setError (Aborted,"Nothing selected");
  1.1072 +		} else if (! selb )
  1.1073 +		{				  
  1.1074 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1075 +		} else if (parser.checkParCount(1))
  1.1076 +		{
  1.1077 +			//s=parser.parString (ok,0);	// selection
  1.1078 +			t=parser.parString (ok,0);	// path to map
  1.1079 +			if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
  1.1080 +			addMapReplaceInt(model->getSelectString(selb),t);	
  1.1081 +		}
  1.1082 +	/////////////////////////////////////////////////////////////////////
  1.1083 +	} else if (com==QString("addMapInsert"))
  1.1084 +	{
  1.1085 +		if (xelection.isEmpty())
  1.1086 +		{
  1.1087 +			parser.setError (Aborted,"Nothing selected");
  1.1088 +		} else if (! selb )
  1.1089 +		{				  
  1.1090 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1091 +		} else 
  1.1092 +		{	
  1.1093 +			if (parser.checkParCount(2))
  1.1094 +			{
  1.1095 +				t=parser.parString (ok,0);	// path to map
  1.1096 +				n=parser.parInt(ok,1);		// position
  1.1097 +				if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
  1.1098 +				addMapInsertInt(t,n);	
  1.1099 +			}
  1.1100 +		}
  1.1101 +	/////////////////////////////////////////////////////////////////////
  1.1102 +	} else if (com=="clearFlags")
  1.1103 +	{
  1.1104 +		if (xelection.isEmpty() )
  1.1105 +		{
  1.1106 +			parser.setError (Aborted,"Nothing selected");
  1.1107 +		} else if (! selb )
  1.1108 +		{				  
  1.1109 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1110 +		} else if (parser.checkParCount(0))
  1.1111 +		{
  1.1112 +			selb->clearStandardFlags();	
  1.1113 +			selb->updateFlagsToolbar();
  1.1114 +		}
  1.1115 +	/////////////////////////////////////////////////////////////////////
  1.1116 +	} else if (com=="colorBranch")
  1.1117 +	{
  1.1118 +		if (xelection.isEmpty())
  1.1119 +		{
  1.1120 +			parser.setError (Aborted,"Nothing selected");
  1.1121 +		} else if (! selb )
  1.1122 +		{				  
  1.1123 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1124 +		} else if (parser.checkParCount(1))
  1.1125 +		{	
  1.1126 +			QColor c=parser.parColor (ok,0);
  1.1127 +			if (ok) colorBranch (c);
  1.1128 +		}	
  1.1129 +	/////////////////////////////////////////////////////////////////////
  1.1130 +	} else if (com=="colorSubtree")
  1.1131 +	{
  1.1132 +		if (xelection.isEmpty())
  1.1133 +		{
  1.1134 +			parser.setError (Aborted,"Nothing selected");
  1.1135 +		} else if (! selb )
  1.1136 +		{				  
  1.1137 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1138 +		} else if (parser.checkParCount(1))
  1.1139 +		{	
  1.1140 +			QColor c=parser.parColor (ok,0);
  1.1141 +			if (ok) colorSubtree (c);
  1.1142 +		}	
  1.1143 +	/////////////////////////////////////////////////////////////////////
  1.1144 +	} else if (com=="copy")
  1.1145 +	{
  1.1146 +		if (xelection.isEmpty())
  1.1147 +		{
  1.1148 +			parser.setError (Aborted,"Nothing selected");
  1.1149 +		} else if (! selb )
  1.1150 +		{				  
  1.1151 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1152 +		} else if (parser.checkParCount(0))
  1.1153 +		{	
  1.1154 +			//FIXME missing action for copy
  1.1155 +		}	
  1.1156 +	/////////////////////////////////////////////////////////////////////
  1.1157 +	} else if (com=="cut")
  1.1158 +	{
  1.1159 +		if (xelection.isEmpty())
  1.1160 +		{
  1.1161 +			parser.setError (Aborted,"Nothing selected");
  1.1162 +		} else if ( xelection.type()!=Selection::Branch  && 
  1.1163 +					xelection.type()!=Selection::MapCenter  &&
  1.1164 +					xelection.type()!=Selection::FloatImage )
  1.1165 +		{				  
  1.1166 +			parser.setError (Aborted,"Type of selection is not a branch or floatimage");
  1.1167 +		} else if (parser.checkParCount(0))
  1.1168 +		{	
  1.1169 +			cut();
  1.1170 +		}	
  1.1171 +	/////////////////////////////////////////////////////////////////////
  1.1172 +	} else if (com=="delete")
  1.1173 +	{
  1.1174 +		if (xelection.isEmpty())
  1.1175 +		{
  1.1176 +			parser.setError (Aborted,"Nothing selected");
  1.1177 +		} 
  1.1178 +		/*else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage )
  1.1179 +		{
  1.1180 +			parser.setError (Aborted,"Type of selection is wrong.");
  1.1181 +		} 
  1.1182 +		*/
  1.1183 +		else if (parser.checkParCount(0))
  1.1184 +		{	
  1.1185 +			deleteSelection();
  1.1186 +		}	
  1.1187 +	/////////////////////////////////////////////////////////////////////
  1.1188 +	} else if (com=="deleteKeepChilds")
  1.1189 +	{
  1.1190 +		if (xelection.isEmpty())
  1.1191 +		{
  1.1192 +			parser.setError (Aborted,"Nothing selected");
  1.1193 +		} else if (! selb )
  1.1194 +		{
  1.1195 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1196 +		} else if (parser.checkParCount(0))
  1.1197 +		{	
  1.1198 +			deleteKeepChilds();
  1.1199 +		}	
  1.1200 +	/////////////////////////////////////////////////////////////////////
  1.1201 +	} else if (com=="deleteChilds")
  1.1202 +	{
  1.1203 +		if (xelection.isEmpty())
  1.1204 +		{
  1.1205 +			parser.setError (Aborted,"Nothing selected");
  1.1206 +		} else if (! selb)
  1.1207 +		{
  1.1208 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1209 +		} else if (parser.checkParCount(0))
  1.1210 +		{	
  1.1211 +			deleteChilds();
  1.1212 +		}	
  1.1213 +	/////////////////////////////////////////////////////////////////////
  1.1214 +	} else if (com=="exportASCII")
  1.1215 +	{
  1.1216 +		QString fname="";
  1.1217 +		ok=true;
  1.1218 +		if (parser.parCount()>=1)
  1.1219 +			// Hey, we even have a filename
  1.1220 +			fname=parser.parString(ok,0); 
  1.1221 +		if (!ok)
  1.1222 +		{
  1.1223 +			parser.setError (Aborted,"Could not read filename");
  1.1224 +		} else
  1.1225 +		{
  1.1226 +				exportASCII (fname,false);
  1.1227 +		}
  1.1228 +	/////////////////////////////////////////////////////////////////////
  1.1229 +	} else if (com=="exportImage")
  1.1230 +	{
  1.1231 +		QString fname="";
  1.1232 +		ok=true;
  1.1233 +		if (parser.parCount()>=2)
  1.1234 +			// Hey, we even have a filename
  1.1235 +			fname=parser.parString(ok,0); 
  1.1236 +		if (!ok)
  1.1237 +		{
  1.1238 +			parser.setError (Aborted,"Could not read filename");
  1.1239 +		} else
  1.1240 +		{
  1.1241 +			QString format="PNG";
  1.1242 +			if (parser.parCount()>=2)
  1.1243 +			{
  1.1244 +				format=parser.parString(ok,1);
  1.1245 +			}
  1.1246 +			exportImage (fname,false,format);
  1.1247 +		}
  1.1248 +	/////////////////////////////////////////////////////////////////////
  1.1249 +	} else if (com=="exportXHTML")
  1.1250 +	{
  1.1251 +		QString fname="";
  1.1252 +		ok=true;
  1.1253 +		if (parser.parCount()>=2)
  1.1254 +			// Hey, we even have a filename
  1.1255 +			fname=parser.parString(ok,1); 
  1.1256 +		if (!ok)
  1.1257 +		{
  1.1258 +			parser.setError (Aborted,"Could not read filename");
  1.1259 +		} else
  1.1260 +		{
  1.1261 +			exportXHTML (fname,false);
  1.1262 +		}
  1.1263 +	/////////////////////////////////////////////////////////////////////
  1.1264 +	} else if (com=="exportXML")
  1.1265 +	{
  1.1266 +		QString fname="";
  1.1267 +		ok=true;
  1.1268 +		if (parser.parCount()>=2)
  1.1269 +			// Hey, we even have a filename
  1.1270 +			fname=parser.parString(ok,1); 
  1.1271 +		if (!ok)
  1.1272 +		{
  1.1273 +			parser.setError (Aborted,"Could not read filename");
  1.1274 +		} else
  1.1275 +		{
  1.1276 +			exportXML (fname,false);
  1.1277 +		}
  1.1278 +	/////////////////////////////////////////////////////////////////////
  1.1279 +	} else if (com=="importDir")
  1.1280 +	{
  1.1281 +		if (xelection.isEmpty())
  1.1282 +		{
  1.1283 +			parser.setError (Aborted,"Nothing selected");
  1.1284 +		} else if (! selb )
  1.1285 +		{				  
  1.1286 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1287 +		} else if (parser.checkParCount(1))
  1.1288 +		{
  1.1289 +			s=parser.parString(ok,0);
  1.1290 +			if (ok) importDirInt(s);
  1.1291 +		}	
  1.1292 +	/////////////////////////////////////////////////////////////////////
  1.1293 +	} else if (com=="linkTo")
  1.1294 +	{
  1.1295 +		if (xelection.isEmpty())
  1.1296 +		{
  1.1297 +			parser.setError (Aborted,"Nothing selected");
  1.1298 +		} else if ( selb)
  1.1299 +		{
  1.1300 +			if (parser.checkParCount(4))
  1.1301 +			{
  1.1302 +				// 0	selectstring of parent
  1.1303 +				// 1	num in parent (for branches)
  1.1304 +				// 2,3	x,y of mainbranch or mapcenter
  1.1305 +				s=parser.parString(ok,0);
  1.1306 +				LinkableMapObj *dst=model->findObjBySelect (s);
  1.1307 +				if (dst)
  1.1308 +				{	
  1.1309 +					if (typeid(*dst) == typeid(BranchObj) ) 
  1.1310 +					{
  1.1311 +						// Get number in parent
  1.1312 +						n=parser.parInt (ok,1);
  1.1313 +						if (ok)
  1.1314 +						{
  1.1315 +							selb->linkTo ((BranchObj*)(dst),n);
  1.1316 +							xelection.update();
  1.1317 +						}	
  1.1318 +					} else if (typeid(*dst) == typeid(MapCenterObj) ) 
  1.1319 +					{
  1.1320 +						selb->linkTo ((BranchObj*)(dst),-1);
  1.1321 +						// Get coordinates of mainbranch
  1.1322 +						x=parser.parDouble(ok,2);
  1.1323 +						if (ok)
  1.1324 +						{
  1.1325 +							y=parser.parDouble(ok,3);
  1.1326 +							if (ok) 
  1.1327 +							{
  1.1328 +								selb->move (x,y);
  1.1329 +								xelection.update();
  1.1330 +							}
  1.1331 +						}
  1.1332 +					}	
  1.1333 +				}	
  1.1334 +			}	
  1.1335 +		} else if ( xelection.type() == Selection::FloatImage) 
  1.1336 +		{
  1.1337 +			if (parser.checkParCount(1))
  1.1338 +			{
  1.1339 +				// 0	selectstring of parent
  1.1340 +				s=parser.parString(ok,0);
  1.1341 +				LinkableMapObj *dst=model->findObjBySelect (s);
  1.1342 +				if (dst)
  1.1343 +				{	
  1.1344 +					if (typeid(*dst) == typeid(BranchObj) ||
  1.1345 +						typeid(*dst) == typeid(MapCenterObj)) 
  1.1346 +						linkTo (model->getSelectString(dst));
  1.1347 +				} else	
  1.1348 +					parser.setError (Aborted,"Destination is not a branch");
  1.1349 +			}		
  1.1350 +		} else
  1.1351 +			parser.setError (Aborted,"Type of selection is not a floatimage or branch");
  1.1352 +	/////////////////////////////////////////////////////////////////////
  1.1353 +	} else if (com=="loadImage")
  1.1354 +	{
  1.1355 +		if (xelection.isEmpty())
  1.1356 +		{
  1.1357 +			parser.setError (Aborted,"Nothing selected");
  1.1358 +		} else if (! selb )
  1.1359 +		{				  
  1.1360 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1361 +		} else if (parser.checkParCount(1))
  1.1362 +		{
  1.1363 +			s=parser.parString(ok,0);
  1.1364 +			if (ok) loadFloatImageInt (s);
  1.1365 +		}	
  1.1366 +	/////////////////////////////////////////////////////////////////////
  1.1367 +	} else if (com=="moveBranchUp")
  1.1368 +	{
  1.1369 +		if (xelection.isEmpty() )
  1.1370 +		{
  1.1371 +			parser.setError (Aborted,"Nothing selected");
  1.1372 +		} else if (! selb )
  1.1373 +		{				  
  1.1374 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1375 +		} else if (parser.checkParCount(0))
  1.1376 +		{
  1.1377 +			moveBranchUp();
  1.1378 +		}	
  1.1379 +	/////////////////////////////////////////////////////////////////////
  1.1380 +	} else if (com=="moveBranchDown")
  1.1381 +	{
  1.1382 +		if (xelection.isEmpty() )
  1.1383 +		{
  1.1384 +			parser.setError (Aborted,"Nothing selected");
  1.1385 +		} else if (! selb )
  1.1386 +		{				  
  1.1387 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1388 +		} else if (parser.checkParCount(0))
  1.1389 +		{
  1.1390 +			moveBranchDown();
  1.1391 +		}	
  1.1392 +	/////////////////////////////////////////////////////////////////////
  1.1393 +	} else if (com=="move")
  1.1394 +	{
  1.1395 +		if (xelection.isEmpty() )
  1.1396 +		{
  1.1397 +			parser.setError (Aborted,"Nothing selected");
  1.1398 +		} else if ( xelection.type()!=Selection::Branch  && 
  1.1399 +					xelection.type()!=Selection::MapCenter  &&
  1.1400 +					xelection.type()!=Selection::FloatImage )
  1.1401 +		{				  
  1.1402 +			parser.setError (Aborted,"Type of selection is not a branch or floatimage");
  1.1403 +		} else if (parser.checkParCount(2))
  1.1404 +		{	
  1.1405 +			x=parser.parDouble (ok,0);
  1.1406 +			if (ok)
  1.1407 +			{
  1.1408 +				y=parser.parDouble (ok,1);
  1.1409 +				if (ok) move (x,y);
  1.1410 +			}
  1.1411 +		}	
  1.1412 +	/////////////////////////////////////////////////////////////////////
  1.1413 +	} else if (com=="moveRel")
  1.1414 +	{
  1.1415 +		if (xelection.isEmpty() )
  1.1416 +		{
  1.1417 +			parser.setError (Aborted,"Nothing selected");
  1.1418 +		} else if ( xelection.type()!=Selection::Branch  && 
  1.1419 +					xelection.type()!=Selection::MapCenter  &&
  1.1420 +					xelection.type()!=Selection::FloatImage )
  1.1421 +		{				  
  1.1422 +			parser.setError (Aborted,"Type of selection is not a branch or floatimage");
  1.1423 +		} else if (parser.checkParCount(2))
  1.1424 +		{	
  1.1425 +			x=parser.parDouble (ok,0);
  1.1426 +			if (ok)
  1.1427 +			{
  1.1428 +				y=parser.parDouble (ok,1);
  1.1429 +				if (ok) moveRel (x,y);
  1.1430 +			}
  1.1431 +		}	
  1.1432 +	/////////////////////////////////////////////////////////////////////
  1.1433 +	} else if (com=="nop")
  1.1434 +	{
  1.1435 +	/////////////////////////////////////////////////////////////////////
  1.1436 +	} else if (com=="paste")
  1.1437 +	{
  1.1438 +		if (xelection.isEmpty() )
  1.1439 +		{
  1.1440 +			parser.setError (Aborted,"Nothing selected");
  1.1441 +		} else if (! selb )
  1.1442 +		{				  
  1.1443 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1444 +		} else if (parser.checkParCount(1))
  1.1445 +		{	
  1.1446 +			n=parser.parInt (ok,0);
  1.1447 +			if (ok) pasteNoSave(n);
  1.1448 +		}	
  1.1449 +	/////////////////////////////////////////////////////////////////////
  1.1450 +	} else if (com=="qa")
  1.1451 +	{
  1.1452 +		if (xelection.isEmpty() )
  1.1453 +		{
  1.1454 +			parser.setError (Aborted,"Nothing selected");
  1.1455 +		} else if (! selb )
  1.1456 +		{				  
  1.1457 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1458 +		} else if (parser.checkParCount(4))
  1.1459 +		{	
  1.1460 +			QString c,u;
  1.1461 +			c=parser.parString (ok,0);
  1.1462 +			if (!ok)
  1.1463 +			{
  1.1464 +				parser.setError (Aborted,"No comment given");
  1.1465 +			} else
  1.1466 +			{
  1.1467 +				s=parser.parString (ok,1);
  1.1468 +				if (!ok)
  1.1469 +				{
  1.1470 +					parser.setError (Aborted,"First parameter is not a string");
  1.1471 +				} else
  1.1472 +				{
  1.1473 +					t=parser.parString (ok,2);
  1.1474 +					if (!ok)
  1.1475 +					{
  1.1476 +						parser.setError (Aborted,"Condition is not a string");
  1.1477 +					} else
  1.1478 +					{
  1.1479 +						u=parser.parString (ok,3);
  1.1480 +						if (!ok)
  1.1481 +						{
  1.1482 +							parser.setError (Aborted,"Third parameter is not a string");
  1.1483 +						} else
  1.1484 +						{
  1.1485 +							if (s!="heading")
  1.1486 +							{
  1.1487 +								parser.setError (Aborted,"Unknown type: "+s);
  1.1488 +							} else
  1.1489 +							{
  1.1490 +								if (! (t=="eq") ) 
  1.1491 +								{
  1.1492 +									parser.setError (Aborted,"Unknown operator: "+t);
  1.1493 +								} else
  1.1494 +								{
  1.1495 +									if (! selb    )
  1.1496 +									{
  1.1497 +										parser.setError (Aborted,"Type of selection is not a branch");
  1.1498 +									} else
  1.1499 +									{
  1.1500 +										if (selb->getHeading() == u)
  1.1501 +										{
  1.1502 +											cout << "PASSED: " << qPrintable (c)  << endl;
  1.1503 +										} else
  1.1504 +										{
  1.1505 +											cout << "FAILED: " << qPrintable (c)  << endl;
  1.1506 +										}
  1.1507 +									}
  1.1508 +								}
  1.1509 +							}
  1.1510 +						} 
  1.1511 +					} 
  1.1512 +				} 
  1.1513 +			}
  1.1514 +		}	
  1.1515 +	/////////////////////////////////////////////////////////////////////
  1.1516 +	} else if (com=="saveImage")
  1.1517 +	{
  1.1518 +		FloatImageObj *fio=xelection.getFloatImage();
  1.1519 +		if (!fio)
  1.1520 +		{
  1.1521 +			parser.setError (Aborted,"Type of selection is not an image");
  1.1522 +		} else if (parser.checkParCount(2))
  1.1523 +		{
  1.1524 +			s=parser.parString(ok,0);
  1.1525 +			if (ok)
  1.1526 +			{
  1.1527 +				t=parser.parString(ok,1);
  1.1528 +				if (ok) saveFloatImageInt (fio,t,s);
  1.1529 +			}
  1.1530 +		}	
  1.1531 +	/////////////////////////////////////////////////////////////////////
  1.1532 +	} else if (com=="scroll")
  1.1533 +	{
  1.1534 +		if (xelection.isEmpty() )
  1.1535 +		{
  1.1536 +			parser.setError (Aborted,"Nothing selected");
  1.1537 +		} else if (! selb )
  1.1538 +		{				  
  1.1539 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1540 +		} else if (parser.checkParCount(0))
  1.1541 +		{	
  1.1542 +			if (!scrollBranch (selb))	
  1.1543 +				parser.setError (Aborted,"Could not scroll branch");
  1.1544 +		}	
  1.1545 +	/////////////////////////////////////////////////////////////////////
  1.1546 +	} else if (com=="select")
  1.1547 +	{
  1.1548 +		if (parser.checkParCount(1))
  1.1549 +		{
  1.1550 +			s=parser.parString(ok,0);
  1.1551 +			if (ok) select (s);
  1.1552 +		}	
  1.1553 +	/////////////////////////////////////////////////////////////////////
  1.1554 +	} else if (com=="selectLastBranch")
  1.1555 +	{
  1.1556 +		if (xelection.isEmpty() )
  1.1557 +		{
  1.1558 +			parser.setError (Aborted,"Nothing selected");
  1.1559 +		} else if (! selb )
  1.1560 +		{				  
  1.1561 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1562 +		} else if (parser.checkParCount(0))
  1.1563 +		{	
  1.1564 +			BranchObj *bo=selb->getLastBranch();
  1.1565 +			if (!bo)
  1.1566 +				parser.setError (Aborted,"Could not select last branch");
  1.1567 +			selectInt (bo);	
  1.1568 +				
  1.1569 +		}	
  1.1570 +	/////////////////////////////////////////////////////////////////////
  1.1571 +	} else if (com=="selectLastImage")
  1.1572 +	{
  1.1573 +		if (xelection.isEmpty() )
  1.1574 +		{
  1.1575 +			parser.setError (Aborted,"Nothing selected");
  1.1576 +		} else if (! selb )
  1.1577 +		{				  
  1.1578 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1579 +		} else if (parser.checkParCount(0))
  1.1580 +		{	
  1.1581 +			FloatImageObj *fio=selb->getLastFloatImage();
  1.1582 +			if (!fio)
  1.1583 +				parser.setError (Aborted,"Could not select last image");
  1.1584 +			selectInt (fio);	
  1.1585 +				
  1.1586 +		}	
  1.1587 +	/////////////////////////////////////////////////////////////////////
  1.1588 +	} else if (com=="selectLatestAdded")
  1.1589 +	{
  1.1590 +		if (latestSelection.isEmpty() )
  1.1591 +		{
  1.1592 +			parser.setError (Aborted,"No latest added object");
  1.1593 +		} else
  1.1594 +		{	
  1.1595 +			if (!select (latestSelection))
  1.1596 +				parser.setError (Aborted,"Could not select latest added object "+latestSelection);
  1.1597 +		}	
  1.1598 +	/////////////////////////////////////////////////////////////////////
  1.1599 +	} else if (com=="setFrameType")
  1.1600 +	{
  1.1601 +		if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
  1.1602 +		{
  1.1603 +			parser.setError (Aborted,"Type of selection does not allow setting frame type");
  1.1604 +		}
  1.1605 +		else if (parser.checkParCount(1))
  1.1606 +		{
  1.1607 +			s=parser.parString(ok,0);
  1.1608 +			if (ok) setFrameType (s);
  1.1609 +		}	
  1.1610 +	/////////////////////////////////////////////////////////////////////
  1.1611 +	} else if (com=="setFramePenColor")
  1.1612 +	{
  1.1613 +		if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
  1.1614 +		{
  1.1615 +			parser.setError (Aborted,"Type of selection does not allow setting of pen color");
  1.1616 +		}
  1.1617 +		else if (parser.checkParCount(1))
  1.1618 +		{
  1.1619 +			QColor c=parser.parColor(ok,0);
  1.1620 +			if (ok) setFramePenColor (c);
  1.1621 +		}	
  1.1622 +	/////////////////////////////////////////////////////////////////////
  1.1623 +	} else if (com=="setFrameBrushColor")
  1.1624 +	{
  1.1625 +		if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
  1.1626 +		{
  1.1627 +			parser.setError (Aborted,"Type of selection does not allow setting brush color");
  1.1628 +		}
  1.1629 +		else if (parser.checkParCount(1))
  1.1630 +		{
  1.1631 +			QColor c=parser.parColor(ok,0);
  1.1632 +			if (ok) setFrameBrushColor (c);
  1.1633 +		}	
  1.1634 +	/////////////////////////////////////////////////////////////////////
  1.1635 +	} else if (com=="setFramePadding")
  1.1636 +	{
  1.1637 +		if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
  1.1638 +		{
  1.1639 +			parser.setError (Aborted,"Type of selection does not allow setting frame padding");
  1.1640 +		}
  1.1641 +		else if (parser.checkParCount(1))
  1.1642 +		{
  1.1643 +			n=parser.parInt(ok,0);
  1.1644 +			if (ok) setFramePadding(n);
  1.1645 +		}	
  1.1646 +	/////////////////////////////////////////////////////////////////////
  1.1647 +	} else if (com=="setFrameBorderWidth")
  1.1648 +	{
  1.1649 +		if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
  1.1650 +		{
  1.1651 +			parser.setError (Aborted,"Type of selection does not allow setting frame border width");
  1.1652 +		}
  1.1653 +		else if (parser.checkParCount(1))
  1.1654 +		{
  1.1655 +			n=parser.parInt(ok,0);
  1.1656 +			if (ok) setFrameBorderWidth (n);
  1.1657 +		}	
  1.1658 +	/////////////////////////////////////////////////////////////////////
  1.1659 +	} else if (com=="setMapAuthor")
  1.1660 +	{
  1.1661 +		if (parser.checkParCount(1))
  1.1662 +		{
  1.1663 +			s=parser.parString(ok,0);
  1.1664 +			if (ok) setMapAuthor (s);
  1.1665 +		}	
  1.1666 +	/////////////////////////////////////////////////////////////////////
  1.1667 +	} else if (com=="setMapComment")
  1.1668 +	{
  1.1669 +		if (parser.checkParCount(1))
  1.1670 +		{
  1.1671 +			s=parser.parString(ok,0);
  1.1672 +			if (ok) setMapComment(s);
  1.1673 +		}	
  1.1674 +	/////////////////////////////////////////////////////////////////////
  1.1675 +	} else if (com=="setMapBackgroundColor")
  1.1676 +	{
  1.1677 +		if (xelection.isEmpty() )
  1.1678 +		{
  1.1679 +			parser.setError (Aborted,"Nothing selected");
  1.1680 +		} else if (! xelection.getBranch() )
  1.1681 +		{				  
  1.1682 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1683 +		} else if (parser.checkParCount(1))
  1.1684 +		{
  1.1685 +			QColor c=parser.parColor (ok,0);
  1.1686 +			if (ok) setMapBackgroundColor (c);
  1.1687 +		}	
  1.1688 +	/////////////////////////////////////////////////////////////////////
  1.1689 +	} else if (com=="setMapDefLinkColor")
  1.1690 +	{
  1.1691 +		if (xelection.isEmpty() )
  1.1692 +		{
  1.1693 +			parser.setError (Aborted,"Nothing selected");
  1.1694 +		} else if (! selb )
  1.1695 +		{				  
  1.1696 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1697 +		} else if (parser.checkParCount(1))
  1.1698 +		{
  1.1699 +			QColor c=parser.parColor (ok,0);
  1.1700 +			if (ok) setMapDefLinkColor (c);
  1.1701 +		}	
  1.1702 +	/////////////////////////////////////////////////////////////////////
  1.1703 +	} else if (com=="setMapLinkStyle")
  1.1704 +	{
  1.1705 +		if (parser.checkParCount(1))
  1.1706 +		{
  1.1707 +			s=parser.parString (ok,0);
  1.1708 +			if (ok) setMapLinkStyle(s);
  1.1709 +		}	
  1.1710 +	/////////////////////////////////////////////////////////////////////
  1.1711 +	} else if (com=="setHeading")
  1.1712 +	{
  1.1713 +		if (xelection.isEmpty() )
  1.1714 +		{
  1.1715 +			parser.setError (Aborted,"Nothing selected");
  1.1716 +		} else if (! selb )
  1.1717 +		{				  
  1.1718 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1719 +		} else if (parser.checkParCount(1))
  1.1720 +		{
  1.1721 +			s=parser.parString (ok,0);
  1.1722 +			if (ok) 
  1.1723 +				setHeading (s);
  1.1724 +		}	
  1.1725 +	/////////////////////////////////////////////////////////////////////
  1.1726 +	} else if (com=="setHideExport")
  1.1727 +	{
  1.1728 +		if (xelection.isEmpty() )
  1.1729 +		{
  1.1730 +			parser.setError (Aborted,"Nothing selected");
  1.1731 +		} else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage)
  1.1732 +		{				  
  1.1733 +			parser.setError (Aborted,"Type of selection is not a branch or floatimage");
  1.1734 +		} else if (parser.checkParCount(1))
  1.1735 +		{
  1.1736 +			b=parser.parBool(ok,0);
  1.1737 +			if (ok) setHideExport (b);
  1.1738 +		}
  1.1739 +	/////////////////////////////////////////////////////////////////////
  1.1740 +	} else if (com=="setIncludeImagesHorizontally")
  1.1741 +	{ 
  1.1742 +		if (xelection.isEmpty() )
  1.1743 +		{
  1.1744 +			parser.setError (Aborted,"Nothing selected");
  1.1745 +		} else if (! selb)
  1.1746 +		{				  
  1.1747 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1748 +		} else if (parser.checkParCount(1))
  1.1749 +		{
  1.1750 +			b=parser.parBool(ok,0);
  1.1751 +			if (ok) setIncludeImagesHor(b);
  1.1752 +		}
  1.1753 +	/////////////////////////////////////////////////////////////////////
  1.1754 +	} else if (com=="setIncludeImagesVertically")
  1.1755 +	{
  1.1756 +		if (xelection.isEmpty() )
  1.1757 +		{
  1.1758 +			parser.setError (Aborted,"Nothing selected");
  1.1759 +		} else if (! selb)
  1.1760 +		{				  
  1.1761 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1762 +		} else if (parser.checkParCount(1))
  1.1763 +		{
  1.1764 +			b=parser.parBool(ok,0);
  1.1765 +			if (ok) setIncludeImagesVer(b);
  1.1766 +		}
  1.1767 +	/////////////////////////////////////////////////////////////////////
  1.1768 +	} else if (com=="setHideLinkUnselected")
  1.1769 +	{
  1.1770 +		if (xelection.isEmpty() )
  1.1771 +		{
  1.1772 +			parser.setError (Aborted,"Nothing selected");
  1.1773 +		} else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
  1.1774 +		{				  
  1.1775 +			parser.setError (Aborted,"Type of selection does not allow hiding the link");
  1.1776 +		} else if (parser.checkParCount(1))
  1.1777 +		{
  1.1778 +			b=parser.parBool(ok,0);
  1.1779 +			if (ok) setHideLinkUnselected(b);
  1.1780 +		}
  1.1781 +	/////////////////////////////////////////////////////////////////////
  1.1782 +	} else if (com=="setSelectionColor")
  1.1783 +	{
  1.1784 +		if (parser.checkParCount(1))
  1.1785 +		{
  1.1786 +			QColor c=parser.parColor (ok,0);
  1.1787 +			if (ok) setSelectionColorInt (c);
  1.1788 +		}	
  1.1789 +	/////////////////////////////////////////////////////////////////////
  1.1790 +	} else if (com=="setURL")
  1.1791 +	{
  1.1792 +		if (xelection.isEmpty() )
  1.1793 +		{
  1.1794 +			parser.setError (Aborted,"Nothing selected");
  1.1795 +		} else if (! selb )
  1.1796 +		{				  
  1.1797 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1798 +		} else if (parser.checkParCount(1))
  1.1799 +		{
  1.1800 +			s=parser.parString (ok,0);
  1.1801 +			if (ok) setURL(s);
  1.1802 +		}	
  1.1803 +	/////////////////////////////////////////////////////////////////////
  1.1804 +	} else if (com=="setVymLink")
  1.1805 +	{
  1.1806 +		if (xelection.isEmpty() )
  1.1807 +		{
  1.1808 +			parser.setError (Aborted,"Nothing selected");
  1.1809 +		} else if (! selb )
  1.1810 +		{				  
  1.1811 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1812 +		} else if (parser.checkParCount(1))
  1.1813 +		{
  1.1814 +			s=parser.parString (ok,0);
  1.1815 +			if (ok) setVymLinkInt(s);
  1.1816 +		}	
  1.1817 +	}
  1.1818 +	/////////////////////////////////////////////////////////////////////
  1.1819 +	else if (com=="setFlag")
  1.1820 +	{
  1.1821 +		if (xelection.isEmpty() )
  1.1822 +		{
  1.1823 +			parser.setError (Aborted,"Nothing selected");
  1.1824 +		} else if (! selb )
  1.1825 +		{				  
  1.1826 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1827 +		} else if (parser.checkParCount(1))
  1.1828 +		{
  1.1829 +			s=parser.parString(ok,0);
  1.1830 +			if (ok) 
  1.1831 +			{
  1.1832 +				selb->activateStandardFlag(s);
  1.1833 +				selb->updateFlagsToolbar();
  1.1834 +			}	
  1.1835 +		}
  1.1836 +	/////////////////////////////////////////////////////////////////////
  1.1837 +	} else if (com=="setFrameType")
  1.1838 +	{
  1.1839 +		if (xelection.isEmpty() )
  1.1840 +		{
  1.1841 +			parser.setError (Aborted,"Nothing selected");
  1.1842 +		} else if (! selb )
  1.1843 +		{				  
  1.1844 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1845 +		} else if (parser.checkParCount(1))
  1.1846 +		{
  1.1847 +			s=parser.parString(ok,0);
  1.1848 +			if (ok) 
  1.1849 +				setFrameType (s);
  1.1850 +		}
  1.1851 +	/////////////////////////////////////////////////////////////////////
  1.1852 +	} else if (com=="sortChildren")
  1.1853 +	{
  1.1854 +		if (xelection.isEmpty() )
  1.1855 +		{
  1.1856 +			parser.setError (Aborted,"Nothing selected");
  1.1857 +		} else if (! selb )
  1.1858 +		{				  
  1.1859 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1860 +		} else if (parser.checkParCount(0))
  1.1861 +		{
  1.1862 +			sortChildren();
  1.1863 +		}
  1.1864 +	/////////////////////////////////////////////////////////////////////
  1.1865 +	} else if (com=="toggleFlag")
  1.1866 +	{
  1.1867 +		if (xelection.isEmpty() )
  1.1868 +		{
  1.1869 +			parser.setError (Aborted,"Nothing selected");
  1.1870 +		} else if (! selb )
  1.1871 +		{				  
  1.1872 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1873 +		} else if (parser.checkParCount(1))
  1.1874 +		{
  1.1875 +			s=parser.parString(ok,0);
  1.1876 +			if (ok) 
  1.1877 +			{
  1.1878 +				selb->toggleStandardFlag(s);	
  1.1879 +				selb->updateFlagsToolbar();
  1.1880 +			}	
  1.1881 +		}
  1.1882 +	/////////////////////////////////////////////////////////////////////
  1.1883 +	} else if (com=="unscroll")
  1.1884 +	{
  1.1885 +		if (xelection.isEmpty() )
  1.1886 +		{
  1.1887 +			parser.setError (Aborted,"Nothing selected");
  1.1888 +		} else if (! selb )
  1.1889 +		{				  
  1.1890 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1891 +		} else if (parser.checkParCount(0))
  1.1892 +		{	
  1.1893 +			if (!unscrollBranch (selb))	
  1.1894 +				parser.setError (Aborted,"Could not unscroll branch");
  1.1895 +		}	
  1.1896 +	/////////////////////////////////////////////////////////////////////
  1.1897 +	} else if (com=="unscrollChilds")
  1.1898 +	{
  1.1899 +		if (xelection.isEmpty() )
  1.1900 +		{
  1.1901 +			parser.setError (Aborted,"Nothing selected");
  1.1902 +		} else if (! selb )
  1.1903 +		{				  
  1.1904 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1905 +		} else if (parser.checkParCount(0))
  1.1906 +		{	
  1.1907 +			unscrollChilds ();
  1.1908 +		}	
  1.1909 +	/////////////////////////////////////////////////////////////////////
  1.1910 +	} else if (com=="unsetFlag")
  1.1911 +	{
  1.1912 +		if (xelection.isEmpty() )
  1.1913 +		{
  1.1914 +			parser.setError (Aborted,"Nothing selected");
  1.1915 +		} else if (! selb )
  1.1916 +		{				  
  1.1917 +			parser.setError (Aborted,"Type of selection is not a branch");
  1.1918 +		} else if (parser.checkParCount(1))
  1.1919 +		{
  1.1920 +			s=parser.parString(ok,0);
  1.1921 +			if (ok) 
  1.1922 +			{
  1.1923 +				selb->deactivateStandardFlag(s);
  1.1924 +				selb->updateFlagsToolbar();
  1.1925 +			}	
  1.1926 +		}
  1.1927 +	} else
  1.1928 +		parser.setError (Aborted,"Unknown command");
  1.1929 +
  1.1930 +	// Any errors?
  1.1931 +	if (parser.errorLevel()==NoError)
  1.1932 +	{
  1.1933 +		// setChanged();  FIXME should not be called e.g. for export?!
  1.1934 +		model->reposition();
  1.1935 +	}	
  1.1936 +	else	
  1.1937 +	{
  1.1938 +		// TODO Error handling
  1.1939 +		qWarning("MapEditor::parseAtom: Error!");
  1.1940 +		qWarning(parser.errorMessage());
  1.1941 +	} 
  1.1942 +}
  1.1943 +
  1.1944 +void MapEditor::runScript (QString script)
  1.1945 +{
  1.1946 +	parser.setScript (script);
  1.1947 +	parser.runScript();
  1.1948 +	while (parser.next() ) 
  1.1949 +		parseAtom(parser.getAtom());
  1.1950 +}
  1.1951  
  1.1952  bool MapEditor::isDefault()
  1.1953  {
  1.1954      return mapDefault;
  1.1955  }
  1.1956  
  1.1957 -bool MapEditor::isUnsaved()
  1.1958 -{
  1.1959 -    return mapUnsaved;
  1.1960 -}
  1.1961 -
  1.1962  bool MapEditor::hasChanged()
  1.1963  {
  1.1964      return mapChanged;
  1.1965 @@ -598,49 +1485,55 @@
  1.1966  
  1.1967  void MapEditor::setChanged()
  1.1968  {
  1.1969 +	if (!mapChanged)
  1.1970 +		autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
  1.1971  	mapChanged=true;
  1.1972  	mapDefault=false;
  1.1973  	mapUnsaved=true;
  1.1974 -	actionEditUndo->setEnabled (true);
  1.1975 -	actionFileSave->setEnabled (true);
  1.1976  	findReset();
  1.1977 +
  1.1978  }
  1.1979  
  1.1980  void MapEditor::closeMap()
  1.1981  {
  1.1982 -	// Finish open lineEdits
  1.1983 -	if (lineedit) finishedLineEditNoSave();
  1.1984 -
  1.1985  	// Unselect before disabling the toolbar actions
  1.1986 -	if (selection) selection->unselect();
  1.1987 -	selection=NULL;
  1.1988 +	if (!xelection.isEmpty() ) xelection.unselect();
  1.1989 +	xelection.clear();
  1.1990  	updateActions();
  1.1991  
  1.1992      clear();
  1.1993 -	close();
  1.1994 +	// close();  FIXME needed?
  1.1995  }
  1.1996  
  1.1997 -void MapEditor::setFilePath(QString fname)
  1.1998 -{
  1.1999 -	setFilePath (fname,fname);
  1.2000 +void MapEditor::setFilePath(QString fpath, QString destname)
  1.2001 +{
  1.2002 +	if (fpath.isEmpty() || fpath=="")
  1.2003 +	{
  1.2004 +		filePath="";
  1.2005 +		fileName="";
  1.2006 +		destPath="";
  1.2007 +	} else
  1.2008 +	{
  1.2009 +		filePath=fpath;		// becomes absolute path
  1.2010 +		fileName=fpath;		// gets stripped of path
  1.2011 +		destPath=destname;	// needed for vymlinks and during load to reset fileChangedTime
  1.2012 +
  1.2013 +		// If fpath is not an absolute path, complete it
  1.2014 +		filePath=QDir(fpath).absPath();
  1.2015 +		fileDir=filePath.left (1+filePath.findRev ("/"));
  1.2016 +
  1.2017 +		// Set short name, too. Search from behind:
  1.2018 +		int i=fileName.findRev("/");
  1.2019 +		if (i>=0) fileName=fileName.remove (0,i+1);
  1.2020 +
  1.2021 +		// Forget the .vym (or .xml) for name of map
  1.2022 +		mapName=fileName.left(fileName.findRev(".",-1,true) );
  1.2023 +	}
  1.2024  }
  1.2025  
  1.2026 -void MapEditor::setFilePath(QString fname, QString destname)
  1.2027 -{
  1.2028 -	filePath=fname;
  1.2029 -	fileName=fname;
  1.2030 -	destPath=destname;
  1.2031 -
  1.2032 -	// If fname is not an absolute path, complete it
  1.2033 -	filePath=QDir(fname).absPath();
  1.2034 -	fileDir=filePath.left (1+filePath.findRev ("/"));
  1.2035 -
  1.2036 -	// Set short name, too. Search from behind:
  1.2037 -	int i=fileName.findRev("/");
  1.2038 -	if (i>=0) fileName=fileName.remove (0,i+1);
  1.2039 -
  1.2040 -	// Forget the .vym (or .xml) for name of map
  1.2041 -	mapName=fileName.left(fileName.findRev(".",-1,true) );
  1.2042 +void MapEditor::setFilePath(QString fpath)
  1.2043 +{
  1.2044 +	setFilePath (fpath,fpath);
  1.2045  }
  1.2046  
  1.2047  QString MapEditor::getFilePath()
  1.2048 @@ -663,150 +1556,311 @@
  1.2049  	return destPath;
  1.2050  }
  1.2051  
  1.2052 -int MapEditor::load (QString &fname, const LoadMode &lmode)
  1.2053 -{
  1.2054 -	// Finish open lineEdits
  1.2055 -	if (lineedit) finishedLineEditNoSave();
  1.2056 -
  1.2057 -	int returnCode=0;
  1.2058 -
  1.2059 +ErrorCode MapEditor::load (QString fname, const LoadMode &lmode, const FileType &ftype)
  1.2060 +{
  1.2061 +	ErrorCode err=success;
  1.2062 +
  1.2063 +	parseBaseHandler *handler;
  1.2064 +	fileType=ftype;
  1.2065 +	switch (fileType)
  1.2066 +	{
  1.2067 +		case VymMap: handler=new parseVYMHandler; break;
  1.2068 +		case FreemindMap : handler=new parseFreemindHandler; break;
  1.2069 +		default: 
  1.2070 +			QMessageBox::critical( 0, tr( "Critical Parse Error" ),
  1.2071 +				   "Unknown FileType in MapEditor::load()");
  1.2072 +		return aborted;	
  1.2073 +	}
  1.2074  	if (lmode==NewMap)
  1.2075  	{
  1.2076 -		if (selection) selection->unselect();
  1.2077 -		selection=NULL;
  1.2078 -		mapCenter->clear();
  1.2079 -		mapCenter->setMapEditor(this);
  1.2080 +		xelection.clear();
  1.2081 +		model->setMapEditor(this);
  1.2082  		// (map state is set later at end of load...)
  1.2083  	} else
  1.2084  	{
  1.2085 -		setChanged();
  1.2086 -		saveState(PartOfMap,selection);
  1.2087 +		BranchObj *bo=xelection.getBranch();
  1.2088 +		if (!bo) return aborted;
  1.2089 +		if (lmode==ImportAdd)
  1.2090 +			saveStateChangingPart(
  1.2091 +				bo,
  1.2092 +				bo,
  1.2093 +				QString("addMapInsert (%1)").arg(fname),
  1.2094 +				QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
  1.2095 +		else	
  1.2096 +			saveStateChangingPart(
  1.2097 +				bo,
  1.2098 +				bo,
  1.2099 +				QString("addMapReplace(%1)").arg(fname),
  1.2100 +				QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
  1.2101  	}	
  1.2102 -	
  1.2103      
  1.2104 -    mapBuilderHandler handler;
  1.2105 -	QFile file( fname );
  1.2106 +
  1.2107 +	// Create temporary directory for packing
  1.2108 +	bool ok;
  1.2109 +	QString tmpZipDir=makeTmpDir (ok,"vym-pack");
  1.2110 +	if (!ok)
  1.2111 +	{
  1.2112 +		QMessageBox::critical( 0, tr( "Critical Load Error" ),
  1.2113 +		   tr("Couldn't create temporary directory before load\n"));
  1.2114 +		return aborted; 
  1.2115 +	}
  1.2116 +
  1.2117 +	// Try to unzip file
  1.2118 +	err=unzipDir (tmpZipDir,fname);
  1.2119 +	QString xmlfile;
  1.2120 +	if (err==nozip)
  1.2121 +	{
  1.2122 +		xmlfile=fname;
  1.2123 +		zipped=false;
  1.2124 +	} else
  1.2125 +	{
  1.2126 +		zipped=true;
  1.2127 +		
  1.2128 +		// Look for mapname.xml
  1.2129 +		xmlfile= fname.left(fname.findRev(".",-1,true));
  1.2130 +		xmlfile=xmlfile.section( '/', -1 );
  1.2131 +		QFile mfile( tmpZipDir + "/" + xmlfile + ".xml");
  1.2132 +		if (!mfile.exists() )
  1.2133 +		{
  1.2134 +			// mapname.xml does not exist, well, 
  1.2135 +			// maybe someone renamed the mapname.vym file...
  1.2136 +			// Try to find any .xml in the toplevel 
  1.2137 +			// directory of the .vym file
  1.2138 +			QStringList flist=QDir (tmpZipDir).entryList("*.xml");
  1.2139 +			if (flist.count()==1) 
  1.2140 +			{
  1.2141 +				// Only one entry, take this one
  1.2142 +				xmlfile=tmpZipDir + "/"+flist.first();
  1.2143 +			} else
  1.2144 +			{
  1.2145 +				for ( QStringList::Iterator it = flist.begin(); it != flist.end(); ++it ) 
  1.2146 +					*it=tmpZipDir + "/" + *it;
  1.2147 +				// TODO Multiple entries, load all (but only the first one into this ME)
  1.2148 +				//mainWindow->fileLoadFromTmp (flist);
  1.2149 +				//returnCode=1;	// Silently forget this attempt to load
  1.2150 +				qWarning ("MainWindow::load (fn)  multimap found...");
  1.2151 +			}	
  1.2152 +				
  1.2153 +			if (flist.isEmpty() )
  1.2154 +			{
  1.2155 +				QMessageBox::critical( 0, tr( "Critical Load Error" ),
  1.2156 +						   tr("Couldn't find a map (*.xml) in .vym archive.\n"));
  1.2157 +				err=aborted;				   
  1.2158 +			}	
  1.2159 +		} //file doesn't exist	
  1.2160 +		else
  1.2161 +			xmlfile=mfile.name();
  1.2162 +	}
  1.2163 +
  1.2164 +	QFile file( xmlfile);
  1.2165  
  1.2166  	// I am paranoid: file should exist anyway
  1.2167  	// according to check in mainwindow.
  1.2168  	if (!file.exists() )
  1.2169  	{
  1.2170  		QMessageBox::critical( 0, tr( "Critical Parse Error" ),
  1.2171 -				   tr("Couldn't open map " +fname)+".");
  1.2172 -		returnCode=1;	
  1.2173 +				   tr(QString("Couldn't open map %1").arg(file.name())));
  1.2174 +		err=aborted;	
  1.2175  	} else
  1.2176  	{
  1.2177 -		blockreposition=true;
  1.2178 +		bool blockSaveStateOrg=blockSaveState;
  1.2179 +		blockReposition=true;
  1.2180 +		blockSaveState=true;
  1.2181  		QXmlInputSource source( file);
  1.2182  		QXmlSimpleReader reader;
  1.2183 -		reader.setContentHandler( &handler );
  1.2184 -		reader.setErrorHandler( &handler );
  1.2185 -		handler.setMapEditor( this );
  1.2186 -		handler.setTmpDir (filePath.left(filePath.findRev("/",-1)));	// needed to load files with rel. path
  1.2187 -		handler.setLoadMode (lmode);
  1.2188 +		reader.setContentHandler( handler );
  1.2189 +		reader.setErrorHandler( handler );
  1.2190 +		handler->setModel ( model);
  1.2191 +
  1.2192 +
  1.2193 +		// We need to set the tmpDir in order  to load files with rel. path
  1.2194 +		QString tmpdir;
  1.2195 +		if (zipped)
  1.2196 +			tmpdir=tmpZipDir;
  1.2197 +		else
  1.2198 +			tmpdir=fname.left(fname.findRev("/",-1));	
  1.2199 +		handler->setTmpDir (tmpdir);
  1.2200 +		handler->setInputFile (file.name());
  1.2201 +		handler->setLoadMode (lmode);
  1.2202  		bool ok = reader.parse( source );
  1.2203 -		blockreposition=false;
  1.2204 +		blockReposition=false;
  1.2205 +		blockSaveState=blockSaveStateOrg;
  1.2206  		file.close();
  1.2207  		if ( ok ) 
  1.2208  		{
  1.2209 -			mapCenter->reposition();
  1.2210 -			adjustCanvasSize();
  1.2211 +			model->reposition();	// FIXME reposition the view instead...
  1.2212 +			xelection.update();
  1.2213  			if (lmode==NewMap)
  1.2214  			{
  1.2215  				mapDefault=false;
  1.2216  				mapChanged=false;
  1.2217  				mapUnsaved=false;
  1.2218 +				autosaveTimer->stop();
  1.2219  			}
  1.2220 +
  1.2221 +			// Reset timestamp to check for later updates of file
  1.2222 +			fileChangedTime=QFileInfo (destPath).lastModified();
  1.2223  		} else 
  1.2224  		{
  1.2225  			QMessageBox::critical( 0, tr( "Critical Parse Error" ),
  1.2226 -					   tr( handler.errorProtocol() ) );
  1.2227 +					   tr( handler->errorProtocol() ) );
  1.2228  			// returnCode=1;	
  1.2229  			// Still return "success": the map maybe at least
  1.2230  			// partially read by the parser
  1.2231  		}	
  1.2232  	}	
  1.2233 +
  1.2234 +	// Delete tmpZipDir
  1.2235 +	removeDir (QDir(tmpZipDir));
  1.2236 +
  1.2237  	updateActions();
  1.2238 -	return returnCode;
  1.2239 +
  1.2240 +	return err;
  1.2241  }
  1.2242  
  1.2243 -int MapEditor::save (const SaveMode &savemode)
  1.2244 -{
  1.2245 -	// Finish open lineEdits
  1.2246 -	if (lineedit) finishedLineEditNoSave();
  1.2247 -
  1.2248 -	int returnCode=0;
  1.2249 +ErrorCode MapEditor::save (const SaveMode &savemode)
  1.2250 +{
  1.2251 +	QString tmpZipDir;
  1.2252 +	QString mapFileName;
  1.2253 +	QString safeFilePath;
  1.2254 +
  1.2255 +	ErrorCode err=success;
  1.2256 +
  1.2257 +	if (zipped)
  1.2258 +		// save as .xml
  1.2259 +		mapFileName=mapName+".xml";
  1.2260 +	else
  1.2261 +		// use name given by user, even if he chooses .doc
  1.2262 +		mapFileName=fileName;
  1.2263 +
  1.2264 +	// Look, if we should zip the data:
  1.2265 +	if (!zipped)
  1.2266 +	{
  1.2267 +		QMessageBox mb( vymName,
  1.2268 +			tr("The map %1\ndid not use the compressed "
  1.2269 +			"vym file format.\nWriting it uncompressed will also write images \n"
  1.2270 +			"and flags and thus may overwrite files in the "
  1.2271 +			"given directory\n\nDo you want to write the map").arg(filePath),
  1.2272 +			QMessageBox::Warning,
  1.2273 +			QMessageBox::Yes | QMessageBox::Default,
  1.2274 +			QMessageBox::No ,
  1.2275 +			QMessageBox::Cancel | QMessageBox::Escape);
  1.2276 +		mb.setButtonText( QMessageBox::Yes, tr("compressed (vym default)") );
  1.2277 +		mb.setButtonText( QMessageBox::No, tr("uncompressed") );
  1.2278 +		mb.setButtonText( QMessageBox::Cancel, tr("Cancel"));
  1.2279 +		switch( mb.exec() ) 
  1.2280 +		{
  1.2281 +			case QMessageBox::Yes:
  1.2282 +				// save compressed (default file format)
  1.2283 +				zipped=true;
  1.2284 +				break;
  1.2285 +			case QMessageBox::No:
  1.2286 +				// save uncompressed
  1.2287 +				zipped=false;
  1.2288 +				break;
  1.2289 +			case QMessageBox::Cancel:
  1.2290 +				// do nothing
  1.2291 +				return aborted;
  1.2292 +				break;
  1.2293 +		}
  1.2294 +	}
  1.2295 +
  1.2296 +	// First backup existing file, we 
  1.2297 +	// don't want to add to old zip archives
  1.2298 +	QFile f(destPath);
  1.2299 +	if (f.exists())
  1.2300 +	{
  1.2301 +		if ( settings.value ("/mapeditor/writeBackupFile").toBool())
  1.2302 +		{
  1.2303 +			QString backupFileName(destPath + "~");
  1.2304 +			QFile backupFile(backupFileName);
  1.2305 +			if (backupFile.exists() && !backupFile.remove())
  1.2306 +			{
  1.2307 +				QMessageBox::warning(0, tr("Save Error"),
  1.2308 +									 tr("%1\ncould not be removed before saving").arg(backupFileName));
  1.2309 +			}
  1.2310 +			else if (!f.rename(backupFileName))
  1.2311 +			{
  1.2312 +				QMessageBox::warning(0, tr("Save Error"),
  1.2313 +									 tr("%1\ncould not be renamed before saving").arg(destPath));
  1.2314 +			}
  1.2315 +		}
  1.2316 +	}
  1.2317 +
  1.2318 +	if (zipped)
  1.2319 +	{
  1.2320 +		// Create temporary directory for packing
  1.2321 +		bool ok;
  1.2322 +		tmpZipDir=makeTmpDir (ok,"vym-zip");
  1.2323 +		if (!ok)
  1.2324 +		{
  1.2325 +			QMessageBox::critical( 0, tr( "Critical Load Error" ),
  1.2326 +			   tr("Couldn't create temporary directory before save\n"));
  1.2327 +			return aborted; 
  1.2328 +		}
  1.2329 +
  1.2330 +		safeFilePath=filePath;
  1.2331 +		setFilePath (tmpZipDir+"/"+ mapName+ ".xml", safeFilePath);
  1.2332 +	} // zipped
  1.2333  
  1.2334  	// Create mapName and fileDir
  1.2335  	makeSubDirs (fileDir);
  1.2336 -	QString fname;
  1.2337 -	if (saveZipped())
  1.2338 -		// save as .xml
  1.2339 -		fname=mapName+".xml";
  1.2340 -	else
  1.2341 -		// use name given by user, even if he chooses .doc
  1.2342 -		fname=fileName;
  1.2343 -
  1.2344 -
  1.2345 -	// Check if fname is writeable
  1.2346 -	QFile file( fileDir+fname);
  1.2347 -	if (!file.open( IO_WriteOnly ) ) 
  1.2348 -	{
  1.2349 -		QMessageBox::critical( 0, tr( "Critical Save Error" ),
  1.2350 -					   tr("Couldn't write to ") +fileDir+fname);
  1.2351 -		return 1;
  1.2352 -	}	
  1.2353 -	file.close();
  1.2354  
  1.2355  	QString saveFile;
  1.2356 -	saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),savemode);
  1.2357 -
  1.2358 -	file.setName ( fileDir  + fname);
  1.2359 -	if ( !file.open( IO_WriteOnly ) )
  1.2360 -	{
  1.2361 -		// This should neverever happen
  1.2362 -		QMessageBox::critical(0, tr("Critcal save error"),"MapEditor::save() Couldn't open "+file.name());
  1.2363 -		return 1;
  1.2364 -	}	
  1.2365 -
  1.2366 -	// Write it finally, and write in UTF8, no matter what 
  1.2367 -	QTextStream ts( &file );
  1.2368 -	ts.setEncoding (QTextStream::UnicodeUTF8);
  1.2369 -	ts << saveFile;
  1.2370 -	file.close();
  1.2371 -
  1.2372 -	if (returnCode==0)
  1.2373 -	{
  1.2374 +	if (savemode==CompleteMap || xelection.isEmpty())
  1.2375 +	{
  1.2376 +		// Save complete map
  1.2377 +		saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
  1.2378  		mapChanged=false;
  1.2379  		mapUnsaved=false;
  1.2380 -		actionFileSave->setEnabled(false);
  1.2381 +		autosaveTimer->stop();
  1.2382  	}
  1.2383 -
  1.2384 -	return returnCode;
  1.2385 +	else	
  1.2386 +	{
  1.2387 +		// Save part of map
  1.2388 +		if (xelection.type()==Selection::FloatImage)
  1.2389 +			saveFloatImage();
  1.2390 +		else	
  1.2391 +			saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());	
  1.2392 +		// TODO take care of multiselections
  1.2393 +	}	
  1.2394 +
  1.2395 +	if (!saveStringToDisk(fileDir+mapFileName,saveFile))
  1.2396 +	{
  1.2397 +		err=aborted;
  1.2398 +		qWarning ("ME::saveStringToDisk failed!");
  1.2399 +	}
  1.2400 +
  1.2401 +	if (zipped)
  1.2402 +	{
  1.2403 +		// zip
  1.2404 +		if (err==success) err=zipDir (tmpZipDir,destPath);
  1.2405 +
  1.2406 +		// Delete tmpDir
  1.2407 +		removeDir (QDir(tmpZipDir));
  1.2408 +
  1.2409 +		// Restore original filepath outside of tmp zip dir
  1.2410 +		setFilePath (safeFilePath);
  1.2411 +	}
  1.2412 +
  1.2413 +	updateActions();
  1.2414 +	fileChangedTime=QFileInfo (destPath).lastModified();
  1.2415 +	return err;
  1.2416  }
  1.2417  
  1.2418 -void MapEditor::setZipped (bool z)
  1.2419 -{
  1.2420 -	zipped=z;
  1.2421 -}
  1.2422 -
  1.2423 -bool MapEditor::saveZipped ()
  1.2424 -{
  1.2425 -	return zipped;
  1.2426 -}
  1.2427  
  1.2428  void MapEditor::print()
  1.2429  {
  1.2430 -	// Finish open lineEdits
  1.2431 -	if (lineedit) finishedLineEditNoSave();
  1.2432 -
  1.2433  	if ( !printer ) 
  1.2434  	{
  1.2435  		printer = new QPrinter;
  1.2436  		printer->setColorMode (QPrinter::Color);
  1.2437 +		printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
  1.2438 +		printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
  1.2439 +		printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
  1.2440  	}
  1.2441  
  1.2442 -	QRect totalBBox=mapCenter->getTotalBBox();
  1.2443 +	QRectF totalBBox=model->getTotalBBox();
  1.2444  
  1.2445  	// Try to set orientation automagically
  1.2446  	// Note: Interpretation of generated postscript is amibiguous, if 
  1.2447 @@ -825,208 +1879,256 @@
  1.2448  	{
  1.2449  		QPainter pp(printer);
  1.2450  
  1.2451 +		pp.setRenderHint(QPainter::Antialiasing,true);
  1.2452 +
  1.2453  		// Don't print the visualisation of selection
  1.2454 -		LinkableMapObj *oldselection=NULL;
  1.2455 -		if (selection) 
  1.2456 +		xelection.unselect();
  1.2457 +
  1.2458 +		QRectF mapRect=totalBBox;
  1.2459 +		QGraphicsRectItem *frame=NULL;
  1.2460 +
  1.2461 +		if (printFrame) 
  1.2462  		{
  1.2463 -			oldselection=selection;
  1.2464 -			selection->unselect();
  1.2465 -		}
  1.2466 -
  1.2467 -		// Handle sizes of map and paper:
  1.2468 -		//
  1.2469 -		// setWindow defines which part of the canvas will be transformed 
  1.2470 -		// setViewport defines area on paper in device coordinates (dpi)
  1.2471 -		// e.g. (0,50,700,700) is upper part on A4
  1.2472 -		// see also /usr/lib/qt3/doc/html/coordsys.html
  1.2473 -
  1.2474 -		QPaintDeviceMetrics metrics (printer);
  1.2475 -
  1.2476 -		double paperAspect = (double)metrics.width()   / (double)metrics.height();
  1.2477 -		double   mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
  1.2478 -
  1.2479 -		QRect mapRect=mapCenter->getTotalBBox();
  1.2480 -		QCanvasRectangle *frame=NULL;
  1.2481 -		QCanvasText *footerFN=NULL;
  1.2482 -		QCanvasText *footerDate=NULL;
  1.2483 -		if (printFrame || printFooter)
  1.2484 -		{
  1.2485 -			
  1.2486 -			if (printFrame) 
  1.2487 -			{
  1.2488 -				// Print frame around map
  1.2489 -				mapRect.setRect (mapRect.x()-10, mapRect.y()-10, 
  1.2490 -					mapRect.width()+20, mapRect.height()+20);
  1.2491 -				frame=new QCanvasRectangle (mapRect,mapCanvas);
  1.2492 -				frame->setBrush (QColor(white));
  1.2493 -				frame->setPen (QColor(black));
  1.2494 -				frame->setZ(0);
  1.2495 -				frame->show();    
  1.2496 -			}		
  1.2497 -			if (printFooter) 
  1.2498 -			{
  1.2499 -				// Print footer below map
  1.2500 -				QFont font;		
  1.2501 -				font.setPointSize(10);
  1.2502 -				footerFN=new QCanvasText (mapCanvas);
  1.2503 -				footerFN->setText ("VYM - " + fileName);
  1.2504 -				footerFN->setFont(font);
  1.2505 -				footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
  1.2506 -				footerFN->setZ(Z_TEXT);
  1.2507 -				footerFN->show();    
  1.2508 -				footerDate=new QCanvasText (mapCanvas);
  1.2509 -				footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
  1.2510 -				footerDate->setFont(font);
  1.2511 -				footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
  1.2512 -				footerDate->setZ(Z_TEXT);
  1.2513 -				footerDate->show();    
  1.2514 -				mapRect.setRect (mapRect.x(), mapRect.y(), 
  1.2515 -					mapRect.width(), mapRect.height()+20);
  1.2516 -			}
  1.2517 -			pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height());
  1.2518 -		}	else	
  1.2519 -		{
  1.2520 -			pp.setWindow (mapRect);
  1.2521 -		}	
  1.2522 -
  1.2523 +			// Print frame around map
  1.2524 +			mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10, 
  1.2525 +				totalBBox.width()+20, totalBBox.height()+20);
  1.2526 +			frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
  1.2527 +			frame->setZValue(0);
  1.2528 +			frame->show();    
  1.2529 +		}		
  1.2530 +
  1.2531 +
  1.2532 +		double paperAspect = (double)printer->width()   / (double)printer->height();
  1.2533 +		double   mapAspect = (double)mapRect.width() / (double)mapRect.height();
  1.2534 +		int viewBottom;
  1.2535  		if (mapAspect>=paperAspect)
  1.2536  		{
  1.2537  			// Fit horizontally to paper width
  1.2538 -			pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );	
  1.2539 +			//pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );	
  1.2540 +			viewBottom=(int)(printer->width()/mapAspect);	
  1.2541  		}	else
  1.2542  		{
  1.2543  			// Fit vertically to paper height
  1.2544 -			pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());	
  1.2545 +			//pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());	
  1.2546 +			viewBottom=printer->height();	
  1.2547  		}	
  1.2548 -
  1.2549 -		mapCanvas->drawArea(mapRect, &pp);	// draw Canvas to printer
  1.2550 -
  1.2551 -		// Delete Frame and footer
  1.2552 -		if (footerFN) 
  1.2553 +		
  1.2554 +		if (printFooter) 
  1.2555  		{
  1.2556 -			delete (footerFN);
  1.2557 -			delete (footerDate);
  1.2558 -		}	
  1.2559 +			// Print footer below map
  1.2560 +			QFont font;		
  1.2561 +			font.setPointSize(10);
  1.2562 +			pp.setFont (font);
  1.2563 +			QRectF footerBox(0,viewBottom,printer->width(),15);
  1.2564 +			pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
  1.2565 +			pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
  1.2566 +		}
  1.2567 +		mapScene->render (
  1.2568 +			&pp, 
  1.2569 +			QRectF (0,0,printer->width(),printer->height()-15),
  1.2570 +			QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
  1.2571 +		);
  1.2572 +		
  1.2573 +		// Viewport has paper dimension
  1.2574  		if (frame)  delete (frame);
  1.2575  
  1.2576  		// Restore selection
  1.2577 -		if (oldselection) 
  1.2578 -		{
  1.2579 -			selection=oldselection;
  1.2580 -			selection->select();
  1.2581 -		}	
  1.2582 +		xelection.reselect();
  1.2583 +
  1.2584 +		// Save settings in vymrc
  1.2585 +		settings.writeEntry("/mainwindow/printerName",printer->printerName());
  1.2586 +		settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
  1.2587 +		settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
  1.2588  	}
  1.2589  }
  1.2590  
  1.2591 +void MapEditor::setAntiAlias (bool b)
  1.2592 +{
  1.2593 +	setRenderHint(QPainter::Antialiasing,b);
  1.2594 +}
  1.2595 +
  1.2596 +void MapEditor::setSmoothPixmap(bool b)
  1.2597 +{
  1.2598 +	setRenderHint(QPainter::SmoothPixmapTransform,b);
  1.2599 +}
  1.2600 +
  1.2601  QPixmap MapEditor::getPixmap()
  1.2602  {
  1.2603 -	QRect mapRect=mapCenter->getTotalBBox();
  1.2604 -	QPixmap pix (mapRect.size());
  1.2605 +	QRectF mapRect=model->getTotalBBox();
  1.2606 +	QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+1);
  1.2607  	QPainter pp (&pix);
  1.2608 +	
  1.2609 +	pp.setRenderHints(renderHints());
  1.2610  
  1.2611  	// Don't print the visualisation of selection
  1.2612 -	LinkableMapObj *oldselection=NULL;
  1.2613 -	if (selection) 
  1.2614 -	{
  1.2615 -		oldselection=selection;
  1.2616 -		selection->unselect();
  1.2617 -	}
  1.2618 -
  1.2619 -	pp.setWindow (mapRect);
  1.2620 -
  1.2621 -	mapCanvas->drawArea(mapRect, &pp);	// draw Canvas to painter
  1.2622 -
  1.2623 +	xelection.unselect();
  1.2624 +
  1.2625 +	mapScene->render (	&pp, 
  1.2626 +		QRectF(0,0,mapRect.width()+1,mapRect.height()+1),
  1.2627 +		QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
  1.2628  
  1.2629  	// Restore selection
  1.2630 -	if (oldselection) 
  1.2631 -	{
  1.2632 -		selection=oldselection;
  1.2633 -		selection->select();
  1.2634 -	}	
  1.2635 +	xelection.reselect();
  1.2636  	
  1.2637  	return pix;
  1.2638  }
  1.2639  
  1.2640 -void MapEditor::exportImage(QString fn)
  1.2641 -{
  1.2642 -	// Finish open lineEdits
  1.2643 -	if (lineedit) finishedLineEditNoSave();
  1.2644 -
  1.2645 -	QPixmap pix (getPixmap());
  1.2646 -	pix.save(fn, "PNG");
  1.2647 +void MapEditor::setHideTmpMode (HideTmpMode mode)
  1.2648 +{
  1.2649 +	hidemode=mode;
  1.2650 +	model->setHideTmp (hidemode);
  1.2651 +	model->reposition();
  1.2652 +	scene()->update();
  1.2653  }
  1.2654  
  1.2655 -void MapEditor::exportImage(QString fn, int item)
  1.2656 -{
  1.2657 -	// Finish open lineEdits
  1.2658 -	if (lineedit) finishedLineEditNoSave();
  1.2659 -
  1.2660 -	QPixmap pix (getPixmap());
  1.2661 -	pix.save(fn, exportImageFormatMenu->text(item) );
  1.2662 +HideTmpMode MapEditor::getHideTmpMode()
  1.2663 +{
  1.2664 +	return hidemode;
  1.2665  }
  1.2666  
  1.2667 -void MapEditor::exportASCII()
  1.2668 -{
  1.2669 -	// FIXME still experimental
  1.2670 -	QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (ASCII)"));
  1.2671 -	fd->addFilter ("TXT (*.txt)");
  1.2672 -	fd->setCaption("VYM - Export (ASCII) (still experimental)");
  1.2673 -	fd->setMode( QFileDialog::AnyFile );
  1.2674 -	fd->show();
  1.2675 -
  1.2676 -	if ( fd->exec() == QDialog::Accepted )
  1.2677 -	{
  1.2678 -		if (QFile (fd->selectedFile()).exists() )
  1.2679 -		{
  1.2680 -			QMessageBox mb( "VYM",
  1.2681 -				tr("The file ") + fd->selectedFile() + 
  1.2682 -				tr(" exists already. Do you want to overwrite it?"),
  1.2683 -			QMessageBox::Warning,
  1.2684 -			QMessageBox::Yes | QMessageBox::Default,
  1.2685 -			QMessageBox::Cancel | QMessageBox::Escape,
  1.2686 -			QMessageBox::NoButton );
  1.2687 -
  1.2688 -			mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
  1.2689 -			mb.setButtonText( QMessageBox::No, tr("Cancel"));
  1.2690 -			Export ex;
  1.2691 -			switch( mb.exec() ) 
  1.2692 -			{
  1.2693 -				case QMessageBox::Yes:
  1.2694 -					// save 
  1.2695 -					if (!ex.setOutputDir ("out"))
  1.2696 -					{
  1.2697 -						QMessageBox::critical (0,tr("Critical Export Error "),tr("Couldn't create directory ") + "out");
  1.2698 -						return;
  1.2699 -					}
  1.2700 -					break;;
  1.2701 -				case QMessageBox::Cancel:
  1.2702 -					// do nothing
  1.2703 -					return;
  1.2704 -					break;
  1.2705 -			}
  1.2706 -		}
  1.2707 -		Export ex;
  1.2708 -		ex.setPath (fd->selectedFile() );
  1.2709 -		ex.setMapCenter(mapCenter);
  1.2710 -		ex.exportMap();
  1.2711 +void MapEditor::setExportMode (bool b)
  1.2712 +{
  1.2713 +	// should be called before and after exports
  1.2714 +	// depending on the settings
  1.2715 +	if (b && settings.value("/export/useHideExport","true")=="true")
  1.2716 +		setHideTmpMode (HideExport);
  1.2717 +	else	
  1.2718 +		setHideTmpMode (HideNone);
  1.2719 +}
  1.2720 +
  1.2721 +void MapEditor::exportASCII(QString fname,bool askName)
  1.2722 +{
  1.2723 +	ExportASCII ex;
  1.2724 +	ex.setModel (model);
  1.2725 +	if (fname=="") 
  1.2726 +		ex.setFile (mapName+".txt");	
  1.2727 +	else
  1.2728 +		ex.setFile (fname);
  1.2729 +
  1.2730 +	if (askName)
  1.2731 +	{
  1.2732 +		//ex.addFilter ("TXT (*.txt)");
  1.2733 +		ex.setDir(lastImageDir);
  1.2734 +		//ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
  1.2735 +		ex.execDialog() ; 
  1.2736 +	} 
  1.2737 +	if (!ex.canceled())
  1.2738 +	{
  1.2739 +		setExportMode(true);
  1.2740 +		ex.doExport();
  1.2741 +		setExportMode(false);
  1.2742  	}
  1.2743  }
  1.2744  
  1.2745 -
  1.2746 -void MapEditor::exportXML(const QString &dir)
  1.2747 -{
  1.2748 +void MapEditor::exportImage(QString fname, bool askName, QString format)
  1.2749 +{
  1.2750 +	if (fname=="")
  1.2751 +	{
  1.2752 +		fname=mapName+".png";
  1.2753 +		format="PNG";
  1.2754 +	} 	
  1.2755 +
  1.2756 +	if (askName)
  1.2757 +	{
  1.2758 +		QStringList fl;
  1.2759 +		QFileDialog *fd=new QFileDialog (this);
  1.2760 +		fd->setCaption (tr("Export map as image"));
  1.2761 +		fd->setDirectory (lastImageDir);
  1.2762 +		fd->setFileMode(QFileDialog::AnyFile);
  1.2763 +		fd->setFilters  (imageIO.getFilters() );
  1.2764 +		if (fd->exec())
  1.2765 +		{
  1.2766 +			fl=fd->selectedFiles();
  1.2767 +			fname=fl.first();
  1.2768 +			format=imageIO.getType(fd->selectedFilter());
  1.2769 +		} 
  1.2770 +	}
  1.2771 +
  1.2772 +	setExportMode (true);
  1.2773 +	QPixmap pix (getPixmap());
  1.2774 +	pix.save(fname, format);
  1.2775 +	setExportMode (false);
  1.2776 +}
  1.2777 +
  1.2778 +void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
  1.2779 +{
  1.2780 +	ExportOO ex;
  1.2781 +	ex.setFile (fn);
  1.2782 +	ex.setModel (model);
  1.2783 +	if (ex.setConfigFile(cf)) 
  1.2784 +	{
  1.2785 +		setExportMode (true);
  1.2786 +		ex.exportPresentation();
  1.2787 +		setExportMode (false);
  1.2788 +	}
  1.2789 +}
  1.2790 +
  1.2791 +void MapEditor::exportXHTML (const QString &dir, bool askForName)
  1.2792 +{
  1.2793 +			ExportXHTMLDialog dia(this);
  1.2794 +			dia.setFilePath (filePath );
  1.2795 +			dia.setMapName (mapName );
  1.2796 +			dia.readSettings();
  1.2797 +			if (dir!="") dia.setDir (dir);
  1.2798 +
  1.2799 +			bool ok=true;
  1.2800 +			
  1.2801 +			if (askForName)
  1.2802 +			{
  1.2803 +				if (dia.exec()!=QDialog::Accepted) 
  1.2804 +					ok=false;
  1.2805 +				else	
  1.2806 +				{
  1.2807 +					QDir d (dia.getDir());
  1.2808 +					// Check, if warnings should be used before overwriting
  1.2809 +					// the output directory
  1.2810 +					if (d.exists() && d.count()>0)
  1.2811 +					{
  1.2812 +						WarningDialog warn;
  1.2813 +						warn.showCancelButton (true);
  1.2814 +						warn.setText(QString(
  1.2815 +							"The directory %1 is not empty.\n"
  1.2816 +							"Do you risk to overwrite some of its contents?").arg(d.path() ));
  1.2817 +						warn.setCaption("Warning: Directory not empty");
  1.2818 +						warn.setShowAgainName("mainwindow/overwrite-dir-xhtml");
  1.2819 +
  1.2820 +						if (warn.exec()!=QDialog::Accepted) ok=false;
  1.2821 +					}
  1.2822 +				}	
  1.2823 +			}
  1.2824 +
  1.2825 +			if (ok)
  1.2826 +			{
  1.2827 +				exportXML (dia.getDir(),false );
  1.2828 +				dia.doExport(mapName );
  1.2829 +				//if (dia.hasChanged()) setChanged();
  1.2830 +			}
  1.2831 +}
  1.2832 +
  1.2833 +void MapEditor::exportXML(QString dir, bool askForName)
  1.2834 +{
  1.2835 +	if (askForName)
  1.2836 +	{
  1.2837 +		dir=browseDirectory(this,tr("Export XML to directory"));
  1.2838 +		if (dir =="" && !reallyWriteDirectory(dir) )
  1.2839 +		return;
  1.2840 +	}
  1.2841 +
  1.2842 +	// Hide stuff during export, if settings want this
  1.2843 +	setExportMode (true);
  1.2844 +
  1.2845  	// Create subdirectories
  1.2846  	makeSubDirs (dir);
  1.2847  
  1.2848  	// write to directory
  1.2849 -	QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,CompleteMap);
  1.2850 +	QString saveFile=saveToDir (dir,mapName+"-",true,model->getTotalBBox().topLeft() ,NULL);
  1.2851  	QFile file;
  1.2852  
  1.2853  	file.setName ( dir + "/"+mapName+".xml");
  1.2854 -	if ( !file.open( IO_WriteOnly ) )
  1.2855 +	if ( !file.open( QIODevice::WriteOnly ) )
  1.2856  	{
  1.2857  		// This should neverever happen
  1.2858 -		QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open ")+file.name());
  1.2859 +		QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
  1.2860  		return;
  1.2861  	}	
  1.2862  
  1.2863 @@ -1037,494 +2139,783 @@
  1.2864  	file.close();
  1.2865  
  1.2866  	// Now write image, too
  1.2867 -	exportImage (dir+"/images/"+mapName+".png");
  1.2868 +	exportImage (dir+"/images/"+mapName+".png",false,"PNG");
  1.2869 +
  1.2870 +	setExportMode (false);
  1.2871  }
  1.2872  
  1.2873  void MapEditor::clear()
  1.2874  {
  1.2875 -	if (selection)
  1.2876 -	{
  1.2877 -		selection->unselect();
  1.2878 -		selection=NULL;
  1.2879 +	xelection.unselect();
  1.2880 +	model->clear();
  1.2881 +}
  1.2882 +
  1.2883 +void MapEditor::copy()
  1.2884 +{
  1.2885 +	LinkableMapObj *sel=xelection.single();
  1.2886 +	if (sel)
  1.2887 +	{
  1.2888 +		if (redosAvail == 0)
  1.2889 +		{
  1.2890 +			// Copy to history
  1.2891 +			QString s=model->getSelectString(sel);
  1.2892 +			saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel  );
  1.2893 +			curClipboard=curStep;
  1.2894 +		}
  1.2895 +
  1.2896 +		// Copy also to global clipboard, because we are at last step in history
  1.2897 +		QString bakMapName(QString("history-%1").arg(curStep));
  1.2898 +		QString bakMapDir(tmpMapDir +"/"+bakMapName);
  1.2899 +		copyDir (bakMapDir,clipboardDir );
  1.2900 +
  1.2901 +		clipboardEmpty=false;
  1.2902 +		updateActions();
  1.2903 +	}	    
  1.2904 +}
  1.2905 +
  1.2906 +void MapEditor::redo()
  1.2907 +{
  1.2908 +	// Can we undo at all?
  1.2909 +	if (redosAvail<1) return;
  1.2910 +
  1.2911 +	bool blockSaveStateOrg=blockSaveState;
  1.2912 +	blockSaveState=true;
  1.2913 +	
  1.2914 +	redosAvail--;
  1.2915 +
  1.2916 +	if (undosAvail<stepsTotal) undosAvail++;
  1.2917 +	curStep++;
  1.2918 +	if (curStep>stepsTotal) curStep=1;
  1.2919 +	QString undoCommand=  undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
  1.2920 +	QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
  1.2921 +	QString redoCommand=  undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
  1.2922 +	QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
  1.2923 +	QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
  1.2924 +	QString version=undoSet.readEntry ("/history/version");
  1.2925 +
  1.2926 +	/* TODO Maybe check for version, if we save the history
  1.2927 +	if (!checkVersion(version))
  1.2928 +		QMessageBox::warning(0,tr("Warning"),
  1.2929 +			tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
  1.2930 +	*/ 
  1.2931 +
  1.2932 +	// Find out current undo directory
  1.2933 +	QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
  1.2934 +
  1.2935 +	if (debug)
  1.2936 +	{
  1.2937 +		cout << "ME::redo() begin\n";
  1.2938 +		cout << "    undosAvail="<<undosAvail<<endl;
  1.2939 +		cout << "    redosAvail="<<redosAvail<<endl;
  1.2940 +		cout << "       curStep="<<curStep<<endl;
  1.2941 +		cout << "    ---------------------------"<<endl;
  1.2942 +		cout << "    comment="<<comment.toStdString()<<endl;
  1.2943 +		cout << "    undoCom="<<undoCommand.toStdString()<<endl;
  1.2944 +		cout << "    undoSel="<<undoSelection.toStdString()<<endl;
  1.2945 +		cout << "    redoCom="<<redoCommand.toStdString()<<endl;
  1.2946 +		cout << "    redoSel="<<redoSelection.toStdString()<<endl;
  1.2947 +		cout << "    ---------------------------"<<endl<<endl;
  1.2948 +	}
  1.2949 +
  1.2950 +	// select  object before redo
  1.2951 +	if (!redoSelection.isEmpty())
  1.2952 +		select (redoSelection);
  1.2953 +
  1.2954 +
  1.2955 +	parseAtom (redoCommand);
  1.2956 +	model->reposition();
  1.2957 +
  1.2958 +	blockSaveState=blockSaveStateOrg;
  1.2959 +
  1.2960 +	undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
  1.2961 +	undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
  1.2962 +	undoSet.setEntry ("/history/curStep",QString::number(curStep));
  1.2963 +	undoSet.writeSettings(histPath);
  1.2964 +
  1.2965 +	mainWindow->updateHistory (undoSet);
  1.2966 +	updateActions();
  1.2967 +
  1.2968 +	/* TODO remove testing
  1.2969 +	cout << "ME::redo() end\n";
  1.2970 +	cout << "    undosAvail="<<undosAvail<<endl;
  1.2971 +	cout << "    redosAvail="<<redosAvail<<endl;
  1.2972 +	cout << "       curStep="<<curStep<<endl;
  1.2973 +	cout << "    ---------------------------"<<endl<<endl;
  1.2974 +	*/
  1.2975 +
  1.2976 +
  1.2977 +}
  1.2978 +
  1.2979 +bool MapEditor::isRedoAvailable()
  1.2980 +{
  1.2981 +	if (undoSet.readNumEntry("/history/redosAvail",0)>0)
  1.2982 +		return true;
  1.2983 +	else	
  1.2984 +		return false;
  1.2985 +}
  1.2986 +
  1.2987 +void MapEditor::undo()
  1.2988 +{
  1.2989 +	// Can we undo at all?
  1.2990 +	if (undosAvail<1) return;
  1.2991 +
  1.2992 +	mainWindow->statusMessage (tr("Autosave disabled during undo."));
  1.2993 +
  1.2994 +	bool blockSaveStateOrg=blockSaveState;
  1.2995 +	blockSaveState=true;
  1.2996 +	
  1.2997 +	QString undoCommand=  undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
  1.2998 +	QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
  1.2999 +	QString redoCommand=  undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
  1.3000 +	QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
  1.3001 +	QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
  1.3002 +	QString version=undoSet.readEntry ("/history/version");
  1.3003 +
  1.3004 +	/* TODO Maybe check for version, if we save the history
  1.3005 +	if (!checkVersion(version))
  1.3006 +		QMessageBox::warning(0,tr("Warning"),
  1.3007 +			tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
  1.3008 +	*/
  1.3009 +
  1.3010 +	// Find out current undo directory
  1.3011 +	QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
  1.3012 +
  1.3013 +	// select  object before undo
  1.3014 +	if (!undoSelection.isEmpty())
  1.3015 +		select (undoSelection);
  1.3016 +
  1.3017 +	if (debug)
  1.3018 +	{
  1.3019 +		cout << "ME::undo() begin\n";
  1.3020 +		cout << "    undosAvail="<<undosAvail<<endl;
  1.3021 +		cout << "    redosAvail="<<redosAvail<<endl;
  1.3022 +		cout << "       curStep="<<curStep<<endl;
  1.3023 +		cout << "    ---------------------------"<<endl;
  1.3024 +		cout << "    comment="<<comment.toStdString()<<endl;
  1.3025 +		cout << "    undoCom="<<undoCommand.toStdString()<<endl;
  1.3026 +		cout << "    undoSel="<<undoSelection.toStdString()<<endl;
  1.3027 +		cout << "    redoCom="<<redoCommand.toStdString()<<endl;
  1.3028 +		cout << "    redoSel="<<redoSelection.toStdString()<<endl;
  1.3029 +		cout << "    ---------------------------"<<endl<<endl;
  1.3030  	}	
  1.3031 -
  1.3032 -	mapCenter->clear();
  1.3033 +	parseAtom (undoCommand);
  1.3034 +	model->reposition();
  1.3035 +
  1.3036 +	undosAvail--;
  1.3037 +	curStep--; 
  1.3038 +	if (curStep<1) curStep=stepsTotal;
  1.3039 +
  1.3040 +	redosAvail++;
  1.3041 +
  1.3042 +	blockSaveState=blockSaveStateOrg;
  1.3043 +/* TODO remove testing
  1.3044 +	cout << "ME::undo() end\n";
  1.3045 +	cout << "    undosAvail="<<undosAvail<<endl;
  1.3046 +	cout << "    redosAvail="<<redosAvail<<endl;
  1.3047 +	cout << "       curStep="<<curStep<<endl;
  1.3048 +	cout << "    ---------------------------"<<endl<<endl;
  1.3049 +*/
  1.3050 +
  1.3051 +	undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
  1.3052 +	undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
  1.3053 +	undoSet.setEntry ("/history/curStep",QString::number(curStep));
  1.3054 +	undoSet.writeSettings(histPath);
  1.3055 +
  1.3056 +	mainWindow->updateHistory (undoSet);
  1.3057 +	updateActions();
  1.3058 +	xelection.update();
  1.3059 +	ensureSelectionVisible();
  1.3060  }
  1.3061  
  1.3062 -void MapEditor::undo()
  1.3063 -{
  1.3064 -	QDir d;
  1.3065 -	d.setPath(bakMapDir);
  1.3066 +bool MapEditor::isUndoAvailable()
  1.3067 +{
  1.3068 +	if (undoSet.readNumEntry("/history/undosAvail",0)>0)
  1.3069 +		return true;
  1.3070 +	else	
  1.3071 +		return false;
  1.3072 +}
  1.3073 +
  1.3074 +void MapEditor::gotoHistoryStep (int i)
  1.3075 +{
  1.3076 +	// Restore variables
  1.3077 +	int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
  1.3078 +	int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
  1.3079 +
  1.3080 +	if (i<0) i=undosAvail+redosAvail;
  1.3081 +
  1.3082 +	// Clicking above current step makes us undo things
  1.3083 +	if (i<undosAvail) 
  1.3084 +	{	
  1.3085 +		for (int j=0; j<undosAvail-i; j++) undo();
  1.3086 +		return;
  1.3087 +	}	
  1.3088 +	// Clicking below current step makes us redo things
  1.3089 +	if (i>undosAvail) 
  1.3090 +		for (int j=undosAvail; j<i; j++) 
  1.3091 +		{
  1.3092 +			if (debug) cout << "ME::gotoHistoryStep redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
  1.3093 +			redo();
  1.3094 +		}
  1.3095 +
  1.3096 +	// And ignore clicking the current row ;-)	
  1.3097 +}
  1.3098 +
  1.3099 +void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
  1.3100 +{
  1.3101 +	QString pathDir=path.left(path.findRev("/"));
  1.3102 +	QDir d(pathDir);
  1.3103 +	QFile file (path);
  1.3104 +
  1.3105  	if (d.exists() )
  1.3106  	{
  1.3107 -		// Finish open lineEdits
  1.3108 -		if (lineedit) finishedLineEditNoSave();
  1.3109 -
  1.3110 -		if (selection) 
  1.3111 -		{
  1.3112 -			selection->unselect();
  1.3113 -			selection=NULL;
  1.3114 -		}	
  1.3115 -		
  1.3116 -		mapBuilderHandler handler;
  1.3117 -		QXmlInputSource source;
  1.3118 -		source.setData(backupXML);
  1.3119 +		// We need to parse saved XML data
  1.3120 +		parseVYMHandler handler;
  1.3121 +		QXmlInputSource source( file);
  1.3122  		QXmlSimpleReader reader;
  1.3123  		reader.setContentHandler( &handler );
  1.3124  		reader.setErrorHandler( &handler );
  1.3125 -		handler.setMapEditor( this );
  1.3126 -		handler.setTmpDir ( bakMapDir );	// needed to load files with rel. path
  1.3127 -		if (undoSelection)
  1.3128 +		handler.setModel ( model);
  1.3129 +		handler.setTmpDir ( pathDir );	// needed to load files with rel. path
  1.3130 +		if (undoSel.isEmpty())
  1.3131  		{
  1.3132 -			selection=undoSelection;
  1.3133 -			selection->select();
  1.3134 -			handler.setLoadMode (ImportReplace);
  1.3135 -
  1.3136 +			unselect();
  1.3137 +			model->clear();
  1.3138 +			handler.setLoadMode (NewMap);
  1.3139  		} else	
  1.3140  		{
  1.3141 -			mapCenter->clear();
  1.3142 -			handler.setLoadMode (NewMap);
  1.3143 +			select (undoSel);
  1.3144 +			handler.setLoadMode (ImportReplace);
  1.3145  		}	
  1.3146 -		blockreposition=true;
  1.3147 +		blockReposition=true;
  1.3148  		bool ok = reader.parse( source );
  1.3149 -		blockreposition=false;
  1.3150 -		if ( ok ) 
  1.3151 -			mapCenter->reposition();
  1.3152 -			
  1.3153 -		else 
  1.3154 +		blockReposition=false;
  1.3155 +		if (! ok ) 
  1.3156  		{	
  1.3157  			// This should never ever happen
  1.3158 -			QMessageBox::critical( 0, tr( "Critical Parse Error by reading backupFile" ),
  1.3159 -								   tr( handler.errorProtocol() )+" in "+backupXML );
  1.3160 +			QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
  1.3161 +								    handler.errorProtocol());
  1.3162  		}
  1.3163 -		// Undo not longer available now
  1.3164 -		actionEditUndo->setEnabled (false);
  1.3165 -		undoSelection=false;
  1.3166 -		mapChanged=false;
  1.3167 -		return;
  1.3168  	} else	
  1.3169 -	{
  1.3170 -		QMessageBox::critical( 0, tr( "Critical Error" ),
  1.3171 -			"Temporary directory " +bakMapDir + 
  1.3172 -			tr (" used for undo is gone. \n"
  1.3173 -			"I will create a new one, but at the moment no undo is available.\n"
  1.3174 -			"Maybe you want to reload your original data.\n\n"
  1.3175 -			"Sorry for any inconveniences.") );
  1.3176 -		makeTmpDirs();	
  1.3177 -	}							
  1.3178 +		QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
  1.3179  }
  1.3180  
  1.3181 -void MapEditor::copy()
  1.3182 -{
  1.3183 -	// Finish open lineEdits
  1.3184 -	if (lineedit) finishedLineEditNoSave();
  1.3185 -
  1.3186 -	if (selection) 
  1.3187 -	{
  1.3188 -		if (typeid(*selection) == typeid(BranchObj) ) 
  1.3189 +void MapEditor::addMapInsertInt (const QString &path, int pos)
  1.3190 +{
  1.3191 +	BranchObj *sel=xelection.getBranch();
  1.3192 +	if (sel)
  1.3193 +	{
  1.3194 +		QString pathDir=path.left(path.findRev("/"));
  1.3195 +		QDir d(pathDir);
  1.3196 +		QFile file (path);
  1.3197 +
  1.3198 +		if (d.exists() )
  1.3199  		{
  1.3200 -			BranchObj* to;
  1.3201 -			BranchObj* from;
  1.3202 -			clipboardME->clear();
  1.3203 -			clipboardME->getMapCenter()->addBranch();
  1.3204 -			to=clipboardME->getMapCenter()->getLastBranch();
  1.3205 -			if (to) 
  1.3206 -			{
  1.3207 -				from=(BranchObj*)(selection);
  1.3208 -				to->copy(from);
  1.3209 -
  1.3210 -				// keep position relative to parent
  1.3211 -				to->move2RelPos ( from->getRelPos());
  1.3212 -
  1.3213 -				// select data in clipboard
  1.3214 -				clipboardME->select ("bo:0");
  1.3215 -
  1.3216 -				// repositioning makes testing nicer,
  1.3217 -				// but is not needed usually:
  1.3218 -				if (clipboardME->isVisible())
  1.3219 -				{
  1.3220 -					clipboardME->getMapCenter()->reposition();  
  1.3221 -				}	
  1.3222 -				else
  1.3223 -					clipboardME->hide();
  1.3224 +			// We need to parse saved XML data
  1.3225 +			parseVYMHandler handler;
  1.3226 +			QXmlInputSource source( file);
  1.3227 +			QXmlSimpleReader reader;
  1.3228 +			reader.setContentHandler( &handler );
  1.3229 +			reader.setErrorHandler( &handler );
  1.3230 +			handler.setModel (model);
  1.3231 +			handler.setTmpDir ( pathDir );	// needed to load files with rel. path
  1.3232 +			handler.setLoadMode (ImportAdd);
  1.3233 +			blockReposition=true;
  1.3234 +			bool ok = reader.parse( source );
  1.3235 +			blockReposition=false;
  1.3236 +			if (! ok ) 
  1.3237 +			{	
  1.3238 +				// This should never ever happen
  1.3239 +				QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
  1.3240 +										handler.errorProtocol());
  1.3241  			}
  1.3242 -		}    
  1.3243 -		if (typeid(*selection) == typeid(FloatImageObj) ) 
  1.3244 -		{
  1.3245 -			FloatImageObj* to;
  1.3246 -			FloatImageObj* from;
  1.3247 -			clipboardME->clear();
  1.3248 -			clipboardME->getMapCenter()->addFloatImage();
  1.3249 -			to=clipboardME->getMapCenter()->getLastFloatImage();
  1.3250 -			if (to) 
  1.3251 -			{
  1.3252 -				from=(FloatImageObj*)(selection);
  1.3253 -				to->copy(from);
  1.3254 -
  1.3255 -				// select data in clipboard
  1.3256 -				clipboardME->select ("fi:0");
  1.3257 -
  1.3258 -				// repositioning makes testing nicer,
  1.3259 -				// but is not needed usually:
  1.3260 -				if (clipboardME->isVisible())
  1.3261 -				{
  1.3262 -					clipboardME->getMapCenter()->reposition();  
  1.3263 -				}	
  1.3264 -				else
  1.3265 -					clipboardME->hide();
  1.3266 -			}
  1.3267 -		}    
  1.3268 -	}	    
  1.3269 +			if (sel->getDepth()>0)
  1.3270 +				sel->getLastBranch()->linkTo (sel,pos);
  1.3271 +		} else	
  1.3272 +			QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
  1.3273 +	}		
  1.3274  }
  1.3275  
  1.3276 -LinkableMapObj* MapEditor::pasteNoSave()
  1.3277 -{
  1.3278 -	return pasteAtNoSave (-1);
  1.3279 +void MapEditor::pasteNoSave(const int &n)
  1.3280 +{
  1.3281 +	bool old=blockSaveState;
  1.3282 +	blockSaveState=true;
  1.3283 +	bool zippedOrg=zipped;
  1.3284 +	if (redosAvail > 0 || n!=0)
  1.3285 +	{
  1.3286 +		// Use the "historical" buffer
  1.3287 +		QString bakMapName(QString("history-%1").arg(n));
  1.3288 +		QString bakMapDir(tmpMapDir +"/"+bakMapName);
  1.3289 +		load (bakMapDir+"/"+clipboardFile,ImportAdd, VymMap);
  1.3290 +	} else
  1.3291 +		// Use the global buffer
  1.3292 +		load (clipboardDir+"/"+clipboardFile,ImportAdd, VymMap);
  1.3293 +	zipped=zippedOrg;
  1.3294 +	blockSaveState=old;
  1.3295  }
  1.3296  
  1.3297 -LinkableMapObj* MapEditor::pasteAtNoSave(int pos)
  1.3298 -{
  1.3299 -	// Finish open lineEdits
  1.3300 -	if (lineedit) finishedLineEditNoSave();
  1.3301 -
  1.3302 -	LinkableMapObj *fromLMO=clipboardME->getSelection();
  1.3303 -	LinkableMapObj *returnLMO=NULL;
  1.3304 -
  1.3305 -	if (selection && fromLMO) 
  1.3306 -	{
  1.3307 -
  1.3308 -		if (typeid(*fromLMO) == typeid(BranchObj) ) 
  1.3309 -		{
  1.3310 -			if (typeid(*selection) == typeid(MapCenterObj)) 
  1.3311 -			{
  1.3312 -				returnLMO=mapCenter->addBranch( (BranchObj*)(fromLMO) );
  1.3313 -				((BranchObj*)(returnLMO))->move2RelPos(normalise(fromLMO->getRelPos() ) );
  1.3314 -			}     
  1.3315 -			if (typeid(*selection) == typeid(BranchObj)) 
  1.3316 -				if (pos<0)
  1.3317 -					returnLMO=((BranchObj*)(selection))->addBranch((BranchObj*)(fromLMO) );
  1.3318 -				else
  1.3319 -				{
  1.3320 -					BranchObj *par=(BranchObj*)(selection->getParObj());
  1.3321 -					if (par) returnLMO=par->insertBranch((BranchObj*)(fromLMO),pos );
  1.3322 -				}	
  1.3323 -		}
  1.3324 -		
  1.3325 -		if (typeid(*fromLMO) == typeid(FloatImageObj) &&
  1.3326 -			(typeid(*selection) == typeid (BranchObj) || 
  1.3327 -			 typeid(*selection)==typeid(MapCenterObj)) )
  1.3328 -			returnLMO=((BranchObj*) (selection))->addFloatImage ((FloatImageObj*)(fromLMO));
  1.3329 -		
  1.3330 -	}	    
  1.3331 -	return returnLMO;
  1.3332 +void MapEditor::paste()		
  1.3333 +{   
  1.3334 +	BranchObj *sel=xelection.getBranch();
  1.3335 +	if (sel)
  1.3336 +	{
  1.3337 +		saveStateChangingPart(
  1.3338 +			sel,
  1.3339 +			sel,
  1.3340 +			QString ("paste (%1)").arg(curClipboard),
  1.3341 +			QString("Paste to %1").arg( getName(sel))
  1.3342 +		);
  1.3343 +		pasteNoSave(0);
  1.3344 +		model->reposition();
  1.3345 +	}
  1.3346  }
  1.3347  
  1.3348 -void MapEditor::cutNoSave()
  1.3349 -{
  1.3350 -	// Finish open lineEdits
  1.3351 -	if (lineedit) finishedLineEditNoSave();
  1.3352 -
  1.3353 -	BranchObj* bo;
  1.3354 -	BranchObj* par; 
  1.3355 -	if (selection != NULL) {
  1.3356 -		if (typeid(*selection) == typeid(BranchObj) ) 
  1.3357 -		{
  1.3358 -			bo=(BranchObj*)(selection);
  1.3359 -			par=(BranchObj*)(bo->getParObj());
  1.3360 -			bo->unselect();
  1.3361 -			selection=NULL;
  1.3362 -			par->removeBranch(bo);
  1.3363 -			selection=par;
  1.3364 -			selection->select();
  1.3365 -		}
  1.3366 -		if (typeid(*selection) == typeid(FloatImageObj) ) 
  1.3367 -		{
  1.3368 -			FloatImageObj* fio=(FloatImageObj*)(selection);
  1.3369 -			par=(BranchObj*)(fio->getParObj());
  1.3370 -			fio->unselect();
  1.3371 -			selection=NULL;
  1.3372 -			par->removeFloatImage(fio);
  1.3373 -			selection=par;
  1.3374 -			selection->select();
  1.3375 -		}
  1.3376 -	}	    
  1.3377 +void MapEditor::cut()
  1.3378 +{
  1.3379 +	LinkableMapObj *sel=xelection.single();
  1.3380 +	if ( sel && (xelection.type() == Selection::Branch ||
  1.3381 +		xelection.type()==Selection::MapCenter ||
  1.3382 +		xelection.type()==Selection::FloatImage))
  1.3383 +	{
  1.3384 +	/* No savestate! savestate is called in cutNoSave
  1.3385 +		saveStateChangingPart(
  1.3386 +			sel->getParObj(),
  1.3387 +			sel,
  1.3388 +			"cut ()",
  1.3389 +			QString("Cut %1").arg(getName(sel ))
  1.3390 +		);
  1.3391 +	*/	
  1.3392 +		copy();
  1.3393 +		deleteSelection();
  1.3394 +		model->reposition();
  1.3395 +	}
  1.3396  }
  1.3397  
  1.3398 -void MapEditor::paste()
  1.3399 -{   
  1.3400 -	setChanged();
  1.3401 -	saveState(PartOfMap,selection);
  1.3402 -	pasteNoSave();
  1.3403 -	mapCenter->reposition();
  1.3404 -	adjustCanvasSize();
  1.3405 +void MapEditor::move(const double &x, const double &y)
  1.3406 +{
  1.3407 +	LinkableMapObj *sel=xelection.single();
  1.3408 +	if (sel)
  1.3409 +	{
  1.3410 +        QPointF ap(sel->getAbsPos());
  1.3411 +        QPointF to(x, y);
  1.3412 +        if (ap != to)
  1.3413 +        {
  1.3414 +            QString ps=qpointfToString(ap);
  1.3415 +            QString s=xelection.getSelectString();
  1.3416 +            saveState(
  1.3417 +                s, "move "+ps, 
  1.3418 +                s, "move "+qpointfToString(to), 
  1.3419 +                QString("Move %1 to %2").arg(getName(sel)).arg(ps));
  1.3420 +            sel->move(x,y);
  1.3421 +            model->reposition();
  1.3422 +            xelection.update();
  1.3423 +        }
  1.3424 +	}
  1.3425  }
  1.3426  
  1.3427 -void MapEditor::cut()
  1.3428 -{
  1.3429 -	setChanged();
  1.3430 -	saveState(PartOfMap,selection->getParObj());
  1.3431 -	copy();
  1.3432 -	cutNoSave();
  1.3433 -	mapCenter->reposition();
  1.3434 -	adjustCanvasSize();
  1.3435 +void MapEditor::moveRel (const double &x, const double &y)
  1.3436 +{
  1.3437 +	LinkableMapObj *sel=xelection.single();
  1.3438 +	if (sel)
  1.3439 +	{
  1.3440 +        QPointF rp(sel->getRelPos());
  1.3441 +        QPointF to(x, y);
  1.3442 +        if (rp != to)
  1.3443 +        {
  1.3444 +            QString ps=qpointfToString (sel->getRelPos());
  1.3445 +            QString s=model->getSelectString(sel);
  1.3446 +            saveState(
  1.3447 +                s, "moveRel "+ps, 
  1.3448 +                s, "moveRel "+qpointfToString(to), 
  1.3449 +                QString("Move %1 to relative position %2").arg(getName(sel)).arg(ps));
  1.3450 +            ((OrnamentedObj*)sel)->move2RelPos (x,y);
  1.3451 +            model->reposition();
  1.3452 +            sel->updateLink();
  1.3453 +            xelection.update();
  1.3454 +        }
  1.3455 +	}
  1.3456  }
  1.3457  
  1.3458  void MapEditor::moveBranchUp()
  1.3459  {
  1.3460 -	// Finish open lineEdits
  1.3461 -	if (lineedit) finishedLineEditNoSave();
  1.3462 -
  1.3463 -	BranchObj* bo;
  1.3464 +	BranchObj* bo=xelection.getBranch();
  1.3465  	BranchObj* par;
  1.3466 -	if (typeid(*selection) == typeid(BranchObj)  ) 
  1.3467 -	{
  1.3468 -		setChanged();
  1.3469 -		saveState(PartOfMap,selection->getParObj());
  1.3470 -		bo=(BranchObj*)(selection);
  1.3471 +	if (bo)
  1.3472 +	{
  1.3473 +		if (!bo->canMoveBranchUp()) return;
  1.3474  		par=(BranchObj*)(bo->getParObj());
  1.3475 -		selection->unselect();
  1.3476 -		selection=par->moveBranchUp (bo);
  1.3477 -		selection->select();
  1.3478 -		mapCenter->reposition();
  1.3479 +		BranchObj *obo=par->moveBranchUp (bo);	// bo will be the one below selection
  1.3480 +		saveState (model->getSelectString(bo),"moveBranchDown ()",model->getSelectString(obo),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
  1.3481 +		model->reposition();
  1.3482 +		scene()->update();
  1.3483 +		xelection.update();
  1.3484  		ensureSelectionVisible();
  1.3485  	}
  1.3486  }
  1.3487  
  1.3488  void MapEditor::moveBranchDown()
  1.3489  {
  1.3490 -	// Finish open lineEdits
  1.3491 -	if (lineedit) finishedLineEditNoSave();
  1.3492 -
  1.3493 -	BranchObj* bo;
  1.3494 +	BranchObj* bo=xelection.getBranch();
  1.3495  	BranchObj* par;
  1.3496 -	if (typeid(*selection) == typeid(BranchObj)  ) 
  1.3497 -	{
  1.3498 -		setChanged();
  1.3499 -		saveState(PartOfMap,selection->getParObj());
  1.3500 -		bo=(BranchObj*)(selection);
  1.3501 +	if (bo)
  1.3502 +	{
  1.3503 +		if (!bo->canMoveBranchDown()) return;
  1.3504  		par=(BranchObj*)(bo->getParObj());
  1.3505 -		selection->unselect(); 
  1.3506 -		selection=par->moveBranchDown(bo);
  1.3507 -		selection->select();
  1.3508 -		mapCenter->reposition();
  1.3509 +		BranchObj *obo=par->moveBranchDown(bo);	// bo will be the one above selection
  1.3510 +		saveState(model->getSelectString(bo),"moveBranchUp ()",model->getSelectString(obo),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
  1.3511 +		model->reposition();
  1.3512 +		scene()->update();
  1.3513 +		xelection.update();
  1.3514  		ensureSelectionVisible();
  1.3515  	}	
  1.3516  }
  1.3517  
  1.3518 -void MapEditor::editHeading()
  1.3519 -{
  1.3520 -	// Finish open lineEdits
  1.3521 -	if (lineedit) finishedLineEditNoSave();
  1.3522 -
  1.3523 -	if (selection  &&  
  1.3524 -		 (typeid(*selection) == typeid(BranchObj) || 
  1.3525 -		  typeid(*selection) == typeid(MapCenterObj) ) ) 
  1.3526 -	{
  1.3527 -		setChanged();
  1.3528 -		saveState(PartOfMap,selection);
  1.3529 -
  1.3530 +void MapEditor::sortChildren()
  1.3531 +{
  1.3532 +	BranchObj* bo=xelection.getBranch();
  1.3533 +	if (bo)
  1.3534 +	{
  1.3535 +		if(bo->countBranches()>1)
  1.3536 +		{
  1.3537 +			saveStateChangingPart(bo,bo, "sortChildren ()",QString("Sort children of %1").arg(getName(bo)));
  1.3538 +			bo->sortChildren();
  1.3539 +			model->reposition();
  1.3540 +			ensureSelectionVisible();
  1.3541 +		}
  1.3542 +	}
  1.3543 +}
  1.3544 +
  1.3545 +void MapEditor::linkTo(const QString &dstString)	
  1.3546 +{
  1.3547 +	FloatImageObj *fio=xelection.getFloatImage();
  1.3548 +	if (fio)
  1.3549 +	{
  1.3550 +		BranchObj *dst=(BranchObj*)(model->findObjBySelect(dstString));
  1.3551 +		if (dst && (typeid(*dst)==typeid (BranchObj) || 
  1.3552 +					typeid(*dst)==typeid (MapCenterObj)))
  1.3553 +		{			
  1.3554 +			LinkableMapObj *dstPar=dst->getParObj();
  1.3555 +			QString parString=model->getSelectString(dstPar);
  1.3556 +			QString fioPreSelectString=model->getSelectString(fio);
  1.3557 +			QString fioPreParentSelectString=model->getSelectString (fio->getParObj());
  1.3558 +			((BranchObj*)(dst))->addFloatImage (fio);
  1.3559 +			xelection.unselect();
  1.3560 +			((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
  1.3561 +			fio=((BranchObj*)(dst))->getLastFloatImage();
  1.3562 +			fio->setRelPos();
  1.3563 +			fio->reposition();
  1.3564 +			xelection.select(fio);
  1.3565 +			saveState(
  1.3566 +				model->getSelectString(fio),
  1.3567 +				QString("linkTo (\"%1\")").arg(fioPreParentSelectString), 
  1.3568 +				fioPreSelectString, 
  1.3569 +				QString ("linkTo (\"%1\")").arg(dstString),
  1.3570 +				QString ("Link floatimage to %1").arg(getName(dst)));
  1.3571 +		}
  1.3572 +	}
  1.3573 +}
  1.3574 +
  1.3575 +QString MapEditor::getHeading(bool &ok, QPoint &p)
  1.3576 +{
  1.3577 +	BranchObj *bo=xelection.getBranch();
  1.3578 +	if (bo)
  1.3579 +	{
  1.3580 +		ok=true;
  1.3581 +		p=mapFromScene(bo->getAbsPos());
  1.3582 +		return bo->getHeading();
  1.3583 +	}
  1.3584 +	ok=false;
  1.3585 +	return QString();
  1.3586 +}
  1.3587 +
  1.3588 +void MapEditor::setHeading(const QString &s)
  1.3589 +{
  1.3590 +	BranchObj *sel=xelection.getBranch();
  1.3591 +	if (sel)
  1.3592 +	{
  1.3593 +		saveState(
  1.3594 +			sel,
  1.3595 +			"setHeading (\""+sel->getHeading()+"\")", 
  1.3596 +			sel,
  1.3597 +			"setHeading (\""+s+"\")", 
  1.3598 +			QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
  1.3599 +		sel->setHeading(s );
  1.3600 +		model->reposition();
  1.3601 +		xelection.update();
  1.3602  		ensureSelectionVisible();
  1.3603 -		BranchObj *bo=(BranchObj*)(selection);
  1.3604 -		editingBO=(BranchObj*)(selection);
  1.3605 -		QPoint p = worldMatrix().map(QPoint (bo->x(),bo->y()));
  1.3606 -		lineedit->setGeometry(p.x()-contentsX(),p.y()-contentsY(),200,25);
  1.3607 -		QString s=bo->getHeading();
  1.3608 -		lineedit->setText(s);
  1.3609 -		lineedit->setCursorPosition(1);
  1.3610 -		if (actionSettingsAutoselectText->isOn() && !s.isEmpty() && actionSettingsPasteNewHeading->isOn() )
  1.3611 -			lineedit->selectAll();
  1.3612 -		lineedit->show();
  1.3613 -
  1.3614 -		lineedit->grabKeyboard();
  1.3615 -		lineedit->setFocus();
  1.3616 -	}				
  1.3617 +	}
  1.3618  }
  1.3619  
  1.3620 -
  1.3621 -void MapEditor::addNewBranch(int pos)
  1.3622 -{
  1.3623 -	// Finish open lineEdits
  1.3624 -	if (lineedit) finishedLineEditNoSave();
  1.3625 -
  1.3626 -	if (selection  &&  
  1.3627 -		 (typeid(*selection) == typeid(BranchObj) || 
  1.3628 -		  typeid(*selection) == typeid(MapCenterObj) ) ) 
  1.3629 -	{
  1.3630 -		setChanged();
  1.3631 -		saveState(PartOfMap,selection);
  1.3632 -
  1.3633 -		BranchObj* bo1 = (BranchObj*) (selection);
  1.3634 -		bool wasScrolled=false;
  1.3635 -		BranchObj *newbo=NULL;
  1.3636 -		if (pos==0)
  1.3637 +void MapEditor::setHeadingInt(const QString &s)
  1.3638 +{
  1.3639 +	BranchObj *bo=xelection.getBranch();
  1.3640 +	if (bo)
  1.3641 +	{
  1.3642 +		bo->setHeading(s);
  1.3643 +		model->reposition();
  1.3644 +		xelection.update();
  1.3645 +		ensureSelectionVisible();
  1.3646 +	}
  1.3647 +}
  1.3648 +
  1.3649 +void MapEditor::setVymLinkInt (const QString &s)
  1.3650 +{
  1.3651 +	// Internal function, no saveState needed
  1.3652 +	BranchObj *bo=xelection.getBranch();
  1.3653 +	if (bo)
  1.3654 +	{
  1.3655 +		bo->setVymLink(s);
  1.3656 +		model->reposition();
  1.3657 +		updateActions();
  1.3658 +		xelection.update();
  1.3659 +		ensureSelectionVisible();
  1.3660 +	}
  1.3661 +}
  1.3662 +
  1.3663 +BranchObj* MapEditor::addMapCenter ()
  1.3664 +{
  1.3665 +	MapCenterObj *mco= model->addMapCenter(contextMenuPos);
  1.3666 +	xelection.select (mco);
  1.3667 +	updateActions();
  1.3668 +	ensureSelectionVisible();
  1.3669 +	saveState (
  1.3670 +		mco,
  1.3671 +		"delete()",
  1.3672 +		NULL,
  1.3673 +		QString ("addMapCenter (%1,%2)").arg (contextMenuPos.x()).arg(contextMenuPos.y()),
  1.3674 +		QString ("Adding MapCenter to (%1,%2").arg (contextMenuPos.x()).arg(contextMenuPos.y())
  1.3675 +	);	
  1.3676 +	return mco;	
  1.3677 +}
  1.3678 +
  1.3679 +BranchObj* MapEditor::addNewBranchInt(int num)
  1.3680 +{
  1.3681 +	// Depending on pos:
  1.3682 +	// -3		insert in childs of parent  above selection 
  1.3683 +	// -2		add branch to selection 
  1.3684 +	// -1		insert in childs of parent below selection 
  1.3685 +	// 0..n		insert in childs of parent at pos
  1.3686 +	BranchObj *newbo=NULL;
  1.3687 +	BranchObj *bo=xelection.getBranch();
  1.3688 +	if (bo)
  1.3689 +	{
  1.3690 +		if (num==-2)
  1.3691  		{
  1.3692  			// save scroll state. If scrolled, automatically select
  1.3693  			// new branch in order to tmp unscroll parent...
  1.3694 -			wasScrolled=bo1->isScrolled();
  1.3695 -			newbo=bo1->addBranch();
  1.3696 -		}	else 
  1.3697 +			newbo=bo->addBranch();
  1.3698 +			
  1.3699 +		}else if (num==-1)
  1.3700  		{
  1.3701 -			BranchObj *parbo=(BranchObj*)(selection->getParObj());
  1.3702 -			if (parbo)
  1.3703 -			{
  1.3704 -				if (pos<0)
  1.3705 -					// add above selection
  1.3706 -					newbo=parbo->insertBranch(bo1->getNum());
  1.3707 -				else
  1.3708 -					// add below selection
  1.3709 -					newbo=parbo->insertBranch(bo1->getNum()+1);
  1.3710 -			} else
  1.3711 -				// This should not happen...
  1.3712 -				return;
  1.3713 -			
  1.3714 +			num=bo->getNum()+1;
  1.3715 +			bo=(BranchObj*)bo->getParObj();
  1.3716 +			if (bo) newbo=bo->insertBranch(num);
  1.3717 +		}else if (num==-3)
  1.3718 +		{
  1.3719 +			num=bo->getNum();
  1.3720 +			bo=(BranchObj*)bo->getParObj();
  1.3721 +			if (bo) newbo=bo->insertBranch(num);
  1.3722 +		}
  1.3723 +		if (!newbo) return NULL;
  1.3724 +	}	
  1.3725 +	return newbo;
  1.3726 +}	
  1.3727 +
  1.3728 +BranchObj* MapEditor::addNewBranch(int pos)
  1.3729 +{
  1.3730 +	// Different meaning than num in addNewBranchInt!
  1.3731 +	// -1	add above
  1.3732 +	//  0	add as child
  1.3733 +	// +1	add below
  1.3734 +	BranchObj *bo = xelection.getBranch();
  1.3735 +	BranchObj *newbo=NULL;
  1.3736 +
  1.3737 +	if (bo)
  1.3738 +	{
  1.3739 +		setCursor (Qt::ArrowCursor);
  1.3740 +
  1.3741 +		newbo=addNewBranchInt (pos-2);
  1.3742 +
  1.3743 +		if (newbo)
  1.3744 +		{
  1.3745 +			saveState(
  1.3746 +				newbo,		
  1.3747 +				"delete ()",
  1.3748 +				bo,
  1.3749 +				QString ("addBranch (%1)").arg(pos),
  1.3750 +				QString ("Add new branch to %1").arg(getName(bo)));	
  1.3751 +
  1.3752 +			model->reposition();
  1.3753 +			xelection.update();
  1.3754 +			latestSelection=model->getSelectString(newbo);
  1.3755 +			// In Network mode, the client needs to know where the new branch is,
  1.3756 +			// so we have to pass on this information via saveState.
  1.3757 +			// TODO: Get rid of this positioning workaround
  1.3758 +			QString ps=qpointfToString (newbo->getAbsPos());
  1.3759 +			sendData ("selectLatestAdded ()");
  1.3760 +			sendData (QString("move %1").arg(ps));
  1.3761 +			sendSelection();
  1.3762 +		}
  1.3763 +	}	
  1.3764 +	return newbo;
  1.3765 +}
  1.3766 +
  1.3767 +
  1.3768 +BranchObj* MapEditor::addNewBranchBefore()
  1.3769 +{
  1.3770 +	BranchObj *newbo=NULL;
  1.3771 +	BranchObj *bo = xelection.getBranch();
  1.3772 +	if (bo && xelection.type()==Selection::Branch)
  1.3773 +		 // We accept no MapCenterObj here, so we _have_ a parent
  1.3774 +	{
  1.3775 +		QPointF p=bo->getRelPos();
  1.3776 +
  1.3777 +
  1.3778 +		BranchObj *parbo=(BranchObj*)(bo->getParObj());
  1.3779 +
  1.3780 +		// add below selection
  1.3781 +		newbo=parbo->insertBranch(bo->getNum()+1);
  1.3782 +		if (newbo)
  1.3783 +		{
  1.3784 +			newbo->move2RelPos (p);
  1.3785 +
  1.3786 +			// Move selection to new branch
  1.3787 +			bo->linkTo (newbo,-1);
  1.3788 +
  1.3789 +			saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()", 
  1.3790 +				QString ("Add branch before %1").arg(getName(bo)));
  1.3791 +
  1.3792 +			model->reposition();
  1.3793 +			xelection.update();
  1.3794 +		}
  1.3795 +	}	
  1.3796 +	latestSelection=xelection.getSelectString();
  1.3797 +	return newbo;
  1.3798 +}
  1.3799 +
  1.3800 +void MapEditor::deleteSelection()
  1.3801 +{
  1.3802 +	BranchObj *bo = xelection.getBranch();
  1.3803 +	if (bo && xelection.type()==Selection::MapCenter)
  1.3804 +	{
  1.3805 +	//	BranchObj* par=(BranchObj*)(bo->getParObj());
  1.3806 +		xelection.unselect();
  1.3807 +	/* FIXME Note:  does saveStateRemovingPart work for MCO? (No parent!)
  1.3808 +		saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
  1.3809 +		*/
  1.3810 +		bo=model->removeMapCenter ((MapCenterObj*)bo);
  1.3811 +		if (bo) 
  1.3812 +		{
  1.3813 +			xelection.select (bo);
  1.3814 +			ensureSelectionVisible();
  1.3815 +			xelection.update();
  1.3816  		}	
  1.3817 -
  1.3818 -		LinkableMapObj *oldselection=selection;
  1.3819 -
  1.3820 -		mapCenter->reposition();
  1.3821 -		adjustCanvasSize();
  1.3822 -		if (actionSettingsAutoedit->isOn() ||
  1.3823 -			actionSettingsAutoselectHeading->isOn() )
  1.3824 -		{
  1.3825 -			selection->unselect();
  1.3826 -			selection=newbo;
  1.3827 -			selection->select();
  1.3828 -			if (actionSettingsPasteNewHeading->isOn() )
  1.3829 -			{
  1.3830 -				BranchObj *bo2= (BranchObj*)(selection);
  1.3831 -				bo2->setHeading("");
  1.3832 -			}	
  1.3833 -			if (actionSettingsAutoedit->isOn() )
  1.3834 -				editHeading();
  1.3835 -			if (!actionSettingsAutoselectHeading->isOn()
  1.3836 -				&& !wasScrolled)
  1.3837 -			{
  1.3838 -				selection->unselect();
  1.3839 -				selection=oldselection;
  1.3840 -				selection->select();
  1.3841 -			}
  1.3842 -		}	
  1.3843 +		model->reposition();
  1.3844 +		return;
  1.3845 +	}
  1.3846 +	if (bo && xelection.type()==Selection::Branch)
  1.3847 +	{
  1.3848 +		BranchObj* par=(BranchObj*)bo->getParObj();
  1.3849 +		xelection.unselect();
  1.3850 +		saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
  1.3851 +		par->removeBranch(bo);
  1.3852 +		xelection.select (par);
  1.3853 +		ensureSelectionVisible();
  1.3854 +		model->reposition();
  1.3855 +//		xelection.update();
  1.3856 +		xelection.update();
  1.3857 +		return;
  1.3858 +	}
  1.3859 +	FloatImageObj *fio=xelection.getFloatImage();
  1.3860 +	if (fio)
  1.3861 +	{
  1.3862 +		BranchObj* par=(BranchObj*)fio->getParObj();
  1.3863 +		saveStateChangingPart(
  1.3864 +			par, 
  1.3865 +			fio,
  1.3866 +			"delete ()",
  1.3867 +			QString("Delete %1").arg(getName(fio))
  1.3868 +		);
  1.3869 +		xelection.unselect();
  1.3870 +		par->removeFloatImage(fio);
  1.3871 +		xelection.select (par);
  1.3872 +		model->reposition();
  1.3873 +		xelection.update();
  1.3874 +		ensureSelectionVisible();
  1.3875 +		return;
  1.3876 +	}
  1.3877 +}
  1.3878 +
  1.3879 +LinkableMapObj* MapEditor::getSelection()
  1.3880 +{
  1.3881 +	return xelection.single();
  1.3882 +}
  1.3883 +
  1.3884 +BranchObj* MapEditor::getSelectedBranch()
  1.3885 +{
  1.3886 +	return xelection.getBranch();
  1.3887 +}
  1.3888 +
  1.3889 +FloatImageObj* MapEditor::getSelectedFloatImage()
  1.3890 +{
  1.3891 +	return xelection.getFloatImage();
  1.3892 +}
  1.3893 +
  1.3894 +void MapEditor::unselect()
  1.3895 +{
  1.3896 +	xelection.unselect();
  1.3897 +}	
  1.3898 +
  1.3899 +void MapEditor::reselect()
  1.3900 +{
  1.3901 +	xelection.reselect();
  1.3902 +}	
  1.3903 +
  1.3904 +bool MapEditor::select (const QString &s)
  1.3905 +{
  1.3906 +	if (xelection.select(s))
  1.3907 +	{
  1.3908 +		xelection.update();
  1.3909 +		ensureSelectionVisible();
  1.3910 +		sendSelection ();
  1.3911 +		return true;
  1.3912 +	}
  1.3913 +	return false;
  1.3914 +}
  1.3915 +
  1.3916 +bool MapEditor::select (LinkableMapObj *lmo)
  1.3917 +{
  1.3918 +	if (xelection.select(lmo))
  1.3919 +	{
  1.3920 +		xelection.update();
  1.3921 +		ensureSelectionVisible();
  1.3922 +		sendSelection ();
  1.3923 +		return true;
  1.3924 +	}
  1.3925 +	return false;
  1.3926 +}
  1.3927 +
  1.3928 +QString MapEditor::getSelectString()
  1.3929 +{
  1.3930 +	return xelection.getSelectString();
  1.3931 +}
  1.3932 +
  1.3933 +void MapEditor::selectInt (LinkableMapObj *lmo)
  1.3934 +{
  1.3935 +	if (lmo && xelection.single()!= lmo && isSelectBlocked()==false )
  1.3936 +	{
  1.3937 +		xelection.select(lmo);
  1.3938 +		xelection.update();
  1.3939 +		sendSelection ();
  1.3940  	}	
  1.3941  }
  1.3942  
  1.3943 -void MapEditor::deleteSelection()
  1.3944 -{
  1.3945 -	// Finish open lineEdits
  1.3946 -	if (lineedit) finishedLineEditNoSave();
  1.3947 -
  1.3948 -	if (selection  && typeid(*selection) ==typeid(BranchObj) ) 
  1.3949 -	{
  1.3950 -		setChanged();
  1.3951 -		saveState(PartOfMap,selection->getParObj());
  1.3952 -		BranchObj* bo=dynamic_cast <BranchObj*> (selection);
  1.3953 -		BranchObj* par=(BranchObj*)(bo->getParObj());
  1.3954 -		bo->unselect();
  1.3955 -		selection=NULL;
  1.3956 -		par->removeBranch(bo);
  1.3957 -		selection=par;
  1.3958 -		selection->select();
  1.3959 -		ensureSelectionVisible();
  1.3960 -		mapCenter->reposition();
  1.3961 -		adjustCanvasSize();
  1.3962 -	}
  1.3963 -	if (selection  && typeid(*selection) ==typeid(FloatImageObj) ) 
  1.3964 -	{
  1.3965 -		setChanged();
  1.3966 -		saveState(PartOfMap,selection->getParObj());
  1.3967 -		FloatImageObj* fio=dynamic_cast <FloatImageObj*> (selection);
  1.3968 -		BranchObj* par=(BranchObj*)(fio->getParObj());
  1.3969 -		fio->unselect();
  1.3970 -		selection=NULL;
  1.3971 -		par->removeFloatImage(fio);
  1.3972 -		selection=par;
  1.3973 -		selection->select();
  1.3974 -		ensureSelectionVisible();
  1.3975 -		mapCenter->reposition();
  1.3976 -		adjustCanvasSize();
  1.3977 -	}
  1.3978 -}
  1.3979 -
  1.3980 -LinkableMapObj* MapEditor::getSelection()
  1.3981 -{
  1.3982 -	return selection;
  1.3983 -}
  1.3984 -
  1.3985 -bool MapEditor::select (QString s)
  1.3986 -{
  1.3987 -	LinkableMapObj *lmo=mapCenter;
  1.3988 -	QString part;
  1.3989 -	QString typ;
  1.3990 -	QString num;
  1.3991 -	while (!s.isEmpty() )
  1.3992 -	{
  1.3993 -		part=s.section(",",0,0);
  1.3994 -		typ=part.left (3);
  1.3995 -		num=part.right(part.length() - 3);
  1.3996 -		
  1.3997 -		if (typ=="mc:")
  1.3998 -		{
  1.3999 -			if (num=="")
  1.4000 -				break;
  1.4001 -			else
  1.4002 -				lmo=mapCenter->getBranchNum (num.toUInt());
  1.4003 -		} else
  1.4004 -			if (typ=="bo:")
  1.4005 -				lmo=((BranchObj*)(lmo))->getBranchNum (num.toUInt());
  1.4006 -			else
  1.4007 -				if (typ=="fi:")
  1.4008 -					lmo=((BranchObj*)(lmo))->getFloatImageNum (num.toUInt());
  1.4009 -				
  1.4010 -		
  1.4011 -		
  1.4012 -		if (!lmo) break;
  1.4013 -		
  1.4014 -		if (s.contains(","))
  1.4015 -			s=s.right(s.length() - part.length() -1 );
  1.4016 -		else	
  1.4017 -			break;
  1.4018 -	}
  1.4019 -
  1.4020 -	// Finally select the found object
  1.4021 -	if (lmo)
  1.4022 -	{
  1.4023 -		if (selection) selection->unselect();
  1.4024 -		selection=lmo;
  1.4025 -		selection->select();
  1.4026 -		adjustCanvasSize();
  1.4027 -		ensureSelectionVisible();
  1.4028 -		return true;
  1.4029 -	} else
  1.4030 -		return false;
  1.4031 -	
  1.4032 -	
  1.4033 -}
  1.4034 -
  1.4035 -void MapEditor::unselect()
  1.4036 -{
  1.4037 -	if (selection) 
  1.4038 -	{
  1.4039 -		selectionLast=selection;
  1.4040 -		selection->unselect();
  1.4041 -		selection=NULL;
  1.4042 -	}
  1.4043 -}	
  1.4044 -
  1.4045 -void MapEditor::reselect()
  1.4046 -{
  1.4047 -	if (selectionLast)
  1.4048 -	{
  1.4049 -		selection=selectionLast;
  1.4050 -		selection->select();
  1.4051 -		selectionLast=NULL;
  1.4052 -	}
  1.4053 -}	
  1.4054 -
  1.4055 -void MapEditor::selectNextBranch()
  1.4056 +void MapEditor::selectNextBranchInt()
  1.4057  {
  1.4058  	// Increase number of branch
  1.4059 -	if (selection)
  1.4060 -	{
  1.4061 -		QString s=selection->getSelectString();
  1.4062 +	LinkableMapObj *sel=xelection.single();
  1.4063 +	if (sel)
  1.4064 +	{
  1.4065 +		QString s=xelection.getSelectString();
  1.4066  		QString part;
  1.4067  		QString typ;
  1.4068  		QString num;
  1.4069 @@ -1548,7 +2939,7 @@
  1.4070  		// try to increase the parental number in order to
  1.4071  		// find a successor with same depth
  1.4072  
  1.4073 -		int d=selection->getDepth();
  1.4074 +		int d=xelection.single()->getDepth();
  1.4075  		int oldDepth=d;
  1.4076  		int i;
  1.4077  		bool found=false;
  1.4078 @@ -1569,7 +2960,7 @@
  1.4079  			} else
  1.4080  			{
  1.4081  				// Special case, look at orientation
  1.4082 -				if (selection->getOrientation()==OrientRightOfCenter)
  1.4083 +				if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
  1.4084  					num=QString ("%1").arg(num.toUInt()+1);
  1.4085  				else	
  1.4086  					num=QString ("%1").arg(num.toUInt()-1);
  1.4087 @@ -1583,7 +2974,7 @@
  1.4088  					b=select (s);
  1.4089  					if (b)
  1.4090  					{	
  1.4091 -						if ( ((BranchObj*)(selection))->countBranches()>0)
  1.4092 +						if ( xelection.getBranch()->countBranches()>0)
  1.4093  							s+=",bo:0";
  1.4094  						else	
  1.4095  							break;
  1.4096 @@ -1599,12 +2990,13 @@
  1.4097  	}	
  1.4098  }
  1.4099  
  1.4100 -void MapEditor::selectPrevBranch()
  1.4101 +void MapEditor::selectPrevBranchInt()
  1.4102  {
  1.4103  	// Decrease number of branch
  1.4104 -	if (selection)
  1.4105 -	{
  1.4106 -		QString s=selection->getSelectString();
  1.4107 +	BranchObj *bo=xelection.getBranch();
  1.4108 +	if (bo)
  1.4109 +	{
  1.4110 +		QString s=xelection.getSelectString();
  1.4111  		QString part;
  1.4112  		QString typ;
  1.4113  		QString num;
  1.4114 @@ -1616,19 +3008,20 @@
  1.4115  
  1.4116  		s=s.left (s.length() -num.length());
  1.4117  
  1.4118 +		int n=num.toInt()-1;
  1.4119 +		
  1.4120  		// Go to next lmo
  1.4121 -		num=QString ("%1").arg(num.toUInt()-1);
  1.4122 -
  1.4123 +		num=QString ("%1").arg(n);
  1.4124  		s=s+num;
  1.4125  		
  1.4126  		// Try to select this one
  1.4127 -		if (select (s)) return;
  1.4128 +		if (n>=0 && select (s)) return;
  1.4129  
  1.4130  		// We have no direct precessor, 
  1.4131  		// try to decrease the parental number in order to
  1.4132  		// find a precessor with same depth
  1.4133  
  1.4134 -		int d=selection->getDepth();
  1.4135 +		int d=xelection.single()->getDepth();
  1.4136  		int oldDepth=d;
  1.4137  		int i;
  1.4138  		bool found=false;
  1.4139 @@ -1644,15 +3037,15 @@
  1.4140  			if (d>1)
  1.4141  			{
  1.4142  				// decrease number of parent
  1.4143 -				num=QString ("%1").arg(num.toUInt()-1);
  1.4144 +				num=QString ("%1").arg(num.toInt()-1);
  1.4145  				s=s.section (",",0,d-2) + ","+ typ+num;
  1.4146  			} else
  1.4147  			{
  1.4148  				// Special case, look at orientation
  1.4149 -				if (selection->getOrientation()==OrientRightOfCenter)
  1.4150 -					num=QString ("%1").arg(num.toUInt()-1);
  1.4151 +				if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
  1.4152 +					num=QString ("%1").arg(num.toInt()-1);
  1.4153  				else	
  1.4154 -					num=QString ("%1").arg(num.toUInt()+1);
  1.4155 +					num=QString ("%1").arg(num.toInt()+1);
  1.4156  				s=typ+num;
  1.4157  			}	
  1.4158  
  1.4159 @@ -1662,8 +3055,8 @@
  1.4160  				{
  1.4161  					b=select (s);
  1.4162  					if (b)
  1.4163 -						if ( ((BranchObj*)(selection))->countBranches()>0)
  1.4164 -							s+=",bo:"+ QString ("%1").arg( ((BranchObj*)(selection))->countBranches()-1 );
  1.4165 +						if ( xelection.getBranch()->countBranches()>0)
  1.4166 +							s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
  1.4167  						else	
  1.4168  							break;
  1.4169  					else
  1.4170 @@ -1680,100 +3073,90 @@
  1.4171  
  1.4172  void MapEditor::selectUpperBranch()
  1.4173  {
  1.4174 -	// Finish open lineEdits
  1.4175 -	if (lineedit) finishedLineEditNoSave();
  1.4176 -
  1.4177 -	if (selection) 
  1.4178 -	{
  1.4179 -		if (typeid(*selection) == typeid(BranchObj))
  1.4180 -		{
  1.4181 -			if (selection->getOrientation()==OrientRightOfCenter)
  1.4182 -				selectPrevBranch();
  1.4183 +	if (isSelectBlocked() ) return;
  1.4184 +
  1.4185 +	BranchObj *bo=xelection.getBranch();
  1.4186 +	if (bo && xelection.type()==Selection::Branch)
  1.4187 +	{
  1.4188 +		if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
  1.4189 +			selectPrevBranchInt();
  1.4190 +		else
  1.4191 +			if (bo->getDepth()==1)
  1.4192 +				selectNextBranchInt();
  1.4193  			else
  1.4194 -				if (selection->getDepth()==1)
  1.4195 -					selectNextBranch();
  1.4196 -				else
  1.4197 -					selectPrevBranch();
  1.4198 -		}		
  1.4199 +				selectPrevBranchInt();
  1.4200  	}
  1.4201  }
  1.4202  
  1.4203  void MapEditor::selectLowerBranch()
  1.4204  {
  1.4205 -	// Finish open lineEdits
  1.4206 -	if (lineedit) finishedLineEditNoSave();
  1.4207 -
  1.4208 -	if (selection) 
  1.4209 -	{
  1.4210 -		if (typeid(*selection) == typeid(BranchObj))
  1.4211 -		{
  1.4212 -			if (selection->getOrientation()==OrientRightOfCenter)
  1.4213 -				selectNextBranch();
  1.4214 +	if (isSelectBlocked() ) return;
  1.4215 +
  1.4216 +	BranchObj *bo=xelection.getBranch();
  1.4217 +	if (bo && xelection.type()==Selection::Branch)
  1.4218 +	{
  1.4219 +		if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
  1.4220 +			selectNextBranchInt();
  1.4221 +		else
  1.4222 +			if (bo->getDepth()==1)
  1.4223 +				selectPrevBranchInt();
  1.4224  			else
  1.4225 -				if (selection->getDepth()==1)
  1.4226 -					selectPrevBranch();
  1.4227 -				else
  1.4228 -					selectNextBranch();
  1.4229 -		}		
  1.4230 -	}
  1.4231 +				selectNextBranchInt();
  1.4232 +	}			
  1.4233  }
  1.4234  
  1.4235  
  1.4236  void MapEditor::selectLeftBranch()
  1.4237  {
  1.4238 -	// Finish open lineEdits
  1.4239 -	if (lineedit) finishedLineEditNoSave();
  1.4240 +	if (isSelectBlocked() ) return;
  1.4241  
  1.4242  	BranchObj* bo;
  1.4243  	BranchObj* par;
  1.4244 -	if (selection) 
  1.4245 -	{
  1.4246 -		if (typeid(*selection) == typeid(MapCenterObj))
  1.4247 +	LinkableMapObj *sel=xelection.single();
  1.4248 +	if (sel)
  1.4249 +	{
  1.4250 +		if (xelection.type()== Selection::MapCenter)
  1.4251  		{
  1.4252 -			par=  (BranchObj*) (selection);
  1.4253 +			par=xelection.getBranch();
  1.4254  			bo=par->getLastSelectedBranch();
  1.4255  			if (bo)
  1.4256  			{
  1.4257  				// Workaround for reselecting on left and right side
  1.4258 -				if (bo->getOrientation()==OrientRightOfCenter)
  1.4259 +				if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
  1.4260 +					bo=par->getLastBranch();
  1.4261 +				if (bo)
  1.4262  				{
  1.4263  					bo=par->getLastBranch();
  1.4264 -				}	
  1.4265 -				if (bo)
  1.4266 -				{
  1.4267 -					par->unselect();
  1.4268 -					selection=bo;
  1.4269 -					selection->select();
  1.4270 -					adjustCanvasSize();
  1.4271 +					xelection.select(bo);
  1.4272 +					xelection.update();
  1.4273  					ensureSelectionVisible();
  1.4274 +					sendSelection();
  1.4275  				}
  1.4276  			}	
  1.4277  		} else
  1.4278  		{
  1.4279 -			par=(BranchObj*)(selection->getParObj());
  1.4280 -			if (selection->getOrientation()==OrientRightOfCenter)
  1.4281 +			par=(BranchObj*)(sel->getParObj());
  1.4282 +			if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
  1.4283  			{
  1.4284 -				if (typeid(*selection) == typeid(BranchObj) ||
  1.4285 -					typeid(*selection) == typeid(FloatImageObj))
  1.4286 +				if (xelection.type() == Selection::Branch ||
  1.4287 +					xelection.type() == Selection::FloatImage)
  1.4288  				{
  1.4289 -					selection->unselect();
  1.4290 -					selection=par;
  1.4291 -					selection->select();
  1.4292 -					adjustCanvasSize();
  1.4293 +					xelection.select(par);
  1.4294 +					xelection.update();
  1.4295  					ensureSelectionVisible();
  1.4296 +					sendSelection();
  1.4297  				}
  1.4298  			} else
  1.4299  			{
  1.4300 -				if (typeid(*selection) == typeid(BranchObj) )
  1.4301 +				if (xelection.type() == Selection::Branch )
  1.4302  				{
  1.4303 -					bo=((BranchObj*)(selection))->getLastSelectedBranch();
  1.4304 +					bo=xelection.getBranch()->getLastSelectedBranch();
  1.4305  					if (bo) 
  1.4306  					{
  1.4307 -						selection->unselect();
  1.4308 -						selection=bo;
  1.4309 -						selection->select();
  1.4310 -						adjustCanvasSize();
  1.4311 +						xelection.select(bo);
  1.4312 +						xelection.update();
  1.4313  						ensureSelectionVisible();
  1.4314 +					sendSelection();
  1.4315  					}
  1.4316  				}
  1.4317  			}
  1.4318 @@ -1783,57 +3166,54 @@
  1.4319  
  1.4320  void MapEditor::selectRightBranch()
  1.4321  {
  1.4322 -	// Finish open lineEdits
  1.4323 -	if (lineedit) finishedLineEditNoSave();
  1.4324 +	if (isSelectBlocked() ) return;
  1.4325  
  1.4326  	BranchObj* bo;
  1.4327  	BranchObj* par;
  1.4328 -
  1.4329 -	if (selection) 
  1.4330 -	{
  1.4331 -		if (typeid(*selection) == typeid(MapCenterObj))
  1.4332 +	LinkableMapObj *sel=xelection.single();
  1.4333 +	if (sel)
  1.4334 +	{
  1.4335 +		if (xelection.type()==Selection::MapCenter) 
  1.4336  		{
  1.4337 -			par=  (BranchObj*) (selection);
  1.4338 +			par=xelection.getBranch();
  1.4339  			bo=par->getLastSelectedBranch();
  1.4340  			if (bo)
  1.4341  			{
  1.4342 -				// Workaround for relecting on left and right side
  1.4343 -				if (bo->getOrientation()==OrientLeftOfCenter)
  1.4344 +				// Workaround for reselecting on left and right side
  1.4345 +				if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
  1.4346  					bo=par->getFirstBranch();
  1.4347  				if (bo)
  1.4348  				{
  1.4349 -					par->unselect();
  1.4350 -					selection=bo;
  1.4351 -					selection->select();
  1.4352 +					xelection.select(bo);
  1.4353 +					xelection.update();
  1.4354  					ensureSelectionVisible();
  1.4355 +					sendSelection();
  1.4356  				}
  1.4357  			}
  1.4358  		} else
  1.4359  		{
  1.4360 -			par=(BranchObj*)(selection->getParObj());
  1.4361 -			if (selection->getOrientation()==OrientLeftOfCenter)
  1.4362 +			par=(BranchObj*)(xelection.single()->getParObj());
  1.4363 +			if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
  1.4364  			{
  1.4365 -				if (typeid(*selection) == typeid(BranchObj) ||
  1.4366 -					typeid(*selection) == typeid(FloatImageObj))
  1.4367 +				if (xelection.type() == Selection::Branch ||
  1.4368 +					xelection.type() == Selection::FloatImage)
  1.4369  				{
  1.4370 -					selection->unselect();
  1.4371 -					selection=par;
  1.4372 -					selection->select();
  1.4373 -					adjustCanvasSize();
  1.4374 +					xelection.select(par);
  1.4375 +					xelection.update();
  1.4376  					ensureSelectionVisible();
  1.4377 +					sendSelection();
  1.4378  				}
  1.4379  			} else
  1.4380  			{
  1.4381 -				if (typeid(*selection) == typeid(BranchObj) )
  1.4382 +				if (xelection.type()  == Selection::Branch) 
  1.4383  				{
  1.4384 -					bo=((BranchObj*)(selection))->getLastSelectedBranch();
  1.4385 +					bo=xelection.getBranch()->getLastSelectedBranch();
  1.4386  					if (bo) 
  1.4387  					{
  1.4388 -						selection->unselect();
  1.4389 -						selection=bo;
  1.4390 -						selection->select();
  1.4391 -						adjustCanvasSize();
  1.4392 +						xelection.select(bo);
  1.4393 +						xelection.update();
  1.4394  						ensureSelectionVisible();
  1.4395 +					sendSelection();
  1.4396  					}
  1.4397  				}
  1.4398  			}
  1.4399 @@ -1843,146 +3223,183 @@
  1.4400  
  1.4401  void MapEditor::selectFirstBranch()
  1.4402  {
  1.4403 -	// Finish open lineEdits
  1.4404 -	if (lineedit) finishedLineEditNoSave();
  1.4405 -
  1.4406 -	BranchObj *bo1;
  1.4407 +	BranchObj *bo1=xelection.getBranch();
  1.4408  	BranchObj *bo2;
  1.4409  	BranchObj* par;
  1.4410 -	if (selection) {
  1.4411 -		if (typeid(*selection) == typeid(BranchObj))
  1.4412 +	if (bo1)
  1.4413 +	{
  1.4414 +		par=(BranchObj*)(bo1->getParObj());
  1.4415 +		if (!par) return;
  1.4416 +		bo2=par->getFirstBranch();
  1.4417 +		if (bo2) {
  1.4418 +			xelection.select(bo2);
  1.4419 +			xelection.update();
  1.4420 +			ensureSelectionVisible();
  1.4421 +			sendSelection();
  1.4422 +		}
  1.4423 +	}		
  1.4424 +}
  1.4425 +
  1.4426 +void MapEditor::selectLastBranch()
  1.4427 +{
  1.4428 +	BranchObj *bo1=xelection.getBranch();
  1.4429 +	BranchObj *bo2;
  1.4430 +	BranchObj* par;
  1.4431 +	if (bo1)
  1.4432 +	{
  1.4433 +		par=(BranchObj*)(bo1->getParObj());
  1.4434 +		if (!par) return;
  1.4435 +		bo2=par->getLastBranch();
  1.4436 +		if (bo2) 
  1.4437  		{
  1.4438 -			bo1=  (BranchObj*) (selection);
  1.4439 -			par=(BranchObj*)(bo1->getParObj());
  1.4440 -			bo2=par->getFirstBranch();
  1.4441 -			if (bo2) {
  1.4442 -				bo1->unselect();
  1.4443 -				selection=bo2;
  1.4444 -				selection->select();
  1.4445 -				ensureSelectionVisible();
  1.4446 -			}
  1.4447 -		}		
  1.4448 -		adjustCanvasSize();
  1.4449 +			xelection.select(bo2);
  1.4450 +			xelection.update();
  1.4451 +			ensureSelectionVisible();
  1.4452 +			sendSelection();
  1.4453 +		}
  1.4454 +	}		
  1.4455 +}
  1.4456 +
  1.4457 +void MapEditor::selectMapBackgroundImage ()
  1.4458 +{
  1.4459 +	Q3FileDialog *fd=new Q3FileDialog( this);
  1.4460 +	fd->setMode (Q3FileDialog::ExistingFile);
  1.4461 +	fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
  1.4462 +	ImagePreview *p =new ImagePreview (fd);
  1.4463 +	fd->setContentsPreviewEnabled( TRUE );
  1.4464 +	fd->setContentsPreview( p, p );
  1.4465 +	fd->setPreviewMode( Q3FileDialog::Contents );
  1.4466 +	fd->setCaption(vymName+" - " +tr("Load background image"));
  1.4467 +	fd->setDir (lastImageDir);
  1.4468 +	fd->show();
  1.4469 +
  1.4470 +	if ( fd->exec() == QDialog::Accepted )
  1.4471 +	{
  1.4472 +		// TODO selectMapBackgroundImg in QT4 use:	lastImageDir=fd->directory();
  1.4473 +		lastImageDir=QDir (fd->dirPath());
  1.4474 +		setMapBackgroundImage (fd->selectedFile());
  1.4475 +	}
  1.4476 +}	
  1.4477 +
  1.4478 +void MapEditor::setMapBackgroundImage (const QString &fn)	//FIXME missing savestate
  1.4479 +{
  1.4480 +	QColor oldcol=mapScene->backgroundBrush().color();
  1.4481 +	/*
  1.4482 +	saveState(
  1.4483 +		selection,
  1.4484 +		QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
  1.4485 +		selection,
  1.4486 +		QString ("setMapBackgroundImage (%1)").arg(col.name()),
  1.4487 +		QString("Set background color of map to %1").arg(col.name()));
  1.4488 +	*/	
  1.4489 +	QBrush brush;
  1.4490 +	brush.setTextureImage (QPixmap (fn));
  1.4491 +	mapScene->setBackgroundBrush(brush);
  1.4492 +}
  1.4493 +
  1.4494 +void MapEditor::selectMapBackgroundColor()
  1.4495 +{
  1.4496 +	QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
  1.4497 +	if ( !col.isValid() ) return;
  1.4498 +	setMapBackgroundColor( col );
  1.4499 +}
  1.4500 +
  1.4501 +
  1.4502 +void MapEditor::setMapBackgroundColor(QColor col)
  1.4503 +{
  1.4504 +	QColor oldcol=mapScene->backgroundBrush().color();
  1.4505 +	saveState(
  1.4506 +		QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
  1.4507 +		QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
  1.4508 +		QString("Set background color of map to %1").arg(col.name()));
  1.4509 +	mapScene->setBackgroundBrush(col);
  1.4510 +}
  1.4511 +
  1.4512 +QColor MapEditor::getMapBackgroundColor()
  1.4513 +{
  1.4514 +    return mapScene->backgroundBrush().color();
  1.4515 +}
  1.4516 +
  1.4517 +QColor MapEditor::getCurrentHeadingColor()
  1.4518 +{
  1.4519 +	BranchObj *bo=xelection.getBranch();
  1.4520 +	if (bo) return bo->getColor(); 
  1.4521 +	
  1.4522 +	QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
  1.4523 +	return Qt::black;
  1.4524 +}
  1.4525 +
  1.4526 +void MapEditor::colorBranch (QColor c)
  1.4527 +{
  1.4528 +	BranchObj *bo=xelection.getBranch();
  1.4529 +	if (bo)
  1.4530 +	{
  1.4531 +		saveState(
  1.4532 +			bo, 
  1.4533 +			QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
  1.4534 +			bo,
  1.4535 +			QString ("colorBranch (\"%1\")").arg(c.name()),
  1.4536 +			QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
  1.4537 +		);	
  1.4538 +		bo->setColor(c); // color branch
  1.4539  	}
  1.4540  }
  1.4541  
  1.4542 -void MapEditor::selectLastBranch()
  1.4543 -{
  1.4544 -	// Finish open lineEdits
  1.4545 -	if (lineedit) finishedLineEditNoSave();
  1.4546 -
  1.4547 -	BranchObj *bo1;
  1.4548 -	BranchObj *bo2;
  1.4549 -	BranchObj* par;
  1.4550 -	if (selection) {
  1.4551 -		if (typeid(*selection) == typeid(BranchObj))
  1.4552 -		{
  1.4553 -			bo1=  (BranchObj*) (selection);
  1.4554 -			par=(BranchObj*)(bo1->getParObj());
  1.4555 -			bo2=par->getLastBranch();
  1.4556 -			if (bo2) {
  1.4557 -				bo1->unselect();
  1.4558 -				selection=bo2;
  1.4559 -				selection->select();
  1.4560 -				ensureSelectionVisible();
  1.4561 -			}
  1.4562 -		}		
  1.4563 -		adjustCanvasSize();
  1.4564 +void MapEditor::colorSubtree (QColor c)
  1.4565 +{
  1.4566 +	BranchObj *bo=xelection.getBranch();
  1.4567 +	if (bo) 
  1.4568 +	{
  1.4569 +		saveStateChangingPart(
  1.4570 +			bo, 
  1.4571 +			bo,
  1.4572 +			QString ("colorSubtree (\"%1\")").arg(c.name()),
  1.4573 +			QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
  1.4574 +		);	
  1.4575 +		bo->setColorSubtree (c); // color links, color childs
  1.4576  	}
  1.4577  }
  1.4578  
  1.4579 -void MapEditor::setColor(QColor c)
  1.4580 -{
  1.4581 -	actColor=c;
  1.4582 -}
  1.4583 -
  1.4584 -void MapEditor::selectBackgroundColor()
  1.4585 -{
  1.4586 -	// Finish open lineEdits
  1.4587 -	if (lineedit) finishedLineEditNoSave();
  1.4588 -
  1.4589 -	QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
  1.4590 -	if ( !col.isValid() ) return;
  1.4591 -	setBackgroundColor( col );
  1.4592 -	setChanged();
  1.4593 -}
  1.4594 -
  1.4595 -void MapEditor::setBackgroundColor(QColor c)
  1.4596 -{
  1.4597 -	mapCanvas->setBackgroundColor (c);
  1.4598 -}
  1.4599 -
  1.4600 -QColor MapEditor::pickColor()
  1.4601 -{
  1.4602 -	if (selection) 
  1.4603 -	{
  1.4604 -		if (typeid(*selection) == typeid(BranchObj) ||
  1.4605 -			typeid(*selection) == typeid(MapCenterObj))
  1.4606 +
  1.4607 +void MapEditor::toggleStandardFlag(QString f)
  1.4608 +{
  1.4609 +	BranchObj *bo=xelection.getBranch();
  1.4610 +	if (bo) 
  1.4611 +	{
  1.4612 +		QString u,r;
  1.4613 +		if (bo->isSetStandardFlag(f))
  1.4614  		{
  1.4615 -			BranchObj *bo=(BranchObj*)(selection);
  1.4616 -			actColor=bo->getColor(); 
  1.4617 -		}    
  1.4618 -	}
  1.4619 -	return actColor;
  1.4620 -}
  1.4621 -
  1.4622 -void MapEditor::colorItem()
  1.4623 -{
  1.4624 -	if (selection) 
  1.4625 -	{
  1.4626 -		if (typeid(*selection) == typeid(BranchObj) ||
  1.4627 -			typeid(*selection) == typeid(MapCenterObj))
  1.4628 +			r="unsetFlag";
  1.4629 +			u="setFlag";
  1.4630 +		}	
  1.4631 +		else
  1.4632  		{
  1.4633 -			setChanged();
  1.4634 -			saveState(PartOfMap,selection);
  1.4635 -			BranchObj *bo=(BranchObj*)(selection);
  1.4636 -			bo->setColor(actColor, false); // color links, color childs
  1.4637 -		}    
  1.4638 +			u="unsetFlag";
  1.4639 +			r="setFlag";
  1.4640 +		}	
  1.4641 +		saveState(
  1.4642 +			bo,
  1.4643 +			QString("%1 (\"%2\")").arg(u).arg(f), 
  1.4644 +			bo,
  1.4645 +			QString("%1 (\"%2\")").arg(r).arg(f),
  1.4646 +			QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
  1.4647 +		bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
  1.4648 +		xelection.update();
  1.4649  	}
  1.4650  }
  1.4651  
  1.4652 -void MapEditor::colorBranch()
  1.4653 -{
  1.4654 -	if (selection) 
  1.4655 -	{
  1.4656 -		if (typeid(*selection) == typeid(BranchObj) ||
  1.4657 -			typeid(*selection) == typeid(MapCenterObj))
  1.4658 -		{
  1.4659 -			setChanged();
  1.4660 -			saveState(PartOfMap,selection);
  1.4661 -			BranchObj *bo=(BranchObj*)(selection);
  1.4662 -			bo->setColor(actColor, true); // color links, color childs
  1.4663 -		}    
  1.4664 -	}
  1.4665 -}
  1.4666 -
  1.4667 -
  1.4668 -void MapEditor::toggleStandardFlag(QString f)
  1.4669 -{
  1.4670 -	if (selection)
  1.4671 -	{
  1.4672 -		setChanged();
  1.4673 -		saveState(PartOfMap,selection);	
  1.4674 -		((BranchObj*)(selection))->toggleStandardFlag (f);
  1.4675 -	}	
  1.4676 -}
  1.4677 -
  1.4678 -void MapEditor::setViewCenter()
  1.4679 -{
  1.4680 -	// transform to CanvasView Coord:
  1.4681 -	QPoint p=worldMatrix().map(movingCenter);
  1.4682 -	center ( p.x(), p.y());
  1.4683 -}
  1.4684 -
  1.4685  
  1.4686  BranchObj* MapEditor::findText (QString s, bool cs)
  1.4687  {
  1.4688 +	QTextDocument::FindFlags flags=0;
  1.4689 +	if (cs) flags=QTextDocument::FindCaseSensitively;
  1.4690 +
  1.4691  	if (!itFind) 
  1.4692  	{	// Nothing found or new find process
  1.4693  		if (EOFind)
  1.4694  			// nothing found, start again
  1.4695  			EOFind=false;
  1.4696 -		itFind=mapCenter->first();
  1.4697 +		itFind=model->first();
  1.4698  	}	
  1.4699  	bool searching=true;
  1.4700  	bool foundNote=false;
  1.4701 @@ -1993,15 +3410,12 @@
  1.4702  			// Searching in Note
  1.4703  			if (itFind->getNote().contains(s,cs))
  1.4704  			{
  1.4705 -				if (selection!=itFind) 
  1.4706 +				if (xelection.single()!=itFind) 
  1.4707  				{
  1.4708 -					if (selection) ((BranchObj*)(selection))->unselect();
  1.4709 -					selection=itFind;
  1.4710 -					selection->select();
  1.4711 -					adjustCanvasSize();
  1.4712 +					xelection.select(itFind);
  1.4713  					ensureSelectionVisible();
  1.4714  				}
  1.4715 -				if (textEditor->findText(s,cs)) 
  1.4716 +				if (textEditor->findText(s,flags)) 
  1.4717  				{
  1.4718  					searching=false;
  1.4719  					foundNote=true;
  1.4720 @@ -2010,25 +3424,21 @@
  1.4721  			// Searching in Heading
  1.4722  			if (searching && itFind->getHeading().contains (s,cs) ) 
  1.4723  			{
  1.4724 -				if (selection) ((BranchObj*)(selection))->unselect();
  1.4725 -				selection=itFind;
  1.4726 -				selection->select();
  1.4727 -				adjustCanvasSize();
  1.4728 +				xelection.select(itFind);
  1.4729  				ensureSelectionVisible();
  1.4730  				searching=false;
  1.4731  			}
  1.4732  		}	
  1.4733  		if (!foundNote)
  1.4734  		{
  1.4735 -			itFind=itFind->next();
  1.4736 +			itFind=model->next(itFind);
  1.4737  			if (!itFind) EOFind=true;
  1.4738  		}
  1.4739 +	//cout <<"still searching...  "<<qPrintable( itFind->getHeading())<<endl;
  1.4740  	}	
  1.4741  	if (!searching)
  1.4742 -	{
  1.4743 -		adjustCanvasSize();
  1.4744 -		return (BranchObj*)(selection);
  1.4745 -	}	else
  1.4746 +		return xelection.getBranch();
  1.4747 +	else
  1.4748  		return NULL;
  1.4749  }
  1.4750  
  1.4751 @@ -2037,154 +3447,305 @@
  1.4752  	itFind=NULL;
  1.4753  	EOFind=false;
  1.4754  }
  1.4755 -
  1.4756 -void MapEditor::openURL()
  1.4757 -{
  1.4758 -	if (selection )
  1.4759 -	{
  1.4760 -		if (typeid(*selection) == typeid(BranchObj) ||
  1.4761 -			typeid(*selection) == typeid(MapCenterObj))
  1.4762 -		{
  1.4763 -			QString url=((BranchObj*)(selection))->getURL();
  1.4764 -
  1.4765 -			QProcess *proc = new QProcess( this );
  1.4766 -
  1.4767 -#if !defined(Q_OS_MACX)
  1.4768 -			proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL","konqueror" ));
  1.4769 -#else			
  1.4770 -			proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL",
  1.4771 -				"/Applications/Safari.app/Contents/MacOS/Safari" ));
  1.4772 -#endif			
  1.4773 -
  1.4774 -			proc->addArgument( url);
  1.4775 -
  1.4776 -			if ( !proc->start() ) 
  1.4777 -				// error handling
  1.4778 -				if (mainWindow->settingsURL() ) 
  1.4779 -					openURL();
  1.4780 -		}	
  1.4781 -	}	
  1.4782 -}
  1.4783 +void MapEditor::setURL(const QString &url)
  1.4784 +{
  1.4785 +	BranchObj *bo=xelection.getBranch();
  1.4786 +	if (bo)
  1.4787 +	{
  1.4788 +		QString oldurl=bo->getURL();
  1.4789 +		bo->setURL (url);
  1.4790 +		saveState (
  1.4791 +			bo,
  1.4792 +			QString ("setURL (\"%1\")").arg(oldurl),
  1.4793 +			bo,
  1.4794 +			QString ("setURL (\"%1\")").arg(url),
  1.4795 +			QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
  1.4796 +		);
  1.4797 +		updateActions();
  1.4798 +		model->reposition();
  1.4799 +		xelection.update();
  1.4800 +		ensureSelectionVisible();
  1.4801 +	}
  1.4802 +}	
  1.4803  
  1.4804  void MapEditor::editURL()
  1.4805  {
  1.4806 -	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.4807 -			typeid(*selection) == typeid(MapCenterObj)) )
  1.4808 +	BranchObj *bo=xelection.getBranch();
  1.4809 +	if (bo)
  1.4810  	{		
  1.4811  		bool ok;
  1.4812  		QString text = QInputDialog::getText(
  1.4813  				"VYM", tr("Enter URL:"), QLineEdit::Normal,
  1.4814 -				((BranchObj*)(selection))->getURL(), &ok, this );
  1.4815 +				bo->getURL(), &ok, this );
  1.4816  		if ( ok) 
  1.4817 -		{
  1.4818  			// user entered something and pressed OK
  1.4819 -			((BranchObj*)(selection))->setURL (text);
  1.4820 -			updateActions();
  1.4821 -			setChanged();
  1.4822 -		}	
  1.4823 +			setURL (text);
  1.4824  	}
  1.4825  }
  1.4826  
  1.4827 +void MapEditor::editLocalURL()
  1.4828 +{
  1.4829 +	BranchObj *bo=xelection.getBranch();
  1.4830 +	if (bo)
  1.4831 +	{		
  1.4832 +		QStringList filters;
  1.4833 +		filters <<"All files (*)";
  1.4834 +		filters << tr("Text","Filedialog") + " (*.txt)";
  1.4835 +		filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
  1.4836 +		filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
  1.4837 +		filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
  1.4838 +		QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Set URL to a local file"));
  1.4839 +		fd->setFilters (filters);
  1.4840 +		fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
  1.4841 +		fd->setDirectory (lastFileDir);
  1.4842 +		if (! bo->getVymLink().isEmpty() )
  1.4843 +			fd->selectFile( bo->getURL() );
  1.4844 +		fd->show();
  1.4845 +
  1.4846 +		if ( fd->exec() == QDialog::Accepted )
  1.4847 +		{
  1.4848 +			lastFileDir=QDir (fd->directory().path());
  1.4849 +			setURL (fd->selectedFile() );
  1.4850 +		}
  1.4851 +	}
  1.4852 +}
  1.4853 +
  1.4854 +QString MapEditor::getURL()
  1.4855 +{
  1.4856 +	BranchObj *bo=xelection.getBranch();
  1.4857 +	if (bo)
  1.4858 +		return bo->getURL();
  1.4859 +	else
  1.4860 +		return "";
  1.4861 +}
  1.4862 +
  1.4863 +QStringList MapEditor::getURLs()
  1.4864 +{
  1.4865 +	QStringList urls;
  1.4866 +	BranchObj *bo=xelection.getBranch();
  1.4867 +	if (bo)
  1.4868 +	{		
  1.4869 +		bo=bo->first();	
  1.4870 +		while (bo) 
  1.4871 +		{
  1.4872 +			if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
  1.4873 +			bo=bo->next();
  1.4874 +		}	
  1.4875 +	}	
  1.4876 +	return urls;
  1.4877 +}
  1.4878 +
  1.4879 +
  1.4880  void MapEditor::editHeading2URL()
  1.4881  {
  1.4882 -	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.4883 -			typeid(*selection) == typeid(MapCenterObj)) )
  1.4884 +	BranchObj *bo=xelection.getBranch();
  1.4885 +	if (bo)
  1.4886 +		setURL (bo->getHeading());
  1.4887 +}	
  1.4888 +
  1.4889 +void MapEditor::editBugzilla2URL()
  1.4890 +{
  1.4891 +	BranchObj *bo=xelection.getBranch();
  1.4892 +	if (bo)
  1.4893  	{		
  1.4894 -		BranchObj *b=(BranchObj*)(selection);
  1.4895 -		b->setURL (b->getHeading());
  1.4896 -		updateActions();
  1.4897 -		setChanged();
  1.4898 +		QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
  1.4899 +		setURL (url);
  1.4900  	}
  1.4901  }	
  1.4902  
  1.4903 -void MapEditor::editBugzilla2URL()
  1.4904 -{
  1.4905 -	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.4906 -			typeid(*selection) == typeid(MapCenterObj)) )
  1.4907 +void MapEditor::editFATE2URL()
  1.4908 +{
  1.4909 +	BranchObj *bo=xelection.getBranch();
  1.4910 +	if (bo)
  1.4911  	{		
  1.4912 -		BranchObj *b=(BranchObj*)(selection);
  1.4913 -		b->setURL ("http://bugzilla.suse.de/show_bug.cgi?id="+b->getHeading());
  1.4914 +		QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
  1.4915 +		saveState(
  1.4916 +			bo,
  1.4917 +			"setURL (\""+bo->getURL()+"\")",
  1.4918 +			bo,
  1.4919 +			"setURL (\""+url+"\")",
  1.4920 +			QString("Use heading of %1 as link to FATE").arg(getName(bo))
  1.4921 +		);	
  1.4922 +		bo->setURL (url);
  1.4923  		updateActions();
  1.4924 -		setChanged();
  1.4925  	}
  1.4926  }	
  1.4927  
  1.4928  void MapEditor::editVymLink()
  1.4929  {
  1.4930 -	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.4931 -			typeid(*selection) == typeid(MapCenterObj)) )
  1.4932 +	BranchObj *bo=xelection.getBranch();
  1.4933 +	if (bo)
  1.4934  	{		
  1.4935 -		QFileDialog *fd=new QFileDialog( this,tr("VYM - Link to another map"));
  1.4936 -		fd->addFilter (QString (tr("vym map") + " (*.vym)"));
  1.4937 -		fd->setCaption(tr("VYM - Link to another map"));
  1.4938 -		if (! ((BranchObj*)(selection))->getVymLink().isEmpty() )
  1.4939 -			fd->setSelection( ((BranchObj*)(selection))->getVymLink() );
  1.4940 +		QStringList filters;
  1.4941 +		filters <<"VYM map (*.vym)";
  1.4942 +		QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
  1.4943 +		fd->setFilters (filters);
  1.4944 +		fd->setCaption(vymName+" - " +tr("Link to another map"));
  1.4945 +		fd->setDirectory (lastFileDir);
  1.4946 +		if (! bo->getVymLink().isEmpty() )
  1.4947 +			fd->selectFile( bo->getVymLink() );
  1.4948  		fd->show();
  1.4949  
  1.4950  		QString fn;
  1.4951  		if ( fd->exec() == QDialog::Accepted )
  1.4952 -			((BranchObj*)(selection))->setVymLink (fd->selectedFile() );
  1.4953 -		updateActions();
  1.4954 -		mapCenter->reposition();
  1.4955 -		adjustCanvasSize();
  1.4956 -		canvas()->update();
  1.4957 -		setChanged();
  1.4958 +		{
  1.4959 +			lastFileDir=QDir (fd->directory().path());
  1.4960 +			saveState(
  1.4961 +				bo,
  1.4962 +				"setVymLink (\""+bo->getVymLink()+"\")",
  1.4963 +				bo,
  1.4964 +				"setVymLink (\""+fd->selectedFile()+"\")",
  1.4965 +				QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
  1.4966 +			);	
  1.4967 +			setVymLinkInt (fd->selectedFile() );
  1.4968 +		}
  1.4969  	}
  1.4970  }
  1.4971  
  1.4972  void MapEditor::deleteVymLink()
  1.4973  {
  1.4974 -	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.4975 -			typeid(*selection) == typeid(MapCenterObj)) )
  1.4976 +	BranchObj *bo=xelection.getBranch();
  1.4977 +	if (bo)
  1.4978  	{		
  1.4979 -		((BranchObj*)(selection))->setVymLink ("" );
  1.4980 +		saveState(
  1.4981 +			bo,
  1.4982 +			"setVymLink (\""+bo->getVymLink()+"\")",
  1.4983 +			bo,
  1.4984 +			"setVymLink (\"\")",
  1.4985 +			QString("Unset vymlink of %1").arg(getName(bo))
  1.4986 +		);	
  1.4987 +		bo->setVymLink ("" );
  1.4988  		updateActions();
  1.4989 -		mapCenter->reposition();
  1.4990 -		adjustCanvasSize();
  1.4991 -		canvas()->update();
  1.4992 -		setChanged();
  1.4993 +		model->reposition();
  1.4994 +		scene()->update();
  1.4995  	}
  1.4996  }
  1.4997  
  1.4998 +void MapEditor::setHideExport(bool b)
  1.4999 +{
  1.5000 +	BranchObj *bo=xelection.getBranch();
  1.5001 +	if (bo)
  1.5002 +	{
  1.5003 +		bo->setHideInExport (b);
  1.5004 +		QString u= b ? "false" : "true";
  1.5005 +		QString r=!b ? "false" : "true";
  1.5006 +		
  1.5007 +		saveState(
  1.5008 +			bo,
  1.5009 +			QString ("setHideExport (%1)").arg(u),
  1.5010 +			bo,
  1.5011 +			QString ("setHideExport (%1)").arg(r),
  1.5012 +			QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
  1.5013 +		);	
  1.5014 +		updateActions();
  1.5015 +		model->reposition();
  1.5016 +		xelection.update();
  1.5017 +		scene()->update();
  1.5018 +	}
  1.5019 +}
  1.5020 +
  1.5021 +void MapEditor::toggleHideExport()
  1.5022 +{
  1.5023 +	BranchObj *bo=xelection.getBranch();
  1.5024 +	if (bo)
  1.5025 +		setHideExport ( !bo->hideInExport() );
  1.5026 +}
  1.5027 +
  1.5028  QString MapEditor::getVymLink()
  1.5029  {
  1.5030 -	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  1.5031 -			typeid(*selection) == typeid(MapCenterObj)) )
  1.5032 -	{		
  1.5033 -		return ((BranchObj*)(selection))->getVymLink();
  1.5034 -	}
  1.5035 -	return "";
  1.5036 +	BranchObj *bo=xelection.getBranch();
  1.5037 +	if (bo)
  1.5038 +		return bo->getVymLink();
  1.5039 +	else	
  1.5040 +		return "";
  1.5041  	
  1.5042  }
  1.5043  
  1.5044 +QStringList MapEditor::getVymLinks()
  1.5045 +{
  1.5046 +	QStringList links;
  1.5047 +	BranchObj *bo=xelection.getBranch();
  1.5048 +	if (bo)
  1.5049 +	{		
  1.5050 +		bo=bo->first();	
  1.5051 +		while (bo) 
  1.5052 +		{
  1.5053 +			if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
  1.5054 +			bo=bo->next();
  1.5055 +		}	
  1.5056 +	}	
  1.5057 +	return links;
  1.5058 +}
  1.5059 +
  1.5060 +
  1.5061 +void MapEditor::deleteKeepChilds()
  1.5062 +{
  1.5063 +	BranchObj *bo=xelection.getBranch();
  1.5064 +	BranchObj *par;
  1.5065 +	if (bo)
  1.5066 +	{
  1.5067 +		par=(BranchObj*)(bo->getParObj());
  1.5068 +		QPointF p=bo->getRelPos();
  1.5069 +		saveStateChangingPart(
  1.5070 +			bo->getParObj(),
  1.5071 +			bo,
  1.5072 +			"deleteKeepChilds ()",
  1.5073 +			QString("Remove %1 and keep its childs").arg(getName(bo))
  1.5074 +		);
  1.5075 +
  1.5076 +		QString sel=model->getSelectString(bo);
  1.5077 +		unselect();
  1.5078 +		par->removeBranchHere(bo);
  1.5079 +		model->reposition();
  1.5080 +		select (sel);
  1.5081 +		xelection.getBranch()->move2RelPos (p);
  1.5082 +		model->reposition();
  1.5083 +	}	
  1.5084 +}
  1.5085 +
  1.5086 +void MapEditor::deleteChilds()
  1.5087 +{
  1.5088 +	BranchObj *bo=xelection.getBranch();
  1.5089 +	if (bo)
  1.5090 +	{		
  1.5091 +		saveStateChangingPart(
  1.5092 +			bo, 
  1.5093 +			bo,
  1.5094 +			"deleteChilds ()",
  1.5095 +			QString( "Remove childs of branch %1").arg(getName(bo))
  1.5096 +		);
  1.5097 +		bo->removeChilds();
  1.5098 +		model->reposition();
  1.5099 +	}	
  1.5100 +}
  1.5101 +
  1.5102  void MapEditor::editMapInfo()
  1.5103  {
  1.5104  	ExtraInfoDialog dia;
  1.5105  	dia.setMapName (getFileName() );
  1.5106 -	dia.setAuthor (mapCenter->getAuthor() );
  1.5107 -	dia.setComment(mapCenter->getComment() );
  1.5108 +	dia.setAuthor (model->getAuthor() );
  1.5109 +	dia.setComment(model->getComment() );
  1.5110  
  1.5111  	// Calc some stats
  1.5112  	QString stats;
  1.5113 -    int i=0;
  1.5114 -    QCanvasItemList l=canvas()->allItems();
  1.5115 -    for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) 
  1.5116 -        i++;
  1.5117 -    stats+=QString ("%1 items on canvas\n").arg (i,6);
  1.5118 +    stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
  1.5119  
  1.5120  	uint b=0;
  1.5121  	uint f=0;
  1.5122  	uint n=0;
  1.5123 +	uint xl=0;
  1.5124  	BranchObj *bo;
  1.5125 -	bo=mapCenter->first();
  1.5126 +	bo=model->first();
  1.5127  	while (bo) 
  1.5128  	{
  1.5129  		if (!bo->getNote().isEmpty() ) n++;
  1.5130  		f+= bo->countFloatImages();
  1.5131  		b++;
  1.5132 -		bo=bo->next();
  1.5133 +		xl+=bo->countXLinks();
  1.5134 +		bo=model->next(bo);
  1.5135  	}
  1.5136      stats+=QString ("%1 branches\n").arg (b-1,6);
  1.5137 +    stats+=QString ("%1 xLinks \n").arg (xl,6);
  1.5138      stats+=QString ("%1 notes\n").arg (n,6);
  1.5139      stats+=QString ("%1 images\n").arg (f,6);
  1.5140  	dia.setStats (stats);
  1.5141 @@ -2192,350 +3753,389 @@
  1.5142  	// Finally show dialog
  1.5143  	if (dia.exec() == QDialog::Accepted)
  1.5144  	{
  1.5145 -		mapCenter->setAuthor (dia.getAuthor() );
  1.5146 -		mapCenter->setComment (dia.getComment() );
  1.5147 -		setChanged();
  1.5148 +		setMapAuthor (dia.getAuthor() );
  1.5149 +		setMapComment (dia.getComment() );
  1.5150  	}
  1.5151  }
  1.5152  
  1.5153 +void MapEditor::ensureSelectionVisible()
  1.5154 +{
  1.5155 +	LinkableMapObj *lmo=xelection.single();
  1.5156 +	if (lmo) ensureVisible (lmo->getBBox() );
  1.5157 +	
  1.5158 +}
  1.5159 +
  1.5160 +void MapEditor::updateSelection()
  1.5161 +{
  1.5162 +	// Tell selection to update geometries
  1.5163 +	xelection.update();
  1.5164 +}
  1.5165 +
  1.5166  void MapEditor::updateActions()
  1.5167  {
  1.5168 -	if (getLinkColorHint()==HeadingColor) 
  1.5169 -		actionFormatLinkColorHint->setOn(true);
  1.5170 -	else	
  1.5171 -		actionFormatLinkColorHint->setOn(false);
  1.5172 -
  1.5173 -	switch (linkstyle)
  1.5174 -	{
  1.5175 -		case StyleLine: 
  1.5176 -			actionFormatLinkStyleLine->setOn(true);
  1.5177 -			break;
  1.5178 -		case StyleParabel:
  1.5179 -			actionFormatLinkStyleParabel->setOn(true);
  1.5180 -			break;
  1.5181 -		case StylePolyLine:	
  1.5182 -			actionFormatLinkStylePolyLine->setOn(true);
  1.5183 -			break;
  1.5184 -		case StylePolyParabel:	
  1.5185 -			actionFormatLinkStylePolyParabel->setOn(true);
  1.5186 -			break;
  1.5187 -		default:
  1.5188 -			break;
  1.5189 -	}	
  1.5190 -
  1.5191 -	QPixmap pix( 16, 16 );
  1.5192 -    pix.fill( mapCanvas->backgroundColor() );
  1.5193 -    actionFormatBackColor->setIconSet( pix );
  1.5194 -    pix.fill( deflinkcolor );
  1.5195 -    actionFormatLinkColor->setIconSet( pix );
  1.5196 -
  1.5197 -	actionEditUndo->setEnabled( mapChanged );
  1.5198 -	actionFileSave->setEnabled( mapUnsaved );
  1.5199 -
  1.5200 -	if (selection)
  1.5201 -	{
  1.5202 -		if ( (typeid(*selection) == typeid(BranchObj)) || 
  1.5203 -			(typeid(*selection) == typeid(MapCenterObj))  )
  1.5204 -		{
  1.5205 -			standardFlagsDefault->setEnabled (true);
  1.5206 -
  1.5207 -			if ( ((BranchObj*)(selection))->getURL().isEmpty() )
  1.5208 -				actionEditOpenURL->setEnabled (false);
  1.5209 -			else	
  1.5210 -				actionEditOpenURL->setEnabled (true);
  1.5211 -			actionEditURL->setEnabled (true);	
  1.5212 -			actionEditHeading2URL->setEnabled (true);	
  1.5213 -			actionEditBugzilla2URL->setEnabled (true);	
  1.5214 -
  1.5215 -			if ( ((BranchObj*)(selection))->getVymLink().isEmpty() )
  1.5216 -			{
  1.5217 -				actionEditOpenVymLink->setEnabled (false);
  1.5218 -				actionEditDeleteVymLink->setEnabled (false);
  1.5219 -			} else	
  1.5220 -			{
  1.5221 -				actionEditOpenVymLink->setEnabled (true);
  1.5222 -				actionEditDeleteVymLink->setEnabled (true);
  1.5223 -			}	
  1.5224 -			actionEditVymLink->setEnabled (true);	
  1.5225 -
  1.5226 -			actionEditCopy->setEnabled (true);	
  1.5227 -			actionEditCut->setEnabled (true);	
  1.5228 -			actionEditPaste->setEnabled (true);	
  1.5229 -			actionEditMoveUp->setEnabled (true);	
  1.5230 -			actionEditMoveDown->setEnabled (true);	
  1.5231 -			actionEditToggleScroll->setEnabled (true);	
  1.5232 -			actionEditHeading->setEnabled (true);
  1.5233 -			actionEditDelete->setEnabled (true);
  1.5234 -			actionEditAddBranch->setEnabled (true);
  1.5235 -			actionEditAddBranchAbove->setEnabled (true);
  1.5236 -			actionEditAddBranchBelow->setEnabled (true);
  1.5237 -			actionEditImportAdd->setEnabled (true);
  1.5238 -			actionEditImportReplace->setEnabled (true);
  1.5239 -			actionEditSaveBranch->setEnabled (true);
  1.5240 -			actionEditSelectFirst->setEnabled (true);
  1.5241 -			actionEditSelectLast->setEnabled (true);
  1.5242 -			actionEditToggleFloatExport->setEnabled (false);
  1.5243 -			actionFormatPickColor->setEnabled (true);
  1.5244 -			actionFormatColorBranch->setEnabled (true);
  1.5245 -			actionFormatColorSubtree->setEnabled (true);
  1.5246 -			switch (selection->getFrameType())
  1.5247 -			{
  1.5248 -				case NoFrame: 
  1.5249 -					actionFormatFrameNone->setOn(true);
  1.5250 -					break;
  1.5251 -				case Rectangle:
  1.5252 -					actionFormatFrameRectangle->setOn(true);
  1.5253 -					break;
  1.5254 -				default:
  1.5255 -					break;
  1.5256 -			}	
  1.5257 -		}
  1.5258 -		if ( (typeid(*selection) == typeid(FloatImageObj)) )
  1.5259 -		{
  1.5260 -			standardFlagsDefault->setEnabled (false);
  1.5261 -
  1.5262 -			actionEditOpenURL->setEnabled (false);
  1.5263 -			actionEditURL->setEnabled (false);	
  1.5264 -			actionEditHeading2URL->setEnabled (false);	
  1.5265 -			actionEditBugzilla2URL->setEnabled (false);	
  1.5266 -			actionEditOpenVymLink->setEnabled (false);
  1.5267 -			actionEditVymLink->setEnabled (false);	
  1.5268 -			actionEditDeleteVymLink->setEnabled (false);	
  1.5269 -
  1.5270 -			actionEditCopy->setEnabled (true);
  1.5271 -			actionEditCut->setEnabled (true);	
  1.5272 -			actionEditPaste->setEnabled (false);	//FIXME
  1.5273 -			actionEditMoveUp->setEnabled (false);	
  1.5274 -			actionEditMoveDown->setEnabled (false);	
  1.5275 -			actionEditToggleScroll->setEnabled (false);	
  1.5276 -			actionEditHeading->setEnabled (false);
  1.5277 -			actionEditDelete->setEnabled (true);
  1.5278 -			actionEditAddBranch->setEnabled (false);
  1.5279 -			actionEditAddBranchAbove->setEnabled (false);
  1.5280 -			actionEditAddBranchBelow->setEnabled (false);
  1.5281 -			actionEditImportAdd->setEnabled (false);
  1.5282 -			actionEditSaveBranch->setEnabled (false);
  1.5283 -			actionEditImportReplace->setEnabled (false);
  1.5284 -			actionEditSelectFirst->setEnabled (false);
  1.5285 -			actionEditSelectLast->setEnabled (false);
  1.5286 -			actionEditToggleFloatExport->setOn
  1.5287 -				( ((FloatImageObj*)(selection))->getFloatExport() );
  1.5288 -			actionFormatPickColor->setEnabled (false);
  1.5289 -			actionFormatColorBranch->setEnabled (false);
  1.5290 -			actionFormatColorSubtree->setEnabled (false);
  1.5291 -		}
  1.5292 -
  1.5293 -	} else
  1.5294 -	{
  1.5295 -		standardFlagsDefault->setEnabled (false);
  1.5296 -
  1.5297 -		actionEditCopy->setEnabled (false);	
  1.5298 -		actionEditCut->setEnabled (false);	
  1.5299 -		actionEditPaste->setEnabled (false);	
  1.5300 -		actionEditMoveUp->setEnabled (false);	
  1.5301 -		actionEditMoveDown->setEnabled (false);	
  1.5302 -		actionEditToggleScroll->setEnabled (false);	
  1.5303 -		actionEditOpenURL->setEnabled (false);
  1.5304 -		actionEditURL->setEnabled (false);	
  1.5305 -		actionEditOpenVymLink->setEnabled (false);
  1.5306 -		actionEditVymLink->setEnabled (false);	
  1.5307 -		actionEditDeleteVymLink->setEnabled (false);	
  1.5308 -		actionEditHeading2URL->setEnabled (false);	
  1.5309 -		actionEditBugzilla2URL->setEnabled (false);	
  1.5310 -		actionEditHeading->setEnabled (false);
  1.5311 -		actionEditDelete->setEnabled (false);
  1.5312 -		actionEditAddBranch->setEnabled (false);
  1.5313 -		actionEditAddBranchAbove->setEnabled (false);
  1.5314 -		actionEditAddBranchBelow->setEnabled (false);
  1.5315 -		actionEditSaveBranch->setEnabled (false);
  1.5316 -		actionEditImportReplace->setEnabled (false);
  1.5317 -		actionEditSelectFirst->setEnabled (false);
  1.5318 -		actionEditSelectLast->setEnabled (false);
  1.5319 -		actionEditToggleFloatExport->setEnabled (false);
  1.5320 -		actionFormatPickColor->setEnabled (false);
  1.5321 -		actionFormatColorBranch->setEnabled (false);
  1.5322 -		actionFormatColorSubtree->setEnabled (false);
  1.5323 +	// Tell mainwindow to update states of actions
  1.5324 +	mainWindow->updateActions();
  1.5325 +	// TODO maybe don't update if blockReposition is set
  1.5326 +}
  1.5327 +
  1.5328 +void MapEditor::updateNoteFlag()
  1.5329 +{
  1.5330 +	setChanged();
  1.5331 +	BranchObj *bo=xelection.getBranch();
  1.5332 +	if (bo) 
  1.5333 +	{
  1.5334 +		bo->updateNoteFlag();
  1.5335 +		mainWindow->updateActions();
  1.5336  	}	
  1.5337  }
  1.5338  
  1.5339 -void MapEditor::setLinkStyle (LinkStyle ls)
  1.5340 -{
  1.5341 -	linkstyle=ls;
  1.5342 +void MapEditor::setMapAuthor (const QString &s)
  1.5343 +{
  1.5344 +	saveState (
  1.5345 +		QString ("setMapAuthor (\"%1\")").arg(model->getAuthor()),
  1.5346 +		QString ("setMapAuthor (\"%1\")").arg(s),
  1.5347 +		QString ("Set author of map to \"%1\"").arg(s)
  1.5348 +	);
  1.5349 +	model->setAuthor (s);
  1.5350 +}
  1.5351 +
  1.5352 +void MapEditor::setMapComment (const QString &s)
  1.5353 +{
  1.5354 +	saveState (
  1.5355 +		QString ("setMapComment (\"%1\")").arg(model->getComment()),
  1.5356 +		QString ("setMapComment (\"%1\")").arg(s),
  1.5357 +		QString ("Set comment of map")
  1.5358 +	);
  1.5359 +	model->setComment (s);
  1.5360 +}
  1.5361 +
  1.5362 +void MapEditor::setMapLinkStyle (const QString & s)
  1.5363 +{
  1.5364 +	QString snow;
  1.5365 +	if (linkstyle==LinkableMapObj::Line)
  1.5366 +		snow="StyleLine";
  1.5367 +	else if (linkstyle==LinkableMapObj::Parabel)
  1.5368 +		snow="StyleParabel";
  1.5369 +	else if (linkstyle==LinkableMapObj::PolyLine)
  1.5370 +		snow="StylePolyLine";
  1.5371 +	else if (linkstyle==LinkableMapObj::PolyParabel)
  1.5372 +		snow="StyleParabel";
  1.5373 +
  1.5374 +	saveState (
  1.5375 +		QString("setMapLinkStyle (\"%1\")").arg(s),
  1.5376 +		QString("setMapLinkStyle (\"%1\")").arg(snow),
  1.5377 +		QString("Set map link style (\"%1\")").arg(s)
  1.5378 +	);	
  1.5379 +
  1.5380 +	if (s=="StyleLine")
  1.5381 +		linkstyle=LinkableMapObj::Line;
  1.5382 +	else if (s=="StyleParabel")
  1.5383 +		linkstyle=LinkableMapObj::Parabel;
  1.5384 +	else if (s=="StylePolyLine")
  1.5385 +		linkstyle=LinkableMapObj::PolyLine;
  1.5386 +	else	
  1.5387 +		linkstyle=LinkableMapObj::PolyParabel;
  1.5388  
  1.5389  	BranchObj *bo;
  1.5390 -	bo=mapCenter->first();
  1.5391 -	bo=bo->next();
  1.5392 +	bo=model->first();
  1.5393 +	bo=model->next(bo);
  1.5394  	while (bo) 
  1.5395  	{
  1.5396  		bo->setLinkStyle(bo->getDefLinkStyle());
  1.5397 -		bo=bo->next();
  1.5398 +		bo=model->next(bo);
  1.5399  	}
  1.5400 -	//setChanged();
  1.5401 -	//saveState();
  1.5402 +	model->reposition();
  1.5403  }
  1.5404  
  1.5405 -LinkStyle MapEditor::getLinkStyle ()
  1.5406 +LinkableMapObj::Style MapEditor::getMapLinkStyle ()
  1.5407  {
  1.5408  	return linkstyle;
  1.5409  }	
  1.5410  
  1.5411 -void MapEditor::setLinkColor(QColor c)
  1.5412 -{
  1.5413 -	deflinkcolor=c;
  1.5414 +void MapEditor::setMapDefLinkColor(QColor c)
  1.5415 +{
  1.5416 +	defLinkColor=c;
  1.5417 +	BranchObj *bo;
  1.5418 +	bo=model->first();
  1.5419 +	while (bo) 
  1.5420 +	{
  1.5421 +		bo->setLinkColor();
  1.5422 +		bo=model->next(bo);
  1.5423 +	}
  1.5424  	updateActions();
  1.5425  }
  1.5426  
  1.5427 -void MapEditor::setLinkColorHint()
  1.5428 -{
  1.5429 -	// called from setLinkColorHint(lch) or at end of parse
  1.5430 +void MapEditor::setMapLinkColorHintInt()
  1.5431 +{
  1.5432 +	// called from setMapLinkColorHint(lch) or at end of parse
  1.5433  	BranchObj *bo;
  1.5434 -	bo=mapCenter->first();
  1.5435 +	bo=model->first();
  1.5436  	while (bo) 
  1.5437  	{
  1.5438  		bo->setLinkColor();
  1.5439 -		bo=bo->next();
  1.5440 +		bo=model->next(bo);
  1.5441  	}
  1.5442  }
  1.5443  
  1.5444 -void MapEditor::setLinkColorHint(LinkColorHint lch)
  1.5445 +void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
  1.5446  {
  1.5447  	linkcolorhint=lch;
  1.5448 -	setLinkColorHint();
  1.5449 +	setMapLinkColorHintInt();
  1.5450  }
  1.5451  
  1.5452 -void MapEditor::toggleLinkColorHint()
  1.5453 -{
  1.5454 -	if (linkcolorhint==HeadingColor)
  1.5455 -		linkcolorhint=DefaultColor;
  1.5456 +void MapEditor::toggleMapLinkColorHint()
  1.5457 +{
  1.5458 +	if (linkcolorhint==LinkableMapObj::HeadingColor)
  1.5459 +		linkcolorhint=LinkableMapObj::DefaultColor;
  1.5460  	else	
  1.5461 -		linkcolorhint=HeadingColor;
  1.5462 +		linkcolorhint=LinkableMapObj::HeadingColor;
  1.5463  	BranchObj *bo;
  1.5464 -	bo=mapCenter->first();
  1.5465 +	bo=model->first();
  1.5466  	while (bo) 
  1.5467  	{
  1.5468  		bo->setLinkColor();
  1.5469 -		bo=bo->next();
  1.5470 +		bo=model->next(bo);
  1.5471  	}
  1.5472  }
  1.5473  
  1.5474 -LinkColorHint MapEditor::getLinkColorHint()
  1.5475 +LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
  1.5476  {
  1.5477  	return linkcolorhint;
  1.5478  }
  1.5479  
  1.5480 -QColor MapEditor::getDefLinkColor()
  1.5481 -{
  1.5482 -	return deflinkcolor;
  1.5483 +QColor MapEditor::getMapDefLinkColor()
  1.5484 +{
  1.5485 +	return defLinkColor;
  1.5486  }
  1.5487  
  1.5488 -void MapEditor::selectLinkColor()
  1.5489 -{
  1.5490 -	// Finish open lineEdits
  1.5491 -	if (lineedit) finishedLineEditNoSave();
  1.5492 -
  1.5493 -	QColor col = QColorDialog::getColor( deflinkcolor, this );
  1.5494 +void MapEditor::setMapDefXLinkColor(QColor col)
  1.5495 +{
  1.5496 +	defXLinkColor=col;
  1.5497 +}
  1.5498 +
  1.5499 +QColor MapEditor::getMapDefXLinkColor()
  1.5500 +{
  1.5501 +	return defXLinkColor;
  1.5502 +}
  1.5503 +
  1.5504 +void MapEditor::setMapDefXLinkWidth (int w)
  1.5505 +{
  1.5506 +	defXLinkWidth=w;
  1.5507 +}
  1.5508 +
  1.5509 +int MapEditor::getMapDefXLinkWidth()
  1.5510 +{
  1.5511 +	return defXLinkWidth;
  1.5512 +}
  1.5513 +
  1.5514 +void MapEditor::selectMapLinkColor()
  1.5515 +{
  1.5516 +	QColor col = QColorDialog::getColor( defLinkColor, this );
  1.5517  	if ( !col.isValid() ) return;
  1.5518 -	setLinkColor( col );
  1.5519 -	setChanged();
  1.5520 +	saveState (
  1.5521 +		QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
  1.5522 +		QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
  1.5523 +		QString("Set map link color to %1").arg(col.name())
  1.5524 +	);
  1.5525 +	setMapDefLinkColor( col );
  1.5526  }
  1.5527  
  1.5528 +void MapEditor::selectMapSelectionColor()
  1.5529 +{
  1.5530 +	QColor col = QColorDialog::getColor( defLinkColor, this );
  1.5531 +	setSelectionColor (col);
  1.5532 +}
  1.5533 +
  1.5534 +void MapEditor::setSelectionColorInt (QColor col)
  1.5535 +{
  1.5536 +	if ( !col.isValid() ) return;
  1.5537 +	xelection.setColor (col);
  1.5538 +}
  1.5539 +
  1.5540 +void MapEditor::setSelectionColor(QColor col)
  1.5541 +{
  1.5542 +	if ( !col.isValid() ) return;
  1.5543 +	saveState (
  1.5544 +		QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
  1.5545 +		QString("setSelectionColor (%1)").arg(col.name()),
  1.5546 +		QString("Set color of selection box to %1").arg(col.name())
  1.5547 +	);
  1.5548 +	setSelectionColorInt (col);
  1.5549 +}
  1.5550 +
  1.5551 +QColor MapEditor::getSelectionColor()
  1.5552 +{
  1.5553 +	return xelection.getColor();
  1.5554 +}
  1.5555 +
  1.5556 +bool MapEditor::scrollBranch(BranchObj *bo)
  1.5557 +{
  1.5558 +	if (bo)
  1.5559 +	{
  1.5560 +		if (bo->isScrolled()) return false;
  1.5561 +		if (bo->countBranches()==0) return false;
  1.5562 +		if (bo->getDepth()==0) return false;
  1.5563 +		QString u,r;
  1.5564 +		r="scroll";
  1.5565 +		u="unscroll";
  1.5566 +		saveState(
  1.5567 +			bo,
  1.5568 +			QString ("%1 ()").arg(u),
  1.5569 +			bo,
  1.5570 +			QString ("%1 ()").arg(r),
  1.5571 +			QString ("%1 %2").arg(r).arg(getName(bo))
  1.5572 +		);
  1.5573 +		bo->toggleScroll();
  1.5574 +		xelection.update();
  1.5575 +		scene()->update();
  1.5576 +		return true;
  1.5577 +	}	
  1.5578 +	return false;
  1.5579 +}
  1.5580 +
  1.5581 +bool MapEditor::unscrollBranch(BranchObj *bo)
  1.5582 +{
  1.5583 +	if (bo)
  1.5584 +	{
  1.5585 +		if (!bo->isScrolled()) return false;
  1.5586 +		if (bo->countBranches()==0) return false;
  1.5587 +		if (bo->getDepth()==0) return false;
  1.5588 +		QString u,r;
  1.5589 +		u="scroll";
  1.5590 +		r="unscroll";
  1.5591 +		saveState(
  1.5592 +			bo,
  1.5593 +			QString ("%1 ()").arg(u),
  1.5594 +			bo,
  1.5595 +			QString ("%1 ()").arg(r),
  1.5596 +			QString ("%1 %2").arg(r).arg(getName(bo))
  1.5597 +		);
  1.5598 +		bo->toggleScroll();
  1.5599 +		xelection.update();
  1.5600 +		scene()->update();
  1.5601 +		return true;
  1.5602 +	}	
  1.5603 +	return false;
  1.5604 +}
  1.5605 +
  1.5606  void MapEditor::toggleScroll()
  1.5607  {
  1.5608 -	if (selection && (typeid(*selection) == typeid(BranchObj)) )
  1.5609 -	{
  1.5610 -		BranchObj *bo=((BranchObj*)(selection));
  1.5611 -		if (bo->countBranches()==0) return;
  1.5612 -		if (bo->getDepth()==0) return;
  1.5613 -		setChanged();
  1.5614 -		saveState(PartOfMap,selection);
  1.5615 -		bo->toggleScroll();
  1.5616 -		adjustCanvasSize();
  1.5617 -		canvas()->update();
  1.5618 +	BranchObj *bo=xelection.getBranch();
  1.5619 +	if (xelection.type()==Selection::Branch )
  1.5620 +	{
  1.5621 +		if (bo->isScrolled())
  1.5622 +			unscrollBranch (bo);
  1.5623 +		else
  1.5624 +			scrollBranch (bo);
  1.5625  	}
  1.5626  }
  1.5627  
  1.5628 -void MapEditor::unScrollAll()
  1.5629 -{
  1.5630 -	BranchObj *bo;
  1.5631 -	bo=mapCenter->first();
  1.5632 -	while (bo) 
  1.5633 -	{
  1.5634 -		if (bo->isScrolled()) bo->toggleScroll();
  1.5635 -		bo=bo->next();
  1.5636 +void MapEditor::unscrollChilds() 
  1.5637 +{
  1.5638 +	BranchObj *bo=xelection.getBranch();
  1.5639 +	if (bo)
  1.5640 +	{
  1.5641 +		bo->first();
  1.5642 +		while (bo) 
  1.5643 +		{
  1.5644 +			if (bo->isScrolled()) unscrollBranch (bo);
  1.5645 +			bo=bo->next();
  1.5646 +		}
  1.5647 +	}	
  1.5648 +}
  1.5649 +
  1.5650 +FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
  1.5651 +{
  1.5652 +	BranchObj *bo=xelection.getBranch();
  1.5653 +	if (bo)
  1.5654 +	{
  1.5655 +		FloatImageObj *fio;
  1.5656 +		bo->addFloatImage();
  1.5657 +		fio=bo->getLastFloatImage();
  1.5658 +		fio->load(fn);
  1.5659 +		model->reposition();
  1.5660 +		scene()->update();
  1.5661 +		return fio;
  1.5662  	}
  1.5663 -}
  1.5664 +	return NULL;
  1.5665 +}	
  1.5666  
  1.5667  void MapEditor::loadFloatImage ()
  1.5668  {
  1.5669 -	if (selection && 
  1.5670 -		(typeid(*selection) == typeid(BranchObj)) || 
  1.5671 -		(typeid(*selection) == typeid(MapCenterObj))  )
  1.5672 -	{
  1.5673 -		BranchObj *bo=((BranchObj*)(selection));
  1.5674 -
  1.5675 -		QFileDialog *fd=new QFileDialog( this,tr("vym - load image"));
  1.5676 +	BranchObj *bo=xelection.getBranch();
  1.5677 +	if (bo)
  1.5678 +	{
  1.5679 +
  1.5680 +		Q3FileDialog *fd=new Q3FileDialog( this);
  1.5681 +		fd->setMode (Q3FileDialog::ExistingFiles);
  1.5682  		fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
  1.5683  		ImagePreview *p =new ImagePreview (fd);
  1.5684  		fd->setContentsPreviewEnabled( TRUE );
  1.5685  		fd->setContentsPreview( p, p );
  1.5686 -		fd->setPreviewMode( QFileDialog::Contents );
  1.5687 -		fd->setCaption(tr("vym - Load image"));
  1.5688 +		fd->setPreviewMode( Q3FileDialog::Contents );
  1.5689 +		fd->setCaption(vymName+" - " +tr("Load image"));
  1.5690  		fd->setDir (lastImageDir);
  1.5691  		fd->show();
  1.5692  
  1.5693 -		QString fn;
  1.5694  		if ( fd->exec() == QDialog::Accepted )
  1.5695  		{
  1.5696 -			setChanged();
  1.5697 -			saveState(PartOfMap,selection);
  1.5698 -			QString fn=fd->selectedFile();
  1.5699 -			lastImageDir=fn.left(fn.findRev ("/"));
  1.5700 -			bo->addFloatImage();
  1.5701 -			// FIXME check if load was successful
  1.5702 -			bo->getLastFloatImage()->load(fn);
  1.5703 -			bo->getLastFloatImage()->setOriginalFilename(fn);
  1.5704 -			mapCenter->reposition();
  1.5705 -			adjustCanvasSize();
  1.5706 -			canvas()->update();
  1.5707 +			// TODO loadFIO in QT4 use:	lastImageDir=fd->directory();
  1.5708 +			lastImageDir=QDir (fd->dirPath());
  1.5709 +			QString s;
  1.5710 +			FloatImageObj *fio;
  1.5711 +			for (int j=0; j<fd->selectedFiles().count(); j++)
  1.5712 +			{
  1.5713 +				s=fd->selectedFiles().at(j);
  1.5714 +				fio=loadFloatImageInt (s);
  1.5715 +				if (fio)
  1.5716 +					saveState(
  1.5717 +						(LinkableMapObj*)fio,
  1.5718 +						"delete ()",
  1.5719 +						bo, 
  1.5720 +						QString ("loadImage (%1)").arg(s ),
  1.5721 +						QString("Add image %1 to %2").arg(s).arg(getName(bo))
  1.5722 +					);
  1.5723 +				else
  1.5724 +					// TODO loadFIO error handling
  1.5725 +					qWarning ("Failed to load "+s);
  1.5726 +			}
  1.5727  		}
  1.5728 +		delete (p);
  1.5729 +		delete (fd);
  1.5730  	}
  1.5731  }
  1.5732  
  1.5733 -void MapEditor::saveFloatImage (int item)
  1.5734 -{
  1.5735 -	if (selection && 
  1.5736 -		(typeid(*selection) == typeid(FloatImageObj)) )
  1.5737 -	{
  1.5738 -		FloatImageObj *fio=((FloatImageObj*)(selection));
  1.5739 -		const char* fmt = saveImageFormatMenu->text(item);
  1.5740 -
  1.5741 -		QFileDialog *fd=new QFileDialog( this, tr("vym - save image as") + fmt);
  1.5742 -		fd->addFilter ("PNG (*.png)");
  1.5743 -		fd->addFilter ("BMP (*.bmp)");
  1.5744 -		fd->addFilter ("XBM (*.xbm)");
  1.5745 -		fd->addFilter ("JPG (*.jpg)");
  1.5746 -		fd->addFilter ("XPM (*.xpm)");
  1.5747 -		fd->addFilter ("GIF (*.gif)");
  1.5748 -		fd->addFilter ("PNM (*.pnm)");
  1.5749 -		fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
  1.5750 -		fd->setCaption(tr("vym - Save image as ") + fmt);
  1.5751 -		fd->setMode( QFileDialog::AnyFile );
  1.5752 -		fd->setSelection (fio->getOriginalFilename());
  1.5753 +void MapEditor::saveFloatImageInt  (FloatImageObj *fio, const QString &type, const QString &fn)
  1.5754 +{
  1.5755 +	fio->save (fn,type);
  1.5756 +}
  1.5757 +
  1.5758 +void MapEditor::saveFloatImage ()
  1.5759 +{
  1.5760 +	FloatImageObj *fio=xelection.getFloatImage();
  1.5761 +	if (fio)
  1.5762 +	{
  1.5763 +		QFileDialog *fd=new QFileDialog( this);
  1.5764 +		fd->setFilters (imageIO.getFilters());
  1.5765 +		fd->setCaption(vymName+" - " +tr("Save image"));
  1.5766 +		fd->setFileMode( QFileDialog::AnyFile );
  1.5767 +		fd->setDirectory (lastImageDir);
  1.5768 +//		fd->setSelection (fio->getOriginalFilename());
  1.5769  		fd->show();
  1.5770  
  1.5771  		QString fn;
  1.5772 -		if ( fd->exec() == QDialog::Accepted )
  1.5773 +		if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
  1.5774  		{
  1.5775 -			if (QFile (fd->selectedFile()).exists() )
  1.5776 +			fn=fd->selectedFiles().at(0);
  1.5777 +			if (QFile (fn).exists() )
  1.5778  			{
  1.5779 -				QMessageBox mb( "VYM",
  1.5780 -					tr("The file ") + fd->selectedFile() + 
  1.5781 -					tr(" exists already. "
  1.5782 -					"Do you want to overwrite it?"),
  1.5783 +				QMessageBox mb( vymName,
  1.5784 +					tr("The file %1 exists already.\n"
  1.5785 +					"Do you want to overwrite it?").arg(fn),
  1.5786  				QMessageBox::Warning,
  1.5787  				QMessageBox::Yes | QMessageBox::Default,
  1.5788  				QMessageBox::Cancel | QMessageBox::Escape,
  1.5789 -				QMessageBox::QMessageBox::NoButton );
  1.5790 +				QMessageBox::NoButton );
  1.5791  
  1.5792  				mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
  1.5793  				mb.setButtonText( QMessageBox::No, tr("Cancel"));
  1.5794 @@ -2543,170 +4143,351 @@
  1.5795  				{
  1.5796  					case QMessageBox::Yes:
  1.5797  						// save 
  1.5798 -						break;;
  1.5799 +						break;
  1.5800  					case QMessageBox::Cancel:
  1.5801  						// do nothing
  1.5802 +						delete (fd);
  1.5803  						return;
  1.5804  						break;
  1.5805  				}
  1.5806  			}
  1.5807 -			fio->save (fd->selectedFile(),fmt);
  1.5808 +			saveFloatImageInt (fio,fd->selectedFilter(),fn );
  1.5809 +		}
  1.5810 +		delete (fd);
  1.5811 +	}
  1.5812 +}
  1.5813 +
  1.5814 +void MapEditor::setFrameType(const FrameObj::FrameType &t)
  1.5815 +{
  1.5816 +	BranchObj *bo=xelection.getBranch();
  1.5817 +	if (bo)
  1.5818 +	{
  1.5819 +		QString s=bo->getFrameTypeName();
  1.5820 +		bo->setFrameType (t);
  1.5821 +		saveState (bo, QString("setFrameType (\"%1\")").arg(s),
  1.5822 +			bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
  1.5823 +		model->reposition();
  1.5824 +		bo->updateLink();
  1.5825 +	}
  1.5826 +}
  1.5827 +
  1.5828 +void MapEditor::setFrameType(const QString &s)	
  1.5829 +{
  1.5830 +	BranchObj *bo=xelection.getBranch();
  1.5831 +	if (bo)
  1.5832 +	{
  1.5833 +		saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
  1.5834 +			bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
  1.5835 +		bo->setFrameType (s);
  1.5836 +		model->reposition();
  1.5837 +		bo->updateLink();
  1.5838 +	}
  1.5839 +}
  1.5840 +
  1.5841 +void MapEditor::setFramePenColor(const QColor &c)	
  1.5842 +{
  1.5843 +	BranchObj *bo=xelection.getBranch();
  1.5844 +	if (bo)
  1.5845 +	{
  1.5846 +		saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
  1.5847 +			bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
  1.5848 +		bo->setFramePenColor (c);
  1.5849 +	}	
  1.5850 +}
  1.5851 +
  1.5852 +void MapEditor::setFrameBrushColor(const QColor &c)	
  1.5853 +{
  1.5854 +	BranchObj *bo=xelection.getBranch();
  1.5855 +	if (bo)
  1.5856 +	{
  1.5857 +		saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
  1.5858 +			bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
  1.5859 +		bo->setFrameBrushColor (c);
  1.5860 +	}	
  1.5861 +}
  1.5862 +
  1.5863 +void MapEditor::setFramePadding (const int &i)
  1.5864 +{
  1.5865 +	BranchObj *bo=xelection.getBranch();
  1.5866 +	if (bo)
  1.5867 +	{
  1.5868 +		saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
  1.5869 +			bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
  1.5870 +		bo->setFramePadding (i);
  1.5871 +		model->reposition();
  1.5872 +		bo->updateLink();
  1.5873 +	}	
  1.5874 +}
  1.5875 +
  1.5876 +void MapEditor::setFrameBorderWidth(const int &i)
  1.5877 +{
  1.5878 +	BranchObj *bo=xelection.getBranch();
  1.5879 +	if (bo)
  1.5880 +	{
  1.5881 +		saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
  1.5882 +			bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
  1.5883 +		bo->setFrameBorderWidth (i);
  1.5884 +		model->reposition();
  1.5885 +		bo->updateLink();
  1.5886 +	}	
  1.5887 +}
  1.5888 +
  1.5889 +void MapEditor::setIncludeImagesVer(bool b)	
  1.5890 +{
  1.5891 +	BranchObj *bo=xelection.getBranch();
  1.5892 +	if (bo)
  1.5893 +	{
  1.5894 +		QString u= b ? "false" : "true";
  1.5895 +		QString r=!b ? "false" : "true";
  1.5896 +		
  1.5897 +		saveState(
  1.5898 +			bo,
  1.5899 +			QString("setIncludeImagesVertically (%1)").arg(u),
  1.5900 +			bo, 
  1.5901 +			QString("setIncludeImagesVertically (%1)").arg(r),
  1.5902 +			QString("Include images vertically in %1").arg(getName(bo))
  1.5903 +		);	
  1.5904 +		bo->setIncludeImagesVer(b);
  1.5905 +		model->reposition();
  1.5906 +	}	
  1.5907 +}
  1.5908 +
  1.5909 +void MapEditor::setIncludeImagesHor(bool b)	
  1.5910 +{
  1.5911 +	BranchObj *bo=xelection.getBranch();
  1.5912 +	if (bo)
  1.5913 +	{
  1.5914 +		QString u= b ? "false" : "true";
  1.5915 +		QString r=!b ? "false" : "true";
  1.5916 +		
  1.5917 +		saveState(
  1.5918 +			bo,
  1.5919 +			QString("setIncludeImagesHorizontally (%1)").arg(u),
  1.5920 +			bo, 
  1.5921 +			QString("setIncludeImagesHorizontally (%1)").arg(r),
  1.5922 +			QString("Include images horizontally in %1").arg(getName(bo))
  1.5923 +		);	
  1.5924 +		bo->setIncludeImagesHor(b);
  1.5925 +		model->reposition();
  1.5926 +	}	
  1.5927 +}
  1.5928 +
  1.5929 +void MapEditor::setHideLinkUnselected (bool b)
  1.5930 +{
  1.5931 +	LinkableMapObj *sel=xelection.single();
  1.5932 +	if (sel &&
  1.5933 +		(xelection.type() == Selection::Branch || 
  1.5934 +		xelection.type() == Selection::MapCenter  ||
  1.5935 +		xelection.type() == Selection::FloatImage ))
  1.5936 +	{
  1.5937 +		QString u= b ? "false" : "true";
  1.5938 +		QString r=!b ? "false" : "true";
  1.5939 +		
  1.5940 +		saveState(
  1.5941 +			sel,
  1.5942 +			QString("setHideLinkUnselected (%1)").arg(u),
  1.5943 +			sel, 
  1.5944 +			QString("setHideLinkUnselected (%1)").arg(r),
  1.5945 +			QString("Hide link of %1 if unselected").arg(getName(sel))
  1.5946 +		);	
  1.5947 +		sel->setHideLinkUnselected(b);
  1.5948 +	}
  1.5949 +}
  1.5950 +
  1.5951 +void MapEditor::importDirInt(BranchObj *dst, QDir d)
  1.5952 +{
  1.5953 +	BranchObj *bo=xelection.getBranch();
  1.5954 +	if (bo)
  1.5955 +	{
  1.5956 +		// Traverse directories
  1.5957 +		d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
  1.5958 +		QFileInfoList list = d.entryInfoList();
  1.5959 +		QFileInfo fi;
  1.5960 +
  1.5961 +		for (int i = 0; i < list.size(); ++i) 
  1.5962 +		{
  1.5963 +			fi=list.at(i);
  1.5964 +			if (fi.fileName() != "." && fi.fileName() != ".." )
  1.5965 +			{
  1.5966 +				dst->addBranch();
  1.5967 +				bo=dst->getLastBranch();
  1.5968 +				bo->setHeading (fi.fileName() );
  1.5969 +				bo->setColor (QColor("blue"));
  1.5970 +				bo->toggleScroll();
  1.5971 +				if ( !d.cd(fi.fileName()) ) 
  1.5972 +					QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
  1.5973 +				else 
  1.5974 +				{
  1.5975 +					// Recursively add subdirs
  1.5976 +					importDirInt (bo,d);
  1.5977 +					d.cdUp();
  1.5978 +				}
  1.5979 +			}	
  1.5980 +		}		
  1.5981 +		// Traverse files
  1.5982 +		d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
  1.5983 +		list = d.entryInfoList();
  1.5984 +
  1.5985 +		for (int i = 0; i < list.size(); ++i) 
  1.5986 +		{
  1.5987 +			fi=list.at(i);
  1.5988 +			dst->addBranch();
  1.5989 +			bo=dst->getLastBranch();
  1.5990 +			bo->setHeading (fi.fileName() );
  1.5991 +			bo->setColor (QColor("black"));
  1.5992 +			if (fi.fileName().right(4) == ".vym" )
  1.5993 +				bo->setVymLink (fi.filePath());
  1.5994 +		}	
  1.5995 +	}		
  1.5996 +}
  1.5997 +
  1.5998 +void MapEditor::importDirInt (const QString &s)
  1.5999 +{
  1.6000 +	BranchObj *bo=xelection.getBranch();
  1.6001 +	if (bo)
  1.6002 +	{
  1.6003 +		saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
  1.6004 +
  1.6005 +		QDir d(s);
  1.6006 +		importDirInt (bo,d);
  1.6007 +	}
  1.6008 +}	
  1.6009 +
  1.6010 +void MapEditor::importDir()
  1.6011 +{
  1.6012 +	BranchObj *bo=xelection.getBranch();
  1.6013 +	if (bo)
  1.6014 +	{
  1.6015 +		QStringList filters;
  1.6016 +		filters <<"VYM map (*.vym)";
  1.6017 +		QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
  1.6018 +		fd->setMode (QFileDialog::DirectoryOnly);
  1.6019 +		fd->setFilters (filters);
  1.6020 +		fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
  1.6021 +		fd->show();
  1.6022 +
  1.6023 +		QString fn;
  1.6024 +		if ( fd->exec() == QDialog::Accepted )
  1.6025 +		{
  1.6026 +			importDirInt (fd->selectedFile() );
  1.6027 +			model->reposition();
  1.6028 +			scene()->update();
  1.6029 +		}
  1.6030 +	}	
  1.6031 +}
  1.6032 +
  1.6033 +void MapEditor::followXLink(int i)
  1.6034 +{
  1.6035 +	BranchObj *bo=xelection.getBranch();
  1.6036 +	if (bo)
  1.6037 +	{
  1.6038 +		bo=bo->XLinkTargetAt(i);
  1.6039 +		if (bo) 
  1.6040 +		{
  1.6041 +			xelection.select(bo);
  1.6042 +			ensureSelectionVisible();
  1.6043  		}
  1.6044  	}
  1.6045  }
  1.6046  
  1.6047 -void MapEditor::toggleFloatExport()
  1.6048 -{
  1.6049 -	if (selection && 
  1.6050 -		(typeid(*selection) == typeid(FloatImageObj))|| 
  1.6051 -		(typeid(*selection) == typeid(FloatObj)) )
  1.6052 -	{
  1.6053 -		FloatImageObj *fio=((FloatImageObj*)(selection));
  1.6054 -		fio->setFloatExport (actionEditToggleFloatExport->isOn() );
  1.6055 +void MapEditor::editXLink(int i)	// FIXME missing saveState
  1.6056 +{
  1.6057 +	BranchObj *bo=xelection.getBranch();
  1.6058 +	if (bo)
  1.6059 +	{
  1.6060 +		XLinkObj *xlo=bo->XLinkAt(i);
  1.6061 +		if (xlo) 
  1.6062 +		{
  1.6063 +			EditXLinkDialog dia;
  1.6064 +			dia.setXLink (xlo);
  1.6065 +			dia.setSelection(bo);
  1.6066 +			if (dia.exec() == QDialog::Accepted)
  1.6067 +			{
  1.6068 +				if (dia.useSettingsGlobal() )
  1.6069 +				{
  1.6070 +					setMapDefXLinkColor (xlo->getColor() );
  1.6071 +					setMapDefXLinkWidth (xlo->getWidth() );
  1.6072 +				}
  1.6073 +				if (dia.deleteXLink())
  1.6074 +					bo->deleteXLinkAt(i);
  1.6075 +			}
  1.6076 +		}	
  1.6077  	}
  1.6078  }
  1.6079  
  1.6080 -void MapEditor::setFrame(const FrameType &t)
  1.6081 -{
  1.6082 -	if (selection && 
  1.6083 -		(typeid(*selection) == typeid(BranchObj)) || 
  1.6084 -		(typeid(*selection) == typeid(MapCenterObj))  )
  1.6085 -	{
  1.6086 -		selection->setFrameType (t);
  1.6087 -		mapCenter->reposition();
  1.6088 -		selection->updateLink();
  1.6089 -	}
  1.6090 +AttributeTable* MapEditor::attributeTable()
  1.6091 +{
  1.6092 +	return attrTable;
  1.6093  }
  1.6094  
  1.6095 -void MapEditor::importDir(BranchObj *dst, QDir d)
  1.6096 -{
  1.6097 -	if (selection && 
  1.6098 -		(typeid(*selection) == typeid(BranchObj)) || 
  1.6099 -		(typeid(*selection) == typeid(MapCenterObj))  )
  1.6100 -	{
  1.6101 -		BranchObj *bo;
  1.6102 -		
  1.6103 -		// Traverse directories
  1.6104 -		d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
  1.6105 -		const QFileInfoList *dirlist = d.entryInfoList();
  1.6106 -		QFileInfoListIterator itdir( *dirlist );
  1.6107 -		QFileInfo *fi;
  1.6108 -
  1.6109 -		while ( (fi = itdir.current()) != 0 ) 
  1.6110 -		{
  1.6111 -			if (fi->fileName() != "." && fi->fileName() != ".." )
  1.6112 -			{
  1.6113 -				dst->addBranch();
  1.6114 -				bo=dst->getLastBranch();
  1.6115 -				bo->setHeading (fi->fileName() );
  1.6116 -				bo->setColor (QColor("blue"),false);
  1.6117 -				bo->toggleScroll();
  1.6118 -				if ( !d.cd(fi->fileName()) ) 
  1.6119 -					QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory"));
  1.6120 -				else 
  1.6121 -				{
  1.6122 -					importDir (bo,d);
  1.6123 -					d.cdUp();
  1.6124 -				}
  1.6125 -			}	
  1.6126 -			++itdir;
  1.6127 -		}		
  1.6128 -		// Traverse files
  1.6129 -		d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
  1.6130 -		const QFileInfoList *filelist = d.entryInfoList();
  1.6131 -		QFileInfoListIterator itfile( *filelist );
  1.6132 -
  1.6133 -		while ( (fi = itfile.current()) != 0 ) 
  1.6134 -		{
  1.6135 -			dst->addBranch();
  1.6136 -			bo=dst->getLastBranch();
  1.6137 -			bo->setHeading (fi->fileName() );
  1.6138 -			bo->setColor (QColor("black"),false);
  1.6139 -			++itfile;
  1.6140 -		}	
  1.6141 -	}		
  1.6142 +void MapEditor::testFunction1()
  1.6143 +{
  1.6144 +	BranchObj *bo=xelection.getBranch();
  1.6145 +	if (bo) model->moveAway (bo);
  1.6146 +	
  1.6147 +/* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
  1.6148 +	if (hidemode==HideNone)
  1.6149 +	{
  1.6150 +		setHideTmpMode (HideExport);
  1.6151 +		mapCenter->calcBBoxSizeWithChilds();
  1.6152 +		QRectF totalBBox=mapCenter->getTotalBBox();
  1.6153 +		QRectF mapRect=totalBBox;
  1.6154 +		QCanvasRectangle *frame=NULL;
  1.6155 +
  1.6156 +		cout << "  map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
  1.6157 +	
  1.6158 +		mapRect.setRect (totalBBox.x(), totalBBox.y(), 
  1.6159 +			totalBBox.width(), totalBBox.height());
  1.6160 +		frame=new QCanvasRectangle (mapRect,mapScene);
  1.6161 +		frame->setBrush (QColor(white));
  1.6162 +		frame->setPen (QColor(black));
  1.6163 +		frame->setZValue(0);
  1.6164 +		frame->show();    
  1.6165 +	}	
  1.6166 +	else	
  1.6167 +	{
  1.6168 +		setHideTmpMode (HideNone);
  1.6169 +	}	
  1.6170 +	cout <<"  hidemode="<<hidemode<<endl;
  1.6171 +	*/
  1.6172 +}	
  1.6173 +	
  1.6174 +void MapEditor::testFunction2()
  1.6175 +{
  1.6176 +
  1.6177 +/*
  1.6178 +	// Toggle hidemode
  1.6179 +	if (hidemode==HideExport)
  1.6180 +		setHideTmpMode (HideNone);
  1.6181 +	else	
  1.6182 +		setHideTmpMode (HideExport);
  1.6183 +*/		
  1.6184  }
  1.6185  
  1.6186 -void MapEditor::importDir()
  1.6187 -{
  1.6188 -	if (selection && 
  1.6189 -		(typeid(*selection) == typeid(BranchObj)) || 
  1.6190 -		(typeid(*selection) == typeid(MapCenterObj))  )
  1.6191 -	{
  1.6192 -		QFileDialog *fd=new QFileDialog( this,tr("VYM - Choose directory structur to import"));
  1.6193 -		fd->setMode (QFileDialog::DirectoryOnly);
  1.6194 -		fd->addFilter (QString (tr("vym map") + " (*.vym)"));
  1.6195 -		fd->setCaption(tr("VYM - Choose directory structur to import"));
  1.6196 -		fd->show();
  1.6197 -
  1.6198 -		QString fn;
  1.6199 -		if ( fd->exec() == QDialog::Accepted )
  1.6200 -		{
  1.6201 -			BranchObj *bo=((BranchObj*)(selection));
  1.6202 -			importDir (bo,QDir(fd->selectedFile()) );
  1.6203 -			mapCenter->reposition();
  1.6204 -			adjustCanvasSize();
  1.6205 -			canvas()->update();
  1.6206 -		}
  1.6207 -	}	
  1.6208 -}
  1.6209 -
  1.6210 -void MapEditor::testFunction()
  1.6211 -{
  1.6212 -	cout << "MapEditor::testFunction() called\n";
  1.6213 -}
  1.6214 -
  1.6215 -void MapEditor::ensureSelectionVisible()
  1.6216 -{
  1.6217 -	LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
  1.6218 -	QPoint p;
  1.6219 -	if (selection->getOrientation() == OrientLeftOfCenter)
  1.6220 -		p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
  1.6221 -	else	
  1.6222 -		p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
  1.6223 -	ensureVisible (p.x(), p.y() );
  1.6224 -
  1.6225 -}
  1.6226 -
  1.6227 -void MapEditor::updateViewCenter()
  1.6228 -{
  1.6229 -	// Update movingCenter, so that we can zoom comfortably later
  1.6230 -	QRect rc = QRect( contentsX(), contentsY(),
  1.6231 -				  visibleWidth(), visibleHeight() );
  1.6232 -	QRect canvasRect = inverseWorldMatrix().mapRect(rc);
  1.6233 -	movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
  1.6234 -	movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
  1.6235 -}
  1.6236 -
  1.6237 -void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e )
  1.6238 +void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
  1.6239  {
  1.6240  	// Lineedits are already closed by preceding
  1.6241  	// mouseEvent, we don't need to close here.
  1.6242  
  1.6243 -    QPoint p = inverseWorldMatrix().map(e->pos());
  1.6244 -    LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
  1.6245 +    QPointF p = mapToScene(e->pos());
  1.6246 +    LinkableMapObj* lmo=model->findMapObj(p, NULL);
  1.6247  	
  1.6248      if (lmo) 
  1.6249  	{	// MapObj was found
  1.6250 -		if (selection != lmo)
  1.6251 +		if (xelection.single() != lmo)
  1.6252  		{
  1.6253  			// select the MapObj
  1.6254 -			if (selection) selection->unselect();
  1.6255 -			selection=lmo;
  1.6256 -			selection->select();
  1.6257 -			adjustCanvasSize();
  1.6258 +			xelection.select(lmo);
  1.6259  		}
  1.6260  		// Context Menu 
  1.6261 -		if (selection) 
  1.6262 +		if (xelection.getBranch() ) 
  1.6263  		{
  1.6264 -			if (typeid(*selection)==typeid(BranchObj) ||
  1.6265 -				typeid(*selection)==typeid(MapCenterObj) )
  1.6266 -			{
  1.6267 -				// Context Menu on branch or mapcenter
  1.6268 -				updateActions();
  1.6269 -				branchContextMenu->popup(e->globalPos() );
  1.6270 -			}	
  1.6271 -			if (typeid(*selection)==typeid(FloatImageObj))
  1.6272 +			// Context Menu on branch or mapcenter
  1.6273 +			updateActions();
  1.6274 +			branchContextMenu->popup(e->globalPos() );
  1.6275 +		} else
  1.6276 +		{
  1.6277 +			if (xelection.getFloatImage() )
  1.6278  			{
  1.6279  				// Context Menu on floatimage
  1.6280  				updateActions();
  1.6281 @@ -2715,348 +4496,947 @@
  1.6282  		}	
  1.6283  	} else 
  1.6284  	{ // No MapObj found, we are on the Canvas itself
  1.6285 -		// Context Menu on Canvas
  1.6286 +		// Context Menu on scene
  1.6287  		updateActions();
  1.6288 +		contextMenuPos=p;
  1.6289  		canvasContextMenu->popup(e->globalPos() );
  1.6290      } 
  1.6291 +	e->accept();
  1.6292  }
  1.6293  
  1.6294 -void MapEditor::contentsMousePressEvent(QMouseEvent* e)
  1.6295 -{
  1.6296 -	// Finish open lineEdits
  1.6297 -	if (lineedit) finishedLineEditNoSave();
  1.6298 -	
  1.6299 -    QPoint p = inverseWorldMatrix().map(e->pos());
  1.6300 -    LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
  1.6301 -	
  1.6302 -	// Special case: CTRL is pressed, don't select anything
  1.6303 -	if (e->state() & QMouseEvent::ControlButton)
  1.6304 -	{
  1.6305 -		pickingColor=true;
  1.6306 -		setCursor (pickColorCursor);
  1.6307 +void MapEditor::keyPressEvent(QKeyEvent* e)
  1.6308 +{
  1.6309 +	if (e->modifiers() & Qt::ControlModifier)
  1.6310 +	{
  1.6311 +		switch (mainWindow->getModMode())
  1.6312 +		{
  1.6313 +			case Main::ModModeColor: 
  1.6314 +				setCursor (PickColorCursor);
  1.6315 +				break;
  1.6316 +			case Main::ModModeCopy: 
  1.6317 +				setCursor (CopyCursor);
  1.6318 +				break;
  1.6319 +			case Main::ModModeXLink: 
  1.6320 +				setCursor (XLinkCursor);
  1.6321 +				break;
  1.6322 +			default :
  1.6323 +				setCursor (Qt::ArrowCursor);
  1.6324 +				break;
  1.6325 +		} 
  1.6326 +	}	
  1.6327 +}
  1.6328 +
  1.6329 +void MapEditor::keyReleaseEvent(QKeyEvent* e)
  1.6330 +{
  1.6331 +	if (!(e->modifiers() & Qt::ControlModifier))
  1.6332 +		setCursor (Qt::ArrowCursor);
  1.6333 +}
  1.6334 +
  1.6335 +void MapEditor::mousePressEvent(QMouseEvent* e)
  1.6336 +{
  1.6337 +	// Ignore right clicks, these will go to context menus
  1.6338 +	if (e->button() == Qt::RightButton )
  1.6339 +	{
  1.6340 +		e->ignore();
  1.6341  		return;
  1.6342  	}
  1.6343  
  1.6344 +	//Ignore clicks while editing heading
  1.6345 +	if (isSelectBlocked() ) 
  1.6346 +	{
  1.6347 +		e->ignore();
  1.6348 +		return;
  1.6349 +	}
  1.6350 +
  1.6351 +    QPointF p = mapToScene(e->pos());
  1.6352 +    LinkableMapObj* lmo=model->findMapObj(p, NULL);
  1.6353 +	
  1.6354 +	e->accept();
  1.6355 +
  1.6356 +	//Take care of  system flags _or_ modifier modes
  1.6357 +	//
  1.6358 +	if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
  1.6359 +		typeid(*lmo)==typeid(MapCenterObj) ))
  1.6360 +	{
  1.6361 +		QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
  1.6362 +		if (!foname.isEmpty())
  1.6363 +		{
  1.6364 +			// systemFlag clicked
  1.6365 +			selectInt (lmo);
  1.6366 +			if (foname=="url") 
  1.6367 +			{
  1.6368 +				if (e->state() & Qt::ControlModifier)
  1.6369 +					mainWindow->editOpenURLTab();
  1.6370 +				else	
  1.6371 +					mainWindow->editOpenURL();
  1.6372 +			}	
  1.6373 +			else if (foname=="vymLink")
  1.6374 +			{
  1.6375 +				mainWindow->editOpenVymLink();
  1.6376 +				// tabWidget may change, better return now
  1.6377 +				// before segfaulting...
  1.6378 +			} else if (foname=="note")
  1.6379 +				mainWindow->windowToggleNoteEditor();
  1.6380 +			else if (foname=="hideInExport")		
  1.6381 +				toggleHideExport();
  1.6382 +			xelection.update();	
  1.6383 +			return;	
  1.6384 +		} 
  1.6385 +	} 
  1.6386 +
  1.6387 +	// No system flag clicked, take care of modmodes (CTRL-Click)
  1.6388 +	if (e->state() & Qt::ControlModifier)
  1.6389 +	{
  1.6390 +		if (mainWindow->getModMode()==Main::ModModeColor)
  1.6391 +		{
  1.6392 +				pickingColor=true;
  1.6393 +				setCursor (PickColorCursor);
  1.6394 +				return;
  1.6395 +		} 
  1.6396 +		if (mainWindow->getModMode()==Main::ModModeXLink)
  1.6397 +		{	
  1.6398 +			BranchObj *bo_begin=NULL;
  1.6399 +			if (lmo)
  1.6400 +				bo_begin=(BranchObj*)(lmo);
  1.6401 +			else	
  1.6402 +				if (xelection.getBranch() ) 
  1.6403 +					bo_begin=xelection.getBranch();
  1.6404 +			if (bo_begin)	
  1.6405 +			{
  1.6406 +				drawingLink=true;
  1.6407 +				linkingObj_src=bo_begin;
  1.6408 +				tmpXLink=new XLinkObj (mapScene);
  1.6409 +				tmpXLink->setBegin (bo_begin);
  1.6410 +				tmpXLink->setEnd   (p);
  1.6411 +				tmpXLink->setColor(defXLinkColor);
  1.6412 +				tmpXLink->setWidth(defXLinkWidth);
  1.6413 +				tmpXLink->updateXLink();
  1.6414 +				tmpXLink->setVisibility (true);
  1.6415 +				return;
  1.6416 +			} 
  1.6417 +		}
  1.6418 +	}	// End of modmodes
  1.6419 +
  1.6420      if (lmo) 
  1.6421 -	{	// MapObj was found
  1.6422 -		if (selection != lmo)
  1.6423 +	{	
  1.6424 +		// Select the clicked object
  1.6425 +		selectInt (lmo);
  1.6426 +
  1.6427 +		// Left Button	    Move Branches
  1.6428 +		if (e->button() == Qt::LeftButton )
  1.6429  		{
  1.6430 -			// select the MapObj
  1.6431 -			if (selection) selection->unselect();
  1.6432 -			selection=lmo;
  1.6433 -			selection->select();
  1.6434 -				
  1.6435 -			adjustCanvasSize();
  1.6436 -		}
  1.6437 -
  1.6438 -		// Check, if systemFlag clicked
  1.6439 -		if (typeid(*selection)==typeid(BranchObj) ||
  1.6440 -			typeid(*selection)==typeid(MapCenterObj) )
  1.6441 -		{
  1.6442 -			QString foname=((BranchObj*)(selection))->getSystemFlagName(p);
  1.6443 -			if (!foname.isEmpty())
  1.6444 +			//movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here	
  1.6445 +			//movingObj_start.setY( p.y() - selection->y() );	
  1.6446 +			movingObj_start.setX( p.x() - lmo->x() );	
  1.6447 +			movingObj_start.setY( p.y() - lmo->y() );	
  1.6448 +			movingObj_orgPos.setX (lmo->x() );
  1.6449 +			movingObj_orgPos.setY (lmo->y() );
  1.6450 +			movingObj_orgRelPos=lmo->getRelPos();
  1.6451 +
  1.6452 +			// If modMode==copy, then we want to "move" the _new_ object around
  1.6453 +			// then we need the offset from p to the _old_ selection, because of tmp
  1.6454 +			if (mainWindow->getModMode()==Main::ModModeCopy &&
  1.6455 +				e->state() & Qt::ControlModifier)
  1.6456  			{
  1.6457 -				// Do not move, if systemFlag clicked
  1.6458 -				if (foname=="url") 
  1.6459 -					openURL();
  1.6460 -				else
  1.6461 -					if (foname=="vymLink")
  1.6462 -					{
  1.6463 -						mainWindow->editOpenVymLink();
  1.6464 -						// tabWidget may change, better return now
  1.6465 -						// before segfaulting...
  1.6466 -						return;
  1.6467 -					} else
  1.6468 -						if (foname=="note")
  1.6469 -							mainWindow->windowToggleNoteEditor();
  1.6470 -			}			
  1.6471 -		}	
  1.6472 -			
  1.6473 -		// Left Button	    Move Branches
  1.6474 -		if (e->button() == QMouseEvent::LeftButton )
  1.6475 -		{
  1.6476 -			movingObj=selection;	
  1.6477 -			movingObj_start.setX( p.x() - selection->x() );	
  1.6478 -			movingObj_start.setY( p.y() - selection->y() );	
  1.6479 +				BranchObj *bo=xelection.getBranch();
  1.6480 +				if (bo)
  1.6481 +				{
  1.6482 +					copyingObj=true;
  1.6483 +					bo->addBranch ((BranchObj*)xelection.single());
  1.6484 +					unselect();
  1.6485 +					xelection.select(bo->getLastBranch());
  1.6486 +					model->reposition();
  1.6487 +				}
  1.6488 +			} 
  1.6489 +
  1.6490 +			movingObj=xelection.single();	
  1.6491  		} else
  1.6492  			// Middle Button    Toggle Scroll
  1.6493  			// (On Mac OS X this won't work, but we still have 
  1.6494  			// a button in the toolbar)
  1.6495 -			if (e->button() == QMouseEvent::MidButton )
  1.6496 -			{
  1.6497 +			if (e->button() == Qt::MidButton )
  1.6498  				toggleScroll();
  1.6499 -			} 
  1.6500  		updateActions();
  1.6501 +		xelection.update();
  1.6502  	} else 
  1.6503 -	{ // No MapObj found, we are on the Canvas itself
  1.6504 -		// Left Button	    move Pos of CanvasView
  1.6505 -		if (e->button() == QMouseEvent::LeftButton )
  1.6506 +	{ // No MapObj found, we are on the scene itself
  1.6507 +		// Left Button	    move Pos of sceneView
  1.6508 +		if (e->button() == Qt::LeftButton )
  1.6509  		{
  1.6510  			movingObj=NULL;	// move Content not Obj
  1.6511  			movingObj_start=e->globalPos();
  1.6512 -			movingCont_start=QPoint (contentsX(), contentsY() );
  1.6513 -			movingVec=QPoint(0,0);
  1.6514 -			setCursor(handOpenCursor);
  1.6515 +			movingCont_start=QPointF (
  1.6516 +				horizontalScrollBar()->value(),
  1.6517 +				verticalScrollBar()->value());
  1.6518 +			movingVec=QPointF(0,0);
  1.6519 +			setCursor(HandOpenCursor);
  1.6520  		} 
  1.6521      } 
  1.6522  }
  1.6523  
  1.6524 -void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
  1.6525 -{
  1.6526 +void MapEditor::mouseMoveEvent(QMouseEvent* e)
  1.6527 +{
  1.6528 +    QPointF p = mapToScene(e->pos());
  1.6529 +	LinkableMapObj *lmosel=xelection.single();
  1.6530 +
  1.6531      // Move the selected MapObj
  1.6532 -    if ( selection && movingObj) 
  1.6533 +    if ( lmosel && movingObj) 
  1.6534      {	
  1.6535 -		QPoint p = inverseWorldMatrix().map(e->pos());
  1.6536 +		// reset cursor if we are moving and don't copy
  1.6537 +		if (mainWindow->getModMode()!=Main::ModModeCopy)
  1.6538 +			setCursor (Qt::ArrowCursor);
  1.6539 +
  1.6540 +		// To avoid jumping of the sceneView, only 
  1.6541 +		// ensureSelectionVisible, if not tmp linked
  1.6542 +		if (!lmosel->hasParObjTmp())
  1.6543 +			ensureSelectionVisible ();
  1.6544  		
  1.6545 -		// Now move the selection, but add relative position (movingObj_start) 
  1.6546 -		// where selection 
  1.6547 -		// was chosen with mousepointer. (This avoids flickering resp. jumping 
  1.6548 +		// Now move the selection, but add relative position 
  1.6549 +		// (movingObj_start) where selection was chosen with 
  1.6550 +		// mousepointer. (This avoids flickering resp. jumping 
  1.6551  		// of selection back to absPos)
  1.6552  		
  1.6553 -		LinkableMapObj *lmosel;
  1.6554 -		lmosel =  dynamic_cast <LinkableMapObj*> (selection);
  1.6555 -
  1.6556  		// Check if we could link 
  1.6557 -		LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
  1.6558 +		LinkableMapObj* lmo=model->findMapObj(p, lmosel);
  1.6559  		
  1.6560  
  1.6561 -		if (typeid(*selection) == typeid(FloatImageObj))
  1.6562 +		FloatObj *fio=xelection.getFloatImage();
  1.6563 +		if (fio)
  1.6564  		{
  1.6565 -			setChanged();
  1.6566 -			saveState();
  1.6567 -			FloatObj *fo=(FloatObj*)(selection);
  1.6568 -			if (fo->getLinkStyle()==StyleUndef) 
  1.6569 -			{
  1.6570 -				fo->setLinkStyle(fo->getDefLinkStyle());
  1.6571 -				fo->setLinkColor(fo->getParObj()->getLinkColor());
  1.6572 -			}	
  1.6573 -			fo->move   (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.6574 -			fo->setRelPos();
  1.6575 -			fo->reposition();
  1.6576 +			fio->move   (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.6577 +			fio->setRelPos();
  1.6578 +			fio->updateLink(); //no need for reposition, if we update link here
  1.6579 +			xelection.update();
  1.6580  
  1.6581  			// Relink float to new mapcenter or branch, if shift is pressed	
  1.6582  			// Only relink, if selection really has a new parent
  1.6583 -			if ( (e->state() & QMouseEvent::ShiftButton) && lmo &&
  1.6584 +			if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
  1.6585  				( (typeid(*lmo)==typeid(BranchObj)) ||
  1.6586  				  (typeid(*lmo)==typeid(MapCenterObj)) ) &&
  1.6587 -				( lmo != fo->getParObj())  
  1.6588 +				( lmo != fio->getParObj())  
  1.6589  				)
  1.6590  			{
  1.6591 -				if (typeid(*fo) == typeid(FloatImageObj)) 
  1.6592 +				if (typeid(*fio) == typeid(FloatImageObj) && 
  1.6593 +				( (typeid(*lmo)==typeid(BranchObj) ||
  1.6594 +				  typeid(*lmo)==typeid(MapCenterObj)) ))  
  1.6595  				{
  1.6596 -					FloatImageObj *fio=(FloatImageObj*)(fo);
  1.6597 -					((BranchObj*)(lmo))->addFloatImage (fio);
  1.6598 -					fio->unselect();
  1.6599 -					((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
  1.6600 -					fio=((BranchObj*)(lmo))->getLastFloatImage();
  1.6601 -					fio->setRelPos();
  1.6602 -					fio->reposition();
  1.6603 -					selection=(LinkableMapObj*)(fio);
  1.6604 -					selection->select();
  1.6605 -					movingObj=(MapObj*)(fio);
  1.6606 -					// setLinkStyle calls updateLink, only set it once
  1.6607 -					if (fio->getLinkStyle()!=fio->getDefLinkStyle() ) 
  1.6608 -						fio->setLinkStyle (fio->getDefLinkStyle());
  1.6609 -
  1.6610 +
  1.6611 +					// Also save the move which was done so far
  1.6612 +					QString pold=qpointfToString(movingObj_orgRelPos);
  1.6613 +					QString pnow=qpointfToString(fio->getRelPos());
  1.6614 +					saveState(
  1.6615 +						fio,
  1.6616 +						"moveRel "+pold,
  1.6617 +						fio,
  1.6618 +						"moveRel "+pnow,
  1.6619 +						QString("Move %1 to relative position %2").arg(getName(fio)).arg(pnow));
  1.6620 +					fio->getParObj()->requestReposition();
  1.6621 +					model->reposition();
  1.6622 +
  1.6623 +					linkTo (model->getSelectString(lmo));
  1.6624 +					//movingObj=lmosel;
  1.6625 +					//movingObj_orgRelPos=lmosel->getRelPos();	
  1.6626 +
  1.6627 +					model->reposition();
  1.6628  				}	
  1.6629 -				// TODO if (typeid(*selection) == typeid(FloatTextObj))
  1.6630  			}
  1.6631 -		} else	// selection != a FloatObj
  1.6632 -		{
  1.6633 +		} else	
  1.6634 +		{	// selection != a FloatObj
  1.6635  			if (lmosel->getDepth()==0)
  1.6636  			{
  1.6637 -				if (e->state() == (LeftButton | !ShiftButton)) 
  1.6638 -					// If mapCenter is moved, move all the rest by default, too.
  1.6639 -					mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.6640 +				// Move MapCenter
  1.6641 +				if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier) 
  1.6642 +					((MapCenterObj*)lmosel)->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.6643  				else	
  1.6644 -					mapCenter->move   (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.6645 +					lmosel->move   (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.6646 +				model->updateRelPositions();
  1.6647  			} else
  1.6648  			{	
  1.6649  				if (lmosel->getDepth()==1)
  1.6650  				{
  1.6651 -					// depth==1, mainbranch
  1.6652 -					setChanged();
  1.6653 -					saveState(PartOfMap,lmosel);
  1.6654 +					// Move mainbranch
  1.6655  					lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  1.6656 +					lmosel->setRelPos();
  1.6657  				} else
  1.6658  				{
  1.6659 -					// depth>1
  1.6660 -					if (lmosel->getOrientation() == OrientLeftOfCenter)
  1.6661 +					// Move ordinary branch
  1.6662 +					if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
  1.6663  						// Add width of bbox here, otherwise alignRelTo will cause jumping around
  1.6664  						lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(), 
  1.6665 -							p.y()-movingObj_start.y() );		
  1.6666 +							p.y()-movingObj_start.y() +lmosel->getTopPad() );		
  1.6667  					else	
  1.6668 -						lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
  1.6669 +						lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
  1.6670  				} 
  1.6671 -				// reposition subbranch
  1.6672 -				lmosel->reposition();	
  1.6673 -				ensureSelectionVisible();
  1.6674 -
  1.6675 -				if (lmo && (lmo!=selection) &&  
  1.6676 -					(typeid(*lmo) == typeid(BranchObj) ||
  1.6677 -					(typeid(*lmo) == typeid(MapCenterObj) )
  1.6678 -					) )
  1.6679 +
  1.6680 +				// Maybe we can relink temporary?
  1.6681 +				if (lmo && (lmo!=lmosel) && xelection.getBranch() && 
  1.6682 +					 (typeid(*lmo)==typeid(BranchObj) ||
  1.6683 +					  typeid(*lmo)==typeid(MapCenterObj)) ) 
  1.6684 +
  1.6685  				{
  1.6686 -					if (e->state() & QMouseEvent::ControlButton)
  1.6687 +					if (e->modifiers()==Qt::ControlModifier)
  1.6688  					{
  1.6689  						// Special case: CTRL to link below lmo
  1.6690  						lmosel->setParObjTmp (lmo,p,+1);
  1.6691  					}
  1.6692 -					else if (e->state() & QMouseEvent::ShiftButton)
  1.6693 +					else if (e->modifiers()==Qt::ShiftModifier)
  1.6694  						lmosel->setParObjTmp (lmo,p,-1);
  1.6695  					else
  1.6696  						lmosel->setParObjTmp (lmo,p,0);
  1.6697  				} else	
  1.6698  				{
  1.6699 -					if (lmo &&(lmo==selection))   
  1.6700 -						// Could link to myself (happens sometimes...)
  1.6701 -						lmosel->unsetParObjTmp();
  1.6702 -					if (!lmo)  
  1.6703 -						// no Obj under selection, go back to original Parent
  1.6704 -						lmosel->unsetParObjTmp();
  1.6705 +					lmosel->unsetParObjTmp();
  1.6706  				}		
  1.6707 +				// reposition subbranch
  1.6708 +				lmosel->reposition();	
  1.6709  			} // depth>0
  1.6710  
  1.6711 +			xelection.update();
  1.6712  		} // no FloatImageObj
  1.6713  
  1.6714 -		canvas()->update();
  1.6715 +		scene()->update();
  1.6716  		return;
  1.6717  	} // selection && moving_obj
  1.6718  		
  1.6719 -    // Move CanvasView 
  1.6720 -    if (!movingObj && !pickingColor) 
  1.6721 -	{
  1.6722 -		QPoint p=e->globalPos();
  1.6723 +	// Draw a link from one branch to another
  1.6724 +	if (drawingLink)
  1.6725 +	{
  1.6726 +		 tmpXLink->setEnd (p);
  1.6727 +		 tmpXLink->updateXLink();
  1.6728 +	}	 
  1.6729 +	
  1.6730 +    // Move sceneView 
  1.6731 +    if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton ) 
  1.6732 +	{
  1.6733 +		QPointF p=e->globalPos();
  1.6734  		movingVec.setX(-p.x() + movingObj_start.x() );
  1.6735  		movingVec.setY(-p.y() + movingObj_start.y() );
  1.6736 -		setContentsPos( movingCont_start.x() + movingVec.x(),
  1.6737 -	    movingCont_start.y() + movingVec.y());
  1.6738 -
  1.6739 -		updateViewCenter();
  1.6740 +		horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
  1.6741 +		verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
  1.6742      }
  1.6743  }
  1.6744  
  1.6745  
  1.6746 -void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e)
  1.6747 -{
  1.6748 +void MapEditor::mouseReleaseEvent(QMouseEvent* e)
  1.6749 +{
  1.6750 +    QPointF p = mapToScene(e->pos());
  1.6751  	LinkableMapObj *dst;
  1.6752 +	LinkableMapObj *lmosel=xelection.single();
  1.6753  	// Have we been picking color?
  1.6754  	if (pickingColor)
  1.6755  	{
  1.6756  		pickingColor=false;
  1.6757 -		setCursor (ArrowCursor);
  1.6758 +		setCursor (Qt::ArrowCursor);
  1.6759  		// Check if we are over another branch
  1.6760 -		dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
  1.6761 -		if (dst && selection) 
  1.6762 +		dst=model->findMapObj(p, NULL);
  1.6763 +		if (dst && lmosel) 
  1.6764  		{	
  1.6765 -			if (e->state() & QMouseEvent::ShiftButton)
  1.6766 -			{
  1.6767 -				((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),false);
  1.6768 -				((BranchObj*)(selection))->setLinkColor ();
  1.6769 -			}	
  1.6770 +			if (e->state() & Qt::ShiftModifier)
  1.6771 +				colorBranch (((BranchObj*)dst)->getColor());
  1.6772  			else	
  1.6773 -			{
  1.6774 -				((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),true);
  1.6775 -				((BranchObj*)(selection))->setLinkColor ();
  1.6776 -			}	
  1.6777 +				colorSubtree (((BranchObj*)dst)->getColor());
  1.6778  		} 
  1.6779  		return;
  1.6780  	}
  1.6781 +
  1.6782 +	// Have we been drawing a link?
  1.6783 +	if (drawingLink)	
  1.6784 +	{
  1.6785 +		drawingLink=false;
  1.6786 +		// Check if we are over another branch
  1.6787 +		dst=model->findMapObj(p, NULL);
  1.6788 +		if (dst && lmosel) 
  1.6789 +		{	
  1.6790 +			tmpXLink->setEnd ( ((BranchObj*)(dst)) );
  1.6791 +			tmpXLink->updateXLink();
  1.6792 +			tmpXLink->activate(); //FIXME savestate missing
  1.6793 +			//saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );	
  1.6794 +		} else
  1.6795 +		{
  1.6796 +			delete(tmpXLink);
  1.6797 +			tmpXLink=NULL;
  1.6798 +		}
  1.6799 +		return;
  1.6800 +	}
  1.6801 +	
  1.6802      // Have we been moving something?
  1.6803 -    if ( selection && movingObj ) 
  1.6804 +    if ( lmosel && movingObj ) 
  1.6805      {	
  1.6806 +		FloatImageObj *fo=xelection.getFloatImage();
  1.6807 +		if(fo)
  1.6808 +		{
  1.6809 +			// Moved FloatObj. Maybe we need to reposition
  1.6810 +		    QString pold=qpointfToString(movingObj_orgRelPos);
  1.6811 +		    QString pnow=qpointfToString(fo->getRelPos());
  1.6812 +			saveState(
  1.6813 +				fo,
  1.6814 +				"moveRel "+pold,
  1.6815 +				fo,
  1.6816 +				"moveRel "+pnow,
  1.6817 +				QString("Move %1 to relative position %2").arg(getName(fo)).arg(pnow));
  1.6818 +
  1.6819 +			fo->getParObj()->requestReposition();
  1.6820 +			model->reposition();
  1.6821 +		}	
  1.6822 +
  1.6823  		// Check if we are over another branch, but ignore 
  1.6824  		// any found LMOs, which are FloatObjs
  1.6825 -		dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), 
  1.6826 -			((LinkableMapObj*)(selection)) );
  1.6827 -
  1.6828 -		if (dst &&
  1.6829 -		(typeid(*dst)!=typeid(BranchObj)&&typeid(*dst)!=typeid(MapCenterObj))) 
  1.6830 -		{
  1.6831 +		dst=model->findMapObj(mapToScene(e->pos() ), lmosel);
  1.6832 +
  1.6833 +		if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj))) 
  1.6834  			dst=NULL;
  1.6835 -		}	
  1.6836  		
  1.6837 -		// Now check, if we have been moving a branch 
  1.6838 -		if (typeid(*selection) == typeid(BranchObj)  )
  1.6839 -		{
  1.6840 +		BranchObj *bo=xelection.getBranch();
  1.6841 +		if (bo && bo->getDepth()==0)
  1.6842 +		{	
  1.6843 +            if (movingObj_orgPos != bo->getAbsPos())
  1.6844 +            {
  1.6845 +                QString pold=qpointfToString(movingObj_orgPos);
  1.6846 +                QString pnow=qpointfToString(bo->getAbsPos());
  1.6847 +                saveState(
  1.6848 +                    fo,
  1.6849 +                    "move "+pold,
  1.6850 +                    fo,
  1.6851 +                    "move "+pnow,
  1.6852 +                    QString("Move mapcenter %1 to position %2").arg(getName(bo)).arg(pnow));
  1.6853 +            }
  1.6854 +		}
  1.6855 +	
  1.6856 +		if (xelection.type() == Selection::Branch )
  1.6857 +		{	// A branch was moved
  1.6858 +			
  1.6859  			// save the position in case we link to mapcenter
  1.6860 -			QPoint savePos=QPoint (selection->x(),selection->y() );
  1.6861 +			QPointF savePos=QPointF (lmosel->getAbsPos()  );
  1.6862  
  1.6863  			// Reset the temporary drawn link to the original one
  1.6864 -			((LinkableMapObj*)(selection))->unsetParObjTmp();
  1.6865 -
  1.6866 +			lmosel->unsetParObjTmp();
  1.6867 +
  1.6868 +			// For Redo we may need to save original selection
  1.6869 +			QString preSelStr=model->getSelectString(lmosel);
  1.6870 +
  1.6871 +			copyingObj=false;	
  1.6872  			if (dst ) 
  1.6873 -			{   
  1.6874 -				setChanged();
  1.6875 -				saveState();
  1.6876 -				// TODO we also could check, if dest and src are on same branch,
  1.6877 -				// then it would be sufficient to saveState of this branch
  1.6878 -
  1.6879 -				// FIXME better introduce BO::move  to speed up and keep IDs
  1.6880 -				copy();			// copy selection to clipboard
  1.6881 -				cutNoSave();	// remove selection here
  1.6882 -
  1.6883 -				selection->unselect();	
  1.6884 -				selection=dst;
  1.6885 -				// Modifiers allow to insert above/below dst
  1.6886 -				if (e->state() & QMouseEvent::ShiftButton)
  1.6887 +			{
  1.6888 +				// We have a destination, relink to that
  1.6889 +
  1.6890 +				BranchObj* bsel=xelection.getBranch();
  1.6891 +				BranchObj* bdst=(BranchObj*)dst;
  1.6892 +
  1.6893 +				QString preParStr=model->getSelectString (bsel->getParObj());
  1.6894 +				QString preNum=QString::number (bsel->getNum(),10);
  1.6895 +				QString preDstParStr;
  1.6896 +
  1.6897 +				if (e->state() & Qt::ShiftModifier && dst->getParObj())
  1.6898 +				{	// Link above dst
  1.6899 +					preDstParStr=model->getSelectString (dst->getParObj());
  1.6900 +					bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
  1.6901 +				} else 
  1.6902 +				if (e->state() & Qt::ControlModifier && dst->getParObj())
  1.6903  				{
  1.6904 -					selection=pasteAtNoSave (((BranchObj*)(dst))->getNum());
  1.6905 -					if (selection) selection->select();
  1.6906 -				}	
  1.6907 -				else if (e->state() & QMouseEvent::ControlButton)
  1.6908 +					// Link below dst
  1.6909 +					preDstParStr=model->getSelectString (dst->getParObj());
  1.6910 +					bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
  1.6911 +				} else	
  1.6912 +				{	// Append to dst
  1.6913 +					preDstParStr=model->getSelectString(dst);
  1.6914 +					bsel->linkTo (bdst,-1);
  1.6915 +					if (dst->getDepth()==0) bsel->move (savePos);
  1.6916 +				} 
  1.6917 +				QString postSelStr=model->getSelectString(lmosel);
  1.6918 +				QString postNum=QString::number (bsel->getNum(),10);
  1.6919 +
  1.6920 +				QString undoCom="linkTo (\""+ 
  1.6921 +					preParStr+ "\"," + preNum  +"," + 
  1.6922 +					QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
  1.6923 +
  1.6924 +				QString redoCom="linkTo (\""+ 
  1.6925 +					preDstParStr + "\"," + postNum + "," +
  1.6926 +					QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
  1.6927 +
  1.6928 +				saveState (
  1.6929 +					postSelStr,undoCom,
  1.6930 +					preSelStr, redoCom,
  1.6931 +					QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
  1.6932 +
  1.6933 +				model->reposition();	// not necessary if we undo temporary move  below
  1.6934 +			} else
  1.6935 +			{
  1.6936 +				// No destination, undo  temporary move
  1.6937 +
  1.6938 +				if (lmosel->getDepth()==1)
  1.6939  				{
  1.6940 -					selection=pasteAtNoSave (((BranchObj*)(dst))->getNum()+1);
  1.6941 -					if (selection) selection->select();
  1.6942 -				}	
  1.6943 -				else	
  1.6944 +					// The select string might be different _after_ moving around.
  1.6945 +					// Therefor reposition and then use string of old selection, too
  1.6946 +					model->reposition();
  1.6947 +
  1.6948 +                    QPointF rp(lmosel->getRelPos());
  1.6949 +                    if (rp != movingObj_orgRelPos)
  1.6950 +                    {
  1.6951 +                        QString ps=qpointfToString(rp);
  1.6952 +                        saveState(
  1.6953 +                            model->getSelectString(lmosel), "moveRel "+qpointfToString(movingObj_orgRelPos), 
  1.6954 +                            preSelStr, "moveRel "+ps, 
  1.6955 +                            QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
  1.6956 +                    }
  1.6957 +				}
  1.6958 +
  1.6959 +				// Draw the original link, before selection was moved around
  1.6960 +				if (settings.value("/animation/use",false).toBool() && lmosel->getDepth()>1) 
  1.6961  				{
  1.6962 -					selection=pasteNoSave();
  1.6963 -					selection->select();
  1.6964 -					if (dst->getDepth()==0) 
  1.6965 -						((BranchObj*)(selection))->move (savePos);
  1.6966 -				}	
  1.6967 -			} 
  1.6968 -			// Draw the original link, before selection was moved around
  1.6969 -			mapCenter->reposition();
  1.6970 +					QPointF p=bo->getParObj()->getChildPos();
  1.6971 +					lmosel->setRelPos();	// calc relPos first
  1.6972 +					model->startAnimation(
  1.6973 +						lmosel->getRelPos(),
  1.6974 +						QPointF (movingObj_orgPos.x() - p.x(), movingObj_orgPos.y() - p.y() )
  1.6975 +					);	
  1.6976 +				} else	
  1.6977 +					model->reposition();
  1.6978 +			}
  1.6979  		}
  1.6980 -		// Finally resize canvas, if needed
  1.6981 -		adjustCanvasSize();
  1.6982 -		canvas()->update();
  1.6983 +		 xelection.update();
  1.6984 +		// Finally resize scene, if needed
  1.6985 +		scene()->update();
  1.6986  		movingObj=NULL;		
  1.6987 +
  1.6988 +		// Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
  1.6989 +		updateActions();
  1.6990  	} else 
  1.6991 -	{	// maybe we moved View: set old cursor
  1.6992 -		setCursor (ArrowCursor);
  1.6993 -    }
  1.6994 +		// maybe we moved View: set old cursor
  1.6995 +		setCursor (Qt::ArrowCursor);
  1.6996 +    
  1.6997  }
  1.6998  
  1.6999 -void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
  1.7000 -{
  1.7001 -	// Finish open lineEdits
  1.7002 -	if (lineedit) finishedLineEditNoSave();
  1.7003 -	
  1.7004 -	if (e->button() == QMouseEvent::LeftButton )
  1.7005 -	{
  1.7006 -		QPoint p = inverseWorldMatrix().map(e->pos());
  1.7007 -		LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
  1.7008 +void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
  1.7009 +{
  1.7010 +	if (isSelectBlocked() ) 
  1.7011 +	{
  1.7012 +		e->ignore();
  1.7013 +		return;
  1.7014 +	}
  1.7015 +
  1.7016 +	if (e->button() == Qt::LeftButton )
  1.7017 +	{
  1.7018 +		QPointF p = mapToScene(e->pos());
  1.7019 +		LinkableMapObj *lmo=model->findMapObj(p, NULL);
  1.7020  		if (lmo) {	// MapObj was found
  1.7021  			// First select the MapObj than edit heading
  1.7022 -			if (selection) selection->unselect();
  1.7023 -			selection=lmo;
  1.7024 -			selection->select();
  1.7025 -			setChanged();
  1.7026 -			saveState(PartOfMap,selection);
  1.7027 -			editHeading();
  1.7028 +			xelection.select(lmo);
  1.7029 +			mainWindow->editHeading();
  1.7030  		}
  1.7031  	}
  1.7032  }
  1.7033  
  1.7034  void MapEditor::resizeEvent (QResizeEvent* e)
  1.7035  {
  1.7036 -	QCanvasView::resizeEvent( e );
  1.7037 +	QGraphicsView::resizeEvent( e );
  1.7038 +}
  1.7039 +
  1.7040 +void MapEditor::dragEnterEvent(QDragEnterEvent *event)
  1.7041 +{
  1.7042 +	//for (unsigned int i=0;event->format(i);i++) // Debug mime type
  1.7043 +	//	cerr << event->format(i) << endl;
  1.7044 +
  1.7045 +	if (event->mimeData()->hasImage())
  1.7046 +		event->acceptProposedAction();
  1.7047 +	else	
  1.7048 +		if (event->mimeData()->hasUrls())
  1.7049 +			event->acceptProposedAction();
  1.7050 +}
  1.7051 +
  1.7052 +void MapEditor::dragMoveEvent(QDragMoveEvent *)
  1.7053 +{
  1.7054 +}
  1.7055 +
  1.7056 +void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
  1.7057 +{
  1.7058 +	event->accept();
  1.7059 +}
  1.7060 +
  1.7061 +void MapEditor::dropEvent(QDropEvent *event)
  1.7062 +{
  1.7063 +	BranchObj *sel=xelection.getBranch();
  1.7064 +	if (sel)
  1.7065 +	{
  1.7066 +		if (debug)
  1.7067 +			foreach (QString format,event->mimeData()->formats()) 
  1.7068 +				cout << "MapEditor: Dropped format: "<<qPrintable (format)<<endl;
  1.7069 +
  1.7070 +
  1.7071 +		QList <QUrl> uris;
  1.7072 +		if (event->mimeData()->hasImage()) 
  1.7073 +		{
  1.7074 +			 QVariant imageData = event->mimeData()->imageData();
  1.7075 +			 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
  1.7076 +		} else
  1.7077 +		if (event->mimeData()->hasUrls())
  1.7078 +			uris=event->mimeData()->urls();
  1.7079 +
  1.7080 +		if (uris.count()>0)
  1.7081 +		{
  1.7082 +			QStringList files;
  1.7083 +			QString s;
  1.7084 +			QString heading;
  1.7085 +			BranchObj *bo;
  1.7086 +			for (int i=0; i<uris.count();i++)
  1.7087 +			{
  1.7088 +				// Workaround to avoid adding empty branches
  1.7089 +				if (!uris.at(i).toString().isEmpty())
  1.7090 +				{
  1.7091 +					bo=sel->addBranch();
  1.7092 +					if (bo)
  1.7093 +					{
  1.7094 +						s=uris.at(i).toLocalFile();
  1.7095 +						if (!s.isEmpty()) 
  1.7096 +						{
  1.7097 +						   QString file = QDir::fromNativeSeparators(s);
  1.7098 +						   heading = QFileInfo(file).baseName();
  1.7099 +						   files.append(file);
  1.7100 +						   if (file.endsWith(".vym", false))
  1.7101 +							   bo->setVymLink(file);
  1.7102 +						   else
  1.7103 +							   bo->setURL(uris.at(i).toString());
  1.7104 +					   } else 
  1.7105 +					   {
  1.7106 +						   bo->setURL(uris.at(i).toString());
  1.7107 +					   }
  1.7108 +
  1.7109 +					   if (!heading.isEmpty())
  1.7110 +						   bo->setHeading(heading);
  1.7111 +					   else
  1.7112 +						   bo->setHeading(uris.at(i).toString());
  1.7113 +					}
  1.7114 +				}
  1.7115 +			}
  1.7116 +			model->reposition();
  1.7117 +		}
  1.7118 +	}	
  1.7119 +	event->acceptProposedAction();
  1.7120 +}
  1.7121 +
  1.7122 +
  1.7123 +void MapEditor::sendSelection()
  1.7124 +{
  1.7125 +	if (netstate!=Server) return;
  1.7126 +	sendData (QString("select (\"%1\")").arg(xelection.getSelectString()) );
  1.7127 +}
  1.7128 +
  1.7129 +void MapEditor::newServer()
  1.7130 +{
  1.7131 +	port=54321;
  1.7132 +	sendCounter=0;
  1.7133 +    tcpServer = new QTcpServer(this);
  1.7134 +    if (!tcpServer->listen(QHostAddress::Any,port)) {
  1.7135 +        QMessageBox::critical(this, "vym server",
  1.7136 +                              QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
  1.7137 +        close();
  1.7138 +        return;
  1.7139 +    }
  1.7140 +	connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
  1.7141 +	netstate=Server;
  1.7142 +	cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
  1.7143 +}
  1.7144 +
  1.7145 +void MapEditor::connectToServer()
  1.7146 +{
  1.7147 +	port=54321;
  1.7148 +	server="salam.suse.de";
  1.7149 +	server="localhost";
  1.7150 +	clientSocket = new QTcpSocket (this);
  1.7151 +	clientSocket->abort();
  1.7152 +    clientSocket->connectToHost(server ,port);
  1.7153 +	connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
  1.7154 +    connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
  1.7155 +            this, SLOT(displayNetworkError(QAbstractSocket::SocketError)));
  1.7156 +	netstate=Client;		
  1.7157 +	cout<<"connected to "<<qPrintable (server)<<" port "<<port<<endl;
  1.7158 +
  1.7159  	
  1.7160 -	QString s="";
  1.7161 -	if (!fileName.isEmpty()) s=fileName;
  1.7162 -	adjustCanvasSize();
  1.7163  }
  1.7164  
  1.7165 +void MapEditor::newClient()
  1.7166 +{
  1.7167 +    QTcpSocket *newClient = tcpServer->nextPendingConnection();
  1.7168 +    connect(newClient, SIGNAL(disconnected()),
  1.7169 +            newClient, SLOT(deleteLater()));
  1.7170 +
  1.7171 +	cout <<"ME::newClient  at "<<qPrintable( newClient->peerAddress().toString() )<<endl;
  1.7172 +
  1.7173 +	clientList.append (newClient);
  1.7174 +}
  1.7175 +
  1.7176 +
  1.7177 +void MapEditor::sendData(const QString &s)
  1.7178 +{
  1.7179 +	if (clientList.size()==0) return;
  1.7180 +
  1.7181 +	// Create bytearray to send
  1.7182 +	QByteArray block;
  1.7183 +    QDataStream out(&block, QIODevice::WriteOnly);
  1.7184 +    out.setVersion(QDataStream::Qt_4_0);
  1.7185 +
  1.7186 +	// Reserve some space for blocksize
  1.7187 +    out << (quint16)0;
  1.7188 +
  1.7189 +	// Write sendCounter
  1.7190 +    out << sendCounter++;
  1.7191 +
  1.7192 +	// Write data
  1.7193 +    out << s;
  1.7194 +
  1.7195 +	// Go back and write blocksize so far
  1.7196 +    out.device()->seek(0);
  1.7197 +    quint16 bs=(quint16)(block.size() - 2*sizeof(quint16));
  1.7198 +	out << bs;
  1.7199 +
  1.7200 +	if (debug)
  1.7201 +		cout << "ME::sendData  bs="<<bs<<"  counter="<<sendCounter<<"  s="<<qPrintable(s)<<endl;
  1.7202 +
  1.7203 +	for (int i=0; i<clientList.size(); ++i)
  1.7204 +	{
  1.7205 +		//cout << "Sending \""<<qPrintable (s)<<"\" to "<<qPrintable (clientList.at(i)->peerAddress().toString())<<endl;
  1.7206 +		clientList.at(i)->write (block);
  1.7207 +	}
  1.7208 +}
  1.7209 +
  1.7210 +void MapEditor::readData ()
  1.7211 +{
  1.7212 +	while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) )
  1.7213 +	{
  1.7214 +		if (debug)
  1.7215 +			cout <<"readData  bytesAvail="<<clientSocket->bytesAvailable();
  1.7216 +		quint16 recCounter;
  1.7217 +		quint16 blockSize;
  1.7218 +
  1.7219 +		QDataStream in(clientSocket);
  1.7220 +		in.setVersion(QDataStream::Qt_4_0);
  1.7221 +
  1.7222 +		in >> blockSize;
  1.7223 +		in >> recCounter;
  1.7224 +		
  1.7225 +		QString t;
  1.7226 +		in >>t;
  1.7227 +		if (debug)
  1.7228 +			cout << "  t="<<qPrintable (t)<<endl;
  1.7229 +		parseAtom (t);
  1.7230 +	}
  1.7231 +	return;
  1.7232 +}
  1.7233 +
  1.7234 +void MapEditor::displayNetworkError(QAbstractSocket::SocketError socketError)
  1.7235 +{
  1.7236 +    switch (socketError) {
  1.7237 +    case QAbstractSocket::RemoteHostClosedError:
  1.7238 +        break;
  1.7239 +    case QAbstractSocket::HostNotFoundError:
  1.7240 +        QMessageBox::information(this, vymName +" Network client",
  1.7241 +                                 "The host was not found. Please check the "
  1.7242 +                                    "host name and port settings.");
  1.7243 +        break;
  1.7244 +    case QAbstractSocket::ConnectionRefusedError:
  1.7245 +        QMessageBox::information(this, vymName + " Network client",
  1.7246 +                                 "The connection was refused by the peer. "
  1.7247 +                                    "Make sure the fortune server is running, "
  1.7248 +                                    "and check that the host name and port "
  1.7249 +                                    "settings are correct.");
  1.7250 +        break;
  1.7251 +    default:
  1.7252 +        QMessageBox::information(this, vymName + " Network client",
  1.7253 +                                 QString("The following error occurred: %1.")
  1.7254 +                                 .arg(clientSocket->errorString()));
  1.7255 +    }
  1.7256 +}
  1.7257 +
  1.7258 +void MapEditor::autosave()
  1.7259 +{
  1.7260 +	QDateTime now=QDateTime().currentDateTime();
  1.7261 +	/* FIXME debug
  1.7262 +	cout << "ME::autosave checking "<<qPrintable(filePath)<<"...\n"; 
  1.7263 +	cout << "fsaved: "<<qPrintable (fileChangedTime.toString())<<endl;
  1.7264 +	cout << "  fnow: "<<qPrintable (QFileInfo(filePath).lastModified().toString())<<endl;
  1.7265 +	cout << "  time: "<<qPrintable (now.toString())<<endl;
  1.7266 +	cout << " zipped="<<zipped<<endl;
  1.7267 +	*/
  1.7268 +	// Disable autosave, while we have gone back in history
  1.7269 +	int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
  1.7270 +	if (redosAvail>0) return;
  1.7271 +
  1.7272 +	// Also disable autosave for new map without filename
  1.7273 +	if (filePath.isEmpty()) return;
  1.7274 +
  1.7275 +
  1.7276 +	if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() )
  1.7277 +	{
  1.7278 +		if (QFileInfo(filePath).lastModified()<=fileChangedTime) 
  1.7279 +			mainWindow->fileSave (this);
  1.7280 +		else
  1.7281 +			if (debug)
  1.7282 +				cout <<"  ME::autosave  rejected, file on disk is newer than last save.\n"; 
  1.7283 +
  1.7284 +	}	
  1.7285 +}
  1.7286 +
  1.7287 +void MapEditor::fileChanged()
  1.7288 +{
  1.7289 +	// Check if file on disk has changed meanwhile
  1.7290 +	if (!filePath.isEmpty())
  1.7291 +	{
  1.7292 +		QDateTime tmod=QFileInfo (filePath).lastModified();
  1.7293 +		if (tmod>fileChangedTime)
  1.7294 +		{
  1.7295 +			
  1.7296 +			/* FIXME debug message, sometimes there's a glitch in the metrics...
  1.7297 +			cout << "ME::fileChanged()\n" 
  1.7298 +			     << "  last saved:     "<<qPrintable (fileChangedTime.toString())<<endl
  1.7299 +				 << "  last modififed: "<<qPrintable (tmod.toString())<<endl;
  1.7300 +			*/	 
  1.7301 +			// FIXME switch to current mapeditor and finish lineedits...
  1.7302 +			QMessageBox mb( vymName,
  1.7303 +				tr("The file of the map  on disk has changed:\n\n"  
  1.7304 +				   "   %1\n\nDo you want to reload that map with the new file?").arg(filePath),
  1.7305 +				QMessageBox::Question,
  1.7306 +				QMessageBox::Yes ,
  1.7307 +				QMessageBox::Cancel | QMessageBox::Default,
  1.7308 +				QMessageBox::NoButton );
  1.7309 +
  1.7310 +			mb.setButtonText( QMessageBox::Yes, tr("Reload"));
  1.7311 +			mb.setButtonText( QMessageBox::No, tr("Ignore"));
  1.7312 +			switch( mb.exec() ) 
  1.7313 +			{
  1.7314 +				case QMessageBox::Yes:
  1.7315 +					// Reload map
  1.7316 +					load (filePath,NewMap,fileType);
  1.7317 +		        case QMessageBox::Cancel:
  1.7318 +					fileChangedTime=tmod; // allow autosave to overwrite newer file!
  1.7319 +			}
  1.7320 +		}
  1.7321 +	}	
  1.7322 +
  1.7323 +}
  1.7324 +
  1.7325 +
  1.7326 +/*TODO not needed? void MapEditor::contentsDropEvent(QDropEvent *event) 
  1.7327 +{
  1.7328 +
  1.7329 +		} else if (event->provides("application/x-moz-file-promise-url") && 
  1.7330 +			 event->provides("application/x-moz-nativeimage")) 
  1.7331 +		{
  1.7332 +			// Contains url to the img src in unicode16
  1.7333 +			QByteArray d = event->encodedData("application/x-moz-file-promise-url");
  1.7334 +			QString url = QString((const QChar*)d.data(),d.size()/2);
  1.7335 +			fetchImage(url);
  1.7336 +			event->accept();
  1.7337 +			update=true;
  1.7338 +		} else if (event->provides ("text/uri-list"))
  1.7339 +		{	// Uris provided e.g. by konqueror
  1.7340 +			Q3UriDrag::decode (event,uris);
  1.7341 +		} else if (event->provides ("_NETSCAPE_URL"))
  1.7342 +		{	// Uris provided by Mozilla
  1.7343 +		  QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
  1.7344 +		  uris.append(l[0]);
  1.7345 +		  heading = l[1];
  1.7346 +		} else if (event->provides("text/html")) {
  1.7347 +
  1.7348 +		  // Handels text mime types
  1.7349 +		  // Look like firefox allways handle text as unicode16 (2 bytes per char.)
  1.7350 +		  QByteArray d = event->encodedData("text/html");
  1.7351 +		  QString text;
  1.7352 +		  if (isUnicode16(d)) 
  1.7353 +		    text = QString((const QChar*)d.data(),d.size()/2);
  1.7354 +		  else 
  1.7355 +		    text = QString(d);
  1.7356 +
  1.7357 +		  textEditor->setText(text);
  1.7358 +
  1.7359 +		  event->accept();
  1.7360 +		  update=true;
  1.7361 +		} else if (event->provides("text/plain")) {
  1.7362 +		  QByteArray d = event->encodedData("text/plain");
  1.7363 +		  QString text;
  1.7364 +		  if (isUnicode16(d))
  1.7365 +		    text = QString((const QChar*)d.data(),d.size()/2);
  1.7366 +		  else 
  1.7367 +		    text = QString(d);
  1.7368 +
  1.7369 +		  textEditor->setText(text);
  1.7370 +		  
  1.7371 +		  event->accept();
  1.7372 +		  update= true;
  1.7373 +		}
  1.7374 +
  1.7375 +		*/
  1.7376 +
  1.7377 +
  1.7378 +
  1.7379 +bool isUnicode16(const QByteArray &d) 
  1.7380 +{
  1.7381 +  // TODO: make more precise check for unicode 16.
  1.7382 +  // Guess unicode16 if any of second bytes are zero
  1.7383 +  unsigned int length = max(0,d.size()-2)/2;
  1.7384 +  for (unsigned int i = 0; i<length ; i++)
  1.7385 +    if (d.at(i*2+1)==0) return true;
  1.7386 +  return false;
  1.7387 +}
  1.7388 +      
  1.7389 +void MapEditor::addFloatImageInt (const QPixmap &img) 
  1.7390 +{
  1.7391 +	BranchObj *bo=xelection.getBranch();
  1.7392 +	if (bo)
  1.7393 +  {
  1.7394 +	FloatImageObj *fio=bo->addFloatImage();
  1.7395 +    fio->load(img);
  1.7396 +    fio->setOriginalFilename("No original filename (image added by dropevent)");	
  1.7397 +	QString s=model->getSelectString(bo);
  1.7398 +	saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio  );
  1.7399 +	saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image");
  1.7400 +    model->reposition();
  1.7401 +    scene()->update();
  1.7402 +  }
  1.7403 +}
  1.7404 +
  1.7405 +/*
  1.7406 +
  1.7407 +void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /) 
  1.7408 +{
  1.7409 +  if (!imageBuffer) imageBuffer = new QBuffer();
  1.7410 +  if (!imageBuffer->isOpen()) {
  1.7411 +    imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
  1.7412 +  }
  1.7413 +  imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
  1.7414 +}
  1.7415 +
  1.7416 +
  1.7417 +void MapEditor::imageDataFinished(Q3NetworkOperation *nop) 
  1.7418 +{
  1.7419 +	if (nop->state()==Q3NetworkProtocol::StDone) {
  1.7420 +		QPixmap img(imageBuffer->buffer());
  1.7421 +		addFloatImageInt (img);
  1.7422 +	}
  1.7423 +
  1.7424 +	if (imageBuffer) {
  1.7425 +		imageBuffer->close();
  1.7426 +		if (imageBuffer) {
  1.7427 +			imageBuffer->close();
  1.7428 +			delete imageBuffer;
  1.7429 +			imageBuffer = 0;
  1.7430 +		}
  1.7431 +	}
  1.7432 +}
  1.7433 +
  1.7434 +void MapEditor::fetchImage(const QString &url) 
  1.7435 +{
  1.7436 +  if (urlOperator) {
  1.7437 +    urlOperator->stop();
  1.7438 +    disconnect(urlOperator);
  1.7439 +    delete urlOperator;
  1.7440 +  }
  1.7441 +  
  1.7442 +  urlOperator = new Q3UrlOperator(url);
  1.7443 +  connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)), 
  1.7444 +	  this, SLOT(imageDataFinished(Q3NetworkOperation*)));
  1.7445 +
  1.7446 +  connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
  1.7447 +	  this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));
  1.7448 +  urlOperator->get();
  1.7449 +}
  1.7450 +*/
  1.7451 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tex/vym.changelog	Thu Jul 17 09:27:20 2008 +0000
     2.3 @@ -0,0 +1,1277 @@
     2.4 +-------------------------------------------------------------------
     2.5 +Thu Jul 17 11:25:39 CEST 2008 - uwedr@suse.de
     2.6 +
     2.7 +- Bugfix: smaller image for export to elliminate pixel jitter on right
     2.8 +          side 
     2.9 +
    2.10 +-------------------------------------------------------------------
    2.11 +Fri Jul 11 14:01:31 CEST 2008 - uwedr@suse.de
    2.12 +
    2.13 +- Bugfix: bnc#407600 vym fails with non-ASCI characters in path names 
    2.14 +
    2.15 +-------------------------------------------------------------------
    2.16 +Tue Jun  8 10:34:12 CEST 2008 - uwedr@suse.de
    2.17 +
    2.18 +- Bugfix: bnc#396365 vym cannot load maps saved with Qt 4.4 
    2.19 +
    2.20 +-------------------------------------------------------------------
    2.21 +Wed May 14 17:00:36 CEST 2008 - uwedr@suse.de
    2.22 +
    2.23 +- Version: 1.12.0 RC 2
    2.24 +- Feature: Russian translation
    2.25 +
    2.26 +-------------------------------------------------------------------
    2.27 +Wed May  7 10:30:21 CEST 2008 - uwedr@suse.de
    2.28 +
    2.29 +- Bugfix: bnc#327078
    2.30 +
    2.31 +-------------------------------------------------------------------
    2.32 +Tue May  6 11:45:46 CEST 2008 - uwedr@suse.de
    2.33 +
    2.34 +- Version: 1.12.0 
    2.35 +
    2.36 +-------------------------------------------------------------------
    2.37 +Wed Apr 30 18:13:43 CEST 2008 - uwedr@suse.de
    2.38 +
    2.39 +- Version: 1.11.9
    2.40 +- Bugfix: Some minor code cleanup 
    2.41 +
    2.42 +-------------------------------------------------------------------
    2.43 +Thu Apr 10 22:45:55 CEST 2008 - uwedr@suse.de
    2.44 +
    2.45 +- Version: 1.11.8
    2.46 +- Feature: Copy to new map now also in branch context menu
    2.47 +
    2.48 +-------------------------------------------------------------------
    2.49 +Thu Apr 10 17:11:14 CEST 2008 - uwedr@suse.de
    2.50 +
    2.51 +- Bugfix: New map is not autosaved, if no filename is known yet
    2.52 +
    2.53 +-------------------------------------------------------------------
    2.54 +Tue Apr  8 09:59:11 CEST 2008 - uwedr@suse.de
    2.55 +
    2.56 +- Version: 1.11.7
    2.57 +- Bugfix: Hangup when find function did not find anything 
    2.58 +
    2.59 +-------------------------------------------------------------------
    2.60 +Thu Mar 13 02:06:59 CET 2008 - uwedr@suse.de
    2.61 +
    2.62 +- Bugfix: vym no longer forgets that a map is zipped
    2.63 +
    2.64 +-------------------------------------------------------------------
    2.65 +Sun Mar  9 13:36:20 CET 2008 - uwedr@suse.de
    2.66 +
    2.67 +- Bugfix: Segfault when pressing Home or End on MapCenter 
    2.68 +
    2.69 +-------------------------------------------------------------------
    2.70 +Wed Mar  5 17:54:12 CET 2008 - uwedr@suse.de
    2.71 +
    2.72 +- Bugfix: Broken paths to floatimages 
    2.73 +
    2.74 +-------------------------------------------------------------------
    2.75 +Wed Feb 27 17:07:57 CET 2008 - uwedr@suse.de
    2.76 +
    2.77 +- Bugfix: Fixed some issues with autosave and regulard file checks 
    2.78 +
    2.79 +-------------------------------------------------------------------
    2.80 +Mon Feb 11 12:22:58 CET 2008 - uwedr@suse.de
    2.81 +
    2.82 +- Version: 1.11.6
    2.83 +- Feature: vym now checks regulary if map has changed on disk and 
    2.84 +           asks for reload if necessary
    2.85 +
    2.86 +-------------------------------------------------------------------
    2.87 +Mon Jan 21 22:52:18 CET 2008 - uwedr@suse.de
    2.88 +
    2.89 +- Bugfix: No more warning dialog for overwriting note, when note is
    2.90 +          empty 
    2.91 +
    2.92 +-------------------------------------------------------------------
    2.93 +Tue Jan  8 22:20:29 CET 2008 - uwedr@suse.de
    2.94 +
    2.95 +- Version: 1.11.5
    2.96 +- Feature: Started to implement multiple MapCenters in one map 
    2.97 +
    2.98 +-------------------------------------------------------------------
    2.99 +Mon Jan  7 14:59:56 CET 2008 - uwedr@suse.de
   2.100 +
   2.101 +- Bugfix: vym.pro includes french translation now
   2.102 +
   2.103 +-------------------------------------------------------------------
   2.104 +Mon Dec 17 16:32:48 CET 2007 - uwedr@suse.de
   2.105 +
   2.106 +- Bugfix: bnc#341952 corrupted positions of mainbranches after updating to
   2.107 +          newer vym
   2.108 +-------------------------------------------------------------------
   2.109 +Wed Dec 12 17:12:50 CET 2007 - uwedr@suse.de
   2.110 +
   2.111 +- Bugfix: Overloaded key shortcut for Alt-N (Network and Next window) 
   2.112 +
   2.113 +-------------------------------------------------------------------
   2.114 +Tue Dec  4 11:46:02 CET 2007 - uwedr@suse.de
   2.115 +
   2.116 +- Bugfix: Temporary hide stuff during export 
   2.117 +- Bugfix: Save parts of map
   2.118 +
   2.119 +-------------------------------------------------------------------
   2.120 +Mon Dec  3 20:57:15 CET 2007 - uwedr@suse.de
   2.121 +
   2.122 +- Bugfix: (Maint.) Exchanged pre- and postscript in XHTML Export dialog
   2.123 +
   2.124 +-------------------------------------------------------------------
   2.125 +Fri Nov  9 10:44:59 CET 2007 - uwedr@suse.de
   2.126 +
   2.127 +- Version: 1.11.3
   2.128 +- Feature: Added patches for better windows support by Andrew Ng
   2.129 +
   2.130 +-------------------------------------------------------------------
   2.131 +Tue Nov  6 22:36:38 CET 2007 - uwedr@suse.de
   2.132 +
   2.133 +- Version: 1.11.2
   2.134 +- Feature: Split up helper functions, started to write attributes
   2.135 +
   2.136 +-------------------------------------------------------------------
   2.137 +Tue Nov  6 14:36:38 CET 2007 - uwedr@suse.de
   2.138 +
   2.139 +- Version: 1.11.1
   2.140 +- Bugfix: sort branches has undo/redo now 
   2.141 +
   2.142 +-------------------------------------------------------------------
   2.143 +Fri Oct 26 11:22:20 CEST 2007 - uwedr@suse.de
   2.144 +
   2.145 +- Bugfix: zip state is changed now, when a .xml is save as .vym 
   2.146 +
   2.147 +-------------------------------------------------------------------
   2.148 +Wed Oct 24 14:11:36 CEST 2007 - uwedr@suse.de
   2.149 +
   2.150 +- Feature: Improved ascii export 
   2.151 +- Bugfix: Present flag now does not set down arrows any longer 
   2.152 +
   2.153 +-------------------------------------------------------------------
   2.154 +Tue Oct 23 13:11:52 CEST 2007 - uwedr@suse.de
   2.155 +
   2.156 +- Bugfix: included more <typeinfo> for compiling with new gcc 4.3
   2.157 +
   2.158 +-------------------------------------------------------------------
   2.159 +Fri Oct 19 18:08:27 CEST 2007 - uwedr@suse.de
   2.160 +
   2.161 +- Version: 1.11.0
   2.162 +- Feature: Added patches from Till Maas for better path handling to ease
   2.163 +           integration into various operating systems
   2.164 +- Feature: Added patch from Till Maas to use xdg-open as default browser
   2.165 +- Feature: Added patch from ????? to sort branches lexically
   2.166 +- Feature: Added patches from Juha Ruotsalainen for compiling on win32
   2.167 +
   2.168 +-------------------------------------------------------------------
   2.169 +Tue Oct 16 11:51:43 CEST 2007 - uwedr@suse.de
   2.170 +
   2.171 +- Bugfix: included <typeinfo> for compiling in beta
   2.172 +
   2.173 +-------------------------------------------------------------------
   2.174 +Wed Oct 04 12:43:48 CEST 2007 - uwedr@suse.de
   2.175 +
   2.176 +- Version: 1.10.1
   2.177 +- Bugfix: Missing action for editing URL in context menu
   2.178 +- Bugfix: "Hide in Export" didn't work
   2.179 +
   2.180 +-------------------------------------------------------------------
   2.181 +Mon Sep 04 15:52:22 CEST 2007 - uwedr@suse.de
   2.182 +
   2.183 +- Bugfix: xLinks were not loaded from previously saved maps
   2.184 +- Bugfix: Find manual in /usr/share/doc/packages/vym
   2.185 +- Bugfix: Updated README.txt
   2.186 +
   2.187 +-------------------------------------------------------------------
   2.188 +Mon Aug 20 17:09:28 CEST 2007 - uwedr@suse.de
   2.189 +
   2.190 +- Version: 1.10.0 Release Candidate
   2.191 +- Bugfix: Added missing standard flag (one of the smileys got lost)
   2.192 +- Bugfix: Wrong parsing of relative positions after load of 
   2.193 +          previously zoomed map
   2.194 +
   2.195 +-------------------------------------------------------------------
   2.196 +Tue Jul 31 22:09:01 CEST 2007 - uwedr@suse.de
   2.197 +
   2.198 +- Bugfix: Smother parabel links (Alexander Rettig) 
   2.199 +
   2.200 +-------------------------------------------------------------------
   2.201 +Fri Jul 27 13:31:41 CEST 2007 - uwedr@suse.de
   2.202 +
   2.203 +- Version: 1.9.4
   2.204 +- Feature: Restructured internal handling of XML based maps
   2.205 +- Feature: Switched from QSimpleTextItem to QTextItem for Freemind support
   2.206 +
   2.207 +-------------------------------------------------------------------
   2.208 +Mon Jul 23 14:40:38 CEST 2007 - uwedr
   2.209 +
   2.210 +- Version: 1.9.3
   2.211 +- Feature: Import of Freemind maps
   2.212 +
   2.213 +-------------------------------------------------------------------
   2.214 +Tue Jul 17 13:16:25 CEST 2007 - uwedr
   2.215 +
   2.216 +- Version: 1.9.2
   2.217 +- Bugfix: Workaround for wrong XML generated by QT with in QRichText
   2.218 +          list items 
   2.219 +- Bugfix: No output from <span> tags in ASCII export any longer		  
   2.220 +
   2.221 +-------------------------------------------------------------------
   2.222 +Wed Jul 11 15:49:10 CEST 2007 - uwedr
   2.223 +
   2.224 +- Version: 1.9.1
   2.225 +- Bugfix: Don't ask for directory in XML-based exports like
   2.226 +          KDE-bookmarks
   2.227 +
   2.228 +-------------------------------------------------------------------
   2.229 +Tue Jul  4 10:57:04 CEST 2007 - uwedr
   2.230 +
   2.231 +- Version: 1.9.0
   2.232 +- Bugfix: auto-select/auto-edit new branches
   2.233 +
   2.234 +-------------------------------------------------------------------
   2.235 +Fri Jun 29 11:12:55 CEST 2007 - uwedr
   2.236 +
   2.237 +- Version: 1.8.76
   2.238 +- Feature: Extended fileformat with object IDs to ease export from
   2.239 +           tomboy to vym
   2.240 +- Bugfix: Visibility of BranchProperty window is saved now 
   2.241 +
   2.242 +-------------------------------------------------------------------
   2.243 +Mon Jun 25 14:53:10 CEST 2007 - uwedr
   2.244 +
   2.245 +- Version: 1.8.75
   2.246 +- Feature: Completed german translation
   2.247 +
   2.248 +-------------------------------------------------------------------
   2.249 +Wed Jun 20 13:52:37 CEST 2007 - uwedr
   2.250 +
   2.251 +- Version: 1.8.74
   2.252 +- Feature: Center on selection with "."
   2.253 +- Feature: Most important exports can be scripted now
   2.254 +
   2.255 +-------------------------------------------------------------------
   2.256 +Mon Jun 18 17:08:46 CEST 2007 - uwedr
   2.257 +
   2.258 +- Version: 1.8.73 - entering beta testing 
   2.259 +
   2.260 +-------------------------------------------------------------------
   2.261 +Mon June 18 17:01:16 CEST 2007 - uwe
   2.262 +
   2.263 +- Feature: Creating new map with selection as MapCenter
   2.264 +- Feature: Simple export to CSV spreadsheet
   2.265 +- Feature: Copy from past steps in history to current one
   2.266 +- Bugfix: Undo/Redo dropping images into map
   2.267 +- Bugfix: Undo/Redo of copy/paste steps
   2.268 +- Bugfix: NoteEditor now appears on first click (not 2nd)
   2.269 +- Bugfix: Disable autosave while there are redos available
   2.270 +- Bugfix: After changing link color, that color is applied to all links
   2.271 +          now
   2.272 +- Bugfix: Pasting of FIOs
   2.273 +- Bugfix: No selection of branches while editing heading
   2.274 +- Bugfix: geometry of selection box gets updated while setting scroll or
   2.275 +          hide flag
   2.276 +- Bugfix: Possible segfault when redoing deleteChilds()		  
   2.277 +
   2.278 +-------------------------------------------------------------------
   2.279 +Mon May  7 09:37:29 CEST 2007 - uwedr
   2.280 +
   2.281 +- Version: 1.8.72
   2.282 +- Bugfix: autosave timeout now read from settings file
   2.283 +- Bugfix: Settings for historywindow correclty read now
   2.284 +- Bugfix: Closing property window toggle corresponding button
   2.285 +
   2.286 +-------------------------------------------------------------------
   2.287 +Thu Apr 26 10:34:48 CEST 2007 - uwe
   2.288 +
   2.289 +- Feature: Editing of frame attributes in branch property window
   2.290 +- Feature: autosave
   2.291 +- Feature: number of undo/redo levels can be changed in settings 
   2.292 +- Feature: branch property window settings are saved
   2.293 +- Bugfix: Unscroll all childs has saveState now
   2.294 +- Bugfix: Invisible selection after switching mapeditor
   2.295 +
   2.296 +-------------------------------------------------------------------
   2.297 +Tue Apr 10 15:18:39 CEST 2007 - uwedr
   2.298 +
   2.299 +- Version: 1.8.71
   2.300 +- Feature: Added basic macros and documentation
   2.301 +
   2.302 +-------------------------------------------------------------------
   2.303 +Sat Mar 31 10:59:55 CEST 2007 - uwe
   2.304 +
   2.305 +- Version: 1.8.70
   2.306 +- Feature: Color of selection can be changed now
   2.307 +- Feature: Pen and brush for frames can be set
   2.308 +- Bugfix: For frames the links always were drawn at bottom of heading 
   2.309 +- Bugfix: BranchPropertyWindow updates when selection is changed
   2.310 +
   2.311 +-------------------------------------------------------------------
   2.312 +Mon Mar  6 22:10:26 CET 2007 - uwe
   2.313 +
   2.314 +- Version: 1.8.69
   2.315 +- Feature: Simple Editor for scripts
   2.316 +- Feature: Added syntax highlighting for editor
   2.317 +
   2.318 +-------------------------------------------------------------------
   2.319 +Tue Feb 20 22:16:09 CET 2007 - uwe
   2.320 +
   2.321 +- Version: 1.8.68
   2.322 +- Bugfix: Crash when trying to temporary link to floatimage 
   2.323 +
   2.324 +-------------------------------------------------------------------
   2.325 +Mon Feb 17 16:32:53 CET 2007 - uwedr
   2.326 +
   2.327 +- Version: 1.8.67
   2.328 +- Feature: Unscroll all now only affects selected subtree 
   2.329 +- Bugfix: Drawing error when temporary linking subtrees
   2.330 +- Bugfix: Import of KDE Bookmarks
   2.331 +- Bugfix: Export to KDE Bookmarks
   2.332 +- Bugfix: Export to XHTML
   2.333 +- Bugfix: Drag and Drop of URLs now only creates one branch
   2.334 +
   2.335 +-------------------------------------------------------------------
   2.336 +Wed Feb 07 17:27:31 CET 2007 - uwedr
   2.337 +
   2.338 +- Version: 1.8.66
   2.339 +- Feature: Using a new class to select objects
   2.340 +- Bugfix: Remember last directory before  ASCII/LaTeX export
   2.341 +- Bugfix: Editing in NoteEditor now updates actions (save) again
   2.342 +- Bugfix: Deleting last branch automatically unscrolls parent now
   2.343 +- Bugfix: Scroll/Unscroll has undo/redo now
   2.344 +
   2.345 +-------------------------------------------------------------------
   2.346 +Fri Jan 19 22:53:27 CET 2007 - uwe
   2.347 +
   2.348 +- Version: 1.8.65
   2.349 +- Feature: New Frame format
   2.350 +- Feature: New vym file format to support new frames
   2.351 +- Bugfix: xml-parsing code simplified
   2.352 +- Bugfix: Fixed pretty annoying repositioning of view after editing a
   2.353 +          heading. (don't call show() before positioning in heading...)
   2.354 +- Bugfix: Wrong Cursors after pressing CTRL and inserting/relinking
   2.355 +- Bugfix: Save PNG images with quality 100 to workaround image problems
   2.356 +- Bugfix: Remember last directory before XML export
   2.357 +
   2.358 +-------------------------------------------------------------------
   2.359 +Thu Jan 11 16:05:49 CET 2007 - uwedr
   2.360 +
   2.361 +- Version: 1.8.65
   2.362 +- Feature: Properties dialog for branches instead of context menu entries
   2.363 +
   2.364 +-------------------------------------------------------------------
   2.365 +Wed Jan 10 19:48:32 CET 2007 - uwe
   2.366 +
   2.367 +- Version: 1.8.64
   2.368 +- Bugfix: move branch up/down calls scene()->update() now => much faster
   2.369 +- Bugfix: Relinking of floatimages undo/redo
   2.370 +
   2.371 +-------------------------------------------------------------------
   2.372 +Tue Jan  2 19:30:50 CET 2007 - uwedr
   2.373 +
   2.374 +- Version: 1.8.64
   2.375 +- Bugfix: printing scales correctly again
   2.376 +- Bugfix: Drag & Drop (basically) works again
   2.377 +- Bugfix: Crash caused by BranchObj::getLastSelected
   2.378 +- Bugfix: Signal handling by changes in TextEditor: Much faster now
   2.379 +
   2.380 +-------------------------------------------------------------------
   2.381 +Thu Dec 21 14:13:13 CET 2006 - uwedr
   2.382 +
   2.383 +- Version: 1.8.63
   2.384 +- Bugfix: printing is working again
   2.385 +
   2.386 +-------------------------------------------------------------------
   2.387 +Mon Dec 11 12:31:46 CET 2006 - uwedr
   2.388 +
   2.389 +- Version: 1.8.61
   2.390 +- Bugfix: move up/down to next subtree is working again
   2.391 +
   2.392 +-------------------------------------------------------------------
   2.393 +Mon Dec  6 22:48:07 CET 2006 - uwe
   2.394 +
   2.395 +- Version: 1.8.61
   2.396 +- Bugfix: Flags are working again
   2.397 +- Bugfix: Floatimages have correct select box again
   2.398 +
   2.399 +-------------------------------------------------------------------
   2.400 +Wed Nov 29 13:48:35 CET 2006 - uwedr
   2.401 +
   2.402 +- Version: 1.8.60
   2.403 +- Bugfix: Image format is saved with floatimage
   2.404 +- Feature: Only one history window for all editors. State is saved.
   2.405 +- Feature: Canvas ported to QT 4.2 GraphicsView
   2.406 +- Feature: Options to use AntiaAliasing and smooth pixmap
   2.407 +           transformations
   2.408 +- Feature: Thick links use polygons now, less objects in scene  
   2.409 +
   2.410 +-------------------------------------------------------------------
   2.411 +Thu Nov 16 14:41:44 CET 2006 - uwedr
   2.412 +
   2.413 +- Bugfix: New recent file handling, fixes crash on Mac OS X 
   2.414 +
   2.415 +-------------------------------------------------------------------
   2.416 +Tue Nov 14 10:00:12 CET 2006 - uwedr
   2.417 +
   2.418 +- Feature: Modifier Modes now change cursor when CTRL is pressed 
   2.419 +
   2.420 +-------------------------------------------------------------------
   2.421 +Fri Nov 10 10:28:55 CEST 2006 - uwe
   2.422 +
   2.423 +- Feature: vym opens spanish documentation, if locale is es*
   2.424 +- Bugfix: Position of floatimages is saved again 
   2.425 +- Bugfix: Position of floatimages survives adjustCanvasSize()
   2.426 +- Bugfix: Adding branch to scrolled branch unscroll the former 
   2.427 +- Bugfix: More undo commands (removed saveStateComplete)
   2.428 +
   2.429 +-------------------------------------------------------------------
   2.430 +Tue Oct 24 17:24:22 CEST 2006 - uwedr
   2.431 +
   2.432 +- Version: 1.8.58
   2.433 +- Feature: More undo commands (and fixes there)
   2.434 +
   2.435 +-------------------------------------------------------------------
   2.436 +Mon Oct 16 14:41:03 CEST 2006 - uwedr
   2.437 +
   2.438 +- Feature: Code simplification
   2.439 +
   2.440 +-------------------------------------------------------------------
   2.441 +Thu Sep 14 12:01:28 CEST 2006 - uwedr
   2.442 +
   2.443 +- Version: 1.8.57
   2.444 +- Feature: Note Editor completly based on QT4 now.
   2.445 +
   2.446 +-------------------------------------------------------------------
   2.447 +Wed Sep  13 16:43:09 CEST 2006 - uwedr
   2.448 +
   2.449 +- Version: 1.8.56
   2.450 +- Feature: New History window, All designer elements ported to QT4
   2.451 +- Bugfix: No more hopping around of floats, when canvas is resized 
   2.452 +          (by using relative positions for mainbranches. This might 
   2.453 +		  confuse parsing 1.8.56 documents with vym <= 1.8.1
   2.454 +
   2.455 +-------------------------------------------------------------------
   2.456 +Wed Sep  6 09:48:12 CEST 2006 - uwedr
   2.457 +
   2.458 +- Bugfix: Mac - XSL stylesheets are found 
   2.459 +- Bugfix: Mac - fonts are scaling
   2.460 +- Bugfix: Mac - hand cursor is shown correctly
   2.461 +
   2.462 +-------------------------------------------------------------------
   2.463 +Tue Sep  5 15:38:20 CEST 2006 - uwedr
   2.464 +
   2.465 +- Version: 1.8.55
   2.466 +- Bugfix: Undo/Redo moving floatimages
   2.467 +- Bugfix: Shortcuts for scrolling branches/removing branch
   2.468 +- Bugfix: update-bookmarks script is not only executed, but
   2.469 +          also found now...
   2.470 +- Feature: Findwindow ported to QT4
   2.471 +
   2.472 +-------------------------------------------------------------------
   2.473 +Tue Sep  5 09:55:55 CEST 2006 - uwedr
   2.474 +
   2.475 +- Bugfix: More undo/redo (move of floatimages, relinking of branches) 
   2.476 +
   2.477 +-------------------------------------------------------------------
   2.478 +Thu Aug 31 13:54:30 CEST 2006 - uwedr
   2.479 +
   2.480 +- Bugfix: More undo/redo commands
   2.481 +- Bugfix: Actions updated after moving a branch now
   2.482 +- Bugfix: vym refuses to start if vymTmpDir can't be created
   2.483 +
   2.484 +-------------------------------------------------------------------
   2.485 +Wed Aug 30 14:14:56 CEST 2006 - uwedr
   2.486 +
   2.487 +- Version: 1.8.54
   2.488 +- Bugfix: Editing headings now works both on Mac and Linux
   2.489 +
   2.490 +-------------------------------------------------------------------
   2.491 +Mon Aug 28 13:15:35 CEST 2006 - uwe
   2.492 +
   2.493 +- Version: 1.8.53
   2.494 +- Feature: Opening of all URLs in a subtree
   2.495 +- Feature: Opening of all vymLinks in a subtree
   2.496 +
   2.497 +-------------------------------------------------------------------
   2.498 +Tue Aug 15 13:39:42 CEST 2006 - uwedr
   2.499 +
   2.500 +- Version: 1.8.52
   2.501 +- Feature: Changed format of configuration file a bit (new file anyway
   2.502 +  with introduction of QT4)
   2.503 +- Feature: Toolbar Layout is saved now
   2.504 +
   2.505 +-------------------------------------------------------------------
   2.506 +Thu Jul 27 14:28:54 CEST 2006 - uwedr
   2.507 +
   2.508 +- Bugfix: Floatimages internally are saved as png, preserving the alpha 
   2.509 +          channel
   2.510 +
   2.511 +-------------------------------------------------------------------
   2.512 +Thu Jul 13 10:39:26 CEST 2006 - uwedr
   2.513 +
   2.514 +- Bugfix: Fixed broken check for non-existent OO-export configuration 
   2.515 +
   2.516 +-------------------------------------------------------------------
   2.517 +Tue Jul  4 12:32:28 CEST 2006 - uwedr
   2.518 +
   2.519 +- Feature: Moved floats in XML Export, e.g. XHTML  shows floatimages at
   2.520 +  beginning of export now
   2.521 +
   2.522 +-------------------------------------------------------------------
   2.523 +Mon July 10 16:53:29 CEST 2006 - uwedr
   2.524 +
   2.525 +- Version: 1.8.50
   2.526 +- Feature: Beginning of QT4 port
   2.527 +
   2.528 +-------------------------------------------------------------------
   2.529 +Thu June 1 16:53:29 CEST 2006 - uwedr
   2.530 +
   2.531 +- Version: 1.7.18
   2.532 +- Feature: Opening of tabs in Firefox or Mozilla
   2.533 +- Feature: Documentation is up to date now
   2.534 +- Bugfix: No more duplicate xLinks
   2.535 +- Bugfix: Saving original filename of floatimages finally works
   2.536 +- Bugfix: Positioning of floatimages while adjusting canvas size (also
   2.537 +          optimized code a bit)
   2.538 +
   2.539 +-------------------------------------------------------------------
   2.540 +Tue May  9 10:05:52 CEST 2006 - uwedr
   2.541 +
   2.542 +- Version: 1.7.17
   2.543 +- Bugfix: Right click e.g. on URL Flag opened URL _and_ context menu 
   2.544 +- Bugfix: Deleting selection works also if Delkey is disabled.
   2.545 +
   2.546 +-------------------------------------------------------------------
   2.547 +Mon May  8 10:29:25 CEST 2006 - uwedr
   2.548 +
   2.549 +- Bugfix: Exclusive flags did not work properly. 
   2.550 +- Bugfix: Wrong icon in texteditor for text underline
   2.551 +- Bugfix: Changed screenshots in docu to represent new look
   2.552 +- Bugfix: Fixed z-plane of floatimage. Images did hide flags.
   2.553 +
   2.554 +-------------------------------------------------------------------
   2.555 +Mon Apr 24 11:59:22 CEST 2006 - uwedr
   2.556 +
   2.557 +- Bugfix: wrong paths in XHTML export (bnc#168033), caused by wrong
   2.558 +          vymBaseDir
   2.559 +
   2.560 +-------------------------------------------------------------------
   2.561 +Mon Apr 10 13:23:02 CEST 2006 - uwedr
   2.562 +
   2.563 +- Feature: More icons 
   2.564 +
   2.565 +-------------------------------------------------------------------
   2.566 +Fri Mar 31 14:18:38 CEST 2006 - uwe
   2.567 +
   2.568 +- Feature: New environment variable VYMHOME 
   2.569 +
   2.570 +-------------------------------------------------------------------
   2.571 +Thu Mar 30 11:00:21 CEST 2006 - uwedr
   2.572 +
   2.573 +- Version: 1.7.15
   2.574 +- Feature: New icons. Icons and flags are not longer linked statically.
   2.575 +
   2.576 +-------------------------------------------------------------------
   2.577 +Tue Mar 28 21:54:31 CEST 2006 - uwe
   2.578 +
   2.579 +- Version: 1.7.13
   2.580 +- Feature: Konqueror can open URLs in new tabs now.
   2.581 +
   2.582 +-------------------------------------------------------------------
   2.583 +Thu Mar 23 13:26:46 CET 2006 - uwedr
   2.584 +
   2.585 +- Version: 1.7.12
   2.586 +- Bugfix: Problem with vymlinks pointing to higher directories (bnc#159770)
   2.587 +- Bugfix: All exports support hiding of objects now
   2.588 +- Bugfix: exportDir in XHTML export is correctly saved in map and
   2.589 +  defaults to current directory
   2.590 +
   2.591 +-------------------------------------------------------------------
   2.592 +Wed Mar 15 11:43:02 CET 2006 - uwedr
   2.593 +
   2.594 +- Version: 1.7.11
   2.595 +- Bugfix: Workaround QT problem, where QT writes invalid XML code by not
   2.596 +  escaping & in fontnames
   2.597 +- Feature: Hide Export Flag lets you hide objects in exports
   2.598 +- Feature: Floatimages now are basically ornamented objects. They could
   2.599 +  have e.g. an URL later
   2.600 +- Feature: On error the XML Parser shows the line which is causing the
   2.601 +           error
   2.602 +
   2.603 +-------------------------------------------------------------------
   2.604 +Wed Mar  8 13:58:40 CET 2006 - uwedr
   2.605 +
   2.606 +- Bugfix: Images preview in filedialog works again. Seemed to be a QT
   2.607 +  issue when multiple fileselections were allowed. 
   2.608 +
   2.609 +-------------------------------------------------------------------
   2.610 +Mon Mar  6 15:02:57 CET 2006 - uwedr
   2.611 +
   2.612 +- Feature: Added export to Taskjuggler. xslt by Matt. 
   2.613 +
   2.614 +-------------------------------------------------------------------
   2.615 +Wed Mar  1 22:29:47 CET 2006 - uwe
   2.616 +
   2.617 +- Bugfix: Canvas Size corrected when flag is toggled 
   2.618 +
   2.619 +-------------------------------------------------------------------
   2.620 +Wed Mar  1 15:38:11 CET 2006 - uwedr
   2.621 +
   2.622 +- Version: 1.7.10
   2.623 +- Feature: Include Images Horizontalls
   2.624 +
   2.625 +-------------------------------------------------------------------
   2.626 +Tue Feb 21 17:17:48 CET 2006 - uwedr
   2.627 +
   2.628 +- Feature: rudimentary import mmaps 
   2.629 +
   2.630 +-------------------------------------------------------------------
   2.631 +Tue Feb 14 21:10:26 CET 2006 - uwe
   2.632 +
   2.633 +- Version 1.7.9
   2.634 +- Feature: Import KDE bookmarks
   2.635 +- Feature: Own class xsltproc for doing xml transformations
   2.636 +
   2.637 +-------------------------------------------------------------------
   2.638 +Tue Jan 31 16:54:52 CET 2006 - uwedr
   2.639 +
   2.640 +- Version 1.7.8
   2.641 +- Bugfix: Hide Include Images Horizontally (not implemented yet) 
   2.642 +- Bugfix: Include Images Vertically was not read from saved file
   2.643 +
   2.644 +-------------------------------------------------------------------
   2.645 +Tue Jan 25 16:07:53 CET 2006 - uwedr
   2.646 +
   2.647 +- Version 1.7.7
   2.648 +- Feature: Export to Open Office 2.x (Open Document) basically works 
   2.649 +- Feature: Export to XHTML uses smaller icon for URLs now
   2.650 +
   2.651 +-------------------------------------------------------------------
   2.652 +Wed Jan 18 13:29:52 CET 2006 - uwedr
   2.653 +
   2.654 +- Feature: Multiple File selection while loading maps and images
   2.655 +
   2.656 +-------------------------------------------------------------------
   2.657 +Tue Jan  3 12:20:08 CET 2006 - uwe
   2.658 +
   2.659 +- Feature: Small optimization in zip/unzip functions
   2.660 +
   2.661 +-------------------------------------------------------------------
   2.662 +Mon Jan  2 21:03:05 CET 2006 - uwe
   2.663 +
   2.664 +- Feature: FATE support for URLs 
   2.665 +
   2.666 +-------------------------------------------------------------------
   2.667 +Wed Dec 28 12:09:59 CET 2005 - uwe
   2.668 +
   2.669 +- Version 1.7.6
   2.670 +- Feature: Added idAttr to BranchObj::saveToDir 
   2.671 +- Bugfix: FloatObjects now use hideLinkIfUnselected, no more drawing
   2.672 +  errors, if FO is selected (undefined link)
   2.673 +- Bugfix: FloatImages don't get lost during save after they have been
   2.674 +  relinked to new parent  
   2.675 +- Bugfix: Editing heading of mapcenter now also corrects position  
   2.676 +
   2.677 +-------------------------------------------------------------------
   2.678 +Mon Oct 10 13:18:29 CEST 2005 - uwedr
   2.679 +
   2.680 +- Bugfix: Copy/Paste was currently not possible for images. Now
   2.681 +  completly rewrote mechanism. Instead of invisible map now XML import
   2.682 +  is used (Multiple clipboards should be not difficult now) 
   2.683 +
   2.684 +-------------------------------------------------------------------
   2.685 +Mon Oct  3 10:33:09 CEST 2005 - uwe
   2.686 +
   2.687 +- Bugfix: Added small fix from Khaled Ahmed needed for display of 
   2.688 +  arabic languages 
   2.689 +
   2.690 +-------------------------------------------------------------------
   2.691 +Mon Sep 12 21:39:38 CEST 2005 - uwedr
   2.692 +
   2.693 +- Version 1.7.5
   2.694 +- Feature: Currently 15 levels of undo (GUI to set value still missing)
   2.695 +- Feature: Experimental LaTeX Export (without headers and opions so far)
   2.696 +
   2.697 +-------------------------------------------------------------------
   2.698 +Sun Sep  5 10:26:15 CEST 2005 - uwedr
   2.699 +
   2.700 +- Version 1.7.4
   2.701 +- Feature: Link of a branch can be hidden, if object is not selected
   2.702 +- Bugfix: Zoomed map no longer "jumps around" when branch is selected
   2.703 +  or moved.
   2.704 +- Bugfix: TextEditor now has grey background again, if it is empty
   2.705 +- Bugfix: BranchObj no longer need to connect to TextEditor, BranchObj
   2.706 +  is no longer a QOBJECT
   2.707 +
   2.708 +-------------------------------------------------------------------
   2.709 +Thu Sep  1 12:26:24 CEST 2005 - uwedr
   2.710 +
   2.711 +- Bugfix: Some minor changes so that translations use arguments now
   2.712 +  instead of several calls to tr()
   2.713 +
   2.714 +-------------------------------------------------------------------
   2.715 +Tue Aug 30 13:38:31 CEST 2005 - uwedr
   2.716 +
   2.717 +- Bugfix: Fixed pasting vymlinks: Pasting a branch to a target in
   2.718 +  another map caused vym to go into an endless loop, if the vymlink of the
   2.719 +  branch pointed to the new map.
   2.720 +- Bugfix: Invisible floatimages (which have a scrolled parent) no longer
   2.721 +  can be selected  
   2.722 +
   2.723 +-------------------------------------------------------------------
   2.724 +Fri Aug 19 09:12:49 CEST 2005 - uwedr
   2.725 +
   2.726 +- Feature: added debian subdirectory created by Steffen Joeris
   2.727 +- Feature: added license to new aboutwindow
   2.728 +
   2.729 +-------------------------------------------------------------------
   2.730 +Tue Aug 16 19:22:56 CEST 2005 - jhilmer
   2.731 +
   2.732 +- Bugfix: Fixed link handling in aboutdialog.
   2.733 +
   2.734 +-------------------------------------------------------------------
   2.735 +Tue Aug 16 12:25:09 CEST 2005 - uwedr
   2.736 +
   2.737 +- Feature: Added keyboard shortcut to reset zoom factor
   2.738 +- Bugfix: Added "..." to menu entries leading to another dialog
   2.739 +- Bugfix: The setting option "Delete Key" is working again
   2.740 +- Bugfix: A branch moved from left side to right had wrong orienation
   2.741 +
   2.742 +-------------------------------------------------------------------
   2.743 +Tue Aug  2 09:59:24 CEST 2005 - uwedr
   2.744 +
   2.745 +-  Bugfix: Heading sizes now correct after moving e.g. mainbranch to 
   2.746 +   a branch
   2.747 +
   2.748 +-------------------------------------------------------------------
   2.749 +Mon Aug  1 22:40:29 CEST 2005 - jhilmer
   2.750 +
   2.751 +- Bugfix: Problems with closing of note editor when text was modified.
   2.752 +- Feature: Added subscript and superscript to note editor
   2.753 +	
   2.754 +-------------------------------------------------------------------
   2.755 +Thu Jul 28 11:57:38 CEST 2005 
   2.756 +
   2.757 +- Version 1.7.3
   2.758 +- Bugfix: Frames didn't become invisible if scrolled
   2.759 +
   2.760 +-------------------------------------------------------------------
   2.761 +Thu Jul 28 11:57:38 CEST 2005 
   2.762 +
   2.763 +- Version 1.7.2
   2.764 +- Bugfix: if selection changed before undo, undo worked on wrong
   2.765 +  branch
   2.766 +- included math.h again to enable compiling with gcc4  
   2.767 +
   2.768 +-------------------------------------------------------------------
   2.769 +Mi Jul 27 17:27:14 CEST 2005
   2.770 +
   2.771 +- Bugfix: if selection changed before undo, undo worked on wrong branch
   2.772 +
   2.773 +-------------------------------------------------------------------
   2.774 +Mon Jul 25 22:22:21 CEST 2005
   2.775 +
   2.776 +- Bugfix: changed MapEditor::undo and ::saveState to also save selection
   2.777 +
   2.778 +-------------------------------------------------------------------
   2.779 +Di Jul 19 16:42:31 CEST 2005
   2.780 +
   2.781 +- Version: 1.7.1
   2.782 +- Feature: Drag and Drop also for .vym and files (Jakob Hilmer)
   2.783 +- Feature: More speedup on moving/relinking branches
   2.784 +
   2.785 +-------------------------------------------------------------------
   2.786 +
   2.787 +Mi Jul 13 11:44:10 CEST 2005 
   2.788 +
   2.789 +- Drag and Drop also for URLs
   2.790 +
   2.791 +-------------------------------------------------------------------
   2.792 +Di Jul 12 20:56:09 CEST 2005
   2.793 +
   2.794 +- Version: 1.7.0
   2.795 +
   2.796 +-------------------------------------------------------------------
   2.797 +Mon Jul  4 21:13:42 CEST 2005 
   2.798 +
   2.799 +- Version: 1.6.9
   2.800 +- Bugfix: TextEditor doesn't get minimized in KDE any longer (KDE-bug?)
   2.801 +
   2.802 +-------------------------------------------------------------------
   2.803 +Tue Jun 14 11:43:44 CEST 2005
   2.804 +
   2.805 +- Feature: printer name is saved in vymrc now
   2.806 +- Feature: added image drag/drop (by Jakob Hilmer)
   2.807 +- Bugfix: Importing map into new map now has correct (empty) filename 
   2.808 +
   2.809 +-------------------------------------------------------------------
   2.810 +2005-06-07 
   2.811 +
   2.812 +- Version: 1.6.8
   2.813 +- Feature: Dramatic speedup in some operations 
   2.814 +				(e.g. move branch up/down) due to extended 
   2.815 +				undo engine
   2.816 +-------------------------------------------------------------------
   2.817 + 2005-05-27 
   2.818 + 
   2.819 +- Version: 1.6.7	
   2.820 +- Feature:Changed default pdf-reader for Mac OSX 
   2.821 +- Bugfix: xLinks stopped working in 1.6.6
   2.822 +- Bugfix: drawing error when using modModeCopy
   2.823 +- Bugfix: replaced lrint by qRound for BSD port
   2.824 +		
   2.825 +-----------------------------------------------------------
   2.826 + 2005-05-23
   2.827 +
   2.828 +- Version 1.6.6	
   2.829 +- Feature: Exclusive standard flags		
   2.830 +
   2.831 +-----------------------------------------------------------
   2.832 +2005-05-19 
   2.833 +
   2.834 +- Version: 1.6.5
   2.835 +- Feature: removing a branch and keeping its childs
   2.836 +- Feature: removing childs of a branch
   2.837 +- Feature: insert branch and make selection its child
   2.838 +- Feature: restructured branch context menu	
   2.839 +           in a basic version (straight line)
   2.840 +- Feature: New shortcuts  for use on Mac OS X
   2.841 +- Feature: Importing directories generates vymlinks now 
   2.842 +- Bugfix: Changing linkstyle now automatically redraws all
   2.843 +	      links again
   2.844 +- Bugfix: Paste icon is disabled if clipboard is empty 
   2.845 +		
   2.846 +-----------------------------------------------------------
   2.847 +2005-04-15
   2.848 +
   2.849 +- Version: 1.6.4	
   2.850 +- Feature: xLinks (connection between 2 branches) works
   2.851 +           in a basic version (straight line)	
   2.852 +
   2.853 +-----------------------------------------------------------
   2.854 +2005-03-30
   2.855 +
   2.856 +- Version: 1.6.3
   2.857 +- Bugfix: Saving of selection to a vym part (.vyp)
   2.858 +- Bugfix: Closing the noteeditor by closing its window now
   2.859 +          also toggles the responding toolbar button. &
   2.860 +
   2.861 +-----------------------------------------------------------
   2.862 +2005-03-24
   2.863 +
   2.864 +- Version: 1.6.2	
   2.865 +- Feature: Introduced Modifier modes: color, link, copy 
   2.866 +- Feature: Linking branches is basically possible, though it can't be
   2.867 +           edited/saved yet 
   2.868 +
   2.869 +-----------------------------------------------------------
   2.870 +2005-01-30
   2.871 +
   2.872 +- Version: 1.6.1	 
   2.873 +- Feature: Optimized moving of branches: much faster especially 
   2.874 +           with huge subtrees					
   2.875 +- Bugfix: Segfault when loading vym part 
   2.876 +- Bugfix: ugly unitialized lines, when temporary drawn link 
   2.877 +          was moved from a temporary parent back to canvas		  
   2.878 +
   2.879 +-----------------------------------------------------------
   2.880 +2004-12-14  
   2.881 +
   2.882 +- Version: 1.6.0 	 
   2.883 +- Feature: Added saving of xhtml settings in map 
   2.884 +
   2.885 +-----------------------------------------------------------
   2.886 +2004-12-13  
   2.887 +
   2.888 +- Version: 1.5.2 	 
   2.889 +- Feature: Added Import of maps with two modes: 
   2.890 +           add/replace						
   2.891 +- Feature: Added export of part of maps		 
   2.892 +- Feature: Added joining of paragraphs in text editor		 
   2.893 +- Feature: Optimized undo: Only relevant parts are saved, which
   2.894 +           dramatically improves e.g. moving branches up/down in most maps  
   2.895 +- Bugfix: QTextEdit generates invalid XML code, which could lead to a
   2.896 +          parse error, if font name contains a \&  (bnc#62283)   
   2.897 +- Bugfix: Wrong order of mainbranches in Export	   
   2.898 +- Bugfix: zip archive was not deleted before save, which could lead to
   2.899 +  much bigger files, e.g.  when working on older \vym maps or deleted
   2.900 +  images   
   2.901 +- Bugfix: Printing in Texteditor         
   2.902 +- Bugfix: Wrong URLs in xhtml output				  
   2.903 +- Bugfix: Segfault fixed at Cursor left/right in empty map  
   2.904 +
   2.905 +-----------------------------------------------------------
   2.906 +2004-10-01 
   2.907 +
   2.908 +- Version: 1.5.1
   2.909 +- Feature: More options in xhtml export: external scripts 	 
   2.910 +
   2.911 +-----------------------------------------------------------
   2.912 +2004-09-26 
   2.913 +
   2.914 +- Version: 1.5.0 	 
   2.915 +- Public release of all changes since 1.4.1      	 
   2.916 +- Feature: New function to replace paragraphs in note editor
   2.917 +   	by linebreaks, this makes pasted text much nicer 
   2.918 +- Feature: New option to toggle exporting of of floatimages 
   2.919 +- Feature: z-plane of floatimages can be set (manually only) 
   2.920 +- Bugfix: Wrong ordering of branches, if mainbranch is exactly left of
   2.921 +  center 
   2.922 +
   2.923 +-----------------------------------------------------------
   2.924 +2004-09-24 
   2.925 +
   2.926 +- Version: 1.4.7 	 
   2.927 +- Feature: New Export to XHTML (by Thomas Schraitle)	 
   2.928 +- Bugfix: vymLink	
   2.929 +- Bugfix: spaces and dots in filenames	 
   2.930 +- Bugfix: Error message if xsltproc is not installed 
   2.931 +
   2.932 +-----------------------------------------------------------
   2.933 +2004-09-15	
   2.934 +
   2.935 +- Version: 1.4.6 	 
   2.936 +- Feature: New file format: notes are saved as part of the .xml file
   2.937 +- Feature: Note Editor supports Rich Text now.
   2.938 +- Feature: Parser now also nows {\tt standardflag} (all letters lowercase)
   2.939 +
   2.940 +-----------------------------------------------------------
   2.941 +2004-08-23	
   2.942 +
   2.943 +- Version: 1.4.5 	 
   2.944 +- Feature: Correct handling of font size in Heading			 
   2.945 +
   2.946 +-----------------------------------------------------------
   2.947 +2004-07-29	
   2.948 +
   2.949 +- Version: 1.4.4 	 
   2.950 +- Selecting with cursor now works between subtrees	 
   2.951 +- Bugfix: vymLink was set to temporary dir in 1.4.3	 
   2.952 +
   2.953 +-----------------------------------------------------------
   2.954 +2004-07-19  
   2.955 +
   2.956 +- Version: 1.4.3 	 
   2.957 +- Optimisation: Reduced canvas objects by only creating objects for used
   2.958 +  flags		 
   2.959 +- Better visualization of moving branch above/below target		
   2.960 +- Find Window informs with dialog, if the search failed
   2.961 +- System Flags are clickable now		
   2.962 +- Reworked CSS and XST stylsheets (comments, indent, browser
   2.963 +  compatibility)						
   2.964 +- vymLinks are shown in statusbar		
   2.965 +- current directory is save			
   2.966 +- Rewritten load/save to improve multimap handling and unzipped files
   2.967 +- Bugfix: vymLinks don't get deleted when Cancel is pressed						
   2.968 +- Bugfix: Fixed a bunch of bugs in XSL for HTML export             
   2.969 +- Bugfix: More toolbar buttons disabled, if action not possible             
   2.970 +- Bugfix: Renaming .vymfile now works		
   2.971 +- Bugfix: mapChanged set when toggling flags		
   2.972 +- Bugfix: CTRL-N was used twice		
   2.973 +- Bugfix: Del didn't work on floatimage 
   2.974 +
   2.975 +-----------------------------------------------------------
   2.976 +- Version: 1.4.2 	 
   2.977 +- Bugfix: Float image could not be deleted  
   2.978 +
   2.979 +-----------------------------------------------------------
   2.980 +2004-05-25  
   2.981 +
   2.982 +- Version: 1.4.1 	 
   2.983 +- Bugfix: Color of branch not saved	 
   2.984 +- Bugfix: wrong path at HTML export	             
   2.985 +- Bugfix: map is not save with special characters in path   
   2.986 +
   2.987 +-----------------------------------------------------------
   2.988 +2004-05-17 
   2.989 +
   2.990 +- Version: 1.4.0 	 
   2.991 +- Ask for confirmation before opening 
   2.992 +				a map in multiple editors			 
   2.993 +- Save state of note editor (visible/minimized) 
   2.994 +- Export to HTML						 
   2.995 +- Author and Comment is saved in map	 
   2.996 +- Stats are shown in Edit MapInfo		 
   2.997 +- Changes for OS X port (QCursor, QContextMenuEvent)	 
   2.998 +- Bugfix: Fonts from note editor are save now			
   2.999 +- Bugfix: invisible image when parent is scrolled		
  2.1000 +- Bugfix: Segfault pressing "enter" for floatimage	
  2.1001 +- Bugfix: Images can't be outside of exported area
  2.1002 +				anymore. 
  2.1003 +- Bugfix: Filenames with blanks		 
  2.1004 +- Bugfix: Old maplink is shown when editing maplink 
  2.1005 +- Bugfix: always show cursor while editing heading  
  2.1006 +
  2.1007 +-----------------------------------------------------------
  2.1008 +2004-04-16 
  2.1009 +
  2.1010 +- Version: 1.3.5 	 
  2.1011 +- Export map to dir					 
  2.1012 +- Export to any of QTs image formats	 
  2.1013 +- Also right side of selection is always visible now. 
  2.101