mapeditor.cpp
author insilmaril
Wed, 18 May 2005 07:39:51 +0000
changeset 100 f79a53ee8cf6
parent 98 58adc2d2ed08
child 102 dba9303a1a5c
permissions -rw-r--r--
fixed some bugs in xlinks, more remove/insert functions
     1 #include "mapeditor.h"
     2 
     3 #include <qstatusbar.h>
     4 #include <qmessagebox.h>
     5 #include <qapplication.h>
     6 #include <qpainter.h>
     7 #include <qpopupmenu.h>
     8 #include <qprinter.h>
     9 #include <qpaintdevicemetrics.h>
    10 #include <qfile.h>
    11 #include <qfiledialog.h>
    12 #include <qdir.h>
    13 #include <qcolor.h>
    14 #include <qcolordialog.h>
    15 #include <qbitmap.h>
    16 #include <qprocess.h>
    17 #include <qinputdialog.h>
    18 
    19 #include <iostream>
    20 #include <cstdlib>
    21 #include <typeinfo>
    22 
    23 #include "version.h"
    24 
    25 #include "xml.h"
    26 #include "texteditor.h"
    27 #include "linkablemapobj.h"
    28 #include "exports.h"
    29 #include "misc.h"
    30 #include "mainwindow.h"
    31 #include "extrainfodialog.h"
    32 #include "editxlinkdialog.h"
    33 #include "settings.h"
    34 
    35 #include "icons/flag-note.xpm"
    36 #include "icons/flag-url.xpm"
    37 #include "icons/flag-vymlink.xpm"	
    38 #include "icons/flag-scrolled-right.xpm"
    39 #include "icons/flag-tmpUnscrolled-right.xpm"
    40 #include "icons/flag-questionmark.xpm"
    41 #include "icons/flag-exclamationmark.xpm"
    42 #include "icons/flag-hook-green.xpm"
    43 #include "icons/flag-cross-red.xpm"
    44 #include "icons/flag-stopsign.xpm"
    45 #include "icons/flag-smiley-good.xpm"
    46 #include "icons/flag-smiley-sad.xpm"
    47 #include "icons/flag-clock.xpm"
    48 #include "icons/flag-lamp.xpm"
    49 #include "icons/flag-arrow-up.xpm"
    50 #include "icons/flag-arrow-down.xpm"
    51 #include "icons/flag-thumb-up.xpm"
    52 #include "icons/flag-thumb-down.xpm"
    53 #include "icons/flag-heart.xpm"
    54 #include "icons/flag-flash.xpm"
    55 #include "icons/flag-lifebelt.xpm"
    56 
    57 extern TextEditor *textEditor;
    58 extern int statusbarTime;
    59 extern Main *mainWindow;
    60 extern FlagRowObj *systemFlagsDefault;
    61 extern FlagRowObj *standardFlagsDefault;
    62 extern MapEditor *clipboardME;
    63 
    64 extern QPtrList <QAction> actionListBranches;
    65 
    66 extern QAction *actionFileSave;
    67 extern QAction *actionEditUndo;
    68 extern QAction *actionEditCopy;
    69 extern QAction *actionEditCut;
    70 extern QAction *actionEditPaste;
    71 extern QAction *actionEditMoveUp;
    72 extern QAction *actionEditMoveDown;
    73 extern QAction *actionEditToggleScroll;
    74 extern QAction *actionEditOpenURL;
    75 extern QAction *actionEditURL;
    76 extern QAction *actionEditHeading2URL;
    77 extern QAction *actionEditBugzilla2URL;
    78 extern QAction *actionEditOpenVymLink;
    79 extern QAction *actionEditVymLink;
    80 extern QAction *actionEditDeleteVymLink;
    81 extern QAction *actionEditHeading;
    82 extern QAction *actionEditDelete;
    83 extern QAction *actionEditAddBranch;
    84 extern QAction *actionEditAddBranchAbove;
    85 extern QAction *actionEditAddBranchBelow;
    86 extern QAction *actionEditRemoveBranchHere;
    87 extern QAction *actionEditRemoveChilds;
    88 extern QAction *actionEditImportAdd;
    89 extern QAction *actionEditImportReplace;
    90 extern QAction *actionEditSaveBranch;
    91 extern QAction *actionEditSelectFirst;
    92 extern QAction *actionEditSelectLast;
    93 extern QAction *actionEditLoadImage;
    94 extern QAction *actionEditToggleFloatExport;
    95 
    96 extern QAction* actionFormatPickColor;
    97 extern QAction* actionFormatColorBranch;
    98 extern QAction* actionFormatColorSubtree;
    99 extern QAction *actionFormatLinkColorHint;
   100 extern QAction *actionFormatBackColor;
   101 extern QAction *actionFormatLinkColor;
   102 
   103 extern QActionGroup* actionGroupModModes;
   104 extern QAction* actionModModeColor;
   105 extern QAction* actionModModeLink;
   106 extern QAction* actionModModeCopy;
   107 
   108 extern QActionGroup *actionGroupFormatFrameTypes;
   109 extern QAction *actionFormatFrameNone;
   110 extern QAction *actionFormatFrameRectangle;
   111 
   112 extern QActionGroup *actionGroupFormatLinkStyles;
   113 extern QAction *actionFormatLinkStyleLine;
   114 extern QAction *actionFormatLinkStyleParabel;
   115 extern QAction *actionFormatLinkStylePolyLine;
   116 extern QAction *actionFormatLinkStylePolyParabel;
   117 
   118 extern QAction *actionViewToggleNoteEditor;
   119 
   120 extern QAction *actionSettingsAutoedit;
   121 extern QAction *actionSettingsAutoselectHeading;
   122 extern QAction *actionSettingsAutoselectText;
   123 extern QAction *actionSettingsPasteNewHeading;
   124 
   125 extern QPopupMenu *branchContextMenu;
   126 extern QPopupMenu *branchLinksContextMenu;
   127 extern QPopupMenu *branchLinksContextMenuDup;
   128 extern QPopupMenu *floatimageContextMenu;
   129 extern QPopupMenu *saveImageFormatMenu;
   130 extern QPopupMenu *exportImageFormatMenu;
   131 extern QPopupMenu *canvasContextMenu;
   132 
   133 extern Settings settings;
   134 
   135 
   136 ///////////////////////////////////////////////////////////////////////
   137 ///////////////////////////////////////////////////////////////////////
   138 MapEditor::MapEditor(
   139 	QWidget* parent, bool interactive, const char* name, WFlags f) :
   140     QCanvasView(parent,name,f)
   141 {
   142 	//cout << "Constructor ME "<<this<<endl;
   143 
   144     mapCanvas = new QCanvas(1000,800);
   145 	mapCanvas->setAdvancePeriod(30);
   146 
   147     setCanvas (mapCanvas);
   148 	
   149 	setVScrollBarMode ( QScrollView::AlwaysOn );
   150 	setHScrollBarMode ( QScrollView::AlwaysOn );
   151 
   152 	// Now create the _global_ system flags _once_:
   153 	// (Later all OrnamentedObj copy from this 
   154 	// and set their own canvas)
   155 	if (!systemFlagsDefault)
   156 	{
   157 		systemFlagsDefault = new FlagRowObj (mapCanvas);
   158 		systemFlagsDefault->setVisibility (false);
   159 		systemFlagsDefault->setName ("systemFlagsDef");
   160 
   161 		FlagObj *fo = new FlagObj (mapCanvas);
   162 		fo->load(QPixmap(flag_note_xpm));
   163 		fo->setName("note");
   164 		fo->setToolTip(tr("Note","Systemflag"));
   165 		systemFlagsDefault->addFlag (fo);	// makes deep copy
   166 
   167 		fo->load(QPixmap(flag_url_xpm));
   168 		fo->setName("url");
   169 		fo->setToolTip(tr("WWW Document (external)","Systemflag"));
   170 		systemFlagsDefault->addFlag (fo);
   171 		
   172 		fo->load(QPixmap(flag_vymlink_xpm));
   173 		fo->setName("vymLink");
   174 		fo->setToolTip(tr("Link to another vym map","Systemflag"));
   175 		systemFlagsDefault->addFlag (fo);	
   176 
   177 		fo->load(QPixmap(flag_scrolled_right_xpm));
   178 		fo->setName("scrolledright");
   179 		fo->setToolTip(tr("subtree is scrolled","Systemflag"));
   180 		systemFlagsDefault->addFlag (fo);
   181 		
   182 		fo->load(QPixmap(flag_tmpUnscrolled_right_xpm));
   183 		fo->setName("tmpUnscrolledright");
   184 		fo->setToolTip(tr("subtree is temporary scrolled","Systemflag"));
   185 		systemFlagsDefault->addFlag (fo);
   186 		delete (fo);
   187 	}
   188 	if (!standardFlagsDefault)
   189 	{
   190 		standardFlagsDefault = new FlagRowObj (mapCanvas);
   191 		standardFlagsDefault->setVisibility (false);
   192 		standardFlagsDefault->setName ("standardFlagsDef");
   193 
   194 		FlagObj *fo = new FlagObj (mapCanvas);
   195 		fo->load(QPixmap(flag_exclamationmark_xpm));
   196 		fo->setName("exclamationmark");
   197 		fo->setToolTip(tr("Take care!","Standardflag"));
   198 		standardFlagsDefault->addFlag (fo);	// makes deep copy
   199 		
   200 		fo->load(QPixmap(flag_questionmark_xpm));
   201 		fo->setName("questionmark");
   202 		fo->setToolTip(tr("Really?","Standardflag"));
   203 		standardFlagsDefault->addFlag (fo);	
   204 
   205 		fo->load(QPixmap(flag_hook_green_xpm));
   206 		fo->setName("hook-green");
   207 		fo->setToolTip(tr("ok!","Standardflag"));
   208 		standardFlagsDefault->addFlag (fo);	
   209 
   210 		fo->load(QPixmap(flag_cross_red_xpm));
   211 		fo->setName("cross-red");
   212 		fo->setToolTip(tr("Not ok!","Standardflag"));
   213 		standardFlagsDefault->addFlag (fo);	
   214 
   215 		fo->load(QPixmap(flag_stopsign_xpm));
   216 		fo->setName("stopsign");
   217 		fo->setToolTip(tr("This won't work!","Standardflag"));
   218 		standardFlagsDefault->addFlag (fo);	
   219 
   220 		fo->load(QPixmap(flag_smiley_good_xpm));
   221 		fo->setName("smiley-good");
   222 		fo->setToolTip(tr("Good","Standardflag"));
   223 		standardFlagsDefault->addFlag (fo);	
   224 
   225 		fo->load(QPixmap(flag_smiley_sad_xpm));
   226 		fo->setName("smiley-sad");
   227 		fo->setToolTip(tr("Bad","Standardflag"));
   228 		standardFlagsDefault->addFlag (fo);	
   229 
   230 		fo->load(QPixmap(flag_clock_xpm));
   231 		fo->setName("clock");
   232 		fo->setToolTip(tr("Time critical","Standardflag"));
   233 		standardFlagsDefault->addFlag (fo);	
   234 
   235 		fo->load(QPixmap(flag_lamp_xpm));
   236 		fo->setName("lamp");
   237 		fo->setToolTip(tr("Idea!","Standardflag"));
   238 		standardFlagsDefault->addFlag (fo);	
   239 
   240 		fo->load(QPixmap(flag_arrow_up_xpm));
   241 		fo->setName("arrow-up");
   242 		fo->setToolTip(tr("Important","Standardflag"));
   243 		standardFlagsDefault->addFlag (fo);	
   244 
   245 		fo->load(QPixmap(flag_arrow_down_xpm));
   246 		fo->setName("arrow-down");
   247 		fo->setToolTip(tr("Unimportant","Standardflag"));
   248 		standardFlagsDefault->addFlag (fo);	
   249 
   250 		fo->load(QPixmap(flag_thumb_up_xpm));
   251 		fo->setName("thumb-up");
   252 		fo->setToolTip(tr("I like this","Standardflag"));
   253 		standardFlagsDefault->addFlag (fo);	
   254 
   255 		fo->load(QPixmap(flag_thumb_down_xpm));
   256 		fo->setName("thumb-down");
   257 		fo->setToolTip(tr("I do not like this","Standardflag"));
   258 		standardFlagsDefault->addFlag (fo);	
   259 		
   260 		fo->load(QPixmap(flag_heart_xpm));
   261 		fo->setName("heart");
   262 		fo->setToolTip(tr("I just love... ","Standardflag"));
   263 		standardFlagsDefault->addFlag (fo);	
   264 
   265 		fo->load(QPixmap(flag_flash_xpm));
   266 		fo->setName("flash");
   267 		fo->setToolTip(tr("Dangerous","Standardflag"));
   268 		standardFlagsDefault->addFlag (fo);	
   269 		
   270 		fo->load(QPixmap(flag_lifebelt_xpm));
   271 		fo->setName("lifebelt");
   272 		fo->setToolTip(tr("This will help","Standardflag"));
   273 		standardFlagsDefault->addFlag (fo);	
   274 		delete (fo);
   275 
   276 	}
   277 	
   278     mapCenter = new MapCenterObj(mapCanvas);
   279     mapCenter->setVisibility (true);
   280 	mapCenter->setMapEditor (this);
   281 	mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
   282 
   283     printer=NULL;
   284 
   285     lineedit = new QLineEdit(this, "lineedit"  );
   286     connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEditNoSave() ) );
   287     lineedit->hide();
   288 
   289     actColor=black; setColor (actColor);
   290 	defLinkColor=QColor (0,0,255);
   291 	defXLinkColor=QColor (180,180,180);
   292 	linkcolorhint=DefaultColor;
   293 	linkstyle=StylePolyParabel;
   294 	mapCanvas->setBackgroundColor (white);
   295 
   296 	// Create bitmap cursors, patform dependant
   297 	#if defined(Q_OS_MACX)
   298 		#include "icons/cursorhandopen16.xpm"
   299 		#include "icons/cursorcolorpicker16.xpm"
   300 		QBitmap cb( 16, 16, chandopen, TRUE );
   301 		QBitmap cm( 16, 16, chandopenmask, TRUE );
   302 		handOpenCursor=QCursor ( cb, cm );		
   303 		// set hot spot to tip of picker			
   304 		pickColorCursor=QCursor ( cursorcolorpicker_xpm, 1,15 ); 
   305 	#else
   306 		#include "icons/cursorhandopen.xpm"
   307 		#include "icons/cursorcolorpicker.xpm"
   308 
   309 		QBitmap cb( 32, 32, chandopen, TRUE );
   310 		QBitmap cm( 32, 32, chandopenmask, TRUE );
   311 		handOpenCursor=QCursor ( cb, cm );		
   312 		// set hot spot to tip of picker			
   313 		pickColorCursor=QCursor ( cursorcolorpicker_xpm, 5,27 ); 
   314 	#endif
   315 
   316 	pickingColor=false;
   317 	drawingLink=false;
   318 	copyingObj=false;
   319 
   320     editingBO=NULL;
   321     selection=NULL;
   322     selectionLast=NULL;
   323     movingObj=NULL;
   324 
   325     mapChanged=false;
   326 	mapDefault=true;
   327 	mapUnsaved=false;
   328 	undoSelection=NULL;
   329 	
   330 	zipped=true;
   331 	filePath="";
   332 	fileName="unnamed";
   333 	mapName="";
   334 
   335 	// Initialize find routine
   336 	itFind=NULL;				
   337 	EOFind=false;
   338 
   339 	printFrame=true;
   340 	printFooter=true;
   341 
   342 	blockreposition=false;
   343 	isInteractive=interactive;
   344 	if (isInteractive)
   345 		// Create temporary files
   346 		makeTmpDirs();
   347 
   348 	// Initially set movingCentre
   349 	updateViewCenter();
   350 
   351 	mapCenter->reposition();	//	for positioning heading
   352 }
   353 
   354 MapEditor::~MapEditor()
   355 {
   356 	//cout <<"Destructor MapEditor\n";
   357 	if (isInteractive) delTmpDirs();
   358 
   359 	// Save Settings
   360 	//settings.writeEntry( "/vym/mapeditor/editmode/autoselect",  );
   361 
   362 }
   363 
   364 QColor MapEditor::color()
   365 {
   366     return actColor;
   367 }
   368 
   369 QColor MapEditor::backgroundColor()
   370 {
   371     return mapCanvas->backgroundColor();
   372 }
   373 
   374 MapCenterObj* MapEditor::getMapCenter()
   375 {
   376     return mapCenter;
   377 }
   378 
   379 QCanvas* MapEditor::getCanvas()
   380 {
   381     return mapCanvas;
   382 }
   383 
   384 void MapEditor::adjustCanvasSize()
   385 {
   386 	// To adjust the canvas to map, viewport size and position, we have to
   387 	// do some coordinate magic...
   388 	//
   389 	// Get rectangle of (scroll-)view. 
   390 	// We want to be in canvas coords, so
   391 	// we map. Important if view is zoomed...
   392 	QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(),
   393 												visibleWidth(), visibleHeight()) );	
   394 												
   395 	// Now we need the bounding box of view AND map to calc the correct canvas size.
   396 	// Why? Because if the map itself is moved out of view, the view has to be enlarged
   397 	// to avoid jumping aroung...
   398 	QRect map=mapCenter->getTotalBBox();
   399 
   400 	// right edge - left edge
   401 	int cw= max(map.x() + map.width(),  view.x() + view.width())  - min(map.x(), view.x());
   402 	int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
   403 
   404 
   405 	if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) ||
   406 		!mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight())
   407 	)	
   408 	{	
   409 		// move the map on canvas (in order to not move it on screen) this is neccessary
   410 		// a) if topleft corner of canvas is left or above topleft corner of view and also left of
   411 		//    above topleft corner of map. E.g. if map is completly inside view, but it would be possible 
   412 		//    to scroll to an empty area of canvas to the left.
   413 		// b) if topleft corner of map left of or above topleft of canvas
   414 		int dx=0;
   415 		int dy=0;
   416 
   417 		if (cw > mapCanvas->width() )
   418 		{
   419 			if (map.x()<0) dx=-map.x();	
   420 		}
   421 		if (cw <  mapCanvas->width() )
   422 			dx=-min (view.x(),map.x());
   423 		if (ch > mapCanvas->height() )
   424 		{
   425 			if (map.y()<0) dy=-map.y();	
   426 		}
   427 		if (ch <  mapCanvas->height() )
   428 		{
   429 			dy=-min (view.y(),map.y());
   430 		}
   431 		// We really have to resize now. Let's go...
   432 		mapCanvas->resize (cw,ch);
   433 		if ( (dx!=0) || (dy!=0) ) 
   434 		{
   435 			mapCenter->moveAllBy(dx,dy);
   436 			mapCenter->reposition();
   437 
   438 			// scroll the view (in order to not move map on screen)
   439 			scrollBy (dx,dy);
   440 		}	
   441 	}
   442 }
   443 
   444 bool MapEditor::blockReposition()
   445 {
   446 	return blockreposition;
   447 }
   448 
   449 void MapEditor::makeTmpDirs()
   450 {
   451 	// Create unique temporary directories
   452 	char tmpdir[]="/tmp/vym-XXXXXX";	
   453 	bakMapDir=mkdtemp(tmpdir);
   454 	makeSubDirs(bakMapDir);
   455 	// FIXME set permissions
   456 	// and maybe use QT method for portability
   457 }
   458 
   459 void MapEditor::delTmpDirs()
   460 {
   461 	//FIXME delete tmp directory, better use QT methods here:
   462 	system ( "rm -rf "+ bakMapDir );
   463 }
   464 
   465 
   466 void MapEditor::makeSubDirs(const QString &s)
   467 {
   468 	QDir d(s);
   469 	d.mkdir ("images");	
   470 	d.mkdir ("flags");	
   471 }
   472 
   473 
   474 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, SaveMode savemode)
   475 {
   476 	// tmpdir		temporary directory to which data will be writte
   477 	// prefix		mapname, which will be appended to images etc.
   478 	// writeflags	Only write flags for "real" save of map, not undo
   479 	// offset		offset of bbox of whole map in canvas. 
   480 	//				Needed for XML export
   481 	// completeMap	if false, only vympart will be written, without
   482 	//				mapcenter
   483 	
   484 	// Save Header
   485 	QString ls;
   486 	switch (linkstyle)
   487 	{
   488 		case StyleLine: 
   489 			ls="StyleLine";
   490 			break;
   491 		case StyleParabel:
   492 			ls="StyleParabel";
   493 			break;
   494 		case StylePolyLine:	
   495 			ls="StylePolyLine";
   496 			break;
   497 		default:
   498 			ls="StylePolyParabel";
   499 			break;
   500 	}	
   501 
   502 	QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
   503 	QString colhint="";
   504 	if (linkcolorhint==HeadingColor) 
   505 		colhint=attribut("linkColorHint","HeadingColor");
   506 
   507 	QString mapAttr=attribut("version",__VYM_VERSION__);
   508 	if (savemode==CompleteMap)
   509 		mapAttr+= attribut("author",mapCenter->getAuthor()) +
   510 				  attribut("comment",mapCenter->getComment()) +
   511 			      attribut("date",mapCenter->getDate()) +
   512 		          attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
   513 		          attribut("linkStyle", ls ) +
   514 		          attribut("linkColor", defLinkColor.name() ) +
   515 		          attribut("xlinkColor", defXLinkColor.name() ) +
   516 		          attribut("xlinkWidth", QString().setNum(defXLinkWidth,10) ) +
   517 		          colhint; 
   518 	s+=beginElement("vymmap",mapAttr);
   519 	incIndent();
   520 
   521 	// Find the used flags while traversing the tree
   522 	standardFlagsDefault->resetUsedCounter();
   523 	
   524 	// Build xml recursivly
   525 	if (savemode==CompleteMap)
   526 		s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
   527 	else
   528 	{
   529 		if ( undoSelection &&
   530 			typeid(*undoSelection) == typeid(BranchObj) )
   531 			s+=((BranchObj*)(undoSelection))->saveToDir(tmpdir,prefix,offset);
   532 		else	
   533 			if (selection && typeid(*selection)==typeid(BranchObj))
   534 				s+=((BranchObj*)(selection))->saveToDir(tmpdir,prefix,offset);
   535 	}
   536 
   537 	// Save local settings
   538 	s+=settings.getXMLData (destPath);
   539 
   540 	// Save selection
   541 	if (selection) 
   542 		s+=valueElement("select",selection->getSelectString());
   543 
   544 	decIndent();
   545 	s+=endElement("vymmap");
   546 
   547 	if (writeflags)
   548 		standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
   549 	
   550 	return s;
   551 }
   552 
   553 void MapEditor::saveState()
   554 {
   555 	saveState (CompleteMap,NULL);
   556 }
   557 
   558 void MapEditor::saveState(const SaveMode &mode, LinkableMapObj *part)
   559 {
   560 	// all binary data is saved in bakMapDir (created in Constructor)
   561 	// the xml data itself is kept in memory in backupXML
   562 	// 
   563 	// For faster write/read of data, a part of the map can be
   564 	// written. Then the undoSelection will mark the part of the
   565 	// map which should be replaced if an undo is wanted later.
   566 
   567 	if (mode==PartOfMap && part && (typeid(*part) == typeid (BranchObj) ) ) 
   568 	{
   569 		// Writing a vympart only is useful for BranchObj
   570 		undoSelection=part;
   571 		backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),PartOfMap);
   572 	} else	
   573 	{
   574 		undoSelection=NULL;
   575 		backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),CompleteMap);
   576 	}	
   577 }
   578 
   579 void MapEditor::finishedLineEditNoSave()
   580 {
   581 	// This is called by finishedLineEdit or any MapEditor method,
   582 	// which wants to assure, that lineedits finish, before e.g. a branch is 
   583 	// deleted
   584     
   585 	// After calling LineEdit and using the clipboard, the 
   586     // focus is not any longer on the main widget, we
   587     // have to restore it using parentWidget()->setFocus()
   588 
   589     if (editingBO!=NULL) 
   590 	{
   591 		editingBO->setHeading(lineedit->text() );
   592 		editingBO=NULL;
   593 		lineedit->releaseKeyboard();
   594 		lineedit->hide();
   595 		parentWidget()->setFocus();
   596 		mapCenter->reposition();
   597 		adjustCanvasSize();
   598 		ensureSelectionVisible();
   599     }		
   600 }
   601 
   602 
   603 bool MapEditor::isDefault()
   604 {
   605     return mapDefault;
   606 }
   607 
   608 bool MapEditor::isUnsaved()
   609 {
   610     return mapUnsaved;
   611 }
   612 
   613 bool MapEditor::hasChanged()
   614 {
   615     return mapChanged;
   616 }
   617 
   618 void MapEditor::setChanged()
   619 {
   620 	mapChanged=true;
   621 	mapDefault=false;
   622 	mapUnsaved=true;
   623 	actionEditUndo->setEnabled (true);
   624 	actionFileSave->setEnabled (true);
   625 	findReset();
   626 }
   627 
   628 void MapEditor::closeMap()
   629 {
   630 	// Finish open lineEdits
   631 	if (lineedit) finishedLineEditNoSave();
   632 
   633 	// Unselect before disabling the toolbar actions
   634 	if (selection) selection->unselect();
   635 	selection=NULL;
   636 	updateActions();
   637 
   638     clear();
   639 	close();
   640 }
   641 
   642 void MapEditor::setFilePath(QString fname)
   643 {
   644 	setFilePath (fname,fname);
   645 }
   646 
   647 void MapEditor::setFilePath(QString fname, QString destname)
   648 {
   649 	filePath=fname;
   650 	fileName=fname;
   651 	destPath=destname;
   652 
   653 	// If fname is not an absolute path, complete it
   654 	filePath=QDir(fname).absPath();
   655 	fileDir=filePath.left (1+filePath.findRev ("/"));
   656 
   657 	// Set short name, too. Search from behind:
   658 	int i=fileName.findRev("/");
   659 	if (i>=0) fileName=fileName.remove (0,i+1);
   660 
   661 	// Forget the .vym (or .xml) for name of map
   662 	mapName=fileName.left(fileName.findRev(".",-1,true) );
   663 }
   664 
   665 QString MapEditor::getFilePath()
   666 {
   667 	return filePath;
   668 }
   669 
   670 QString MapEditor::getFileName()
   671 {
   672 	return fileName;
   673 }
   674 
   675 QString MapEditor::getMapName()
   676 {
   677 	return mapName;
   678 }
   679 
   680 QString MapEditor::getDestPath()
   681 {
   682 	return destPath;
   683 }
   684 
   685 int MapEditor::load (QString &fname, const LoadMode &lmode)
   686 {
   687 	// Finish open lineEdits
   688 	if (lineedit) finishedLineEditNoSave();
   689 
   690 	int returnCode=0;
   691 
   692 	if (lmode==NewMap)
   693 	{
   694 		if (selection) selection->unselect();
   695 		selection=NULL;
   696 		mapCenter->clear();
   697 		mapCenter->setMapEditor(this);
   698 		// (map state is set later at end of load...)
   699 	} else
   700 	{
   701 		setChanged();
   702 		saveState(PartOfMap,selection);
   703 	}	
   704 	
   705     
   706     mapBuilderHandler handler;
   707 	QFile file( fname );
   708 
   709 	// I am paranoid: file should exist anyway
   710 	// according to check in mainwindow.
   711 	if (!file.exists() )
   712 	{
   713 		QMessageBox::critical( 0, tr( "Critical Parse Error" ),
   714 				   tr("Couldn't open map " +fname)+".");
   715 		returnCode=1;	
   716 	} else
   717 	{
   718 		blockreposition=true;
   719 		QXmlInputSource source( file);
   720 		QXmlSimpleReader reader;
   721 		reader.setContentHandler( &handler );
   722 		reader.setErrorHandler( &handler );
   723 		handler.setMapEditor( this );
   724 		handler.setTmpDir (filePath.left(filePath.findRev("/",-1)));	// needed to load files with rel. path
   725 		handler.setLoadMode (lmode);
   726 		bool ok = reader.parse( source );
   727 		blockreposition=false;
   728 		file.close();
   729 		if ( ok ) 
   730 		{
   731 			mapCenter->reposition();
   732 			adjustCanvasSize();
   733 			if (lmode==NewMap)
   734 			{
   735 				mapDefault=false;
   736 				mapChanged=false;
   737 				mapUnsaved=false;
   738 			}
   739 		} else 
   740 		{
   741 			QMessageBox::critical( 0, tr( "Critical Parse Error" ),
   742 					   tr( handler.errorProtocol() ) );
   743 			// returnCode=1;	
   744 			// Still return "success": the map maybe at least
   745 			// partially read by the parser
   746 		}	
   747 	}	
   748 	updateActions();
   749 	return returnCode;
   750 }
   751 
   752 int MapEditor::save (const SaveMode &savemode)
   753 {
   754 	// Finish open lineEdits
   755 	if (lineedit) finishedLineEditNoSave();
   756 
   757 	int returnCode=0;
   758 
   759 	// Create mapName and fileDir
   760 	makeSubDirs (fileDir);
   761 	QString fname;
   762 	if (saveZipped())
   763 		// save as .xml
   764 		fname=mapName+".xml";
   765 	else
   766 		// use name given by user, even if he chooses .doc
   767 		fname=fileName;
   768 
   769 
   770 	// Check if fname is writeable
   771 	QFile file( fileDir+fname);
   772 	if (!file.open( IO_WriteOnly ) ) 
   773 	{
   774 		QMessageBox::critical( 0, tr( "Critical Save Error" ),
   775 					   tr("Couldn't write to ") +fileDir+fname);
   776 		return 1;
   777 	}	
   778 	file.close();
   779 
   780 	QString saveFile;
   781 	saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),savemode);
   782 
   783 	file.setName ( fileDir  + fname);
   784 	if ( !file.open( IO_WriteOnly ) )
   785 	{
   786 		// This should neverever happen
   787 		QMessageBox::critical(0, tr("Critcal Save error"),"MapEditor::save() Couldn't open "+file.name());
   788 		return 1;
   789 	}	
   790 
   791 	// Write it finally, and write in UTF8, no matter what 
   792 	QTextStream ts( &file );
   793 	ts.setEncoding (QTextStream::UnicodeUTF8);
   794 	ts << saveFile;
   795 	file.close();
   796 
   797 	if (returnCode==0)
   798 	{
   799 		mapChanged=false;
   800 		mapUnsaved=false;
   801 		actionFileSave->setEnabled(false);
   802 	}
   803 
   804 	return returnCode;
   805 }
   806 
   807 void MapEditor::setZipped (bool z)
   808 {
   809 	zipped=z;
   810 }
   811 
   812 bool MapEditor::saveZipped ()
   813 {
   814 	return zipped;
   815 }
   816 
   817 void MapEditor::print()
   818 {
   819 	// Finish open lineEdits
   820 	if (lineedit) finishedLineEditNoSave();
   821 
   822 	if ( !printer ) 
   823 	{
   824 		printer = new QPrinter;
   825 		printer->setColorMode (QPrinter::Color);
   826 	}
   827 
   828 	QRect totalBBox=mapCenter->getTotalBBox();
   829 
   830 	// Try to set orientation automagically
   831 	// Note: Interpretation of generated postscript is amibiguous, if 
   832 	// there are problems with landscape mode, see
   833 	// http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
   834 
   835 	if (totalBBox.width()>totalBBox.height())
   836 		// recommend landscape
   837 		printer->setOrientation (QPrinter::Landscape);
   838 	else	
   839 		// recommend portrait
   840 		printer->setOrientation (QPrinter::Portrait);
   841 
   842 	if ( printer->setup(this) ) 
   843 	// returns false, if printing is canceled
   844 	{
   845 		QPainter pp(printer);
   846 
   847 		// Don't print the visualisation of selection
   848 		LinkableMapObj *oldselection=NULL;
   849 		if (selection) 
   850 		{
   851 			oldselection=selection;
   852 			selection->unselect();
   853 		}
   854 
   855 		// Handle sizes of map and paper:
   856 		//
   857 		// setWindow defines which part of the canvas will be transformed 
   858 		// setViewport defines area on paper in device coordinates (dpi)
   859 		// e.g. (0,50,700,700) is upper part on A4
   860 		// see also /usr/lib/qt3/doc/html/coordsys.html
   861 
   862 		QPaintDeviceMetrics metrics (printer);
   863 
   864 		double paperAspect = (double)metrics.width()   / (double)metrics.height();
   865 		double   mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
   866 
   867 		QRect mapRect=mapCenter->getTotalBBox();
   868 		QCanvasRectangle *frame=NULL;
   869 		QCanvasText *footerFN=NULL;
   870 		QCanvasText *footerDate=NULL;
   871 		if (printFrame || printFooter)
   872 		{
   873 			
   874 			if (printFrame) 
   875 			{
   876 				// Print frame around map
   877 				mapRect.setRect (mapRect.x()-10, mapRect.y()-10, 
   878 					mapRect.width()+20, mapRect.height()+20);
   879 				frame=new QCanvasRectangle (mapRect,mapCanvas);
   880 				frame->setBrush (QColor(white));
   881 				frame->setPen (QColor(black));
   882 				frame->setZ(0);
   883 				frame->show();    
   884 			}		
   885 			if (printFooter) 
   886 			{
   887 				// Print footer below map
   888 				QFont font;		
   889 				font.setPointSize(10);
   890 				footerFN=new QCanvasText (mapCanvas);
   891 				footerFN->setText ("VYM - " + fileName);
   892 				footerFN->setFont(font);
   893 				footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
   894 				footerFN->setZ(Z_TEXT);
   895 				footerFN->show();    
   896 				footerDate=new QCanvasText (mapCanvas);
   897 				footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
   898 				footerDate->setFont(font);
   899 				footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
   900 				footerDate->setZ(Z_TEXT);
   901 				footerDate->show();    
   902 				mapRect.setRect (mapRect.x(), mapRect.y(), 
   903 					mapRect.width(), mapRect.height()+20);
   904 			}
   905 			pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height());
   906 		}	else	
   907 		{
   908 			pp.setWindow (mapRect);
   909 		}	
   910 
   911 		if (mapAspect>=paperAspect)
   912 		{
   913 			// Fit horizontally to paper width
   914 			pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );	
   915 		}	else
   916 		{
   917 			// Fit vertically to paper height
   918 			pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());	
   919 		}	
   920 
   921 		mapCanvas->drawArea(mapRect, &pp);	// draw Canvas to printer
   922 
   923 		// Delete Frame and footer
   924 		if (footerFN) 
   925 		{
   926 			delete (footerFN);
   927 			delete (footerDate);
   928 		}	
   929 		if (frame)  delete (frame);
   930 
   931 		// Restore selection
   932 		if (oldselection) 
   933 		{
   934 			selection=oldselection;
   935 			selection->select();
   936 		}	
   937 	}
   938 }
   939 
   940 QPixmap MapEditor::getPixmap()
   941 {
   942 	QRect mapRect=mapCenter->getTotalBBox();
   943 	QPixmap pix (mapRect.size());
   944 	QPainter pp (&pix);
   945 
   946 	// Don't print the visualisation of selection
   947 	LinkableMapObj *oldselection=NULL;
   948 	if (selection) 
   949 	{
   950 		oldselection=selection;
   951 		selection->unselect();
   952 	}
   953 
   954 	pp.setWindow (mapRect);
   955 
   956 	mapCanvas->drawArea(mapRect, &pp);	// draw Canvas to painter
   957 
   958 
   959 	// Restore selection
   960 	if (oldselection) 
   961 	{
   962 		selection=oldselection;
   963 		selection->select();
   964 	}	
   965 	
   966 	return pix;
   967 }
   968 
   969 void MapEditor::exportImage(QString fn)
   970 {
   971 	// Finish open lineEdits
   972 	if (lineedit) finishedLineEditNoSave();
   973 
   974 	QPixmap pix (getPixmap());
   975 	pix.save(fn, "PNG");
   976 }
   977 
   978 void MapEditor::exportImage(QString fn, int item)
   979 {
   980 	// Finish open lineEdits
   981 	if (lineedit) finishedLineEditNoSave();
   982 
   983 	QPixmap pix (getPixmap());
   984 	pix.save(fn, exportImageFormatMenu->text(item) );
   985 }
   986 
   987 void MapEditor::exportASCII()
   988 {
   989 	// FIXME still experimental
   990 	QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (ASCII)"));
   991 	fd->addFilter ("TXT (*.txt)");
   992 	fd->setCaption("VYM - Export (ASCII) (still experimental)");
   993 	fd->setMode( QFileDialog::AnyFile );
   994 	fd->show();
   995 
   996 	if ( fd->exec() == QDialog::Accepted )
   997 	{
   998 		if (QFile (fd->selectedFile()).exists() )
   999 		{
  1000 			QMessageBox mb( "VYM",
  1001 				tr("The file ") + fd->selectedFile() + 
  1002 				tr(" exists already. Do you want to overwrite it?"),
  1003 			QMessageBox::Warning,
  1004 			QMessageBox::Yes | QMessageBox::Default,
  1005 			QMessageBox::Cancel | QMessageBox::Escape,
  1006 			QMessageBox::NoButton );
  1007 
  1008 			mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
  1009 			mb.setButtonText( QMessageBox::No, tr("Cancel"));
  1010 			Export ex;
  1011 			switch( mb.exec() ) 
  1012 			{
  1013 				case QMessageBox::Yes:
  1014 					// save 
  1015 					if (!ex.setOutputDir ("out"))
  1016 					{
  1017 						QMessageBox::critical (0,tr("Critical Export Error "),tr("Couldn't create directory ") + "out");
  1018 						return;
  1019 					}
  1020 					break;;
  1021 				case QMessageBox::Cancel:
  1022 					// do nothing
  1023 					return;
  1024 					break;
  1025 			}
  1026 		}
  1027 		Export ex;
  1028 		ex.setPath (fd->selectedFile() );
  1029 		ex.setMapCenter(mapCenter);
  1030 		ex.exportMap();
  1031 	}
  1032 }
  1033 
  1034 
  1035 void MapEditor::exportXML(const QString &dir)
  1036 {
  1037 	// Create subdirectories
  1038 	makeSubDirs (dir);
  1039 
  1040 	// write to directory
  1041 	QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,CompleteMap);
  1042 	QFile file;
  1043 
  1044 	file.setName ( dir + "/"+mapName+".xml");
  1045 	if ( !file.open( IO_WriteOnly ) )
  1046 	{
  1047 		// This should neverever happen
  1048 		QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open ")+file.name());
  1049 		return;
  1050 	}	
  1051 
  1052 	// Write it finally, and write in UTF8, no matter what 
  1053 	QTextStream ts( &file );
  1054 	ts.setEncoding (QTextStream::UnicodeUTF8);
  1055 	ts << saveFile;
  1056 	file.close();
  1057 
  1058 	// Now write image, too
  1059 	exportImage (dir+"/images/"+mapName+".png");
  1060 }
  1061 
  1062 void MapEditor::clear()
  1063 {
  1064 	if (selection)
  1065 	{
  1066 		selection->unselect();
  1067 		selection=NULL;
  1068 	}	
  1069 
  1070 	mapCenter->clear();
  1071 }
  1072 
  1073 void MapEditor::undo()
  1074 {
  1075 	QDir d;
  1076 	d.setPath(bakMapDir);
  1077 	if (d.exists() )
  1078 	{
  1079 		// Finish open lineEdits
  1080 		if (lineedit) finishedLineEditNoSave();
  1081 
  1082 		if (selection) 
  1083 		{
  1084 			selection->unselect();
  1085 			selection=NULL;
  1086 		}	
  1087 		
  1088 		mapBuilderHandler handler;
  1089 		QXmlInputSource source;
  1090 		source.setData(backupXML);
  1091 		QXmlSimpleReader reader;
  1092 		reader.setContentHandler( &handler );
  1093 		reader.setErrorHandler( &handler );
  1094 		handler.setMapEditor( this );
  1095 		handler.setTmpDir ( bakMapDir );	// needed to load files with rel. path
  1096 		if (undoSelection)
  1097 		{
  1098 			selection=undoSelection;
  1099 			selection->select();
  1100 			handler.setLoadMode (ImportReplace);
  1101 
  1102 		} else	
  1103 		{
  1104 			mapCenter->clear();
  1105 			handler.setLoadMode (NewMap);
  1106 		}	
  1107 		blockreposition=true;
  1108 		bool ok = reader.parse( source );
  1109 		blockreposition=false;
  1110 		if ( ok ) 
  1111 			mapCenter->reposition();
  1112 			
  1113 		else 
  1114 		{	
  1115 			// This should never ever happen
  1116 			QMessageBox::critical( 0, tr( "Critical Parse Error by reading backupFile" ),
  1117 								   tr( handler.errorProtocol() )+" in "+backupXML );
  1118 		}
  1119 		// Undo not longer available now
  1120 		actionEditUndo->setEnabled (false);
  1121 		undoSelection=false;
  1122 		mapChanged=false;
  1123 		return;
  1124 	} else	
  1125 	{
  1126 		QMessageBox::critical( 0, tr( "Critical Error" ),
  1127 			"Temporary directory " +bakMapDir + 
  1128 			tr (" used for undo is gone. \n"
  1129 			"I will create a new one, but at the moment no undo is available.\n"
  1130 			"Maybe you want to reload your original data.\n\n"
  1131 			"Sorry for any inconveniences.") );
  1132 		makeTmpDirs();	
  1133 	}							
  1134 }
  1135 
  1136 void MapEditor::copy()
  1137 {
  1138 	// Finish open lineEdits
  1139 	if (lineedit) finishedLineEditNoSave();
  1140 
  1141 	if (selection) 
  1142 	{
  1143 		if (typeid(*selection) == typeid(BranchObj) ) 
  1144 		{
  1145 			BranchObj* to;
  1146 			BranchObj* from;
  1147 			clipboardME->clear();
  1148 			clipboardME->getMapCenter()->addBranch();
  1149 			to=clipboardME->getMapCenter()->getLastBranch();
  1150 			if (to) 
  1151 			{
  1152 				from=(BranchObj*)(selection);
  1153 				to->copy(from);
  1154 
  1155 				// keep position relative to parent
  1156 				to->move2RelPos ( from->getRelPos());
  1157 
  1158 				// select data in clipboard
  1159 				clipboardME->select ("bo:0");
  1160 
  1161 				// repositioning makes testing nicer,
  1162 				// but is not needed usually:
  1163 				if (clipboardME->isVisible())
  1164 				{
  1165 					clipboardME->getMapCenter()->reposition();  
  1166 				}	
  1167 				else
  1168 					clipboardME->hide();
  1169 			}
  1170 		}    
  1171 		if (typeid(*selection) == typeid(FloatImageObj) ) 
  1172 		{
  1173 			FloatImageObj* to;
  1174 			FloatImageObj* from;
  1175 			clipboardME->clear();
  1176 			clipboardME->getMapCenter()->addFloatImage();
  1177 			to=clipboardME->getMapCenter()->getLastFloatImage();
  1178 			if (to) 
  1179 			{
  1180 				from=(FloatImageObj*)(selection);
  1181 				to->copy(from);
  1182 
  1183 				// select data in clipboard
  1184 				clipboardME->select ("fi:0");
  1185 
  1186 				// repositioning makes testing nicer,
  1187 				// but is not needed usually:
  1188 				if (clipboardME->isVisible())
  1189 				{
  1190 					clipboardME->getMapCenter()->reposition();  
  1191 				}	
  1192 				else
  1193 					clipboardME->hide();
  1194 			}
  1195 		}    
  1196 	}	    
  1197 }
  1198 
  1199 LinkableMapObj* MapEditor::pasteNoSave()
  1200 {
  1201 	// Finish open lineEdits
  1202 	if (lineedit) finishedLineEditNoSave();
  1203 
  1204 	LinkableMapObj *fromLMO=clipboardME->getSelection();
  1205 	LinkableMapObj *returnLMO=NULL;
  1206 
  1207 	if (selection && fromLMO) 
  1208 	{
  1209 
  1210 		if (typeid(*fromLMO) == typeid(BranchObj) ) 
  1211 		{
  1212 			if (typeid(*selection) == typeid(MapCenterObj)) 
  1213 			{
  1214 				returnLMO=mapCenter->addBranch( (BranchObj*)(fromLMO) );
  1215 				((BranchObj*)(returnLMO))->move2RelPos(normalise(fromLMO->getRelPos() ) );
  1216 			}     
  1217 			if (typeid(*selection) == typeid(BranchObj)) 
  1218 					returnLMO=((BranchObj*)(selection))->addBranch((BranchObj*)(fromLMO) );
  1219 		}
  1220 		
  1221 		if (typeid(*fromLMO) == typeid(FloatImageObj) &&
  1222 			(typeid(*selection) == typeid (BranchObj) || 
  1223 			 typeid(*selection)==typeid(MapCenterObj)) )
  1224 			returnLMO=((BranchObj*) (selection))->addFloatImage ((FloatImageObj*)(fromLMO));
  1225 		
  1226 	}	    
  1227 	return returnLMO;
  1228 }
  1229 
  1230 void MapEditor::cutNoSave()
  1231 {
  1232 	// Finish open lineEdits
  1233 	if (lineedit) finishedLineEditNoSave();
  1234 
  1235 	BranchObj* bo;
  1236 	BranchObj* par; 
  1237 	if (selection != NULL) {
  1238 		if (typeid(*selection) == typeid(BranchObj) ) 
  1239 		{
  1240 			bo=(BranchObj*)(selection);
  1241 			par=(BranchObj*)(bo->getParObj());
  1242 			bo->unselect();
  1243 			selection=NULL;
  1244 			par->removeBranch(bo);
  1245 			selection=par;
  1246 			selection->select();
  1247 		}
  1248 		if (typeid(*selection) == typeid(FloatImageObj) ) 
  1249 		{
  1250 			FloatImageObj* fio=(FloatImageObj*)(selection);
  1251 			par=(BranchObj*)(fio->getParObj());
  1252 			fio->unselect();
  1253 			selection=NULL;
  1254 			par->removeFloatImage(fio);
  1255 			selection=par;
  1256 			selection->select();
  1257 		}
  1258 	}	    
  1259 }
  1260 
  1261 void MapEditor::paste()
  1262 {   
  1263 	setChanged();
  1264 	saveState(PartOfMap,selection);
  1265 	pasteNoSave();
  1266 	mapCenter->reposition();
  1267 	adjustCanvasSize();
  1268 }
  1269 
  1270 void MapEditor::cut()
  1271 {
  1272 	setChanged();
  1273 	saveState(PartOfMap,selection->getParObj());
  1274 	copy();
  1275 	cutNoSave();
  1276 	mapCenter->reposition();
  1277 	adjustCanvasSize();
  1278 }
  1279 
  1280 void MapEditor::moveBranchUp()
  1281 {
  1282 	// Finish open lineEdits
  1283 	if (lineedit) finishedLineEditNoSave();
  1284 
  1285 	BranchObj* bo;
  1286 	BranchObj* par;
  1287 	if (typeid(*selection) == typeid(BranchObj)  ) 
  1288 	{
  1289 		setChanged();
  1290 		saveState(PartOfMap,selection->getParObj());
  1291 		bo=(BranchObj*)(selection);
  1292 		par=(BranchObj*)(bo->getParObj());
  1293 		selection->unselect();
  1294 		selection=par->moveBranchUp (bo);
  1295 		selection->select();
  1296 		mapCenter->reposition();
  1297 		ensureSelectionVisible();
  1298 	}
  1299 }
  1300 
  1301 void MapEditor::moveBranchDown()
  1302 {
  1303 	// Finish open lineEdits
  1304 	if (lineedit) finishedLineEditNoSave();
  1305 
  1306 	BranchObj* bo;
  1307 	BranchObj* par;
  1308 	if (typeid(*selection) == typeid(BranchObj)  ) 
  1309 	{
  1310 		setChanged();
  1311 		saveState(PartOfMap,selection->getParObj());
  1312 		bo=(BranchObj*)(selection);
  1313 		par=(BranchObj*)(bo->getParObj());
  1314 		selection->unselect(); 
  1315 		selection=par->moveBranchDown(bo);
  1316 		selection->select();
  1317 		mapCenter->reposition();
  1318 		ensureSelectionVisible();
  1319 	}	
  1320 }
  1321 
  1322 void MapEditor::editHeading()
  1323 {
  1324 	// Finish open lineEdits
  1325 	if (lineedit) finishedLineEditNoSave();
  1326 
  1327 	if (selection  &&  
  1328 		 (typeid(*selection) == typeid(BranchObj) || 
  1329 		  typeid(*selection) == typeid(MapCenterObj) ) ) 
  1330 	{
  1331 		setChanged();
  1332 		saveState(PartOfMap,selection);
  1333 
  1334 		ensureSelectionVisible();
  1335 		editingBO=(BranchObj*)(selection);
  1336 		QPoint p = worldMatrix().map(QPoint (editingBO->x(),editingBO->y()));
  1337 		lineedit->setGeometry(p.x()-contentsX(),p.y()-contentsY(),200,25);
  1338 		QString s=editingBO->getHeading();
  1339 		lineedit->setText(s);
  1340 		lineedit->setCursorPosition(1);
  1341 		if (actionSettingsAutoselectText->isOn() && !s.isEmpty() && actionSettingsPasteNewHeading->isOn() )
  1342 			lineedit->selectAll();
  1343 		lineedit->show();
  1344 
  1345 		lineedit->grabKeyboard();
  1346 		lineedit->setFocus();
  1347 	}				
  1348 }
  1349 
  1350 void MapEditor::addNewBranch(int pos)
  1351 {
  1352 	// Finish open lineEdits
  1353 	if (lineedit) finishedLineEditNoSave();
  1354 
  1355 	if (selection  &&  
  1356 		 (typeid(*selection) == typeid(BranchObj) || 
  1357 		  typeid(*selection) == typeid(MapCenterObj) ) ) 
  1358 	{
  1359 		setChanged();
  1360 		saveState(PartOfMap,selection);
  1361 
  1362 		BranchObj* bo1 = (BranchObj*) (selection);
  1363 		bool wasScrolled=false;
  1364 		BranchObj *newbo=NULL;
  1365 		if (pos==0)
  1366 		{
  1367 			// save scroll state. If scrolled, automatically select
  1368 			// new branch in order to tmp unscroll parent...
  1369 			wasScrolled=bo1->isScrolled();
  1370 			newbo=bo1->addBranch();
  1371 		}	else 
  1372 		{
  1373 			BranchObj *parbo=(BranchObj*)(selection->getParObj());
  1374 			if (parbo)
  1375 			{
  1376 				if (pos<0)
  1377 					// add above selection
  1378 					newbo=parbo->insertBranch(bo1->getNum());
  1379 				else
  1380 					// add below selection
  1381 					newbo=parbo->insertBranch(bo1->getNum()+1);
  1382 			} else
  1383 				// This should not happen...
  1384 				return;
  1385 			
  1386 		}	
  1387 
  1388 		LinkableMapObj *oldselection=selection;
  1389 
  1390 		mapCenter->reposition();
  1391 		adjustCanvasSize();
  1392 		if (actionSettingsAutoedit->isOn() ||
  1393 			actionSettingsAutoselectHeading->isOn() )
  1394 		{
  1395 			selection->unselect();
  1396 			selection=newbo;
  1397 			selection->select();
  1398 			if (actionSettingsPasteNewHeading->isOn() )
  1399 			{
  1400 				BranchObj *bo2= (BranchObj*)(selection);
  1401 				bo2->setHeading("");
  1402 			}	
  1403 			if (actionSettingsAutoedit->isOn() )
  1404 				editHeading();
  1405 			if (!actionSettingsAutoselectHeading->isOn()
  1406 				&& !wasScrolled)
  1407 			{
  1408 				selection->unselect();
  1409 				selection=oldselection;
  1410 				selection->select();
  1411 			}
  1412 		}	
  1413 	}	
  1414 }
  1415 
  1416 
  1417 void MapEditor::addNewBranchHere()
  1418 {
  1419 	// Finish open lineEdits
  1420 	if (lineedit) finishedLineEditNoSave();
  1421 
  1422 	if (selection  &&  
  1423 		 (typeid(*selection) == typeid(BranchObj) ) )
  1424 	{
  1425 		setChanged();
  1426 		saveState(PartOfMap,selection);
  1427 
  1428 		BranchObj* bo1 = (BranchObj*) (selection);
  1429 		bool wasScrolled=false;
  1430 		BranchObj *newbo=NULL;
  1431 		BranchObj *parbo=(BranchObj*)(selection->getParObj());
  1432 		if (parbo)
  1433 		{
  1434 			// add below selection
  1435 			newbo=parbo->insertBranch(bo1->getNum()+1);
  1436 		} 
  1437 
  1438 		LinkableMapObj *oldselection=selection;
  1439 		((BranchObj*)(selection))->moveBranchTo (newbo,-1);
  1440 
  1441 		mapCenter->reposition();
  1442 		adjustCanvasSize();
  1443 		if (actionSettingsAutoedit->isOn() ||
  1444 			actionSettingsAutoselectHeading->isOn() )
  1445 		{
  1446 			selection->unselect();
  1447 			selection=newbo;
  1448 			selection->select();
  1449 			if (actionSettingsPasteNewHeading->isOn() )
  1450 			{
  1451 				BranchObj *bo2= (BranchObj*)(selection);
  1452 				bo2->setHeading("");
  1453 			}	
  1454 			if (actionSettingsAutoedit->isOn() )
  1455 				editHeading();
  1456 			if (!actionSettingsAutoselectHeading->isOn()
  1457 				&& !wasScrolled)
  1458 			{
  1459 				selection->unselect();
  1460 				selection=oldselection;
  1461 				selection->select();
  1462 			}
  1463 		}	
  1464 	}	
  1465 }
  1466 
  1467 void MapEditor::deleteSelection()
  1468 {
  1469 	// Finish open lineEdits
  1470 	if (lineedit) finishedLineEditNoSave();
  1471 
  1472 	if (selection  && typeid(*selection) ==typeid(BranchObj) ) 
  1473 	{
  1474 		setChanged();
  1475 		saveState(PartOfMap,selection->getParObj());
  1476 		BranchObj* bo=dynamic_cast <BranchObj*> (selection);
  1477 		BranchObj* par=(BranchObj*)(bo->getParObj());
  1478 		bo->unselect();
  1479 		selection=NULL;
  1480 		par->removeBranch(bo);
  1481 		selection=par;
  1482 		selection->select();
  1483 		ensureSelectionVisible();
  1484 		mapCenter->reposition();
  1485 		adjustCanvasSize();
  1486 	}
  1487 	if (selection  && typeid(*selection) ==typeid(FloatImageObj) ) 
  1488 	{
  1489 		setChanged();
  1490 		saveState(PartOfMap,selection->getParObj());
  1491 		FloatImageObj* fio=dynamic_cast <FloatImageObj*> (selection);
  1492 		BranchObj* par=(BranchObj*)(fio->getParObj());
  1493 		fio->unselect();
  1494 		selection=NULL;
  1495 		par->removeFloatImage(fio);
  1496 		selection=par;
  1497 		selection->select();
  1498 		ensureSelectionVisible();
  1499 		mapCenter->reposition();
  1500 		adjustCanvasSize();
  1501 	}
  1502 }
  1503 
  1504 LinkableMapObj* MapEditor::getSelection()
  1505 {
  1506 	return selection;
  1507 }
  1508 
  1509 bool MapEditor::select (const QString &s)
  1510 {
  1511 	LinkableMapObj *lmo=mapCenter->findObj(s);
  1512 
  1513 	// Finally select the found object
  1514 	if (lmo)
  1515 	{
  1516 		if (selection) unselect();
  1517 		selection=lmo;
  1518 		selection->select();
  1519 		adjustCanvasSize();
  1520 		ensureSelectionVisible();
  1521 		return true;
  1522 	} else
  1523 		return false;
  1524 }
  1525 
  1526 void MapEditor::unselect()
  1527 {
  1528 	if (selection) 
  1529 	{
  1530 		selectionLast=selection;
  1531 		selection->unselect();
  1532 		selection=NULL;
  1533 	}
  1534 }	
  1535 
  1536 void MapEditor::reselect()
  1537 {
  1538 	if (selectionLast)
  1539 	{
  1540 		selection=selectionLast;
  1541 		selection->select();
  1542 		selectionLast=NULL;
  1543 	}
  1544 }	
  1545 
  1546 void MapEditor::selectNextBranch()
  1547 {
  1548 	// Increase number of branch
  1549 	if (selection)
  1550 	{
  1551 		QString s=selection->getSelectString();
  1552 		QString part;
  1553 		QString typ;
  1554 		QString num;
  1555 
  1556 		// Where am I? 
  1557 		part=s.section(",",-1);
  1558 		typ=part.left (3);
  1559 		num=part.right(part.length() - 3);
  1560 
  1561 		s=s.left (s.length() -num.length());
  1562 
  1563 		// Go to next lmo
  1564 		num=QString ("%1").arg(num.toUInt()+1);
  1565 
  1566 		s=s+num;
  1567 		
  1568 		// Try to select this one
  1569 		if (select (s)) return;
  1570 
  1571 		// We have no direct successor, 
  1572 		// try to increase the parental number in order to
  1573 		// find a successor with same depth
  1574 
  1575 		int d=selection->getDepth();
  1576 		int oldDepth=d;
  1577 		int i;
  1578 		bool found=false;
  1579 		bool b;
  1580 		while (!found && d>0)
  1581 		{
  1582 			s=s.section (",",0,d-1);
  1583 			// replace substring of current depth in s with "1"
  1584 			part=s.section(",",-1);
  1585 			typ=part.left (3);
  1586 			num=part.right(part.length() - 3);
  1587 
  1588 			if (d>1)
  1589 			{	
  1590 				// increase number of parent
  1591 				num=QString ("%1").arg(num.toUInt()+1);
  1592 				s=s.section (",",0,d-2) + ","+ typ+num;
  1593 			} else
  1594 			{
  1595 				// Special case, look at orientation
  1596 				if (selection->getOrientation()==OrientRightOfCenter)
  1597 					num=QString ("%1").arg(num.toUInt()+1);
  1598 				else	
  1599 					num=QString ("%1").arg(num.toUInt()-1);
  1600 				s=typ+num;
  1601 			}	
  1602 
  1603 			if (select (s))
  1604 				// pad to oldDepth, select the first branch for each depth
  1605 				for (i=d;i<oldDepth;i++)
  1606 				{
  1607 					b=select (s);
  1608 					if (b)
  1609 					{	
  1610 						if ( ((BranchObj*)(selection))->countBranches()>0)
  1611 							s+=",bo:0";
  1612 						else	
  1613 							break;
  1614 					} else
  1615 						break;
  1616 				}	
  1617 
  1618 			// try to select the freshly built string
  1619 			found=select(s);
  1620 			d--;
  1621 		}
  1622 		return;
  1623 	}	
  1624 }
  1625 
  1626 void MapEditor::selectPrevBranch()
  1627 {
  1628 	// Decrease number of branch
  1629 	if (selection)
  1630 	{
  1631 		QString s=selection->getSelectString();
  1632 		QString part;
  1633 		QString typ;
  1634 		QString num;
  1635 
  1636 		// Where am I? 
  1637 		part=s.section(",",-1);
  1638 		typ=part.left (3);
  1639 		num=part.right(part.length() - 3);
  1640 
  1641 		s=s.left (s.length() -num.length());
  1642 
  1643 		// Go to next lmo
  1644 		num=QString ("%1").arg(num.toUInt()-1);
  1645 
  1646 		s=s+num;
  1647 		
  1648 		// Try to select this one
  1649 		if (select (s)) return;
  1650 
  1651 		// We have no direct precessor, 
  1652 		// try to decrease the parental number in order to
  1653 		// find a precessor with same depth
  1654 
  1655 		int d=selection->getDepth();
  1656 		int oldDepth=d;
  1657 		int i;
  1658 		bool found=false;
  1659 		bool b;
  1660 		while (!found && d>0)
  1661 		{
  1662 			s=s.section (",",0,d-1);
  1663 			// replace substring of current depth in s with "1"
  1664 			part=s.section(",",-1);
  1665 			typ=part.left (3);
  1666 			num=part.right(part.length() - 3);
  1667 
  1668 			if (d>1)
  1669 			{
  1670 				// decrease number of parent
  1671 				num=QString ("%1").arg(num.toUInt()-1);
  1672 				s=s.section (",",0,d-2) + ","+ typ+num;
  1673 			} else
  1674 			{
  1675 				// Special case, look at orientation
  1676 				if (selection->getOrientation()==OrientRightOfCenter)
  1677 					num=QString ("%1").arg(num.toUInt()-1);
  1678 				else	
  1679 					num=QString ("%1").arg(num.toUInt()+1);
  1680 				s=typ+num;
  1681 			}	
  1682 
  1683 			if (select(s))
  1684 				// pad to oldDepth, select the last branch for each depth
  1685 				for (i=d;i<oldDepth;i++)
  1686 				{
  1687 					b=select (s);
  1688 					if (b)
  1689 						if ( ((BranchObj*)(selection))->countBranches()>0)
  1690 							s+=",bo:"+ QString ("%1").arg( ((BranchObj*)(selection))->countBranches()-1 );
  1691 						else	
  1692 							break;
  1693 					else
  1694 						break;
  1695 				}	
  1696 			
  1697 			// try to select the freshly built string
  1698 			found=select(s);
  1699 			d--;
  1700 		}
  1701 		return;
  1702 	}	
  1703 }
  1704 
  1705 void MapEditor::selectUpperBranch()
  1706 {
  1707 	// Finish open lineEdits
  1708 	if (lineedit) finishedLineEditNoSave();
  1709 
  1710 	if (selection) 
  1711 	{
  1712 		if (typeid(*selection) == typeid(BranchObj))
  1713 		{
  1714 			if (selection->getOrientation()==OrientRightOfCenter)
  1715 				selectPrevBranch();
  1716 			else
  1717 				if (selection->getDepth()==1)
  1718 					selectNextBranch();
  1719 				else
  1720 					selectPrevBranch();
  1721 		}		
  1722 	}
  1723 }
  1724 
  1725 void MapEditor::selectLowerBranch()
  1726 {
  1727 	// Finish open lineEdits
  1728 	if (lineedit) finishedLineEditNoSave();
  1729 
  1730 	if (selection) 
  1731 	{
  1732 		if (typeid(*selection) == typeid(BranchObj))
  1733 		{
  1734 			if (selection->getOrientation()==OrientRightOfCenter)
  1735 				selectNextBranch();
  1736 			else
  1737 				if (selection->getDepth()==1)
  1738 					selectPrevBranch();
  1739 				else
  1740 					selectNextBranch();
  1741 		}		
  1742 	}
  1743 }
  1744 
  1745 
  1746 void MapEditor::selectLeftBranch()
  1747 {
  1748 	// Finish open lineEdits
  1749 	if (lineedit) finishedLineEditNoSave();
  1750 
  1751 	BranchObj* bo;
  1752 	BranchObj* par;
  1753 	if (selection) 
  1754 	{
  1755 		if (typeid(*selection) == typeid(MapCenterObj))
  1756 		{
  1757 			par=  (BranchObj*) (selection);
  1758 			bo=par->getLastSelectedBranch();
  1759 			if (bo)
  1760 			{
  1761 				// Workaround for reselecting on left and right side
  1762 				if (bo->getOrientation()==OrientRightOfCenter)
  1763 				{
  1764 					bo=par->getLastBranch();
  1765 				}	
  1766 				if (bo)
  1767 				{
  1768 					par->unselect();
  1769 					selection=bo;
  1770 					selection->select();
  1771 					adjustCanvasSize();
  1772 					ensureSelectionVisible();
  1773 				}
  1774 			}	
  1775 		} else
  1776 		{
  1777 			par=(BranchObj*)(selection->getParObj());
  1778 			if (selection->getOrientation()==OrientRightOfCenter)
  1779 			{
  1780 				if (typeid(*selection) == typeid(BranchObj) ||
  1781 					typeid(*selection) == typeid(FloatImageObj))
  1782 				{
  1783 					selection->unselect();
  1784 					selection=par;
  1785 					selection->select();
  1786 					adjustCanvasSize();
  1787 					ensureSelectionVisible();
  1788 				}
  1789 			} else
  1790 			{
  1791 				if (typeid(*selection) == typeid(BranchObj) )
  1792 				{
  1793 					bo=((BranchObj*)(selection))->getLastSelectedBranch();
  1794 					if (bo) 
  1795 					{
  1796 						selection->unselect();
  1797 						selection=bo;
  1798 						selection->select();
  1799 						adjustCanvasSize();
  1800 						ensureSelectionVisible();
  1801 					}
  1802 				}
  1803 			}
  1804 		}	
  1805 	}
  1806 }
  1807 
  1808 void MapEditor::selectRightBranch()
  1809 {
  1810 	// Finish open lineEdits
  1811 	if (lineedit) finishedLineEditNoSave();
  1812 
  1813 	BranchObj* bo;
  1814 	BranchObj* par;
  1815 
  1816 	if (selection) 
  1817 	{
  1818 		if (typeid(*selection) == typeid(MapCenterObj))
  1819 		{
  1820 			par=  (BranchObj*) (selection);
  1821 			bo=par->getLastSelectedBranch();
  1822 			if (bo)
  1823 			{
  1824 				// Workaround for relecting on left and right side
  1825 				if (bo->getOrientation()==OrientLeftOfCenter)
  1826 					bo=par->getFirstBranch();
  1827 				if (bo)
  1828 				{
  1829 					par->unselect();
  1830 					selection=bo;
  1831 					selection->select();
  1832 					ensureSelectionVisible();
  1833 				}
  1834 			}
  1835 		} else
  1836 		{
  1837 			par=(BranchObj*)(selection->getParObj());
  1838 			if (selection->getOrientation()==OrientLeftOfCenter)
  1839 			{
  1840 				if (typeid(*selection) == typeid(BranchObj) ||
  1841 					typeid(*selection) == typeid(FloatImageObj))
  1842 				{
  1843 					selection->unselect();
  1844 					selection=par;
  1845 					selection->select();
  1846 					adjustCanvasSize();
  1847 					ensureSelectionVisible();
  1848 				}
  1849 			} else
  1850 			{
  1851 				if (typeid(*selection) == typeid(BranchObj) )
  1852 				{
  1853 					bo=((BranchObj*)(selection))->getLastSelectedBranch();
  1854 					if (bo) 
  1855 					{
  1856 						selection->unselect();
  1857 						selection=bo;
  1858 						selection->select();
  1859 						adjustCanvasSize();
  1860 						ensureSelectionVisible();
  1861 					}
  1862 				}
  1863 			}
  1864 		}
  1865 	}
  1866 }
  1867 
  1868 void MapEditor::selectFirstBranch()
  1869 {
  1870 	// Finish open lineEdits
  1871 	if (lineedit) finishedLineEditNoSave();
  1872 
  1873 	BranchObj *bo1;
  1874 	BranchObj *bo2;
  1875 	BranchObj* par;
  1876 	if (selection) {
  1877 		if (typeid(*selection) == typeid(BranchObj))
  1878 		{
  1879 			bo1=  (BranchObj*) (selection);
  1880 			par=(BranchObj*)(bo1->getParObj());
  1881 			bo2=par->getFirstBranch();
  1882 			if (bo2) {
  1883 				bo1->unselect();
  1884 				selection=bo2;
  1885 				selection->select();
  1886 				ensureSelectionVisible();
  1887 			}
  1888 		}		
  1889 		adjustCanvasSize();
  1890 	}
  1891 }
  1892 
  1893 void MapEditor::selectLastBranch()
  1894 {
  1895 	// Finish open lineEdits
  1896 	if (lineedit) finishedLineEditNoSave();
  1897 
  1898 	BranchObj *bo1;
  1899 	BranchObj *bo2;
  1900 	BranchObj* par;
  1901 	if (selection) {
  1902 		if (typeid(*selection) == typeid(BranchObj))
  1903 		{
  1904 			bo1=  (BranchObj*) (selection);
  1905 			par=(BranchObj*)(bo1->getParObj());
  1906 			bo2=par->getLastBranch();
  1907 			if (bo2) {
  1908 				bo1->unselect();
  1909 				selection=bo2;
  1910 				selection->select();
  1911 				ensureSelectionVisible();
  1912 			}
  1913 		}		
  1914 		adjustCanvasSize();
  1915 	}
  1916 }
  1917 
  1918 void MapEditor::setColor(QColor c)
  1919 {
  1920 	actColor=c;
  1921 }
  1922 
  1923 void MapEditor::selectBackgroundColor()
  1924 {
  1925 	// Finish open lineEdits
  1926 	if (lineedit) finishedLineEditNoSave();
  1927 
  1928 	QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
  1929 	if ( !col.isValid() ) return;
  1930 	setBackgroundColor( col );
  1931 	setChanged();
  1932 }
  1933 
  1934 void MapEditor::setBackgroundColor(QColor c)
  1935 {
  1936 	mapCanvas->setBackgroundColor (c);
  1937 }
  1938 
  1939 QColor MapEditor::pickColor()
  1940 {
  1941 	if (selection) 
  1942 	{
  1943 		if (typeid(*selection) == typeid(BranchObj) ||
  1944 			typeid(*selection) == typeid(MapCenterObj))
  1945 		{
  1946 			BranchObj *bo=(BranchObj*)(selection);
  1947 			actColor=bo->getColor(); 
  1948 		}    
  1949 	}
  1950 	return actColor;
  1951 }
  1952 
  1953 void MapEditor::colorItem()
  1954 {
  1955 	if (selection) 
  1956 	{
  1957 		if (typeid(*selection) == typeid(BranchObj) ||
  1958 			typeid(*selection) == typeid(MapCenterObj))
  1959 		{
  1960 			setChanged();
  1961 			saveState(PartOfMap,selection);
  1962 			BranchObj *bo=(BranchObj*)(selection);
  1963 			bo->setColor(actColor, false); // color links, color childs
  1964 		}    
  1965 	}
  1966 }
  1967 
  1968 void MapEditor::colorBranch()
  1969 {
  1970 	if (selection) 
  1971 	{
  1972 		if (typeid(*selection) == typeid(BranchObj) ||
  1973 			typeid(*selection) == typeid(MapCenterObj))
  1974 		{
  1975 			setChanged();
  1976 			saveState(PartOfMap,selection);
  1977 			BranchObj *bo=(BranchObj*)(selection);
  1978 			bo->setColor(actColor, true); // color links, color childs
  1979 		}    
  1980 	}
  1981 }
  1982 
  1983 
  1984 void MapEditor::toggleStandardFlag(QString f)
  1985 {
  1986 	if (selection)
  1987 	{
  1988 		setChanged();
  1989 		saveState(PartOfMap,selection);	
  1990 		((BranchObj*)(selection))->toggleStandardFlag (f);
  1991 	}	
  1992 }
  1993 
  1994 void MapEditor::setViewCenter()
  1995 {
  1996 	// transform to CanvasView Coord:
  1997 	QPoint p=worldMatrix().map(movingCenter);
  1998 	center ( p.x(), p.y());
  1999 }
  2000 
  2001 
  2002 BranchObj* MapEditor::findText (QString s, bool cs)
  2003 {
  2004 	if (!itFind) 
  2005 	{	// Nothing found or new find process
  2006 		if (EOFind)
  2007 			// nothing found, start again
  2008 			EOFind=false;
  2009 		itFind=mapCenter->first();
  2010 	}	
  2011 	bool searching=true;
  2012 	bool foundNote=false;
  2013 	while (searching && !EOFind)
  2014 	{
  2015 		if (itFind)
  2016 		{
  2017 			// Searching in Note
  2018 			if (itFind->getNote().contains(s,cs))
  2019 			{
  2020 				if (selection!=itFind) 
  2021 				{
  2022 					if (selection) ((BranchObj*)(selection))->unselect();
  2023 					selection=itFind;
  2024 					selection->select();
  2025 					adjustCanvasSize();
  2026 					ensureSelectionVisible();
  2027 				}
  2028 				if (textEditor->findText(s,cs)) 
  2029 				{
  2030 					searching=false;
  2031 					foundNote=true;
  2032 				}	
  2033 			}
  2034 			// Searching in Heading
  2035 			if (searching && itFind->getHeading().contains (s,cs) ) 
  2036 			{
  2037 				if (selection) ((BranchObj*)(selection))->unselect();
  2038 				selection=itFind;
  2039 				selection->select();
  2040 				adjustCanvasSize();
  2041 				ensureSelectionVisible();
  2042 				searching=false;
  2043 			}
  2044 		}	
  2045 		if (!foundNote)
  2046 		{
  2047 			itFind=itFind->next();
  2048 			if (!itFind) EOFind=true;
  2049 		}
  2050 	}	
  2051 	if (!searching)
  2052 	{
  2053 		adjustCanvasSize();
  2054 		return (BranchObj*)(selection);
  2055 	}	else
  2056 		return NULL;
  2057 }
  2058 
  2059 void MapEditor::findReset()
  2060 {	// Necessary if text to find changes during a find process
  2061 	itFind=NULL;
  2062 	EOFind=false;
  2063 }
  2064 
  2065 void MapEditor::openURL()
  2066 {
  2067 	if (selection )
  2068 	{
  2069 		if (typeid(*selection) == typeid(BranchObj) ||
  2070 			typeid(*selection) == typeid(MapCenterObj))
  2071 		{
  2072 			QString url=((BranchObj*)(selection))->getURL();
  2073 
  2074 			QProcess *proc = new QProcess( this );
  2075 
  2076 #if !defined(Q_OS_MACX)
  2077 			proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL","konqueror" ));
  2078 #else			
  2079 			proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL",
  2080 				"/Applications/Safari.app/Contents/MacOS/Safari" ));
  2081 #endif			
  2082 
  2083 			proc->addArgument( url);
  2084 
  2085 			if ( !proc->start() ) 
  2086 				// error handling
  2087 				if (mainWindow->settingsURL() ) 
  2088 					openURL();
  2089 		}	
  2090 	}	
  2091 }
  2092 
  2093 void MapEditor::editURL()
  2094 {
  2095 	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  2096 			typeid(*selection) == typeid(MapCenterObj)) )
  2097 	{		
  2098 		bool ok;
  2099 		QString text = QInputDialog::getText(
  2100 				"VYM", tr("Enter URL:"), QLineEdit::Normal,
  2101 				((BranchObj*)(selection))->getURL(), &ok, this );
  2102 		if ( ok) 
  2103 		{
  2104 			// user entered something and pressed OK
  2105 			((BranchObj*)(selection))->setURL (text);
  2106 			updateActions();
  2107 			setChanged();
  2108 		}	
  2109 	}
  2110 }
  2111 
  2112 void MapEditor::editHeading2URL()
  2113 {
  2114 	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  2115 			typeid(*selection) == typeid(MapCenterObj)) )
  2116 	{		
  2117 		BranchObj *b=(BranchObj*)(selection);
  2118 		b->setURL (b->getHeading());
  2119 		updateActions();
  2120 		setChanged();
  2121 	}
  2122 }	
  2123 
  2124 void MapEditor::editBugzilla2URL()
  2125 {
  2126 	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  2127 			typeid(*selection) == typeid(MapCenterObj)) )
  2128 	{		
  2129 		BranchObj *b=(BranchObj*)(selection);
  2130 		b->setURL ("https://bugzilla.novell.com/show_bug.cgi?id="+b->getHeading());
  2131 		updateActions();
  2132 		setChanged();
  2133 	}
  2134 }	
  2135 
  2136 void MapEditor::editVymLink()
  2137 {
  2138 	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  2139 			typeid(*selection) == typeid(MapCenterObj)) )
  2140 	{		
  2141 		QFileDialog *fd=new QFileDialog( this,tr("VYM - Link to another map"));
  2142 		fd->addFilter (QString (tr("vym map") + " (*.vym)"));
  2143 		fd->setCaption(tr("VYM - Link to another map"));
  2144 		if (! ((BranchObj*)(selection))->getVymLink().isEmpty() )
  2145 			fd->setSelection( ((BranchObj*)(selection))->getVymLink() );
  2146 		fd->show();
  2147 
  2148 		QString fn;
  2149 		if ( fd->exec() == QDialog::Accepted )
  2150 			((BranchObj*)(selection))->setVymLink (fd->selectedFile() );
  2151 		updateActions();
  2152 		mapCenter->reposition();
  2153 		adjustCanvasSize();
  2154 		canvas()->update();
  2155 		setChanged();
  2156 	}
  2157 }
  2158 
  2159 void MapEditor::deleteVymLink()
  2160 {
  2161 	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  2162 			typeid(*selection) == typeid(MapCenterObj)) )
  2163 	{		
  2164 		((BranchObj*)(selection))->setVymLink ("" );
  2165 		updateActions();
  2166 		mapCenter->reposition();
  2167 		adjustCanvasSize();
  2168 		canvas()->update();
  2169 		setChanged();
  2170 	}
  2171 }
  2172 
  2173 QString MapEditor::getVymLink()
  2174 {
  2175 	if (selection && (typeid(*selection) == typeid(BranchObj) ||
  2176 			typeid(*selection) == typeid(MapCenterObj)) )
  2177 	{		
  2178 		return ((BranchObj*)(selection))->getVymLink();
  2179 	}
  2180 	return "";
  2181 	
  2182 }
  2183 
  2184 void MapEditor::removeBranchHere()
  2185 {
  2186 	if (selection && (typeid(*selection) == typeid(BranchObj) ))
  2187 	{		
  2188 		setChanged();
  2189 		saveState(PartOfMap,selection->getParObj());
  2190 		QString sel=selection->getSelectString();
  2191 		BranchObj* bo=(BranchObj*)(selection);
  2192 		BranchObj* par=(BranchObj*)(bo->getParObj());
  2193 		unselect();
  2194 		par->removeBranchHere(bo);
  2195 		mapCenter->reposition();
  2196 		select (sel);
  2197 	}	
  2198 }
  2199 
  2200 void MapEditor::removeChilds()
  2201 {
  2202 	if (selection && (typeid(*selection) == typeid(BranchObj) ))
  2203 	{		
  2204 		setChanged();
  2205 		saveState(PartOfMap,selection->getParObj());
  2206 		((BranchObj*)(selection))->removeChilds();
  2207 		mapCenter->reposition();
  2208 	}	
  2209 }
  2210 
  2211 void MapEditor::editMapInfo()
  2212 {
  2213 	ExtraInfoDialog dia;
  2214 	dia.setMapName (getFileName() );
  2215 	dia.setAuthor (mapCenter->getAuthor() );
  2216 	dia.setComment(mapCenter->getComment() );
  2217 
  2218 	// Calc some stats
  2219 	QString stats;
  2220     int i=0;
  2221     QCanvasItemList l=canvas()->allItems();
  2222     for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) 
  2223         i++;
  2224     stats+=QString ("%1 items on canvas\n").arg (i,6);
  2225 
  2226 	uint b=0;
  2227 	uint f=0;
  2228 	uint n=0;
  2229 	BranchObj *bo;
  2230 	bo=mapCenter->first();
  2231 	while (bo) 
  2232 	{
  2233 		if (!bo->getNote().isEmpty() ) n++;
  2234 		f+= bo->countFloatImages();
  2235 		b++;
  2236 		bo=bo->next();
  2237 	}
  2238     stats+=QString ("%1 branches\n").arg (b-1,6);
  2239     stats+=QString ("%1 notes\n").arg (n,6);
  2240     stats+=QString ("%1 images\n").arg (f,6);
  2241 	dia.setStats (stats);
  2242 
  2243 	// Finally show dialog
  2244 	if (dia.exec() == QDialog::Accepted)
  2245 	{
  2246 		mapCenter->setAuthor (dia.getAuthor() );
  2247 		mapCenter->setComment (dia.getComment() );
  2248 		setChanged();
  2249 	}
  2250 }
  2251 
  2252 void MapEditor::updateActions()
  2253 {
  2254 	QAction *a;
  2255 	if (getLinkColorHint()==HeadingColor) 
  2256 		actionFormatLinkColorHint->setOn(true);
  2257 	else	
  2258 		actionFormatLinkColorHint->setOn(false);
  2259 
  2260 	switch (linkstyle)
  2261 	{
  2262 		case StyleLine: 
  2263 			actionFormatLinkStyleLine->setOn(true);
  2264 			break;
  2265 		case StyleParabel:
  2266 			actionFormatLinkStyleParabel->setOn(true);
  2267 			break;
  2268 		case StylePolyLine:	
  2269 			actionFormatLinkStylePolyLine->setOn(true);
  2270 			break;
  2271 		case StylePolyParabel:	
  2272 			actionFormatLinkStylePolyParabel->setOn(true);
  2273 			break;
  2274 		default:
  2275 			break;
  2276 	}	
  2277 
  2278 	QPixmap pix( 16, 16 );
  2279     pix.fill( mapCanvas->backgroundColor() );
  2280     actionFormatBackColor->setIconSet( pix );
  2281     pix.fill( defLinkColor );
  2282     actionFormatLinkColor->setIconSet( pix );
  2283 
  2284 	actionEditUndo->setEnabled( mapChanged );
  2285 	actionFileSave->setEnabled( mapUnsaved );
  2286 
  2287 	if (selection)
  2288 	{
  2289 		if ( (typeid(*selection) == typeid(BranchObj)) || 
  2290 			(typeid(*selection) == typeid(MapCenterObj))  )
  2291 		{
  2292 			BranchObj *bo=(BranchObj*)(selection);
  2293 			// Take care of links
  2294 			if (bo->countXLinks()==0)
  2295 			{
  2296 				branchLinksContextMenu->clear();
  2297 				branchLinksContextMenu->insertItem ("No link available");
  2298 				branchLinksContextMenuDup->clear();
  2299 				branchLinksContextMenuDup->insertItem ("No link available");
  2300 				
  2301 			} else
  2302 			{
  2303 				BranchObj *bot;
  2304 				QString s;
  2305 				branchLinksContextMenu->clear();
  2306 				branchLinksContextMenuDup->clear();
  2307 				for (int i=0; i<=bo->countXLinks();i++)
  2308 				{
  2309 					bot=bo->XLinkTargetAt(i);
  2310 					if (bot)
  2311 					{
  2312 						s=bot->getHeading();
  2313 						if (s.length()>25)
  2314 							s=s.left(25)+"...";
  2315 						branchLinksContextMenu->insertItem (s);
  2316 						branchLinksContextMenuDup->insertItem (s);
  2317 					}	
  2318 				}
  2319 			}
  2320 
  2321 			standardFlagsDefault->setEnabled (true);
  2322 
  2323 			if ( bo->getURL().isEmpty() )
  2324 				actionEditOpenURL->setEnabled (false);
  2325 			else	
  2326 				actionEditOpenURL->setEnabled (true);
  2327 
  2328 			if ( bo->getVymLink().isEmpty() )
  2329 			{
  2330 				actionEditOpenVymLink->setEnabled (false);
  2331 				actionEditDeleteVymLink->setEnabled (false);
  2332 			} else	
  2333 			{
  2334 				actionEditOpenVymLink->setEnabled (true);
  2335 				actionEditDeleteVymLink->setEnabled (true);
  2336 			}	
  2337 
  2338 			actionEditCopy->setEnabled (true);	
  2339 			actionEditCut->setEnabled (true);	
  2340 			actionEditPaste->setEnabled (true);	
  2341 			for (a=actionListBranches.first();a;a=actionListBranches.next())
  2342 				a->setEnabled(true);
  2343 			actionEditDelete->setEnabled (true);
  2344 			actionEditToggleFloatExport->setEnabled (false);
  2345 			switch (selection->getFrameType())
  2346 			{
  2347 				case NoFrame: 
  2348 					actionFormatFrameNone->setOn(true);
  2349 					break;
  2350 				case Rectangle:
  2351 					actionFormatFrameRectangle->setOn(true);
  2352 					break;
  2353 				default:
  2354 					break;
  2355 			}	
  2356 		}
  2357 		if ( (typeid(*selection) == typeid(FloatImageObj)) )
  2358 		{
  2359 			standardFlagsDefault->setEnabled (false);
  2360 
  2361 			actionEditOpenURL->setEnabled (false);
  2362 			actionEditOpenVymLink->setEnabled (false);
  2363 			actionEditDeleteVymLink->setEnabled (false);	
  2364 
  2365 			actionEditCopy->setEnabled (true);
  2366 			actionEditCut->setEnabled (true);	
  2367 			actionEditPaste->setEnabled (false);	//FIXME
  2368 			for (a=actionListBranches.first();a;a=actionListBranches.next())
  2369 				a->setEnabled(false);
  2370 			actionEditDelete->setEnabled (true);
  2371 			actionEditToggleFloatExport->setOn
  2372 				( ((FloatImageObj*)(selection))->getFloatExport() );
  2373 		}
  2374 
  2375 	} else
  2376 	{
  2377 		standardFlagsDefault->setEnabled (false);
  2378 
  2379 		actionEditCopy->setEnabled (false);	
  2380 		actionEditCut->setEnabled (false);	
  2381 		actionEditPaste->setEnabled (false);	
  2382 		for (a=actionListBranches.first();a;a=actionListBranches.next())
  2383 			a->setEnabled(false);
  2384 
  2385 		actionEditOpenURL->setEnabled (false);
  2386 		actionEditOpenVymLink->setEnabled (false);
  2387 		actionEditDeleteVymLink->setEnabled (false);	
  2388 		actionEditHeading2URL->setEnabled (false);	
  2389 		actionEditDelete->setEnabled (false);
  2390 		actionEditToggleFloatExport->setEnabled (false);
  2391 	}	
  2392 }
  2393 
  2394 void MapEditor::setLinkStyle (LinkStyle ls)
  2395 {
  2396 	linkstyle=ls;
  2397 
  2398 	BranchObj *bo;
  2399 	bo=mapCenter->first();
  2400 	bo=bo->next();
  2401 	while (bo) 
  2402 	{
  2403 		bo->setLinkStyle(bo->getDefLinkStyle());
  2404 		bo=bo->next();
  2405 	}
  2406 	//setChanged();
  2407 	//saveState();
  2408 }
  2409 
  2410 LinkStyle MapEditor::getLinkStyle ()
  2411 {
  2412 	return linkstyle;
  2413 }	
  2414 
  2415 void MapEditor::setLinkColor(QColor c)
  2416 {
  2417 	defLinkColor=c;
  2418 	updateActions();
  2419 }
  2420 
  2421 void MapEditor::setLinkColorHint()
  2422 {
  2423 	// called from setLinkColorHint(lch) or at end of parse
  2424 	BranchObj *bo;
  2425 	bo=mapCenter->first();
  2426 	while (bo) 
  2427 	{
  2428 		bo->setLinkColor();
  2429 		bo=bo->next();
  2430 	}
  2431 }
  2432 
  2433 void MapEditor::setLinkColorHint(LinkColorHint lch)
  2434 {
  2435 	linkcolorhint=lch;
  2436 	setLinkColorHint();
  2437 }
  2438 
  2439 void MapEditor::toggleLinkColorHint()
  2440 {
  2441 	if (linkcolorhint==HeadingColor)
  2442 		linkcolorhint=DefaultColor;
  2443 	else	
  2444 		linkcolorhint=HeadingColor;
  2445 	BranchObj *bo;
  2446 	bo=mapCenter->first();
  2447 	while (bo) 
  2448 	{
  2449 		bo->setLinkColor();
  2450 		bo=bo->next();
  2451 	}
  2452 }
  2453 
  2454 LinkColorHint MapEditor::getLinkColorHint()
  2455 {
  2456 	return linkcolorhint;
  2457 }
  2458 
  2459 QColor MapEditor::getDefLinkColor()
  2460 {
  2461 	return defLinkColor;
  2462 }
  2463 
  2464 void MapEditor::setDefXLinkColor(QColor col)
  2465 {
  2466 	defXLinkColor=col;
  2467 }
  2468 
  2469 QColor MapEditor::getDefXLinkColor()
  2470 {
  2471 	return defXLinkColor;
  2472 }
  2473 
  2474 void MapEditor::setDefXLinkWidth (int w)
  2475 {
  2476 	defXLinkWidth=w;
  2477 }
  2478 
  2479 int MapEditor::getDefXLinkWidth()
  2480 {
  2481 	return defXLinkWidth;
  2482 }
  2483 
  2484 void MapEditor::selectLinkColor()
  2485 {
  2486 	// Finish open lineEdits
  2487 	if (lineedit) finishedLineEditNoSave();
  2488 
  2489 	QColor col = QColorDialog::getColor( defLinkColor, this );
  2490 	if ( !col.isValid() ) return;
  2491 	setLinkColor( col );
  2492 	setChanged();
  2493 }
  2494 
  2495 void MapEditor::toggleScroll()
  2496 {
  2497 	if (selection && (typeid(*selection) == typeid(BranchObj)) )
  2498 	{
  2499 		BranchObj *bo=((BranchObj*)(selection));
  2500 		if (bo->countBranches()==0) return;
  2501 		if (bo->getDepth()==0) return;
  2502 		setChanged();
  2503 		saveState(PartOfMap,selection);
  2504 		bo->toggleScroll();
  2505 		adjustCanvasSize();
  2506 		canvas()->update();
  2507 	}
  2508 }
  2509 
  2510 void MapEditor::unScrollAll()
  2511 {
  2512 	BranchObj *bo;
  2513 	bo=mapCenter->first();
  2514 	while (bo) 
  2515 	{
  2516 		if (bo->isScrolled()) bo->toggleScroll();
  2517 		bo=bo->next();
  2518 	}
  2519 }
  2520 
  2521 void MapEditor::loadFloatImage ()
  2522 {
  2523 	if (selection && 
  2524 		(typeid(*selection) == typeid(BranchObj)) || 
  2525 		(typeid(*selection) == typeid(MapCenterObj))  )
  2526 	{
  2527 		BranchObj *bo=((BranchObj*)(selection));
  2528 
  2529 		QFileDialog *fd=new QFileDialog( this,tr("vym - load image"));
  2530 		fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
  2531 		ImagePreview *p =new ImagePreview (fd);
  2532 		fd->setContentsPreviewEnabled( TRUE );
  2533 		fd->setContentsPreview( p, p );
  2534 		fd->setPreviewMode( QFileDialog::Contents );
  2535 		fd->setCaption(tr("vym - Load image"));
  2536 		fd->setDir (lastImageDir);
  2537 		fd->show();
  2538 
  2539 		QString fn;
  2540 		if ( fd->exec() == QDialog::Accepted )
  2541 		{
  2542 			setChanged();
  2543 			saveState(PartOfMap,selection);
  2544 			QString fn=fd->selectedFile();
  2545 			lastImageDir=fn.left(fn.findRev ("/"));
  2546 			bo->addFloatImage();
  2547 			// FIXME check if load was successful
  2548 			bo->getLastFloatImage()->load(fn);
  2549 			bo->getLastFloatImage()->setOriginalFilename(fn);
  2550 			mapCenter->reposition();
  2551 			adjustCanvasSize();
  2552 			canvas()->update();
  2553 		}
  2554 	}
  2555 }
  2556 
  2557 void MapEditor::saveFloatImage (int item)
  2558 {
  2559 	if (selection && 
  2560 		(typeid(*selection) == typeid(FloatImageObj)) )
  2561 	{
  2562 		FloatImageObj *fio=((FloatImageObj*)(selection));
  2563 		const char* fmt = saveImageFormatMenu->text(item);
  2564 
  2565 		QFileDialog *fd=new QFileDialog( this, tr("vym - save image as") + fmt);
  2566 		fd->addFilter ("PNG (*.png)");
  2567 		fd->addFilter ("BMP (*.bmp)");
  2568 		fd->addFilter ("XBM (*.xbm)");
  2569 		fd->addFilter ("JPG (*.jpg)");
  2570 		fd->addFilter ("XPM (*.xpm)");
  2571 		fd->addFilter ("GIF (*.gif)");
  2572 		fd->addFilter ("PNM (*.pnm)");
  2573 		fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
  2574 		fd->setCaption(tr("vym - Save image as ") + fmt);
  2575 		fd->setMode( QFileDialog::AnyFile );
  2576 		fd->setSelection (fio->getOriginalFilename());
  2577 		fd->show();
  2578 
  2579 		QString fn;
  2580 		if ( fd->exec() == QDialog::Accepted )
  2581 		{
  2582 			if (QFile (fd->selectedFile()).exists() )
  2583 			{
  2584 				QMessageBox mb( "VYM",
  2585 					tr("The file ") + fd->selectedFile() + 
  2586 					tr(" exists already. "
  2587 					"Do you want to overwrite it?"),
  2588 				QMessageBox::Warning,
  2589 				QMessageBox::Yes | QMessageBox::Default,
  2590 				QMessageBox::Cancel | QMessageBox::Escape,
  2591 				QMessageBox::QMessageBox::NoButton );
  2592 
  2593 				mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
  2594 				mb.setButtonText( QMessageBox::No, tr("Cancel"));
  2595 				switch( mb.exec() ) 
  2596 				{
  2597 					case QMessageBox::Yes:
  2598 						// save 
  2599 						break;;
  2600 					case QMessageBox::Cancel:
  2601 						// do nothing
  2602 						return;
  2603 						break;
  2604 				}
  2605 			}
  2606 			fio->save (fd->selectedFile(),fmt);
  2607 		}
  2608 	}
  2609 }
  2610 
  2611 void MapEditor::toggleFloatExport()
  2612 {
  2613 	if (selection && 
  2614 		(typeid(*selection) == typeid(FloatImageObj))|| 
  2615 		(typeid(*selection) == typeid(FloatObj)) )
  2616 	{
  2617 		FloatImageObj *fio=((FloatImageObj*)(selection));
  2618 		fio->setFloatExport (actionEditToggleFloatExport->isOn() );
  2619 	}
  2620 }
  2621 
  2622 void MapEditor::setFrame(const FrameType &t)
  2623 {
  2624 	if (selection && 
  2625 		(typeid(*selection) == typeid(BranchObj)) || 
  2626 		(typeid(*selection) == typeid(MapCenterObj))  )
  2627 	{
  2628 		selection->setFrameType (t);
  2629 		mapCenter->reposition();
  2630 		selection->updateLink();
  2631 	}
  2632 }
  2633 
  2634 void MapEditor::importDir(BranchObj *dst, QDir d)
  2635 {
  2636 	if (selection && 
  2637 		(typeid(*selection) == typeid(BranchObj)) || 
  2638 		(typeid(*selection) == typeid(MapCenterObj))  )
  2639 	{
  2640 		BranchObj *bo;
  2641 		
  2642 		// Traverse directories
  2643 		d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
  2644 		const QFileInfoList *dirlist = d.entryInfoList();
  2645 		QFileInfoListIterator itdir( *dirlist );
  2646 		QFileInfo *fi;
  2647 
  2648 		while ( (fi = itdir.current()) != 0 ) 
  2649 		{
  2650 			if (fi->fileName() != "." && fi->fileName() != ".." )
  2651 			{
  2652 				dst->addBranch();
  2653 				bo=dst->getLastBranch();
  2654 				bo->setHeading (fi->fileName() );
  2655 				bo->setColor (QColor("blue"),false);
  2656 				bo->toggleScroll();
  2657 				if ( !d.cd(fi->fileName()) ) 
  2658 					QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory"));
  2659 				else 
  2660 				{
  2661 					importDir (bo,d);
  2662 					d.cdUp();
  2663 				}
  2664 			}	
  2665 			++itdir;
  2666 		}		
  2667 		// Traverse files
  2668 		d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
  2669 		const QFileInfoList *filelist = d.entryInfoList();
  2670 		QFileInfoListIterator itfile( *filelist );
  2671 
  2672 		while ( (fi = itfile.current()) != 0 ) 
  2673 		{
  2674 			dst->addBranch();
  2675 			bo=dst->getLastBranch();
  2676 			bo->setHeading (fi->fileName() );
  2677 			bo->setColor (QColor("black"),false);
  2678 			++itfile;
  2679 		}	
  2680 	}		
  2681 }
  2682 
  2683 void MapEditor::importDir()
  2684 {
  2685 	if (selection && 
  2686 		(typeid(*selection) == typeid(BranchObj)) || 
  2687 		(typeid(*selection) == typeid(MapCenterObj))  )
  2688 	{
  2689 		QFileDialog *fd=new QFileDialog( this,tr("VYM - Choose directory structur to import"));
  2690 		fd->setMode (QFileDialog::DirectoryOnly);
  2691 		fd->addFilter (QString (tr("vym map") + " (*.vym)"));
  2692 		fd->setCaption(tr("VYM - Choose directory structur to import"));
  2693 		fd->show();
  2694 
  2695 		QString fn;
  2696 		if ( fd->exec() == QDialog::Accepted )
  2697 		{
  2698 			BranchObj *bo=((BranchObj*)(selection));
  2699 			importDir (bo,QDir(fd->selectedFile()) );
  2700 			mapCenter->reposition();
  2701 			adjustCanvasSize();
  2702 			canvas()->update();
  2703 		}
  2704 	}	
  2705 }
  2706 
  2707 void MapEditor::followXLink(int i)
  2708 {
  2709 	if (selection && 
  2710 		(typeid(*selection) == typeid(BranchObj)) || 
  2711 		(typeid(*selection) == typeid(MapCenterObj))  )
  2712 	{
  2713 		BranchObj *bo=((BranchObj*)(selection))->XLinkTargetAt(i);
  2714 		if (bo) 
  2715 		{
  2716 			selection->unselect();
  2717 			selection=bo;
  2718 			selection->select();
  2719 			ensureSelectionVisible();
  2720 		}
  2721 	}
  2722 }
  2723 
  2724 void MapEditor::editXLink(int i)
  2725 {
  2726 	if (selection && 
  2727 		(typeid(*selection) == typeid(BranchObj)) || 
  2728 		(typeid(*selection) == typeid(MapCenterObj))  )
  2729 	{
  2730 		XLinkObj *xlo=((BranchObj*)(selection))->XLinkAt(i);
  2731 		if (xlo) 
  2732 		{
  2733 			EditXLinkDialog dia;
  2734 			dia.setXLink (xlo);
  2735 			if (dia.exec() == QDialog::Accepted)
  2736 			{
  2737 				if (dia.useSettingsGlobal() )
  2738 				{
  2739 					setDefXLinkColor (xlo->getColor() );
  2740 					setDefXLinkWidth (xlo->getWidth() );
  2741 				}
  2742 				if (dia.deleteXLink())
  2743 					((BranchObj*)(selection))->deleteXLinkAt(i);
  2744 				setChanged();
  2745 			}
  2746 		}	
  2747 	}
  2748 }
  2749 
  2750 void MapEditor::testFunction()
  2751 {
  2752 	cout << "MapEditor::testFunction() called\n";
  2753 }
  2754 
  2755 void MapEditor::ensureSelectionVisible()
  2756 {
  2757 	if (selection)
  2758 	{
  2759 		LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
  2760 		QPoint p;
  2761 		if (selection->getOrientation() == OrientLeftOfCenter)
  2762 			p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
  2763 		else	
  2764 			p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
  2765 		ensureVisible (p.x(), p.y() );
  2766 	}
  2767 
  2768 }
  2769 
  2770 void MapEditor::updateViewCenter()
  2771 {
  2772 	// Update movingCenter, so that we can zoom comfortably later
  2773 	QRect rc = QRect( contentsX(), contentsY(),
  2774 				  visibleWidth(), visibleHeight() );
  2775 	QRect canvasRect = inverseWorldMatrix().mapRect(rc);
  2776 	movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
  2777 	movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
  2778 }
  2779 
  2780 void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e )
  2781 {
  2782 	// Lineedits are already closed by preceding
  2783 	// mouseEvent, we don't need to close here.
  2784 
  2785     QPoint p = inverseWorldMatrix().map(e->pos());
  2786     LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
  2787 	
  2788     if (lmo) 
  2789 	{	// MapObj was found
  2790 		if (selection != lmo)
  2791 		{
  2792 			// select the MapObj
  2793 			if (selection) selection->unselect();
  2794 			selection=lmo;
  2795 			selection->select();
  2796 			adjustCanvasSize();
  2797 		}
  2798 		// Context Menu 
  2799 		if (selection) 
  2800 		{
  2801 			if (typeid(*selection)==typeid(BranchObj) ||
  2802 				typeid(*selection)==typeid(MapCenterObj) )
  2803 			{
  2804 				// Context Menu on branch or mapcenter
  2805 				updateActions();
  2806 				branchContextMenu->popup(e->globalPos() );
  2807 			}	
  2808 			if (typeid(*selection)==typeid(FloatImageObj))
  2809 			{
  2810 				// Context Menu on floatimage
  2811 				updateActions();
  2812 				floatimageContextMenu->popup(e->globalPos() );
  2813 			}	
  2814 		}	
  2815 	} else 
  2816 	{ // No MapObj found, we are on the Canvas itself
  2817 		// Context Menu on Canvas
  2818 		updateActions();
  2819 		canvasContextMenu->popup(e->globalPos() );
  2820     } 
  2821 }
  2822 
  2823 void MapEditor::contentsMousePressEvent(QMouseEvent* e)
  2824 {
  2825 	// Finish open lineEdits
  2826 	if (lineedit) finishedLineEditNoSave();
  2827 	
  2828     QPoint p = inverseWorldMatrix().map(e->pos());
  2829     LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
  2830 	
  2831 	// Special case: CTRL is pressed
  2832 	if (e->state() & QMouseEvent::ControlButton)
  2833 	{
  2834 		if (actionModModeColor->isOn())
  2835 		{
  2836 			if (e->state() & QMouseEvent::ControlButton)
  2837 			{
  2838 				pickingColor=true;
  2839 				setCursor (pickColorCursor);
  2840 				return;
  2841 			}
  2842 		} 
  2843 		if (actionModModeLink->isOn())
  2844 		{	
  2845 			BranchObj *bo_begin=NULL;
  2846 			if (lmo)
  2847 				bo_begin=(BranchObj*)(lmo);
  2848 			else	
  2849 				if (selection && 
  2850 					((typeid(*selection) == typeid(BranchObj)) || 
  2851 					(typeid(*selection) == typeid(MapCenterObj)))  )
  2852 				bo_begin=(BranchObj*)(selection);
  2853 			if (bo_begin)	
  2854 			{
  2855 				drawingLink=true;
  2856 				linkingObj_src=bo_begin;
  2857 				tmpXLink=new XLinkObj (mapCanvas);
  2858 				tmpXLink->setBegin (bo_begin);
  2859 				tmpXLink->setEnd   (p);
  2860 				tmpXLink->setColor(defXLinkColor);
  2861 				tmpXLink->setWidth(defXLinkWidth);
  2862 				tmpXLink->updateXLink();
  2863 				tmpXLink->setVisibility (true);
  2864 				return;
  2865 			} 
  2866 		}	
  2867 	}
  2868 
  2869     if (lmo) 
  2870 	{	// MapObj was found
  2871 		if (selection != lmo)
  2872 		{
  2873 			// select the MapObj
  2874 			if (selection) selection->unselect();
  2875 			selection=lmo;
  2876 			selection->select();
  2877 				
  2878 			adjustCanvasSize();
  2879 			
  2880 		}
  2881 
  2882 		// Check, if systemFlag clicked
  2883 		if (typeid(*selection)==typeid(BranchObj) ||
  2884 			typeid(*selection)==typeid(MapCenterObj) )
  2885 		{
  2886 			QString foname=((BranchObj*)(selection))->getSystemFlagName(p);
  2887 			if (!foname.isEmpty())
  2888 			{
  2889 				// Do not move, if systemFlag clicked
  2890 				if (foname=="url") 
  2891 					openURL();
  2892 				else
  2893 					if (foname=="vymLink")
  2894 					{
  2895 						mainWindow->editOpenVymLink();
  2896 						// tabWidget may change, better return now
  2897 						// before segfaulting...
  2898 						return;
  2899 					} else
  2900 						if (foname=="note")
  2901 							mainWindow->windowToggleNoteEditor();
  2902 			}			
  2903 		}	
  2904 			
  2905 		// Left Button	    Move Branches
  2906 		if (e->button() == QMouseEvent::LeftButton )
  2907 		{
  2908 			// If modMode==copy, then we want to "move" the _new_ object around
  2909 			// then we need the offset from p to the _old_ selection, because of tmp
  2910 			if (actionModModeCopy->isOn() &&
  2911 				e->state() & QMouseEvent::ControlButton)
  2912 			{
  2913 				if (typeid(*selection)==typeid(BranchObj) )
  2914 				{
  2915 					copyingObj=true;
  2916 					movingObj_start.setX( p.x() - selection->x() );	
  2917 					movingObj_start.setY( p.y() - selection->y() );	
  2918 					mapCenter->addBranch ((BranchObj*)(selection));
  2919 					unselect();
  2920 					selection=mapCenter->getLastBranch();
  2921 					selection->select();
  2922 					selection->setParObjTmp ((BranchObj*)(selection),p,1); 
  2923 					selection->updateLink();
  2924 				}
  2925 			}	else
  2926 			{
  2927 				movingObj_start.setX( p.x() - selection->x() );	
  2928 				movingObj_start.setY( p.y() - selection->y() );	
  2929 			}
  2930 			
  2931 			movingObj=selection;	
  2932 		} else
  2933 			// Middle Button    Toggle Scroll
  2934 			// (On Mac OS X this won't work, but we still have 
  2935 			// a button in the toolbar)
  2936 			if (e->button() == QMouseEvent::MidButton )
  2937 				toggleScroll();
  2938 		updateActions();
  2939 	} else 
  2940 	{ // No MapObj found, we are on the Canvas itself
  2941 		// Left Button	    move Pos of CanvasView
  2942 		if (e->button() == QMouseEvent::LeftButton )
  2943 		{
  2944 			movingObj=NULL;	// move Content not Obj
  2945 			movingObj_start=e->globalPos();
  2946 			movingCont_start=QPoint (contentsX(), contentsY() );
  2947 			movingVec=QPoint(0,0);
  2948 			setCursor(handOpenCursor);
  2949 		} 
  2950     } 
  2951 }
  2952 
  2953 void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
  2954 {
  2955 	QPoint p = inverseWorldMatrix().map(e->pos());
  2956 
  2957     // Move the selected MapObj
  2958     if ( selection && movingObj) 
  2959     {	
  2960 		ensureVisible (p.x(),p.y());
  2961 		
  2962 		// Now move the selection, but add relative position 
  2963 		// (movingObj_start) where selection was chosen with 
  2964 		// mousepointer. (This avoids flickering resp. jumping 
  2965 		// of selection back to absPos)
  2966 		
  2967 		LinkableMapObj *lmosel;
  2968 		lmosel =  dynamic_cast <LinkableMapObj*> (selection);
  2969 
  2970 		// Check if we could link 
  2971 		LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
  2972 		
  2973 
  2974 		if (typeid(*selection) == typeid(FloatImageObj))
  2975 		{
  2976 			setChanged();
  2977 			saveState();
  2978 			FloatObj *fo=(FloatObj*)(selection);
  2979 			if (fo->getLinkStyle()==StyleUndef) 
  2980 			{
  2981 				fo->setLinkStyle(fo->getDefLinkStyle());
  2982 				fo->setLinkColor(fo->getParObj()->getLinkColor());
  2983 			}	
  2984 			fo->move   (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  2985 			fo->setRelPos();
  2986 			fo->reposition();
  2987 
  2988 			// Relink float to new mapcenter or branch, if shift is pressed	
  2989 			// Only relink, if selection really has a new parent
  2990 			if ( (e->state() & QMouseEvent::ShiftButton) && lmo &&
  2991 				( (typeid(*lmo)==typeid(BranchObj)) ||
  2992 				  (typeid(*lmo)==typeid(MapCenterObj)) ) &&
  2993 				( lmo != fo->getParObj())  
  2994 				)
  2995 			{
  2996 				if (typeid(*fo) == typeid(FloatImageObj)) 
  2997 				{
  2998 					FloatImageObj *fio=(FloatImageObj*)(fo);
  2999 					((BranchObj*)(lmo))->addFloatImage (fio);
  3000 					fio->unselect();
  3001 					((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
  3002 					fio=((BranchObj*)(lmo))->getLastFloatImage();
  3003 					fio->setRelPos();
  3004 					fio->reposition();
  3005 					selection=(LinkableMapObj*)(fio);
  3006 					selection->select();
  3007 					movingObj=(MapObj*)(fio);
  3008 					// setLinkStyle calls updateLink, only set it once
  3009 					if (fio->getLinkStyle()!=fio->getDefLinkStyle() ) 
  3010 						fio->setLinkStyle (fio->getDefLinkStyle());
  3011 
  3012 				}	
  3013 				// TODO if (typeid(*selection) == typeid(FloatTextObj))
  3014 			}
  3015 		} else	// selection != a FloatObj
  3016 		{
  3017 			if (lmosel->getDepth()==0)
  3018 			{
  3019 				if (e->state() == (LeftButton | !ShiftButton)) 
  3020 					// If mapCenter is moved, move all the rest by default, too.
  3021 					mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  3022 				else	
  3023 					mapCenter->move   (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  3024 			} else
  3025 			{	
  3026 				if (lmosel->getDepth()==1)
  3027 				{
  3028 					// depth==1, mainbranch
  3029 					setChanged();
  3030 					saveState(PartOfMap,lmosel);
  3031 					lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );		
  3032 				} else
  3033 				{
  3034 					// depth>1
  3035 					if (lmosel->getOrientation() == OrientLeftOfCenter)
  3036 						// Add width of bbox here, otherwise alignRelTo will cause jumping around
  3037 						lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(), 
  3038 							p.y()-movingObj_start.y() );		
  3039 					else	
  3040 						lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
  3041 				} 
  3042 				// reposition subbranch
  3043 				lmosel->reposition();	
  3044 				//ensureSelectionVisible();
  3045 
  3046 				if (lmo && (lmo!=selection) &&  
  3047 					(typeid(*lmo) == typeid(BranchObj) ||
  3048 					(typeid(*lmo) == typeid(MapCenterObj) )
  3049 					) )
  3050 				{
  3051 					if (e->state() & QMouseEvent::ControlButton)
  3052 					{
  3053 						// Special case: CTRL to link below lmo
  3054 						lmosel->setParObjTmp (lmo,p,+1);
  3055 					}
  3056 					else if (e->state() & QMouseEvent::ShiftButton)
  3057 						lmosel->setParObjTmp (lmo,p,-1);
  3058 					else
  3059 						lmosel->setParObjTmp (lmo,p,0);
  3060 				} else	
  3061 				{
  3062 					lmosel->unsetParObjTmp();
  3063 					/*
  3064 					if (lmo &&(lmo==selection))   
  3065 						// Could link to myself (happens sometimes...)
  3066 						lmosel->unsetParObjTmp();
  3067 					if (!lmo)  
  3068 						// no Obj under selection, go back to original Parent
  3069 						lmosel->unsetParObjTmp();
  3070 					*/	
  3071 				}		
  3072 			} // depth>0
  3073 
  3074 		} // no FloatImageObj
  3075 
  3076 		canvas()->update();
  3077 		return;
  3078 	} // selection && moving_obj
  3079 		
  3080 	// Draw a link from one branch to another
  3081 	if (drawingLink)
  3082 	{
  3083 		 tmpXLink->setEnd (p);
  3084 		 tmpXLink->updateXLink();
  3085 	}	 
  3086 	
  3087     // Move CanvasView 
  3088     if (!movingObj && !pickingColor &&!drawingLink) 
  3089 	{
  3090 		QPoint p=e->globalPos();
  3091 		movingVec.setX(-p.x() + movingObj_start.x() );
  3092 		movingVec.setY(-p.y() + movingObj_start.y() );
  3093 		setContentsPos( movingCont_start.x() + movingVec.x(),
  3094 	    movingCont_start.y() + movingVec.y());
  3095 
  3096 		updateViewCenter();
  3097     }
  3098 }
  3099 
  3100 
  3101 void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e)
  3102 {
  3103 	LinkableMapObj *dst;
  3104 	// Have we been picking color?
  3105 	if (pickingColor)
  3106 	{
  3107 		pickingColor=false;
  3108 		setCursor (ArrowCursor);
  3109 		// Check if we are over another branch
  3110 		dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
  3111 		if (dst && selection) 
  3112 		{	
  3113 			if (e->state() & QMouseEvent::ShiftButton)
  3114 			{
  3115 				((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),false);
  3116 				((BranchObj*)(selection))->setLinkColor ();
  3117 			}	
  3118 			else	
  3119 			{
  3120 				((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),true);
  3121 				((BranchObj*)(selection))->setLinkColor ();
  3122 			}	
  3123 		} 
  3124 		return;
  3125 	}
  3126 
  3127 	// Have we been drawing a link?
  3128 	if (drawingLink)
  3129 	{
  3130 		drawingLink=false;
  3131 		// Check if we are over another branch
  3132 		dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
  3133 		if (dst && selection) 
  3134 		{	
  3135 			tmpXLink->setEnd ( ((BranchObj*)(dst)) );
  3136 			tmpXLink->updateXLink();
  3137 			tmpXLink->activate();
  3138 			setChanged();
  3139 			
  3140 		} else
  3141 		{
  3142 			delete(tmpXLink);
  3143 			tmpXLink=NULL;
  3144 		}
  3145 		return;
  3146 	}
  3147 	
  3148     // Have we been moving something?
  3149     if ( selection && movingObj ) 
  3150     {	
  3151 		// Check if we are over another branch, but ignore 
  3152 		// any found LMOs, which are FloatObjs
  3153 		dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), 
  3154 			((LinkableMapObj*)(selection)) );
  3155 
  3156 		if (dst &&
  3157 		(typeid(*dst)!=typeid(BranchObj)&&typeid(*dst)!=typeid(MapCenterObj))) 
  3158 		{
  3159 			dst=NULL;
  3160 		}	
  3161 		
  3162 		// Now check, if we have been moving a branch 
  3163 		if (typeid(*selection) == typeid(BranchObj)  )
  3164 		{
  3165 			// save the position in case we link to mapcenter
  3166 			QPoint savePos=QPoint (selection->x(),selection->y() );
  3167 
  3168 			// Reset the temporary drawn link to the original one
  3169 			((LinkableMapObj*)(selection))->unsetParObjTmp();
  3170 
  3171 
  3172 			copyingObj=false;	
  3173 			if (!dst ) 
  3174 			{
  3175 				if (copyingObj)
  3176 				{
  3177 					// remove the current selection, if we have no destination
  3178 					selection->unselect();
  3179 					((BranchObj*)(selection->getParObj()))->removeBranch ((BranchObj*)(selection));
  3180 					if (selectionLast)
  3181 					{
  3182 						selection=selectionLast;
  3183 						selectionLast=NULL;
  3184 						selection->select();
  3185 					}
  3186 				}
  3187 			} else
  3188 			{
  3189 				setChanged();
  3190 				saveState();
  3191 				// TODO we also could check, if dest and src are on same branch,
  3192 				// then it would be sufficient to saveState of this branch
  3193 
  3194 				// Modifiers allow to insert above/below dst
  3195 				if (e->state() & QMouseEvent::ShiftButton)
  3196 				{
  3197 						((BranchObj*)(selection))->moveBranchTo 
  3198 						(
  3199 							(BranchObj*)(dst),
  3200 							((BranchObj*)(dst))->getNum()
  3201 						);
  3202 					//if (selection) selection->select();
  3203 				} else 
  3204 				if (e->state() & QMouseEvent::ControlButton)
  3205 				{
  3206 					((BranchObj*)(selection))->moveBranchTo 
  3207 					(
  3208 						(BranchObj*)(dst),
  3209 						((BranchObj*)(dst))->getNum()+1
  3210 					);
  3211 					//if (selection) selection->select();
  3212 				} else	
  3213 				{
  3214 					((BranchObj*)(selection))->moveBranchTo ((BranchObj*)(dst),-1);
  3215 					if (dst->getDepth()==0) 
  3216 						((BranchObj*)(selection))->move (savePos);
  3217 				} 
  3218 			}	
  3219 			// Draw the original link, before selection was moved around
  3220 			mapCenter->reposition();
  3221 		}
  3222 		// Finally resize canvas, if needed
  3223 		adjustCanvasSize();
  3224 		canvas()->update();
  3225 		movingObj=NULL;		
  3226 	} else 
  3227 		// maybe we moved View: set old cursor
  3228 		setCursor (ArrowCursor);
  3229     
  3230 }
  3231 
  3232 void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
  3233 {
  3234 	// Finish open lineEdits
  3235 	if (lineedit) finishedLineEditNoSave();
  3236 	
  3237 	if (e->button() == QMouseEvent::LeftButton )
  3238 	{
  3239 		QPoint p = inverseWorldMatrix().map(e->pos());
  3240 		LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
  3241 		if (lmo) {	// MapObj was found
  3242 			// First select the MapObj than edit heading
  3243 			if (selection) selection->unselect();
  3244 			selection=lmo;
  3245 			selection->select();
  3246 			setChanged();
  3247 			saveState(PartOfMap,selection);
  3248 			editHeading();
  3249 		}
  3250 	}
  3251 }
  3252 
  3253 void MapEditor::resizeEvent (QResizeEvent* e)
  3254 {
  3255 	QCanvasView::resizeEvent( e );
  3256 	
  3257 	QString s="";
  3258 	if (!fileName.isEmpty()) s=fileName;
  3259 	adjustCanvasSize();
  3260 }
  3261