3 #include <qstatusbar.h>
4 #include <qmessagebox.h>
5 #include <qapplication.h>
7 #include <qpopupmenu.h>
9 #include <qpaintdevicemetrics.h>
11 #include <qfiledialog.h>
14 #include <qcolordialog.h>
17 #include <qinputdialog.h>
26 #include "texteditor.h"
27 #include "linkablemapobj.h"
30 #include "mainwindow.h"
31 #include "extrainfodialog.h"
32 #include "editxlinkdialog.h"
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"
57 extern TextEditor *textEditor;
58 extern int statusbarTime;
59 extern Main *mainWindow;
60 extern FlagRowObj *systemFlagsDefault;
61 extern FlagRowObj *standardFlagsDefault;
62 extern MapEditor *clipboardME;
64 extern QPtrList <QAction> actionListBranches;
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;
96 extern QAction* actionFormatPickColor;
97 extern QAction* actionFormatColorBranch;
98 extern QAction* actionFormatColorSubtree;
99 extern QAction *actionFormatLinkColorHint;
100 extern QAction *actionFormatBackColor;
101 extern QAction *actionFormatLinkColor;
103 extern QActionGroup* actionGroupModModes;
104 extern QAction* actionModModeColor;
105 extern QAction* actionModModeLink;
106 extern QAction* actionModModeCopy;
108 extern QActionGroup *actionGroupFormatFrameTypes;
109 extern QAction *actionFormatFrameNone;
110 extern QAction *actionFormatFrameRectangle;
112 extern QActionGroup *actionGroupFormatLinkStyles;
113 extern QAction *actionFormatLinkStyleLine;
114 extern QAction *actionFormatLinkStyleParabel;
115 extern QAction *actionFormatLinkStylePolyLine;
116 extern QAction *actionFormatLinkStylePolyParabel;
118 extern QAction *actionViewToggleNoteEditor;
120 extern QAction *actionSettingsAutoedit;
121 extern QAction *actionSettingsAutoselectHeading;
122 extern QAction *actionSettingsAutoselectText;
123 extern QAction *actionSettingsPasteNewHeading;
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;
133 extern Settings settings;
136 ///////////////////////////////////////////////////////////////////////
137 ///////////////////////////////////////////////////////////////////////
138 MapEditor::MapEditor(
139 QWidget* parent, bool interactive, const char* name, WFlags f) :
140 QCanvasView(parent,name,f)
142 //cout << "Constructor ME "<<this<<endl;
144 mapCanvas = new QCanvas(1000,800);
145 mapCanvas->setAdvancePeriod(30);
147 setCanvas (mapCanvas);
149 setVScrollBarMode ( QScrollView::AlwaysOn );
150 setHScrollBarMode ( QScrollView::AlwaysOn );
152 // Now create the _global_ system flags _once_:
153 // (Later all OrnamentedObj copy from this
154 // and set their own canvas)
155 if (!systemFlagsDefault)
157 systemFlagsDefault = new FlagRowObj (mapCanvas);
158 systemFlagsDefault->setVisibility (false);
159 systemFlagsDefault->setName ("systemFlagsDef");
161 FlagObj *fo = new FlagObj (mapCanvas);
162 fo->load(QPixmap(flag_note_xpm));
164 fo->setToolTip(tr("Note","Systemflag"));
165 systemFlagsDefault->addFlag (fo); // makes deep copy
167 fo->load(QPixmap(flag_url_xpm));
169 fo->setToolTip(tr("WWW Document (external)","Systemflag"));
170 systemFlagsDefault->addFlag (fo);
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);
177 fo->load(QPixmap(flag_scrolled_right_xpm));
178 fo->setName("scrolledright");
179 fo->setToolTip(tr("subtree is scrolled","Systemflag"));
180 systemFlagsDefault->addFlag (fo);
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);
188 if (!standardFlagsDefault)
190 standardFlagsDefault = new FlagRowObj (mapCanvas);
191 standardFlagsDefault->setVisibility (false);
192 standardFlagsDefault->setName ("standardFlagsDef");
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
200 fo->load(QPixmap(flag_questionmark_xpm));
201 fo->setName("questionmark");
202 fo->setToolTip(tr("Really?","Standardflag"));
203 standardFlagsDefault->addFlag (fo);
205 fo->load(QPixmap(flag_hook_green_xpm));
206 fo->setName("hook-green");
207 fo->setToolTip(tr("ok!","Standardflag"));
208 standardFlagsDefault->addFlag (fo);
210 fo->load(QPixmap(flag_cross_red_xpm));
211 fo->setName("cross-red");
212 fo->setToolTip(tr("Not ok!","Standardflag"));
213 standardFlagsDefault->addFlag (fo);
215 fo->load(QPixmap(flag_stopsign_xpm));
216 fo->setName("stopsign");
217 fo->setToolTip(tr("This won't work!","Standardflag"));
218 standardFlagsDefault->addFlag (fo);
220 fo->load(QPixmap(flag_smiley_good_xpm));
221 fo->setName("smiley-good");
222 fo->setToolTip(tr("Good","Standardflag"));
223 standardFlagsDefault->addFlag (fo);
225 fo->load(QPixmap(flag_smiley_sad_xpm));
226 fo->setName("smiley-sad");
227 fo->setToolTip(tr("Bad","Standardflag"));
228 standardFlagsDefault->addFlag (fo);
230 fo->load(QPixmap(flag_clock_xpm));
231 fo->setName("clock");
232 fo->setToolTip(tr("Time critical","Standardflag"));
233 standardFlagsDefault->addFlag (fo);
235 fo->load(QPixmap(flag_lamp_xpm));
237 fo->setToolTip(tr("Idea!","Standardflag"));
238 standardFlagsDefault->addFlag (fo);
240 fo->load(QPixmap(flag_arrow_up_xpm));
241 fo->setName("arrow-up");
242 fo->setToolTip(tr("Important","Standardflag"));
243 standardFlagsDefault->addFlag (fo);
245 fo->load(QPixmap(flag_arrow_down_xpm));
246 fo->setName("arrow-down");
247 fo->setToolTip(tr("Unimportant","Standardflag"));
248 standardFlagsDefault->addFlag (fo);
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);
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);
260 fo->load(QPixmap(flag_heart_xpm));
261 fo->setName("heart");
262 fo->setToolTip(tr("I just love... ","Standardflag"));
263 standardFlagsDefault->addFlag (fo);
265 fo->load(QPixmap(flag_flash_xpm));
266 fo->setName("flash");
267 fo->setToolTip(tr("Dangerous","Standardflag"));
268 standardFlagsDefault->addFlag (fo);
270 fo->load(QPixmap(flag_lifebelt_xpm));
271 fo->setName("lifebelt");
272 fo->setToolTip(tr("This will help","Standardflag"));
273 standardFlagsDefault->addFlag (fo);
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"));
285 lineedit = new QLineEdit(this, "lineedit" );
286 connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEditNoSave() ) );
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);
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 );
306 #include "icons/cursorhandopen.xpm"
307 #include "icons/cursorcolorpicker.xpm"
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 );
326 defXLinkColor=QColor (230,230,230);
338 // Initialize find routine
345 blockreposition=false;
346 isInteractive=interactive;
348 // Create temporary files
351 // Initially set movingCentre
354 mapCenter->reposition(); // for positioning heading
357 MapEditor::~MapEditor()
359 //cout <<"Destructor MapEditor\n";
360 if (isInteractive) delTmpDirs();
363 //settings.writeEntry( "/vym/mapeditor/editmode/autoselect", );
367 QColor MapEditor::color()
372 QColor MapEditor::backgroundColor()
374 return mapCanvas->backgroundColor();
377 MapCenterObj* MapEditor::getMapCenter()
382 QCanvas* MapEditor::getCanvas()
387 void MapEditor::adjustCanvasSize()
389 // To adjust the canvas to map, viewport size and position, we have to
390 // do some coordinate magic...
392 // Get rectangle of (scroll-)view.
393 // We want to be in canvas coords, so
394 // we map. Important if view is zoomed...
395 QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(),
396 visibleWidth(), visibleHeight()) );
398 // Now we need the bounding box of view AND map to calc the correct canvas size.
399 // Why? Because if the map itself is moved out of view, the view has to be enlarged
400 // to avoid jumping aroung...
401 QRect map=mapCenter->getTotalBBox();
403 // right edge - left edge
404 int cw= max(map.x() + map.width(), view.x() + view.width()) - min(map.x(), view.x());
405 int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
408 if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) ||
409 !mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight())
412 // move the map on canvas (in order to not move it on screen) this is neccessary
413 // a) if topleft corner of canvas is left or above topleft corner of view and also left of
414 // above topleft corner of map. E.g. if map is completly inside view, but it would be possible
415 // to scroll to an empty area of canvas to the left.
416 // b) if topleft corner of map left of or above topleft of canvas
420 if (cw > mapCanvas->width() )
422 if (map.x()<0) dx=-map.x();
424 if (cw < mapCanvas->width() )
425 dx=-min (view.x(),map.x());
426 if (ch > mapCanvas->height() )
428 if (map.y()<0) dy=-map.y();
430 if (ch < mapCanvas->height() )
432 dy=-min (view.y(),map.y());
434 // We really have to resize now. Let's go...
435 mapCanvas->resize (cw,ch);
436 if ( (dx!=0) || (dy!=0) )
438 mapCenter->moveAllBy(dx,dy);
439 mapCenter->reposition();
441 // scroll the view (in order to not move map on screen)
447 bool MapEditor::blockReposition()
449 return blockreposition;
452 void MapEditor::makeTmpDirs()
454 // Create unique temporary directories
455 char tmpdir[]="/tmp/vym-XXXXXX";
456 bakMapDir=mkdtemp(tmpdir);
457 makeSubDirs(bakMapDir);
458 // FIXME set permissions
459 // and maybe use QT method for portability
462 void MapEditor::delTmpDirs()
464 //FIXME delete tmp directory, better use QT methods here:
465 system ( "rm -rf "+ bakMapDir );
469 void MapEditor::makeSubDirs(const QString &s)
477 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, SaveMode savemode)
479 // tmpdir temporary directory to which data will be writte
480 // prefix mapname, which will be appended to images etc.
481 // writeflags Only write flags for "real" save of map, not undo
482 // offset offset of bbox of whole map in canvas.
483 // Needed for XML export
484 // completeMap if false, only vympart will be written, without
501 ls="StylePolyParabel";
505 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
507 if (linkcolorhint==HeadingColor)
508 colhint=attribut("linkColorHint","HeadingColor");
510 QString mapAttr=attribut("version",__VYM_VERSION__);
511 if (savemode==CompleteMap)
512 mapAttr+= attribut("author",mapCenter->getAuthor()) +
513 attribut("comment",mapCenter->getComment()) +
514 attribut("date",mapCenter->getDate()) +
515 attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
516 attribut("linkStyle", ls ) +
517 attribut("linkColor", defLinkColor.name() ) +
518 attribut("defXLinkColor", defXLinkColor.name() ) +
519 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
521 s+=beginElement("vymmap",mapAttr);
524 // Find the used flags while traversing the tree
525 standardFlagsDefault->resetUsedCounter();
527 // Build xml recursivly
528 if (savemode==CompleteMap)
529 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
532 if ( undoSelection &&
533 typeid(*undoSelection) == typeid(BranchObj) )
534 s+=((BranchObj*)(undoSelection))->saveToDir(tmpdir,prefix,offset);
536 if (selection && typeid(*selection)==typeid(BranchObj))
537 s+=((BranchObj*)(selection))->saveToDir(tmpdir,prefix,offset);
540 // Save local settings
541 s+=settings.getXMLData (destPath);
545 s+=valueElement("select",selection->getSelectString());
548 s+=endElement("vymmap");
551 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
556 void MapEditor::saveState()
558 saveState (CompleteMap,NULL);
561 void MapEditor::saveState(const SaveMode &mode, LinkableMapObj *part)
563 // all binary data is saved in bakMapDir (created in Constructor)
564 // the xml data itself is kept in memory in backupXML
566 // For faster write/read of data, a part of the map can be
567 // written. Then the undoSelection will mark the part of the
568 // map which should be replaced if an undo is wanted later.
570 if (mode==PartOfMap && part && (typeid(*part) == typeid (BranchObj) ) )
572 // Writing a vympart only is useful for BranchObj
574 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),PartOfMap);
578 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),CompleteMap);
582 void MapEditor::finishedLineEditNoSave()
584 // This is called by finishedLineEdit or any MapEditor method,
585 // which wants to assure, that lineedits finish, before e.g. a branch is
588 // After calling LineEdit and using the clipboard, the
589 // focus is not any longer on the main widget, we
590 // have to restore it using parentWidget()->setFocus()
594 editingBO->setHeading(lineedit->text() );
596 lineedit->releaseKeyboard();
598 parentWidget()->setFocus();
599 mapCenter->reposition();
601 ensureSelectionVisible();
606 bool MapEditor::isDefault()
611 bool MapEditor::isUnsaved()
616 bool MapEditor::hasChanged()
621 void MapEditor::setChanged()
626 actionEditUndo->setEnabled (true);
627 actionFileSave->setEnabled (true);
631 void MapEditor::closeMap()
633 // Finish open lineEdits
634 if (lineedit) finishedLineEditNoSave();
636 // Unselect before disabling the toolbar actions
637 if (selection) selection->unselect();
645 void MapEditor::setFilePath(QString fname)
647 setFilePath (fname,fname);
650 void MapEditor::setFilePath(QString fname, QString destname)
656 // If fname is not an absolute path, complete it
657 filePath=QDir(fname).absPath();
658 fileDir=filePath.left (1+filePath.findRev ("/"));
660 // Set short name, too. Search from behind:
661 int i=fileName.findRev("/");
662 if (i>=0) fileName=fileName.remove (0,i+1);
664 // Forget the .vym (or .xml) for name of map
665 mapName=fileName.left(fileName.findRev(".",-1,true) );
668 QString MapEditor::getFilePath()
673 QString MapEditor::getFileName()
678 QString MapEditor::getMapName()
683 QString MapEditor::getDestPath()
688 int MapEditor::load (QString &fname, const LoadMode &lmode)
690 // Finish open lineEdits
691 if (lineedit) finishedLineEditNoSave();
697 if (selection) selection->unselect();
700 mapCenter->setMapEditor(this);
701 // (map state is set later at end of load...)
705 saveState(PartOfMap,selection);
709 mapBuilderHandler handler;
712 // I am paranoid: file should exist anyway
713 // according to check in mainwindow.
716 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
717 tr("Couldn't open map " +fname)+".");
721 blockreposition=true;
722 QXmlInputSource source( file);
723 QXmlSimpleReader reader;
724 reader.setContentHandler( &handler );
725 reader.setErrorHandler( &handler );
726 handler.setMapEditor( this );
727 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
728 handler.setLoadMode (lmode);
729 bool ok = reader.parse( source );
730 blockreposition=false;
734 mapCenter->reposition();
744 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
745 tr( handler.errorProtocol() ) );
747 // Still return "success": the map maybe at least
748 // partially read by the parser
755 int MapEditor::save (const SaveMode &savemode)
757 // Finish open lineEdits
758 if (lineedit) finishedLineEditNoSave();
762 // Create mapName and fileDir
763 makeSubDirs (fileDir);
767 fname=mapName+".xml";
769 // use name given by user, even if he chooses .doc
773 // Check if fname is writeable
774 QFile file( fileDir+fname);
775 if (!file.open( IO_WriteOnly ) )
777 QMessageBox::critical( 0, tr( "Critical Save Error" ),
778 tr("Couldn't write to ") +fileDir+fname);
784 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),savemode);
786 file.setName ( fileDir + fname);
787 if ( !file.open( IO_WriteOnly ) )
789 // This should neverever happen
790 QMessageBox::critical(0, tr("Critcal Save error"),"MapEditor::save() Couldn't open "+file.name());
794 // Write it finally, and write in UTF8, no matter what
795 QTextStream ts( &file );
796 ts.setEncoding (QTextStream::UnicodeUTF8);
804 actionFileSave->setEnabled(false);
810 void MapEditor::setZipped (bool z)
815 bool MapEditor::saveZipped ()
820 void MapEditor::print()
822 // Finish open lineEdits
823 if (lineedit) finishedLineEditNoSave();
827 printer = new QPrinter;
828 printer->setColorMode (QPrinter::Color);
831 QRect totalBBox=mapCenter->getTotalBBox();
833 // Try to set orientation automagically
834 // Note: Interpretation of generated postscript is amibiguous, if
835 // there are problems with landscape mode, see
836 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
838 if (totalBBox.width()>totalBBox.height())
839 // recommend landscape
840 printer->setOrientation (QPrinter::Landscape);
842 // recommend portrait
843 printer->setOrientation (QPrinter::Portrait);
845 if ( printer->setup(this) )
846 // returns false, if printing is canceled
848 QPainter pp(printer);
850 // Don't print the visualisation of selection
851 LinkableMapObj *oldselection=NULL;
854 oldselection=selection;
855 selection->unselect();
858 // Handle sizes of map and paper:
860 // setWindow defines which part of the canvas will be transformed
861 // setViewport defines area on paper in device coordinates (dpi)
862 // e.g. (0,50,700,700) is upper part on A4
863 // see also /usr/lib/qt3/doc/html/coordsys.html
865 QPaintDeviceMetrics metrics (printer);
867 double paperAspect = (double)metrics.width() / (double)metrics.height();
868 double mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
870 QRect mapRect=totalBBox;
871 QCanvasRectangle *frame=NULL;
872 QCanvasText *footerFN=NULL;
873 QCanvasText *footerDate=NULL;
874 if (printFrame || printFooter)
879 // Print frame around map
880 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
881 totalBBox.width()+20, totalBBox.height()+20);
882 frame=new QCanvasRectangle (mapRect,mapCanvas);
883 frame->setBrush (QColor(white));
884 frame->setPen (QColor(black));
889 QCanvasLine *l=new QCanvasLine (mapCanvas);
890 l->setPoints (0,0,mapRect.width(),mapRect.height());
891 l->setPen (QPen(QColor(black), 1));
898 // Print footer below map
900 font.setPointSize(10);
901 footerFN=new QCanvasText (mapCanvas);
902 footerFN->setText ("VYM - " + fileName);
903 footerFN->setFont(font);
904 footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
905 footerFN->setZ(Z_TEXT);
907 footerDate=new QCanvasText (mapCanvas);
908 footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
909 footerDate->setFont(font);
910 footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
911 footerDate->setZ(Z_TEXT);
914 pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()+20);
917 pp.setWindow (mapRect);
920 if (mapAspect>=paperAspect)
922 // Fit horizontally to paper width
923 pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );
926 // Fit vertically to paper height
927 pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());
930 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to printer
932 // Delete Frame and footer
938 if (frame) delete (frame);
943 selection=oldselection;
949 QPixmap MapEditor::getPixmap()
951 QRect mapRect=mapCenter->getTotalBBox();
952 QPixmap pix (mapRect.size());
955 // Don't print the visualisation of selection
956 LinkableMapObj *oldselection=NULL;
959 oldselection=selection;
960 selection->unselect();
963 pp.setWindow (mapRect);
965 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to painter
971 selection=oldselection;
978 void MapEditor::exportImage(QString fn)
980 // Finish open lineEdits
981 if (lineedit) finishedLineEditNoSave();
983 QPixmap pix (getPixmap());
987 void MapEditor::exportImage(QString fn, int item)
989 // Finish open lineEdits
990 if (lineedit) finishedLineEditNoSave();
992 QPixmap pix (getPixmap());
993 pix.save(fn, exportImageFormatMenu->text(item) );
996 void MapEditor::exportASCII()
998 // FIXME still experimental
999 QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (ASCII)"));
1000 fd->addFilter ("TXT (*.txt)");
1001 fd->setCaption("VYM - Export (ASCII) (still experimental)");
1002 fd->setMode( QFileDialog::AnyFile );
1005 if ( fd->exec() == QDialog::Accepted )
1007 if (QFile (fd->selectedFile()).exists() )
1009 QMessageBox mb( "VYM",
1010 tr("The file ") + fd->selectedFile() +
1011 tr(" exists already. Do you want to overwrite it?"),
1012 QMessageBox::Warning,
1013 QMessageBox::Yes | QMessageBox::Default,
1014 QMessageBox::Cancel | QMessageBox::Escape,
1015 QMessageBox::NoButton );
1017 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
1018 mb.setButtonText( QMessageBox::No, tr("Cancel"));
1022 case QMessageBox::Yes:
1024 if (!ex.setOutputDir ("out"))
1026 QMessageBox::critical (0,tr("Critical Export Error "),tr("Couldn't create directory ") + "out");
1030 case QMessageBox::Cancel:
1037 ex.setPath (fd->selectedFile() );
1038 ex.setMapCenter(mapCenter);
1044 void MapEditor::exportXML(const QString &dir)
1046 // Create subdirectories
1049 // write to directory
1050 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,CompleteMap);
1053 file.setName ( dir + "/"+mapName+".xml");
1054 if ( !file.open( IO_WriteOnly ) )
1056 // This should neverever happen
1057 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open ")+file.name());
1061 // Write it finally, and write in UTF8, no matter what
1062 QTextStream ts( &file );
1063 ts.setEncoding (QTextStream::UnicodeUTF8);
1067 // Now write image, too
1068 exportImage (dir+"/images/"+mapName+".png");
1071 void MapEditor::clear()
1075 selection->unselect();
1082 void MapEditor::undo()
1085 d.setPath(bakMapDir);
1088 // Finish open lineEdits
1089 if (lineedit) finishedLineEditNoSave();
1093 selection->unselect();
1097 mapBuilderHandler handler;
1098 QXmlInputSource source;
1099 source.setData(backupXML);
1100 QXmlSimpleReader reader;
1101 reader.setContentHandler( &handler );
1102 reader.setErrorHandler( &handler );
1103 handler.setMapEditor( this );
1104 handler.setTmpDir ( bakMapDir ); // needed to load files with rel. path
1107 selection=undoSelection;
1108 selection->select();
1109 handler.setLoadMode (ImportReplace);
1114 handler.setLoadMode (NewMap);
1116 blockreposition=true;
1117 bool ok = reader.parse( source );
1118 blockreposition=false;
1120 mapCenter->reposition();
1124 // This should never ever happen
1125 QMessageBox::critical( 0, tr( "Critical Parse Error by reading backupFile" ),
1126 tr( handler.errorProtocol() )+" in "+backupXML );
1128 // Undo not longer available now
1129 actionEditUndo->setEnabled (false);
1130 undoSelection=false;
1135 QMessageBox::critical( 0, tr( "Critical Error" ),
1136 "Temporary directory " +bakMapDir +
1137 tr (" used for undo is gone. \n"
1138 "I will create a new one, but at the moment no undo is available.\n"
1139 "Maybe you want to reload your original data.\n\n"
1140 "Sorry for any inconveniences.") );
1145 void MapEditor::copy()
1147 // Finish open lineEdits
1148 if (lineedit) finishedLineEditNoSave();
1152 if (typeid(*selection) == typeid(BranchObj) )
1156 clipboardME->clear();
1157 clipboardME->getMapCenter()->addBranch();
1158 to=clipboardME->getMapCenter()->getLastBranch();
1161 from=(BranchObj*)(selection);
1164 // keep position relative to parent
1165 to->move2RelPos ( from->getRelPos());
1167 // select data in clipboard
1168 clipboardME->select ("bo:0");
1170 // repositioning makes testing nicer,
1171 // but is not needed usually:
1172 if (clipboardME->isVisible())
1174 clipboardME->getMapCenter()->reposition();
1177 clipboardME->hide();
1180 if (typeid(*selection) == typeid(FloatImageObj) )
1183 FloatImageObj* from;
1184 clipboardME->clear();
1185 clipboardME->getMapCenter()->addFloatImage();
1186 to=clipboardME->getMapCenter()->getLastFloatImage();
1189 from=(FloatImageObj*)(selection);
1192 // select data in clipboard
1193 clipboardME->select ("fi:0");
1195 // repositioning makes testing nicer,
1196 // but is not needed usually:
1197 if (clipboardME->isVisible())
1199 clipboardME->getMapCenter()->reposition();
1202 clipboardME->hide();
1208 LinkableMapObj* MapEditor::pasteNoSave()
1210 // Finish open lineEdits
1211 if (lineedit) finishedLineEditNoSave();
1213 LinkableMapObj *fromLMO=clipboardME->getSelection();
1214 LinkableMapObj *returnLMO=NULL;
1216 if (selection && fromLMO)
1219 if (typeid(*fromLMO) == typeid(BranchObj) )
1221 if (typeid(*selection) == typeid(MapCenterObj))
1223 returnLMO=mapCenter->addBranch( (BranchObj*)(fromLMO) );
1224 ((BranchObj*)(returnLMO))->move2RelPos(normalise(fromLMO->getRelPos() ) );
1226 if (typeid(*selection) == typeid(BranchObj))
1227 returnLMO=((BranchObj*)(selection))->addBranch((BranchObj*)(fromLMO) );
1230 if (typeid(*fromLMO) == typeid(FloatImageObj) &&
1231 (typeid(*selection) == typeid (BranchObj) ||
1232 typeid(*selection)==typeid(MapCenterObj)) )
1233 returnLMO=((BranchObj*) (selection))->addFloatImage ((FloatImageObj*)(fromLMO));
1239 void MapEditor::cutNoSave()
1241 // Finish open lineEdits
1242 if (lineedit) finishedLineEditNoSave();
1246 if (selection != NULL) {
1247 if (typeid(*selection) == typeid(BranchObj) )
1249 bo=(BranchObj*)(selection);
1250 par=(BranchObj*)(bo->getParObj());
1253 par->removeBranch(bo);
1255 selection->select();
1257 if (typeid(*selection) == typeid(FloatImageObj) )
1259 FloatImageObj* fio=(FloatImageObj*)(selection);
1260 par=(BranchObj*)(fio->getParObj());
1263 par->removeFloatImage(fio);
1265 selection->select();
1270 void MapEditor::paste()
1273 saveState(PartOfMap,selection);
1275 mapCenter->reposition();
1279 void MapEditor::cut()
1282 saveState(PartOfMap,selection->getParObj());
1285 mapCenter->reposition();
1289 void MapEditor::moveBranchUp()
1291 // Finish open lineEdits
1292 if (lineedit) finishedLineEditNoSave();
1296 if (typeid(*selection) == typeid(BranchObj) )
1299 saveState(PartOfMap,selection->getParObj());
1300 bo=(BranchObj*)(selection);
1301 par=(BranchObj*)(bo->getParObj());
1302 selection->unselect();
1303 selection=par->moveBranchUp (bo);
1304 selection->select();
1305 mapCenter->reposition();
1306 ensureSelectionVisible();
1310 void MapEditor::moveBranchDown()
1312 // Finish open lineEdits
1313 if (lineedit) finishedLineEditNoSave();
1317 if (typeid(*selection) == typeid(BranchObj) )
1320 saveState(PartOfMap,selection->getParObj());
1321 bo=(BranchObj*)(selection);
1322 par=(BranchObj*)(bo->getParObj());
1323 selection->unselect();
1324 selection=par->moveBranchDown(bo);
1325 selection->select();
1326 mapCenter->reposition();
1327 ensureSelectionVisible();
1331 void MapEditor::editHeading()
1333 // Finish open lineEdits
1334 if (lineedit) finishedLineEditNoSave();
1337 (typeid(*selection) == typeid(BranchObj) ||
1338 typeid(*selection) == typeid(MapCenterObj) ) )
1341 saveState(PartOfMap,selection);
1343 ensureSelectionVisible();
1344 editingBO=(BranchObj*)(selection);
1345 QPoint p = worldMatrix().map(QPoint (editingBO->x(),editingBO->y()));
1346 lineedit->setGeometry(p.x()-contentsX(),p.y()-contentsY(),200,25);
1347 QString s=editingBO->getHeading();
1348 lineedit->setText(s);
1349 lineedit->setCursorPosition(1);
1350 if (actionSettingsAutoselectText->isOn() && !s.isEmpty() && actionSettingsPasteNewHeading->isOn() )
1351 lineedit->selectAll();
1354 lineedit->grabKeyboard();
1355 lineedit->setFocus();
1359 void MapEditor::addNewBranch(int pos)
1361 // Finish open lineEdits
1362 if (lineedit) finishedLineEditNoSave();
1365 (typeid(*selection) == typeid(BranchObj) ||
1366 typeid(*selection) == typeid(MapCenterObj) ) )
1369 saveState(PartOfMap,selection);
1371 BranchObj* bo1 = (BranchObj*) (selection);
1372 bool wasScrolled=false;
1373 BranchObj *newbo=NULL;
1376 // save scroll state. If scrolled, automatically select
1377 // new branch in order to tmp unscroll parent...
1378 wasScrolled=bo1->isScrolled();
1379 newbo=bo1->addBranch();
1382 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1386 // add above selection
1387 newbo=parbo->insertBranch(bo1->getNum());
1389 // add below selection
1390 newbo=parbo->insertBranch(bo1->getNum()+1);
1392 // This should not happen...
1397 LinkableMapObj *oldselection=selection;
1399 mapCenter->reposition();
1401 if (actionSettingsAutoedit->isOn() ||
1402 actionSettingsAutoselectHeading->isOn() )
1404 selection->unselect();
1406 selection->select();
1407 if (actionSettingsPasteNewHeading->isOn() )
1409 BranchObj *bo2= (BranchObj*)(selection);
1410 bo2->setHeading("");
1412 if (actionSettingsAutoedit->isOn() )
1414 if (!actionSettingsAutoselectHeading->isOn()
1417 selection->unselect();
1418 selection=oldselection;
1419 selection->select();
1426 void MapEditor::addNewBranchHere()
1428 // Finish open lineEdits
1429 if (lineedit) finishedLineEditNoSave();
1432 (typeid(*selection) == typeid(BranchObj) ) )
1435 saveState(PartOfMap,selection);
1437 BranchObj* bo1 = (BranchObj*) (selection);
1438 bool wasScrolled=false;
1439 BranchObj *newbo=NULL;
1440 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1443 // add below selection
1444 newbo=parbo->insertBranch(bo1->getNum()+1);
1447 LinkableMapObj *oldselection=selection;
1448 ((BranchObj*)(selection))->moveBranchTo (newbo,-1);
1450 mapCenter->reposition();
1452 if (actionSettingsAutoedit->isOn() ||
1453 actionSettingsAutoselectHeading->isOn() )
1455 selection->unselect();
1457 selection->select();
1458 if (actionSettingsPasteNewHeading->isOn() )
1460 BranchObj *bo2= (BranchObj*)(selection);
1461 bo2->setHeading("");
1463 if (actionSettingsAutoedit->isOn() )
1465 if (!actionSettingsAutoselectHeading->isOn()
1468 selection->unselect();
1469 selection=oldselection;
1470 selection->select();
1476 void MapEditor::deleteSelection()
1478 // Finish open lineEdits
1479 if (lineedit) finishedLineEditNoSave();
1481 if (selection && typeid(*selection) ==typeid(BranchObj) )
1484 saveState(PartOfMap,selection->getParObj());
1485 BranchObj* bo=dynamic_cast <BranchObj*> (selection);
1486 BranchObj* par=(BranchObj*)(bo->getParObj());
1489 par->removeBranch(bo);
1491 selection->select();
1492 ensureSelectionVisible();
1493 mapCenter->reposition();
1496 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
1499 saveState(PartOfMap,selection->getParObj());
1500 FloatImageObj* fio=dynamic_cast <FloatImageObj*> (selection);
1501 BranchObj* par=(BranchObj*)(fio->getParObj());
1504 par->removeFloatImage(fio);
1506 selection->select();
1507 ensureSelectionVisible();
1508 mapCenter->reposition();
1513 LinkableMapObj* MapEditor::getSelection()
1518 bool MapEditor::select (const QString &s)
1520 LinkableMapObj *lmo=mapCenter->findObj(s);
1522 // Finally select the found object
1525 if (selection) unselect();
1527 selection->select();
1529 ensureSelectionVisible();
1535 void MapEditor::unselect()
1539 selectionLast=selection;
1540 selection->unselect();
1545 void MapEditor::reselect()
1549 selection=selectionLast;
1550 selection->select();
1555 void MapEditor::selectNextBranch()
1557 // Increase number of branch
1560 QString s=selection->getSelectString();
1566 part=s.section(",",-1);
1568 num=part.right(part.length() - 3);
1570 s=s.left (s.length() -num.length());
1573 num=QString ("%1").arg(num.toUInt()+1);
1577 // Try to select this one
1578 if (select (s)) return;
1580 // We have no direct successor,
1581 // try to increase the parental number in order to
1582 // find a successor with same depth
1584 int d=selection->getDepth();
1589 while (!found && d>0)
1591 s=s.section (",",0,d-1);
1592 // replace substring of current depth in s with "1"
1593 part=s.section(",",-1);
1595 num=part.right(part.length() - 3);
1599 // increase number of parent
1600 num=QString ("%1").arg(num.toUInt()+1);
1601 s=s.section (",",0,d-2) + ","+ typ+num;
1604 // Special case, look at orientation
1605 if (selection->getOrientation()==OrientRightOfCenter)
1606 num=QString ("%1").arg(num.toUInt()+1);
1608 num=QString ("%1").arg(num.toUInt()-1);
1613 // pad to oldDepth, select the first branch for each depth
1614 for (i=d;i<oldDepth;i++)
1619 if ( ((BranchObj*)(selection))->countBranches()>0)
1627 // try to select the freshly built string
1635 void MapEditor::selectPrevBranch()
1637 // Decrease number of branch
1640 QString s=selection->getSelectString();
1646 part=s.section(",",-1);
1648 num=part.right(part.length() - 3);
1650 s=s.left (s.length() -num.length());
1653 num=QString ("%1").arg(num.toUInt()-1);
1657 // Try to select this one
1658 if (select (s)) return;
1660 // We have no direct precessor,
1661 // try to decrease the parental number in order to
1662 // find a precessor with same depth
1664 int d=selection->getDepth();
1669 while (!found && d>0)
1671 s=s.section (",",0,d-1);
1672 // replace substring of current depth in s with "1"
1673 part=s.section(",",-1);
1675 num=part.right(part.length() - 3);
1679 // decrease number of parent
1680 num=QString ("%1").arg(num.toUInt()-1);
1681 s=s.section (",",0,d-2) + ","+ typ+num;
1684 // Special case, look at orientation
1685 if (selection->getOrientation()==OrientRightOfCenter)
1686 num=QString ("%1").arg(num.toUInt()-1);
1688 num=QString ("%1").arg(num.toUInt()+1);
1693 // pad to oldDepth, select the last branch for each depth
1694 for (i=d;i<oldDepth;i++)
1698 if ( ((BranchObj*)(selection))->countBranches()>0)
1699 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)(selection))->countBranches()-1 );
1706 // try to select the freshly built string
1714 void MapEditor::selectUpperBranch()
1716 // Finish open lineEdits
1717 if (lineedit) finishedLineEditNoSave();
1721 if (typeid(*selection) == typeid(BranchObj))
1723 if (selection->getOrientation()==OrientRightOfCenter)
1726 if (selection->getDepth()==1)
1734 void MapEditor::selectLowerBranch()
1736 // Finish open lineEdits
1737 if (lineedit) finishedLineEditNoSave();
1741 if (typeid(*selection) == typeid(BranchObj))
1743 if (selection->getOrientation()==OrientRightOfCenter)
1746 if (selection->getDepth()==1)
1755 void MapEditor::selectLeftBranch()
1757 // Finish open lineEdits
1758 if (lineedit) finishedLineEditNoSave();
1764 if (typeid(*selection) == typeid(MapCenterObj))
1766 par= (BranchObj*) (selection);
1767 bo=par->getLastSelectedBranch();
1770 // Workaround for reselecting on left and right side
1771 if (bo->getOrientation()==OrientRightOfCenter)
1773 bo=par->getLastBranch();
1779 selection->select();
1781 ensureSelectionVisible();
1786 par=(BranchObj*)(selection->getParObj());
1787 if (selection->getOrientation()==OrientRightOfCenter)
1789 if (typeid(*selection) == typeid(BranchObj) ||
1790 typeid(*selection) == typeid(FloatImageObj))
1792 selection->unselect();
1794 selection->select();
1796 ensureSelectionVisible();
1800 if (typeid(*selection) == typeid(BranchObj) )
1802 bo=((BranchObj*)(selection))->getLastSelectedBranch();
1805 selection->unselect();
1807 selection->select();
1809 ensureSelectionVisible();
1817 void MapEditor::selectRightBranch()
1819 // Finish open lineEdits
1820 if (lineedit) finishedLineEditNoSave();
1827 if (typeid(*selection) == typeid(MapCenterObj))
1829 par= (BranchObj*) (selection);
1830 bo=par->getLastSelectedBranch();
1833 // Workaround for relecting on left and right side
1834 if (bo->getOrientation()==OrientLeftOfCenter)
1835 bo=par->getFirstBranch();
1840 selection->select();
1841 ensureSelectionVisible();
1846 par=(BranchObj*)(selection->getParObj());
1847 if (selection->getOrientation()==OrientLeftOfCenter)
1849 if (typeid(*selection) == typeid(BranchObj) ||
1850 typeid(*selection) == typeid(FloatImageObj))
1852 selection->unselect();
1854 selection->select();
1856 ensureSelectionVisible();
1860 if (typeid(*selection) == typeid(BranchObj) )
1862 bo=((BranchObj*)(selection))->getLastSelectedBranch();
1865 selection->unselect();
1867 selection->select();
1869 ensureSelectionVisible();
1877 void MapEditor::selectFirstBranch()
1879 // Finish open lineEdits
1880 if (lineedit) finishedLineEditNoSave();
1886 if (typeid(*selection) == typeid(BranchObj))
1888 bo1= (BranchObj*) (selection);
1889 par=(BranchObj*)(bo1->getParObj());
1890 bo2=par->getFirstBranch();
1894 selection->select();
1895 ensureSelectionVisible();
1902 void MapEditor::selectLastBranch()
1904 // Finish open lineEdits
1905 if (lineedit) finishedLineEditNoSave();
1911 if (typeid(*selection) == typeid(BranchObj))
1913 bo1= (BranchObj*) (selection);
1914 par=(BranchObj*)(bo1->getParObj());
1915 bo2=par->getLastBranch();
1919 selection->select();
1920 ensureSelectionVisible();
1927 void MapEditor::setColor(QColor c)
1932 void MapEditor::selectBackgroundColor()
1934 // Finish open lineEdits
1935 if (lineedit) finishedLineEditNoSave();
1937 QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
1938 if ( !col.isValid() ) return;
1939 setBackgroundColor( col );
1943 void MapEditor::setBackgroundColor(QColor c)
1945 mapCanvas->setBackgroundColor (c);
1948 QColor MapEditor::pickColor()
1952 if (typeid(*selection) == typeid(BranchObj) ||
1953 typeid(*selection) == typeid(MapCenterObj))
1955 BranchObj *bo=(BranchObj*)(selection);
1956 actColor=bo->getColor();
1962 void MapEditor::colorItem()
1966 if (typeid(*selection) == typeid(BranchObj) ||
1967 typeid(*selection) == typeid(MapCenterObj))
1970 saveState(PartOfMap,selection);
1971 BranchObj *bo=(BranchObj*)(selection);
1972 bo->setColor(actColor, false); // color links, color childs
1977 void MapEditor::colorBranch()
1981 if (typeid(*selection) == typeid(BranchObj) ||
1982 typeid(*selection) == typeid(MapCenterObj))
1985 saveState(PartOfMap,selection);
1986 BranchObj *bo=(BranchObj*)(selection);
1987 bo->setColor(actColor, true); // color links, color childs
1993 void MapEditor::toggleStandardFlag(QString f)
1998 saveState(PartOfMap,selection);
1999 ((BranchObj*)(selection))->toggleStandardFlag (f);
2003 void MapEditor::setViewCenter()
2005 // transform to CanvasView Coord:
2006 QPoint p=worldMatrix().map(movingCenter);
2007 center ( p.x(), p.y());
2011 BranchObj* MapEditor::findText (QString s, bool cs)
2014 { // Nothing found or new find process
2016 // nothing found, start again
2018 itFind=mapCenter->first();
2020 bool searching=true;
2021 bool foundNote=false;
2022 while (searching && !EOFind)
2026 // Searching in Note
2027 if (itFind->getNote().contains(s,cs))
2029 if (selection!=itFind)
2031 if (selection) ((BranchObj*)(selection))->unselect();
2033 selection->select();
2035 ensureSelectionVisible();
2037 if (textEditor->findText(s,cs))
2043 // Searching in Heading
2044 if (searching && itFind->getHeading().contains (s,cs) )
2046 if (selection) ((BranchObj*)(selection))->unselect();
2048 selection->select();
2050 ensureSelectionVisible();
2056 itFind=itFind->next();
2057 if (!itFind) EOFind=true;
2063 return (BranchObj*)(selection);
2068 void MapEditor::findReset()
2069 { // Necessary if text to find changes during a find process
2074 void MapEditor::openURL()
2078 if (typeid(*selection) == typeid(BranchObj) ||
2079 typeid(*selection) == typeid(MapCenterObj))
2081 QString url=((BranchObj*)(selection))->getURL();
2083 QProcess *proc = new QProcess( this );
2085 #if !defined(Q_OS_MACX)
2086 proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL","konqueror" ));
2088 proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL",
2089 "/Applications/Safari.app/Contents/MacOS/Safari" ));
2092 proc->addArgument( url);
2094 if ( !proc->start() )
2096 if (mainWindow->settingsURL() )
2102 void MapEditor::editURL()
2104 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2105 typeid(*selection) == typeid(MapCenterObj)) )
2108 QString text = QInputDialog::getText(
2109 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2110 ((BranchObj*)(selection))->getURL(), &ok, this );
2113 // user entered something and pressed OK
2114 ((BranchObj*)(selection))->setURL (text);
2121 void MapEditor::editHeading2URL()
2123 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2124 typeid(*selection) == typeid(MapCenterObj)) )
2126 BranchObj *b=(BranchObj*)(selection);
2127 b->setURL (b->getHeading());
2133 void MapEditor::editBugzilla2URL()
2135 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2136 typeid(*selection) == typeid(MapCenterObj)) )
2138 BranchObj *b=(BranchObj*)(selection);
2139 b->setURL ("https://bugzilla.novell.com/show_bug.cgi?id="+b->getHeading());
2145 void MapEditor::editVymLink()
2147 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2148 typeid(*selection) == typeid(MapCenterObj)) )
2150 QFileDialog *fd=new QFileDialog( this,tr("VYM - Link to another map"));
2151 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
2152 fd->setCaption(tr("VYM - Link to another map"));
2153 if (! ((BranchObj*)(selection))->getVymLink().isEmpty() )
2154 fd->setSelection( ((BranchObj*)(selection))->getVymLink() );
2158 if ( fd->exec() == QDialog::Accepted )
2159 ((BranchObj*)(selection))->setVymLink (fd->selectedFile() );
2161 mapCenter->reposition();
2168 void MapEditor::deleteVymLink()
2170 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2171 typeid(*selection) == typeid(MapCenterObj)) )
2173 ((BranchObj*)(selection))->setVymLink ("" );
2175 mapCenter->reposition();
2182 QString MapEditor::getVymLink()
2184 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2185 typeid(*selection) == typeid(MapCenterObj)) )
2187 return ((BranchObj*)(selection))->getVymLink();
2193 void MapEditor::removeBranchHere()
2195 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2198 saveState(PartOfMap,selection->getParObj());
2199 QString sel=selection->getSelectString();
2200 BranchObj* bo=(BranchObj*)(selection);
2201 BranchObj* par=(BranchObj*)(bo->getParObj());
2203 par->removeBranchHere(bo);
2204 mapCenter->reposition();
2209 void MapEditor::removeChilds()
2211 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2214 saveState(PartOfMap,selection->getParObj());
2215 ((BranchObj*)(selection))->removeChilds();
2216 mapCenter->reposition();
2220 void MapEditor::editMapInfo()
2222 ExtraInfoDialog dia;
2223 dia.setMapName (getFileName() );
2224 dia.setAuthor (mapCenter->getAuthor() );
2225 dia.setComment(mapCenter->getComment() );
2230 QCanvasItemList l=canvas()->allItems();
2231 for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
2233 stats+=QString ("%1 items on canvas\n").arg (i,6);
2239 bo=mapCenter->first();
2242 if (!bo->getNote().isEmpty() ) n++;
2243 f+= bo->countFloatImages();
2247 stats+=QString ("%1 branches\n").arg (b-1,6);
2248 stats+=QString ("%1 notes\n").arg (n,6);
2249 stats+=QString ("%1 images\n").arg (f,6);
2250 dia.setStats (stats);
2252 // Finally show dialog
2253 if (dia.exec() == QDialog::Accepted)
2255 mapCenter->setAuthor (dia.getAuthor() );
2256 mapCenter->setComment (dia.getComment() );
2261 void MapEditor::updateActions()
2264 if (getLinkColorHint()==HeadingColor)
2265 actionFormatLinkColorHint->setOn(true);
2267 actionFormatLinkColorHint->setOn(false);
2272 actionFormatLinkStyleLine->setOn(true);
2275 actionFormatLinkStyleParabel->setOn(true);
2278 actionFormatLinkStylePolyLine->setOn(true);
2280 case StylePolyParabel:
2281 actionFormatLinkStylePolyParabel->setOn(true);
2287 QPixmap pix( 16, 16 );
2288 pix.fill( mapCanvas->backgroundColor() );
2289 actionFormatBackColor->setIconSet( pix );
2290 pix.fill( defLinkColor );
2291 actionFormatLinkColor->setIconSet( pix );
2293 actionEditUndo->setEnabled( mapChanged );
2294 actionFileSave->setEnabled( mapUnsaved );
2298 if ( (typeid(*selection) == typeid(BranchObj)) ||
2299 (typeid(*selection) == typeid(MapCenterObj)) )
2301 BranchObj *bo=(BranchObj*)(selection);
2302 // Take care of links
2303 if (bo->countXLinks()==0)
2305 branchLinksContextMenu->clear();
2306 branchLinksContextMenu->insertItem ("No link available");
2307 branchLinksContextMenuDup->clear();
2308 branchLinksContextMenuDup->insertItem ("No link available");
2314 branchLinksContextMenu->clear();
2315 branchLinksContextMenuDup->clear();
2316 for (int i=0; i<=bo->countXLinks();i++)
2318 bot=bo->XLinkTargetAt(i);
2321 s=bot->getHeading();
2324 branchLinksContextMenu->insertItem (s);
2325 branchLinksContextMenuDup->insertItem (s);
2330 standardFlagsDefault->setEnabled (true);
2332 if ( bo->getURL().isEmpty() )
2333 actionEditOpenURL->setEnabled (false);
2335 actionEditOpenURL->setEnabled (true);
2337 if ( bo->getVymLink().isEmpty() )
2339 actionEditOpenVymLink->setEnabled (false);
2340 actionEditDeleteVymLink->setEnabled (false);
2343 actionEditOpenVymLink->setEnabled (true);
2344 actionEditDeleteVymLink->setEnabled (true);
2347 actionEditCopy->setEnabled (true);
2348 actionEditCut->setEnabled (true);
2349 actionEditPaste->setEnabled (true);
2350 for (a=actionListBranches.first();a;a=actionListBranches.next())
2351 a->setEnabled(true);
2352 actionEditDelete->setEnabled (true);
2353 actionEditToggleFloatExport->setEnabled (false);
2354 switch (selection->getFrameType())
2357 actionFormatFrameNone->setOn(true);
2360 actionFormatFrameRectangle->setOn(true);
2366 if ( (typeid(*selection) == typeid(FloatImageObj)) )
2368 standardFlagsDefault->setEnabled (false);
2370 actionEditOpenURL->setEnabled (false);
2371 actionEditOpenVymLink->setEnabled (false);
2372 actionEditDeleteVymLink->setEnabled (false);
2374 actionEditCopy->setEnabled (true);
2375 actionEditCut->setEnabled (true);
2376 actionEditPaste->setEnabled (false); //FIXME
2377 for (a=actionListBranches.first();a;a=actionListBranches.next())
2378 a->setEnabled(false);
2379 actionEditDelete->setEnabled (true);
2380 actionEditToggleFloatExport->setOn
2381 ( ((FloatImageObj*)(selection))->getFloatExport() );
2386 standardFlagsDefault->setEnabled (false);
2388 actionEditCopy->setEnabled (false);
2389 actionEditCut->setEnabled (false);
2390 actionEditPaste->setEnabled (false);
2391 for (a=actionListBranches.first();a;a=actionListBranches.next())
2392 a->setEnabled(false);
2394 actionEditOpenURL->setEnabled (false);
2395 actionEditOpenVymLink->setEnabled (false);
2396 actionEditDeleteVymLink->setEnabled (false);
2397 actionEditHeading2URL->setEnabled (false);
2398 actionEditDelete->setEnabled (false);
2399 actionEditToggleFloatExport->setEnabled (false);
2403 void MapEditor::setLinkStyle (LinkStyle ls)
2410 bo=mapCenter->first();
2414 bo->setLinkStyle(bo->getDefLinkStyle());
2417 mapCenter->reposition();
2420 LinkStyle MapEditor::getLinkStyle ()
2425 void MapEditor::setLinkColor(QColor c)
2431 void MapEditor::setLinkColorHint()
2433 // called from setLinkColorHint(lch) or at end of parse
2435 bo=mapCenter->first();
2443 void MapEditor::setLinkColorHint(LinkColorHint lch)
2449 void MapEditor::toggleLinkColorHint()
2451 if (linkcolorhint==HeadingColor)
2452 linkcolorhint=DefaultColor;
2454 linkcolorhint=HeadingColor;
2456 bo=mapCenter->first();
2464 LinkColorHint MapEditor::getLinkColorHint()
2466 return linkcolorhint;
2469 QColor MapEditor::getDefLinkColor()
2471 return defLinkColor;
2474 void MapEditor::setDefXLinkColor(QColor col)
2479 QColor MapEditor::getDefXLinkColor()
2481 return defXLinkColor;
2484 void MapEditor::setDefXLinkWidth (int w)
2489 int MapEditor::getDefXLinkWidth()
2491 return defXLinkWidth;
2494 void MapEditor::selectLinkColor()
2496 // Finish open lineEdits
2497 if (lineedit) finishedLineEditNoSave();
2499 QColor col = QColorDialog::getColor( defLinkColor, this );
2500 if ( !col.isValid() ) return;
2501 setLinkColor( col );
2505 void MapEditor::toggleScroll()
2507 if (selection && (typeid(*selection) == typeid(BranchObj)) )
2509 BranchObj *bo=((BranchObj*)(selection));
2510 if (bo->countBranches()==0) return;
2511 if (bo->getDepth()==0) return;
2513 saveState(PartOfMap,selection);
2520 void MapEditor::unScrollAll()
2523 bo=mapCenter->first();
2526 if (bo->isScrolled()) bo->toggleScroll();
2531 void MapEditor::loadFloatImage ()
2534 (typeid(*selection) == typeid(BranchObj)) ||
2535 (typeid(*selection) == typeid(MapCenterObj)) )
2537 BranchObj *bo=((BranchObj*)(selection));
2539 QFileDialog *fd=new QFileDialog( this,tr("vym - load image"));
2540 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2541 ImagePreview *p =new ImagePreview (fd);
2542 fd->setContentsPreviewEnabled( TRUE );
2543 fd->setContentsPreview( p, p );
2544 fd->setPreviewMode( QFileDialog::Contents );
2545 fd->setCaption(tr("vym - Load image"));
2546 fd->setDir (lastImageDir);
2550 if ( fd->exec() == QDialog::Accepted )
2553 saveState(PartOfMap,selection);
2554 QString fn=fd->selectedFile();
2555 lastImageDir=fn.left(fn.findRev ("/"));
2556 bo->addFloatImage();
2557 // FIXME check if load was successful
2558 bo->getLastFloatImage()->load(fn);
2559 bo->getLastFloatImage()->setOriginalFilename(fn);
2560 mapCenter->reposition();
2567 void MapEditor::saveFloatImage (int item)
2570 (typeid(*selection) == typeid(FloatImageObj)) )
2572 FloatImageObj *fio=((FloatImageObj*)(selection));
2573 const char* fmt = saveImageFormatMenu->text(item);
2575 QFileDialog *fd=new QFileDialog( this, tr("vym - save image as") + fmt);
2576 fd->addFilter ("PNG (*.png)");
2577 fd->addFilter ("BMP (*.bmp)");
2578 fd->addFilter ("XBM (*.xbm)");
2579 fd->addFilter ("JPG (*.jpg)");
2580 fd->addFilter ("XPM (*.xpm)");
2581 fd->addFilter ("GIF (*.gif)");
2582 fd->addFilter ("PNM (*.pnm)");
2583 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2584 fd->setCaption(tr("vym - Save image as ") + fmt);
2585 fd->setMode( QFileDialog::AnyFile );
2586 fd->setSelection (fio->getOriginalFilename());
2590 if ( fd->exec() == QDialog::Accepted )
2592 if (QFile (fd->selectedFile()).exists() )
2594 QMessageBox mb( "VYM",
2595 tr("The file ") + fd->selectedFile() +
2596 tr(" exists already. "
2597 "Do you want to overwrite it?"),
2598 QMessageBox::Warning,
2599 QMessageBox::Yes | QMessageBox::Default,
2600 QMessageBox::Cancel | QMessageBox::Escape,
2601 QMessageBox::QMessageBox::NoButton );
2603 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
2604 mb.setButtonText( QMessageBox::No, tr("Cancel"));
2607 case QMessageBox::Yes:
2610 case QMessageBox::Cancel:
2616 fio->save (fd->selectedFile(),fmt);
2621 void MapEditor::toggleFloatExport()
2624 (typeid(*selection) == typeid(FloatImageObj))||
2625 (typeid(*selection) == typeid(FloatObj)) )
2627 FloatImageObj *fio=((FloatImageObj*)(selection));
2628 fio->setFloatExport (actionEditToggleFloatExport->isOn() );
2632 void MapEditor::setFrame(const FrameType &t)
2635 (typeid(*selection) == typeid(BranchObj)) ||
2636 (typeid(*selection) == typeid(MapCenterObj)) )
2638 selection->setFrameType (t);
2639 mapCenter->reposition();
2640 selection->updateLink();
2644 void MapEditor::importDir(BranchObj *dst, QDir d)
2647 (typeid(*selection) == typeid(BranchObj)) ||
2648 (typeid(*selection) == typeid(MapCenterObj)) )
2652 // Traverse directories
2653 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
2654 const QFileInfoList *dirlist = d.entryInfoList();
2655 QFileInfoListIterator itdir( *dirlist );
2658 while ( (fi = itdir.current()) != 0 )
2660 if (fi->fileName() != "." && fi->fileName() != ".." )
2663 bo=dst->getLastBranch();
2664 bo->setHeading (fi->fileName() );
2665 bo->setColor (QColor("blue"),false);
2667 if ( !d.cd(fi->fileName()) )
2668 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory"));
2678 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
2679 const QFileInfoList *filelist = d.entryInfoList();
2680 QFileInfoListIterator itfile( *filelist );
2682 while ( (fi = itfile.current()) != 0 )
2685 bo=dst->getLastBranch();
2686 bo->setHeading (fi->fileName() );
2687 bo->setColor (QColor("black"),false);
2693 void MapEditor::importDir()
2696 (typeid(*selection) == typeid(BranchObj)) ||
2697 (typeid(*selection) == typeid(MapCenterObj)) )
2699 QFileDialog *fd=new QFileDialog( this,tr("VYM - Choose directory structur to import"));
2700 fd->setMode (QFileDialog::DirectoryOnly);
2701 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
2702 fd->setCaption(tr("VYM - Choose directory structur to import"));
2706 if ( fd->exec() == QDialog::Accepted )
2708 BranchObj *bo=((BranchObj*)(selection));
2709 importDir (bo,QDir(fd->selectedFile()) );
2710 mapCenter->reposition();
2717 void MapEditor::followXLink(int i)
2720 (typeid(*selection) == typeid(BranchObj)) ||
2721 (typeid(*selection) == typeid(MapCenterObj)) )
2723 BranchObj *bo=((BranchObj*)(selection))->XLinkTargetAt(i);
2726 selection->unselect();
2728 selection->select();
2729 ensureSelectionVisible();
2734 void MapEditor::editXLink(int i)
2737 (typeid(*selection) == typeid(BranchObj)) ||
2738 (typeid(*selection) == typeid(MapCenterObj)) )
2740 XLinkObj *xlo=((BranchObj*)(selection))->XLinkAt(i);
2743 EditXLinkDialog dia;
2745 dia.setSelection(selection);
2746 if (dia.exec() == QDialog::Accepted)
2748 if (dia.useSettingsGlobal() )
2750 setDefXLinkColor (xlo->getColor() );
2751 setDefXLinkWidth (xlo->getWidth() );
2753 if (dia.deleteXLink())
2754 ((BranchObj*)(selection))->deleteXLinkAt(i);
2761 void MapEditor::testFunction()
2763 cout << "MapEditor::testFunction() called\n";
2766 void MapEditor::ensureSelectionVisible()
2770 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
2772 if (selection->getOrientation() == OrientLeftOfCenter)
2773 p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
2775 p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
2776 ensureVisible (p.x(), p.y() );
2781 void MapEditor::updateViewCenter()
2783 // Update movingCenter, so that we can zoom comfortably later
2784 QRect rc = QRect( contentsX(), contentsY(),
2785 visibleWidth(), visibleHeight() );
2786 QRect canvasRect = inverseWorldMatrix().mapRect(rc);
2787 movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
2788 movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
2791 void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e )
2793 // Lineedits are already closed by preceding
2794 // mouseEvent, we don't need to close here.
2796 QPoint p = inverseWorldMatrix().map(e->pos());
2797 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
2800 { // MapObj was found
2801 if (selection != lmo)
2803 // select the MapObj
2804 if (selection) selection->unselect();
2806 selection->select();
2812 if (typeid(*selection)==typeid(BranchObj) ||
2813 typeid(*selection)==typeid(MapCenterObj) )
2815 // Context Menu on branch or mapcenter
2817 branchContextMenu->popup(e->globalPos() );
2819 if (typeid(*selection)==typeid(FloatImageObj))
2821 // Context Menu on floatimage
2823 floatimageContextMenu->popup(e->globalPos() );
2827 { // No MapObj found, we are on the Canvas itself
2828 // Context Menu on Canvas
2830 canvasContextMenu->popup(e->globalPos() );
2834 void MapEditor::contentsMousePressEvent(QMouseEvent* e)
2836 // Finish open lineEdits
2837 if (lineedit) finishedLineEditNoSave();
2839 QPoint p = inverseWorldMatrix().map(e->pos());
2840 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
2842 // Special case: CTRL is pressed
2843 if (e->state() & QMouseEvent::ControlButton)
2845 if (actionModModeColor->isOn())
2847 if (e->state() & QMouseEvent::ControlButton)
2850 setCursor (pickColorCursor);
2854 if (actionModModeLink->isOn())
2856 BranchObj *bo_begin=NULL;
2858 bo_begin=(BranchObj*)(lmo);
2861 ((typeid(*selection) == typeid(BranchObj)) ||
2862 (typeid(*selection) == typeid(MapCenterObj))) )
2863 bo_begin=(BranchObj*)(selection);
2867 linkingObj_src=bo_begin;
2868 tmpXLink=new XLinkObj (mapCanvas);
2869 tmpXLink->setBegin (bo_begin);
2870 tmpXLink->setEnd (p);
2871 tmpXLink->setColor(defXLinkColor);
2872 tmpXLink->setWidth(defXLinkWidth);
2873 tmpXLink->updateXLink();
2874 tmpXLink->setVisibility (true);
2881 { // MapObj was found
2882 if (selection != lmo)
2884 // select the MapObj
2885 if (selection) selection->unselect();
2887 selection->select();
2893 // Check, if systemFlag clicked
2894 if (typeid(*selection)==typeid(BranchObj) ||
2895 typeid(*selection)==typeid(MapCenterObj) )
2897 QString foname=((BranchObj*)(selection))->getSystemFlagName(p);
2898 if (!foname.isEmpty())
2900 // Do not move, if systemFlag clicked
2904 if (foname=="vymLink")
2906 mainWindow->editOpenVymLink();
2907 // tabWidget may change, better return now
2908 // before segfaulting...
2912 mainWindow->windowToggleNoteEditor();
2916 // Left Button Move Branches
2917 if (e->button() == QMouseEvent::LeftButton )
2919 // If modMode==copy, then we want to "move" the _new_ object around
2920 // then we need the offset from p to the _old_ selection, because of tmp
2921 if (actionModModeCopy->isOn() &&
2922 e->state() & QMouseEvent::ControlButton)
2924 if (typeid(*selection)==typeid(BranchObj) )
2927 movingObj_start.setX( p.x() - selection->x() );
2928 movingObj_start.setY( p.y() - selection->y() );
2929 mapCenter->addBranch ((BranchObj*)(selection));
2931 selection=mapCenter->getLastBranch();
2932 selection->select();
2933 selection->setParObjTmp ((BranchObj*)(selection),p,1);
2934 selection->updateLink();
2938 movingObj_start.setX( p.x() - selection->x() );
2939 movingObj_start.setY( p.y() - selection->y() );
2942 movingObj=selection;
2944 // Middle Button Toggle Scroll
2945 // (On Mac OS X this won't work, but we still have
2946 // a button in the toolbar)
2947 if (e->button() == QMouseEvent::MidButton )
2951 { // No MapObj found, we are on the Canvas itself
2952 // Left Button move Pos of CanvasView
2953 if (e->button() == QMouseEvent::LeftButton )
2955 movingObj=NULL; // move Content not Obj
2956 movingObj_start=e->globalPos();
2957 movingCont_start=QPoint (contentsX(), contentsY() );
2958 movingVec=QPoint(0,0);
2959 setCursor(handOpenCursor);
2964 void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
2966 QPoint p = inverseWorldMatrix().map(e->pos());
2968 // Move the selected MapObj
2969 if ( selection && movingObj)
2971 ensureVisible (p.x(),p.y());
2973 // Now move the selection, but add relative position
2974 // (movingObj_start) where selection was chosen with
2975 // mousepointer. (This avoids flickering resp. jumping
2976 // of selection back to absPos)
2978 LinkableMapObj *lmosel;
2979 lmosel = dynamic_cast <LinkableMapObj*> (selection);
2981 // Check if we could link
2982 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
2985 if (typeid(*selection) == typeid(FloatImageObj))
2989 FloatObj *fo=(FloatObj*)(selection);
2990 if (fo->getLinkStyle()==StyleUndef)
2992 fo->setLinkStyle(fo->getDefLinkStyle());
2993 fo->setLinkColor(fo->getParObj()->getLinkColor());
2995 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
2999 // Relink float to new mapcenter or branch, if shift is pressed
3000 // Only relink, if selection really has a new parent
3001 if ( (e->state() & QMouseEvent::ShiftButton) && lmo &&
3002 ( (typeid(*lmo)==typeid(BranchObj)) ||
3003 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3004 ( lmo != fo->getParObj())
3007 if (typeid(*fo) == typeid(FloatImageObj))
3009 FloatImageObj *fio=(FloatImageObj*)(fo);
3010 ((BranchObj*)(lmo))->addFloatImage (fio);
3012 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
3013 fio=((BranchObj*)(lmo))->getLastFloatImage();
3016 selection=(LinkableMapObj*)(fio);
3017 selection->select();
3018 movingObj=(MapObj*)(fio);
3019 // setLinkStyle calls updateLink, only set it once
3020 if (fio->getLinkStyle()!=fio->getDefLinkStyle() )
3021 fio->setLinkStyle (fio->getDefLinkStyle());
3024 // TODO if (typeid(*selection) == typeid(FloatTextObj))
3026 } else // selection != a FloatObj
3028 if (lmosel->getDepth()==0)
3030 if (e->state() == (LeftButton | !ShiftButton))
3031 // If mapCenter is moved, move all the rest by default, too.
3032 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3034 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3037 if (lmosel->getDepth()==1)
3039 // depth==1, mainbranch
3041 saveState(PartOfMap,lmosel);
3042 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3046 if (lmosel->getOrientation() == OrientLeftOfCenter)
3047 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3048 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3049 p.y()-movingObj_start.y() );
3051 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3053 // reposition subbranch
3054 lmosel->reposition();
3055 //ensureSelectionVisible();
3057 if (lmo && (lmo!=selection) &&
3058 (typeid(*lmo) == typeid(BranchObj) ||
3059 (typeid(*lmo) == typeid(MapCenterObj) )
3062 if (e->state() & QMouseEvent::ControlButton)
3064 // Special case: CTRL to link below lmo
3065 lmosel->setParObjTmp (lmo,p,+1);
3067 else if (e->state() & QMouseEvent::ShiftButton)
3068 lmosel->setParObjTmp (lmo,p,-1);
3070 lmosel->setParObjTmp (lmo,p,0);
3073 lmosel->unsetParObjTmp();
3075 if (lmo &&(lmo==selection))
3076 // Could link to myself (happens sometimes...)
3077 lmosel->unsetParObjTmp();
3079 // no Obj under selection, go back to original Parent
3080 lmosel->unsetParObjTmp();
3085 } // no FloatImageObj
3089 } // selection && moving_obj
3091 // Draw a link from one branch to another
3094 tmpXLink->setEnd (p);
3095 tmpXLink->updateXLink();
3099 if (!movingObj && !pickingColor &&!drawingLink)
3101 QPoint p=e->globalPos();
3102 movingVec.setX(-p.x() + movingObj_start.x() );
3103 movingVec.setY(-p.y() + movingObj_start.y() );
3104 setContentsPos( movingCont_start.x() + movingVec.x(),
3105 movingCont_start.y() + movingVec.y());
3112 void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e)
3114 LinkableMapObj *dst;
3115 // Have we been picking color?
3119 setCursor (ArrowCursor);
3120 // Check if we are over another branch
3121 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3122 if (dst && selection)
3124 if (e->state() & QMouseEvent::ShiftButton)
3126 ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),false);
3127 ((BranchObj*)(selection))->setLinkColor ();
3131 ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),true);
3132 ((BranchObj*)(selection))->setLinkColor ();
3138 // Have we been drawing a link?
3142 // Check if we are over another branch
3143 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3144 if (dst && selection)
3146 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3147 tmpXLink->updateXLink();
3148 tmpXLink->activate();
3159 // Have we been moving something?
3160 if ( selection && movingObj )
3162 // Check if we are over another branch, but ignore
3163 // any found LMOs, which are FloatObjs
3164 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ),
3165 ((LinkableMapObj*)(selection)) );
3168 (typeid(*dst)!=typeid(BranchObj)&&typeid(*dst)!=typeid(MapCenterObj)))
3173 // Now check, if we have been moving a branch
3174 if (typeid(*selection) == typeid(BranchObj) )
3176 // save the position in case we link to mapcenter
3177 QPoint savePos=QPoint (selection->x(),selection->y() );
3179 // Reset the temporary drawn link to the original one
3180 ((LinkableMapObj*)(selection))->unsetParObjTmp();
3188 // remove the current selection, if we have no destination
3189 selection->unselect();
3190 ((BranchObj*)(selection->getParObj()))->removeBranch ((BranchObj*)(selection));
3193 selection=selectionLast;
3195 selection->select();
3202 // TODO we also could check, if dest and src are on same branch,
3203 // then it would be sufficient to saveState of this branch
3205 // Modifiers allow to insert above/below dst
3206 if (e->state() & QMouseEvent::ShiftButton)
3208 ((BranchObj*)(selection))->moveBranchTo
3211 ((BranchObj*)(dst))->getNum()
3213 //if (selection) selection->select();
3215 if (e->state() & QMouseEvent::ControlButton)
3217 ((BranchObj*)(selection))->moveBranchTo
3220 ((BranchObj*)(dst))->getNum()+1
3222 //if (selection) selection->select();
3225 ((BranchObj*)(selection))->moveBranchTo ((BranchObj*)(dst),-1);
3226 if (dst->getDepth()==0)
3227 ((BranchObj*)(selection))->move (savePos);
3230 // Draw the original link, before selection was moved around
3231 mapCenter->reposition();
3233 // Finally resize canvas, if needed
3238 // maybe we moved View: set old cursor
3239 setCursor (ArrowCursor);
3243 void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
3245 // Finish open lineEdits
3246 if (lineedit) finishedLineEditNoSave();
3248 if (e->button() == QMouseEvent::LeftButton )
3250 QPoint p = inverseWorldMatrix().map(e->pos());
3251 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3252 if (lmo) { // MapObj was found
3253 // First select the MapObj than edit heading
3254 if (selection) selection->unselect();
3256 selection->select();
3258 saveState(PartOfMap,selection);
3264 void MapEditor::resizeEvent (QResizeEvent* e)
3266 QCanvasView::resizeEvent( e );
3269 if (!fileName.isEmpty()) s=fileName;