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>
27 #include "texteditor.h"
28 #include "linkablemapobj.h"
31 #include "mainwindow.h"
32 #include "extrainfodialog.h"
33 #include "editxlinkdialog.h"
36 #include "icons/flag-note.xpm"
37 #include "icons/flag-url.xpm"
38 #include "icons/flag-vymlink.xpm"
39 #include "icons/flag-scrolled-right.xpm"
40 #include "icons/flag-tmpUnscrolled-right.xpm"
41 #include "icons/flag-questionmark.xpm"
42 #include "icons/flag-exclamationmark.xpm"
43 #include "icons/flag-hook-green.xpm"
44 #include "icons/flag-cross-red.xpm"
45 #include "icons/flag-stopsign.xpm"
46 #include "icons/flag-smiley-good.xpm"
47 #include "icons/flag-smiley-sad.xpm"
48 #include "icons/flag-clock.xpm"
49 #include "icons/flag-lamp.xpm"
50 #include "icons/flag-arrow-up.xpm"
51 #include "icons/flag-arrow-down.xpm"
52 #include "icons/flag-thumb-up.xpm"
53 #include "icons/flag-thumb-down.xpm"
54 #include "icons/flag-heart.xpm"
55 #include "icons/flag-flash.xpm"
56 #include "icons/flag-lifebelt.xpm"
58 extern TextEditor *textEditor;
59 extern int statusbarTime;
60 extern Main *mainWindow;
61 extern FlagRowObj *systemFlagsDefault;
62 extern FlagRowObj *standardFlagsDefault;
63 extern MapEditor *clipboardME;
65 extern QPtrList <QAction> actionListBranches;
67 extern QAction *actionFileSave;
68 extern QAction *actionEditUndo;
69 extern QAction *actionEditCopy;
70 extern QAction *actionEditCut;
71 extern QAction *actionEditPaste;
72 extern QAction *actionEditMoveUp;
73 extern QAction *actionEditMoveDown;
74 extern QAction *actionEditToggleScroll;
75 extern QAction *actionEditOpenURL;
76 extern QAction *actionEditURL;
77 extern QAction *actionEditHeading2URL;
78 extern QAction *actionEditBugzilla2URL;
79 extern QAction *actionEditOpenVymLink;
80 extern QAction *actionEditVymLink;
81 extern QAction *actionEditDeleteVymLink;
82 extern QAction *actionEditHeading;
83 extern QAction *actionEditDelete;
84 extern QAction *actionEditAddBranch;
85 extern QAction *actionEditAddBranchAbove;
86 extern QAction *actionEditAddBranchBelow;
87 extern QAction *actionEditRemoveBranchHere;
88 extern QAction *actionEditRemoveChilds;
89 extern QAction *actionEditImportAdd;
90 extern QAction *actionEditImportReplace;
91 extern QAction *actionEditSaveBranch;
92 extern QAction *actionEditSelectFirst;
93 extern QAction *actionEditSelectLast;
94 extern QAction *actionEditLoadImage;
95 extern QAction *actionEditToggleFloatExport;
97 extern QAction* actionFormatPickColor;
98 extern QAction* actionFormatColorBranch;
99 extern QAction* actionFormatColorSubtree;
100 extern QAction *actionFormatLinkColorHint;
101 extern QAction *actionFormatBackColor;
102 extern QAction *actionFormatLinkColor;
104 extern QActionGroup* actionGroupModModes;
105 extern QAction* actionModModeColor;
106 extern QAction* actionModModeLink;
107 extern QAction* actionModModeCopy;
109 extern QActionGroup *actionGroupFormatFrameTypes;
110 extern QAction *actionFormatFrameNone;
111 extern QAction *actionFormatFrameRectangle;
113 extern QActionGroup *actionGroupFormatLinkStyles;
114 extern QAction *actionFormatLinkStyleLine;
115 extern QAction *actionFormatLinkStyleParabel;
116 extern QAction *actionFormatLinkStylePolyLine;
117 extern QAction *actionFormatLinkStylePolyParabel;
119 extern QAction *actionViewToggleNoteEditor;
121 extern QAction *actionSettingsAutoedit;
122 extern QAction *actionSettingsAutoselectHeading;
123 extern QAction *actionSettingsAutoselectText;
124 extern QAction *actionSettingsPasteNewHeading;
125 extern QAction *actionSettingsUseFlagGroups;
127 extern QPopupMenu *branchContextMenu;
128 extern QPopupMenu *branchLinksContextMenu;
129 extern QPopupMenu *branchLinksContextMenuDup;
130 extern QPopupMenu *floatimageContextMenu;
131 extern QPopupMenu *saveImageFormatMenu;
132 extern QPopupMenu *exportImageFormatMenu;
133 extern QPopupMenu *canvasContextMenu;
135 extern Settings settings;
138 ///////////////////////////////////////////////////////////////////////
139 ///////////////////////////////////////////////////////////////////////
140 MapEditor::MapEditor(
141 QWidget* parent, bool interactive, const char* name, WFlags f) :
142 QCanvasView(parent,name,f)
144 //cout << "Constructor ME "<<this<<endl;
146 mapCanvas = new QCanvas(1000,800);
147 mapCanvas->setAdvancePeriod(30);
149 setCanvas (mapCanvas);
151 setVScrollBarMode ( QScrollView::AlwaysOn );
152 setHScrollBarMode ( QScrollView::AlwaysOn );
154 // Now create the _global_ system flags _once_:
155 // (Later all OrnamentedObj copy from this
156 // and set their own canvas)
157 if (!systemFlagsDefault)
159 systemFlagsDefault = new FlagRowObj (mapCanvas);
160 systemFlagsDefault->setVisibility (false);
161 systemFlagsDefault->setName ("systemFlagsDef");
163 FlagObj *fo = new FlagObj (mapCanvas);
164 fo->load(QPixmap(flag_note_xpm));
166 fo->setToolTip(tr("Note","Systemflag"));
167 systemFlagsDefault->addFlag (fo); // makes deep copy
169 fo->load(QPixmap(flag_url_xpm));
171 fo->setToolTip(tr("WWW Document (external)","Systemflag"));
172 systemFlagsDefault->addFlag (fo);
174 fo->load(QPixmap(flag_vymlink_xpm));
175 fo->setName("vymLink");
176 fo->setToolTip(tr("Link to another vym map","Systemflag"));
177 systemFlagsDefault->addFlag (fo);
179 fo->load(QPixmap(flag_scrolled_right_xpm));
180 fo->setName("scrolledright");
181 fo->setToolTip(tr("subtree is scrolled","Systemflag"));
182 systemFlagsDefault->addFlag (fo);
184 fo->load(QPixmap(flag_tmpUnscrolled_right_xpm));
185 fo->setName("tmpUnscrolledright");
186 fo->setToolTip(tr("subtree is temporary scrolled","Systemflag"));
187 systemFlagsDefault->addFlag (fo);
190 if (!standardFlagsDefault)
192 standardFlagsDefault = new FlagRowObj (mapCanvas);
193 standardFlagsDefault->setVisibility (false);
194 standardFlagsDefault->setName ("standardFlagsDef");
196 FlagObj *fo = new FlagObj (mapCanvas);
197 fo->load(QPixmap(flag_exclamationmark_xpm));
198 fo->setName ("exclamationmark");
199 fo->setGroup("standard-mark");
200 fo->setToolTip(tr("Take care!","Standardflag"));
201 standardFlagsDefault->addFlag (fo); // makes deep copy
203 fo->load(QPixmap(flag_questionmark_xpm));
204 fo->setName("questionmark");
205 fo->setGroup("standard-mark");
206 fo->setToolTip(tr("Really?","Standardflag"));
207 standardFlagsDefault->addFlag (fo);
209 fo->load(QPixmap(flag_hook_green_xpm));
210 fo->setName("hook-green");
211 fo->setGroup("standard-hook");
212 fo->setToolTip(tr("ok!","Standardflag"));
213 standardFlagsDefault->addFlag (fo);
215 fo->load(QPixmap(flag_cross_red_xpm));
216 fo->setName("cross-red");
217 fo->setGroup("standard-hook");
218 fo->setToolTip(tr("Not ok!","Standardflag"));
219 standardFlagsDefault->addFlag (fo);
221 fo->load(QPixmap(flag_stopsign_xpm));
222 fo->setName("stopsign");
223 fo->setToolTip(tr("This won't work!","Standardflag"));
224 standardFlagsDefault->addFlag (fo);
226 fo->load(QPixmap(flag_smiley_good_xpm));
227 fo->setName("smiley-good");
228 fo->setGroup("standard-smiley");
229 fo->setToolTip(tr("Good","Standardflag"));
230 standardFlagsDefault->addFlag (fo);
232 fo->load(QPixmap(flag_smiley_sad_xpm));
233 fo->setName("smiley-sad");
234 fo->setGroup("standard-smiley");
235 fo->setToolTip(tr("Bad","Standardflag"));
236 standardFlagsDefault->addFlag (fo);
238 fo->load(QPixmap(flag_clock_xpm));
239 fo->setName("clock");
240 fo->setToolTip(tr("Time critical","Standardflag"));
241 standardFlagsDefault->addFlag (fo);
243 fo->load(QPixmap(flag_lamp_xpm));
245 fo->setToolTip(tr("Idea!","Standardflag"));
246 standardFlagsDefault->addFlag (fo);
248 fo->load(QPixmap(flag_arrow_up_xpm));
249 fo->setName("arrow-up");
250 fo->setGroup("standard-arrow");
251 fo->setToolTip(tr("Important","Standardflag"));
252 standardFlagsDefault->addFlag (fo);
254 fo->load(QPixmap(flag_arrow_down_xpm));
255 fo->setName("arrow-down");
256 fo->setGroup("standard-arrow");
257 fo->setToolTip(tr("Unimportant","Standardflag"));
258 standardFlagsDefault->addFlag (fo);
260 fo->load(QPixmap(flag_thumb_up_xpm));
261 fo->setName("thumb-up");
262 fo->setGroup("standard-thumb");
263 fo->setToolTip(tr("I like this","Standardflag"));
264 standardFlagsDefault->addFlag (fo);
266 fo->load(QPixmap(flag_thumb_down_xpm));
267 fo->setName("thumb-down");
268 fo->setGroup("standard-thumb");
269 fo->setToolTip(tr("I like this","Standardflag"));
270 fo->setToolTip(tr("I do not like this","Standardflag"));
271 standardFlagsDefault->addFlag (fo);
273 fo->load(QPixmap(flag_heart_xpm));
274 fo->setName("heart");
275 fo->setToolTip(tr("I just love... ","Standardflag"));
276 standardFlagsDefault->addFlag (fo);
278 fo->load(QPixmap(flag_flash_xpm));
279 fo->setName("flash");
280 fo->setToolTip(tr("Dangerous","Standardflag"));
281 standardFlagsDefault->addFlag (fo);
283 fo->load(QPixmap(flag_lifebelt_xpm));
284 fo->setName("lifebelt");
285 fo->setToolTip(tr("This will help","Standardflag"));
286 standardFlagsDefault->addFlag (fo);
291 mapCenter = new MapCenterObj(mapCanvas);
292 mapCenter->setVisibility (true);
293 mapCenter->setMapEditor (this);
294 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
298 lineedit = new QLineEdit(this, "lineedit" );
299 connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEditNoSave() ) );
302 actColor=black; setColor (actColor);
303 defLinkColor=QColor (0,0,255);
304 defXLinkColor=QColor (180,180,180);
305 linkcolorhint=DefaultColor;
306 linkstyle=StylePolyParabel;
307 mapCanvas->setBackgroundColor (white);
309 // Create bitmap cursors, patform dependant
310 #if defined(Q_OS_MACX)
311 #include "icons/cursorhandopen16.xpm"
312 #include "icons/cursorcolorpicker16.xpm"
313 QBitmap cb( 16, 16, chandopen, TRUE );
314 QBitmap cm( 16, 16, chandopenmask, TRUE );
315 handOpenCursor=QCursor ( cb, cm );
316 // set hot spot to tip of picker
317 pickColorCursor=QCursor ( cursorcolorpicker_xpm, 1,15 );
319 #include "icons/cursorhandopen.xpm"
320 #include "icons/cursorcolorpicker.xpm"
322 QBitmap cb( 32, 32, chandopen, TRUE );
323 QBitmap cm( 32, 32, chandopenmask, TRUE );
324 handOpenCursor=QCursor ( cb, cm );
325 // set hot spot to tip of picker
326 pickColorCursor=QCursor ( cursorcolorpicker_xpm, 5,27 );
339 defXLinkColor=QColor (230,230,230);
351 // Initialize find routine
358 blockreposition=false;
359 isInteractive=interactive;
361 // Create temporary files
364 // Initially set movingCentre
367 mapCenter->reposition(); // for positioning heading
370 MapEditor::~MapEditor()
372 //cout <<"Destructor MapEditor\n";
373 if (isInteractive) delTmpDirs();
376 //settings.writeEntry( "/vym/mapeditor/editmode/autoselect", );
380 QColor MapEditor::color()
385 QColor MapEditor::backgroundColor()
387 return mapCanvas->backgroundColor();
390 MapCenterObj* MapEditor::getMapCenter()
395 QCanvas* MapEditor::getCanvas()
400 void MapEditor::adjustCanvasSize()
402 // To adjust the canvas to map, viewport size and position, we have to
403 // do some coordinate magic...
405 // Get rectangle of (scroll-)view.
406 // We want to be in canvas coords, so
407 // we map. Important if view is zoomed...
408 QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(),
409 visibleWidth(), visibleHeight()) );
411 // Now we need the bounding box of view AND map to calc the correct canvas size.
412 // Why? Because if the map itself is moved out of view, the view has to be enlarged
413 // to avoid jumping aroung...
414 QRect map=mapCenter->getTotalBBox();
416 // right edge - left edge
417 int cw= max(map.x() + map.width(), view.x() + view.width()) - min(map.x(), view.x());
418 int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
421 if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) ||
422 !mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight())
425 // move the map on canvas (in order to not move it on screen) this is neccessary
426 // a) if topleft corner of canvas is left or above topleft corner of view and also left of
427 // above topleft corner of map. E.g. if map is completly inside view, but it would be possible
428 // to scroll to an empty area of canvas to the left.
429 // b) if topleft corner of map left of or above topleft of canvas
433 if (cw > mapCanvas->width() )
435 if (map.x()<0) dx=-map.x();
437 if (cw < mapCanvas->width() )
438 dx=-min (view.x(),map.x());
439 if (ch > mapCanvas->height() )
441 if (map.y()<0) dy=-map.y();
443 if (ch < mapCanvas->height() )
445 dy=-min (view.y(),map.y());
447 // We really have to resize now. Let's go...
448 mapCanvas->resize (cw,ch);
449 if ( (dx!=0) || (dy!=0) )
451 mapCenter->moveAllBy(dx,dy);
452 mapCenter->reposition();
454 // scroll the view (in order to not move map on screen)
460 bool MapEditor::blockReposition()
462 return blockreposition;
465 void MapEditor::makeTmpDirs()
467 // Create unique temporary directories
468 char tmpdir[]="/tmp/vym-XXXXXX";
469 bakMapDir=mkdtemp(tmpdir);
470 makeSubDirs(bakMapDir);
471 // FIXME set permissions
472 // and maybe use QT method for portability
475 void MapEditor::delTmpDirs()
477 //FIXME delete tmp directory, better use QT methods here:
478 system ( "rm -rf "+ bakMapDir );
482 void MapEditor::makeSubDirs(const QString &s)
490 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, SaveMode savemode)
492 // tmpdir temporary directory to which data will be writte
493 // prefix mapname, which will be appended to images etc.
494 // writeflags Only write flags for "real" save of map, not undo
495 // offset offset of bbox of whole map in canvas.
496 // Needed for XML export
497 // completeMap if false, only vympart will be written, without
514 ls="StylePolyParabel";
518 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
520 if (linkcolorhint==HeadingColor)
521 colhint=attribut("linkColorHint","HeadingColor");
523 QString mapAttr=attribut("version",__VYM_VERSION__);
524 if (savemode==CompleteMap)
525 mapAttr+= attribut("author",mapCenter->getAuthor()) +
526 attribut("comment",mapCenter->getComment()) +
527 attribut("date",mapCenter->getDate()) +
528 attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
529 attribut("linkStyle", ls ) +
530 attribut("linkColor", defLinkColor.name() ) +
531 attribut("defXLinkColor", defXLinkColor.name() ) +
532 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
534 s+=beginElement("vymmap",mapAttr);
537 // Find the used flags while traversing the tree
538 standardFlagsDefault->resetUsedCounter();
540 // Build xml recursivly
541 if (savemode==CompleteMap)
542 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
545 if ( undoSelection &&
546 typeid(*undoSelection) == typeid(BranchObj) )
547 s+=((BranchObj*)(undoSelection))->saveToDir(tmpdir,prefix,offset);
549 if (selection && typeid(*selection)==typeid(BranchObj))
550 s+=((BranchObj*)(selection))->saveToDir(tmpdir,prefix,offset);
553 // Save local settings
554 s+=settings.getXMLData (destPath);
558 s+=valueElement("select",selection->getSelectString());
561 s+=endElement("vymmap");
564 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
568 void MapEditor::saveState()
570 saveState (CompleteMap,NULL);
573 void MapEditor::saveState(const SaveMode &mode, LinkableMapObj *part)
575 saveState (mode,part,"");
578 void MapEditor::saveState(const SaveMode &mode, LinkableMapObj *part, const QString &undoCom)
580 // all binary data is saved in bakMapDir (created in Constructor)
581 // the xml data itself is kept in memory in backupXML
583 // For faster write/read of data, a part of the map can be
584 // written. Then the undoSelection will mark the part of the
585 // map which should be replaced if an undo is wanted later.
587 if (mode==PartOfMap && part && (typeid(*part) == typeid (BranchObj) ) )
589 // So far we only test undoCommands for BranchObjs
596 // Writing a vympart only is useful for BranchObj
598 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),PartOfMap);
604 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),CompleteMap);
608 void MapEditor::finishedLineEditNoSave()
610 // This is called by finishedLineEdit or any MapEditor method,
611 // which wants to assure, that lineedits finish, before e.g. a branch is
614 // After calling LineEdit and using the clipboard, the
615 // focus is not any longer on the main widget, we
616 // have to restore it using parentWidget()->setFocus()
620 editingBO->setHeading(lineedit->text() );
622 lineedit->releaseKeyboard();
624 parentWidget()->setFocus();
625 mapCenter->reposition();
627 ensureSelectionVisible();
632 bool MapEditor::isDefault()
637 bool MapEditor::isUnsaved()
642 bool MapEditor::hasChanged()
647 void MapEditor::setChanged()
652 actionEditUndo->setEnabled (true);
653 actionFileSave->setEnabled (true);
657 void MapEditor::closeMap()
659 // Finish open lineEdits
660 if (lineedit) finishedLineEditNoSave();
662 // Unselect before disabling the toolbar actions
663 if (selection) selection->unselect();
671 void MapEditor::setFilePath(QString fname)
673 setFilePath (fname,fname);
676 void MapEditor::setFilePath(QString fname, QString destname)
682 // If fname is not an absolute path, complete it
683 filePath=QDir(fname).absPath();
684 fileDir=filePath.left (1+filePath.findRev ("/"));
686 // Set short name, too. Search from behind:
687 int i=fileName.findRev("/");
688 if (i>=0) fileName=fileName.remove (0,i+1);
690 // Forget the .vym (or .xml) for name of map
691 mapName=fileName.left(fileName.findRev(".",-1,true) );
694 QString MapEditor::getFilePath()
699 QString MapEditor::getFileName()
704 QString MapEditor::getMapName()
709 QString MapEditor::getDestPath()
714 int MapEditor::load (QString &fname, const LoadMode &lmode)
716 // Finish open lineEdits
717 if (lineedit) finishedLineEditNoSave();
723 if (selection) selection->unselect();
726 mapCenter->setMapEditor(this);
727 // (map state is set later at end of load...)
731 saveState(PartOfMap,selection);
735 mapBuilderHandler handler;
738 // I am paranoid: file should exist anyway
739 // according to check in mainwindow.
742 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
743 tr("Couldn't open map " +fname)+".");
747 blockreposition=true;
748 QXmlInputSource source( file);
749 QXmlSimpleReader reader;
750 reader.setContentHandler( &handler );
751 reader.setErrorHandler( &handler );
752 handler.setMapEditor( this );
753 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
754 handler.setLoadMode (lmode);
755 bool ok = reader.parse( source );
756 blockreposition=false;
760 mapCenter->reposition();
770 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
771 tr( handler.errorProtocol() ) );
773 // Still return "success": the map maybe at least
774 // partially read by the parser
781 int MapEditor::save (const SaveMode &savemode)
783 // Finish open lineEdits
784 if (lineedit) finishedLineEditNoSave();
788 // Create mapName and fileDir
789 makeSubDirs (fileDir);
793 fname=mapName+".xml";
795 // use name given by user, even if he chooses .doc
799 // Check if fname is writeable
800 QFile file( fileDir+fname);
801 if (!file.open( IO_WriteOnly ) )
803 QMessageBox::critical( 0, tr( "Critical Save Error" ),
804 tr("Couldn't write to ") +fileDir+fname);
810 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),savemode);
812 file.setName ( fileDir + fname);
813 if ( !file.open( IO_WriteOnly ) )
815 // This should neverever happen
816 QMessageBox::critical(0, tr("Critcal Save error"),"MapEditor::save() Couldn't open "+file.name());
820 // Write it finally, and write in UTF8, no matter what
821 QTextStream ts( &file );
822 ts.setEncoding (QTextStream::UnicodeUTF8);
830 actionFileSave->setEnabled(false);
836 void MapEditor::setZipped (bool z)
841 bool MapEditor::saveZipped ()
846 void MapEditor::print()
848 // Finish open lineEdits
849 if (lineedit) finishedLineEditNoSave();
853 printer = new QPrinter;
854 printer->setColorMode (QPrinter::Color);
857 QRect totalBBox=mapCenter->getTotalBBox();
859 // Try to set orientation automagically
860 // Note: Interpretation of generated postscript is amibiguous, if
861 // there are problems with landscape mode, see
862 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
864 if (totalBBox.width()>totalBBox.height())
865 // recommend landscape
866 printer->setOrientation (QPrinter::Landscape);
868 // recommend portrait
869 printer->setOrientation (QPrinter::Portrait);
871 if ( printer->setup(this) )
872 // returns false, if printing is canceled
874 QPainter pp(printer);
876 // Don't print the visualisation of selection
877 LinkableMapObj *oldselection=NULL;
880 oldselection=selection;
881 selection->unselect();
884 // Handle sizes of map and paper:
886 // setWindow defines which part of the canvas will be transformed
887 // setViewport defines area on paper in device coordinates (dpi)
888 // e.g. (0,50,700,700) is upper part on A4
889 // see also /usr/lib/qt3/doc/html/coordsys.html
891 QPaintDeviceMetrics metrics (printer);
893 double paperAspect = (double)metrics.width() / (double)metrics.height();
894 double mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
896 QRect mapRect=totalBBox;
897 QCanvasRectangle *frame=NULL;
898 QCanvasText *footerFN=NULL;
899 QCanvasText *footerDate=NULL;
900 if (printFrame || printFooter)
905 // Print frame around map
906 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
907 totalBBox.width()+20, totalBBox.height()+20);
908 frame=new QCanvasRectangle (mapRect,mapCanvas);
909 frame->setBrush (QColor(white));
910 frame->setPen (QColor(black));
915 QCanvasLine *l=new QCanvasLine (mapCanvas);
916 l->setPoints (0,0,mapRect.width(),mapRect.height());
917 l->setPen (QPen(QColor(black), 1));
924 // Print footer below map
926 font.setPointSize(10);
927 footerFN=new QCanvasText (mapCanvas);
928 footerFN->setText ("VYM - " + fileName);
929 footerFN->setFont(font);
930 footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
931 footerFN->setZ(Z_TEXT);
933 footerDate=new QCanvasText (mapCanvas);
934 footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
935 footerDate->setFont(font);
936 footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
937 footerDate->setZ(Z_TEXT);
940 pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()+20);
943 pp.setWindow (mapRect);
946 if (mapAspect>=paperAspect)
948 // Fit horizontally to paper width
949 pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );
952 // Fit vertically to paper height
953 pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());
956 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to printer
958 // Delete Frame and footer
964 if (frame) delete (frame);
969 selection=oldselection;
975 QPixmap MapEditor::getPixmap()
977 QRect mapRect=mapCenter->getTotalBBox();
978 QPixmap pix (mapRect.size());
981 // Don't print the visualisation of selection
982 LinkableMapObj *oldselection=NULL;
985 oldselection=selection;
986 selection->unselect();
989 pp.setWindow (mapRect);
991 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to painter
997 selection=oldselection;
1004 void MapEditor::exportImage(QString fn)
1006 // Finish open lineEdits
1007 if (lineedit) finishedLineEditNoSave();
1009 QPixmap pix (getPixmap());
1010 pix.save(fn, "PNG");
1013 void MapEditor::exportImage(QString fn, int item)
1015 // Finish open lineEdits
1016 if (lineedit) finishedLineEditNoSave();
1018 QPixmap pix (getPixmap());
1019 pix.save(fn, exportImageFormatMenu->text(item) );
1022 void MapEditor::exportASCII()
1024 // FIXME still experimental
1025 QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (ASCII)"));
1026 fd->addFilter ("TXT (*.txt)");
1027 fd->setCaption("VYM - Export (ASCII) (still experimental)");
1028 fd->setMode( QFileDialog::AnyFile );
1031 if ( fd->exec() == QDialog::Accepted )
1033 if (QFile (fd->selectedFile()).exists() )
1035 QMessageBox mb( "VYM",
1036 tr("The file ") + fd->selectedFile() +
1037 tr(" exists already. Do you want to overwrite it?"),
1038 QMessageBox::Warning,
1039 QMessageBox::Yes | QMessageBox::Default,
1040 QMessageBox::Cancel | QMessageBox::Escape,
1041 QMessageBox::NoButton );
1043 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
1044 mb.setButtonText( QMessageBox::No, tr("Cancel"));
1048 case QMessageBox::Yes:
1050 if (!ex.setOutputDir ("out"))
1052 QMessageBox::critical (0,tr("Critical Export Error "),tr("Couldn't create directory ") + "out");
1056 case QMessageBox::Cancel:
1063 ex.setPath (fd->selectedFile() );
1064 ex.setMapCenter(mapCenter);
1070 void MapEditor::exportXML(const QString &dir)
1072 // Create subdirectories
1075 // write to directory
1076 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,CompleteMap);
1079 file.setName ( dir + "/"+mapName+".xml");
1080 if ( !file.open( IO_WriteOnly ) )
1082 // This should neverever happen
1083 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open ")+file.name());
1087 // Write it finally, and write in UTF8, no matter what
1088 QTextStream ts( &file );
1089 ts.setEncoding (QTextStream::UnicodeUTF8);
1093 // Now write image, too
1094 exportImage (dir+"/images/"+mapName+".png");
1097 void MapEditor::clear()
1101 selection->unselect();
1108 void MapEditor::undo()
1111 d.setPath(bakMapDir);
1114 // Finish open lineEdits
1115 if (lineedit) finishedLineEditNoSave();
1119 selection->unselect();
1123 if (undoCommand!="" && undoSelection)
1125 // We don't need to parse XML backup, but
1126 // do the undoCommand
1127 selection=undoSelection;
1128 selection->select();
1129 parseTest (undoCommand);
1133 // We need to parse saved XML data
1134 mapBuilderHandler handler;
1135 QXmlInputSource source;
1136 source.setData(backupXML);
1137 QXmlSimpleReader reader;
1138 reader.setContentHandler( &handler );
1139 reader.setErrorHandler( &handler );
1140 handler.setMapEditor( this );
1141 handler.setTmpDir ( bakMapDir ); // needed to load files with rel. path
1144 selection=undoSelection;
1145 selection->select();
1146 handler.setLoadMode (ImportReplace);
1151 handler.setLoadMode (NewMap);
1153 blockreposition=true;
1154 bool ok = reader.parse( source );
1155 blockreposition=false;
1157 mapCenter->reposition();
1161 // This should never ever happen
1162 QMessageBox::critical( 0, tr( "Critical Parse Error by reading backupFile" ),
1163 tr( handler.errorProtocol() )+" in "+backupXML );
1165 } // restoring saved version
1167 // Undo not longer available now
1168 actionEditUndo->setEnabled (false);
1169 undoSelection=false;
1174 QMessageBox::critical( 0, tr( "Critical Error" ),
1175 "Temporary directory " +bakMapDir +
1176 tr (" used for undo is gone. \n"
1177 "I will create a new one, but at the moment no undo is available.\n"
1178 "Maybe you want to reload your original data.\n\n"
1179 "Sorry for any inconveniences.") );
1184 void MapEditor::copy()
1186 // Finish open lineEdits
1187 if (lineedit) finishedLineEditNoSave();
1191 if (typeid(*selection) == typeid(BranchObj) )
1195 clipboardME->clear();
1196 clipboardME->getMapCenter()->addBranch();
1197 to=clipboardME->getMapCenter()->getLastBranch();
1200 from=(BranchObj*)(selection);
1203 // keep position relative to parent
1204 to->move2RelPos ( from->getRelPos());
1206 // select data in clipboard
1207 clipboardME->select ("bo:0");
1209 // repositioning makes testing nicer,
1210 // but is not needed usually:
1211 if (clipboardME->isVisible())
1213 clipboardME->getMapCenter()->reposition();
1216 clipboardME->hide();
1219 if (typeid(*selection) == typeid(FloatImageObj) )
1222 FloatImageObj* from;
1223 clipboardME->clear();
1224 clipboardME->getMapCenter()->addFloatImage();
1225 to=clipboardME->getMapCenter()->getLastFloatImage();
1228 from=(FloatImageObj*)(selection);
1231 // select data in clipboard
1232 clipboardME->select ("fi:0");
1234 // repositioning makes testing nicer,
1235 // but is not needed usually:
1236 if (clipboardME->isVisible())
1238 clipboardME->getMapCenter()->reposition();
1241 clipboardME->hide();
1247 LinkableMapObj* MapEditor::pasteNoSave()
1249 // Finish open lineEdits
1250 if (lineedit) finishedLineEditNoSave();
1252 LinkableMapObj *fromLMO=clipboardME->getSelection();
1253 LinkableMapObj *returnLMO=NULL;
1255 if (selection && fromLMO)
1258 if (typeid(*fromLMO) == typeid(BranchObj) )
1260 if (typeid(*selection) == typeid(MapCenterObj))
1262 returnLMO=mapCenter->addBranch( (BranchObj*)(fromLMO) );
1263 ((BranchObj*)(returnLMO))->move2RelPos(normalise(fromLMO->getRelPos() ) );
1265 if (typeid(*selection) == typeid(BranchObj))
1266 returnLMO=((BranchObj*)(selection))->addBranch((BranchObj*)(fromLMO) );
1269 if (typeid(*fromLMO) == typeid(FloatImageObj) &&
1270 (typeid(*selection) == typeid (BranchObj) ||
1271 typeid(*selection)==typeid(MapCenterObj)) )
1272 returnLMO=((BranchObj*) (selection))->addFloatImage ((FloatImageObj*)(fromLMO));
1278 void MapEditor::cutNoSave()
1280 // Finish open lineEdits
1281 if (lineedit) finishedLineEditNoSave();
1285 if (selection != NULL) {
1286 if (typeid(*selection) == typeid(BranchObj) )
1288 bo=(BranchObj*)(selection);
1289 par=(BranchObj*)(bo->getParObj());
1292 par->removeBranch(bo);
1294 selection->select();
1296 if (typeid(*selection) == typeid(FloatImageObj) )
1298 FloatImageObj* fio=(FloatImageObj*)(selection);
1299 par=(BranchObj*)(fio->getParObj());
1302 par->removeFloatImage(fio);
1304 selection->select();
1309 void MapEditor::paste()
1312 saveState(PartOfMap,selection);
1314 mapCenter->reposition();
1318 void MapEditor::cut()
1321 saveState(PartOfMap,selection->getParObj());
1324 mapCenter->reposition();
1328 void MapEditor::moveBranchUp()
1330 // Finish open lineEdits
1331 if (lineedit) finishedLineEditNoSave();
1335 if (typeid(*selection) == typeid(BranchObj) )
1338 saveState(PartOfMap,selection,"moveBranchDown ()");
1339 bo=(BranchObj*)(selection);
1340 par=(BranchObj*)(bo->getParObj());
1341 selection->unselect();
1342 selection=par->moveBranchUp (bo);
1343 selection->select();
1344 mapCenter->reposition();
1345 ensureSelectionVisible();
1349 void MapEditor::moveBranchDown()
1351 // Finish open lineEdits
1352 if (lineedit) finishedLineEditNoSave();
1356 if (typeid(*selection) == typeid(BranchObj) )
1359 saveState(PartOfMap,selection,"moveBranchUp ()");
1360 bo=(BranchObj*)(selection);
1361 par=(BranchObj*)(bo->getParObj());
1362 selection->unselect();
1363 selection=par->moveBranchDown(bo);
1364 selection->select();
1365 mapCenter->reposition();
1366 ensureSelectionVisible();
1370 void MapEditor::editHeading()
1372 // Finish open lineEdits
1373 if (lineedit) finishedLineEditNoSave();
1376 (typeid(*selection) == typeid(BranchObj) ||
1377 typeid(*selection) == typeid(MapCenterObj) ) )
1380 saveState(PartOfMap,selection);
1382 ensureSelectionVisible();
1383 editingBO=(BranchObj*)(selection);
1384 QPoint p = worldMatrix().map(QPoint (editingBO->x(),editingBO->y()));
1385 lineedit->setGeometry(p.x()-contentsX(),p.y()-contentsY(),200,25);
1386 QString s=editingBO->getHeading();
1387 lineedit->setText(s);
1388 lineedit->setCursorPosition(1);
1389 if (actionSettingsAutoselectText->isOn() && !s.isEmpty() && actionSettingsPasteNewHeading->isOn() )
1390 lineedit->selectAll();
1393 lineedit->grabKeyboard();
1394 lineedit->setFocus();
1398 void MapEditor::addNewBranch(int pos)
1400 // Finish open lineEdits
1401 if (lineedit) finishedLineEditNoSave();
1404 (typeid(*selection) == typeid(BranchObj) ||
1405 typeid(*selection) == typeid(MapCenterObj) ) )
1408 saveState(PartOfMap,selection);
1410 BranchObj* bo1 = (BranchObj*) (selection);
1411 bool wasScrolled=false;
1412 BranchObj *newbo=NULL;
1415 // save scroll state. If scrolled, automatically select
1416 // new branch in order to tmp unscroll parent...
1417 wasScrolled=bo1->isScrolled();
1418 newbo=bo1->addBranch();
1421 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1425 // add above selection
1426 newbo=parbo->insertBranch(bo1->getNum());
1428 // add below selection
1429 newbo=parbo->insertBranch(bo1->getNum()+1);
1431 // This should not happen...
1436 LinkableMapObj *oldselection=selection;
1438 mapCenter->reposition();
1440 if (actionSettingsAutoedit->isOn() ||
1441 actionSettingsAutoselectHeading->isOn() )
1443 selection->unselect();
1445 selection->select();
1446 if (actionSettingsPasteNewHeading->isOn() )
1448 BranchObj *bo2= (BranchObj*)(selection);
1449 bo2->setHeading("");
1451 if (actionSettingsAutoedit->isOn() )
1453 if (!actionSettingsAutoselectHeading->isOn()
1456 selection->unselect();
1457 selection=oldselection;
1458 selection->select();
1465 void MapEditor::addNewBranchHere()
1467 // Finish open lineEdits
1468 if (lineedit) finishedLineEditNoSave();
1471 (typeid(*selection) == typeid(BranchObj) ) )
1474 saveState(PartOfMap,selection);
1476 BranchObj* bo1 = (BranchObj*) (selection);
1477 bool wasScrolled=false;
1478 BranchObj *newbo=NULL;
1479 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1482 // add below selection
1483 newbo=parbo->insertBranch(bo1->getNum()+1);
1486 LinkableMapObj *oldselection=selection;
1487 ((BranchObj*)(selection))->moveBranchTo (newbo,-1);
1489 mapCenter->reposition();
1491 if (actionSettingsAutoedit->isOn() ||
1492 actionSettingsAutoselectHeading->isOn() )
1494 selection->unselect();
1496 selection->select();
1497 if (actionSettingsPasteNewHeading->isOn() )
1499 BranchObj *bo2= (BranchObj*)(selection);
1500 bo2->setHeading("");
1502 if (actionSettingsAutoedit->isOn() )
1504 if (!actionSettingsAutoselectHeading->isOn()
1507 selection->unselect();
1508 selection=oldselection;
1509 selection->select();
1515 void MapEditor::deleteSelection()
1517 // Finish open lineEdits
1518 if (lineedit) finishedLineEditNoSave();
1520 if (selection && typeid(*selection) ==typeid(BranchObj) )
1523 saveState(PartOfMap,selection->getParObj());
1524 BranchObj* bo=dynamic_cast <BranchObj*> (selection);
1525 BranchObj* par=(BranchObj*)(bo->getParObj());
1528 par->removeBranch(bo);
1530 selection->select();
1531 ensureSelectionVisible();
1532 mapCenter->reposition();
1535 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
1538 saveState(PartOfMap,selection->getParObj());
1539 FloatImageObj* fio=dynamic_cast <FloatImageObj*> (selection);
1540 BranchObj* par=(BranchObj*)(fio->getParObj());
1543 par->removeFloatImage(fio);
1545 selection->select();
1546 ensureSelectionVisible();
1547 mapCenter->reposition();
1552 LinkableMapObj* MapEditor::getSelection()
1557 bool MapEditor::select (const QString &s)
1559 LinkableMapObj *lmo=mapCenter->findObj(s);
1561 // Finally select the found object
1564 if (selection) unselect();
1566 selection->select();
1568 ensureSelectionVisible();
1574 void MapEditor::unselect()
1578 selectionLast=selection;
1579 selection->unselect();
1584 void MapEditor::reselect()
1588 selection=selectionLast;
1589 selection->select();
1594 void MapEditor::selectNextBranch()
1596 // Increase number of branch
1599 QString s=selection->getSelectString();
1605 part=s.section(",",-1);
1607 num=part.right(part.length() - 3);
1609 s=s.left (s.length() -num.length());
1612 num=QString ("%1").arg(num.toUInt()+1);
1616 // Try to select this one
1617 if (select (s)) return;
1619 // We have no direct successor,
1620 // try to increase the parental number in order to
1621 // find a successor with same depth
1623 int d=selection->getDepth();
1628 while (!found && d>0)
1630 s=s.section (",",0,d-1);
1631 // replace substring of current depth in s with "1"
1632 part=s.section(",",-1);
1634 num=part.right(part.length() - 3);
1638 // increase number of parent
1639 num=QString ("%1").arg(num.toUInt()+1);
1640 s=s.section (",",0,d-2) + ","+ typ+num;
1643 // Special case, look at orientation
1644 if (selection->getOrientation()==OrientRightOfCenter)
1645 num=QString ("%1").arg(num.toUInt()+1);
1647 num=QString ("%1").arg(num.toUInt()-1);
1652 // pad to oldDepth, select the first branch for each depth
1653 for (i=d;i<oldDepth;i++)
1658 if ( ((BranchObj*)(selection))->countBranches()>0)
1666 // try to select the freshly built string
1674 void MapEditor::selectPrevBranch()
1676 // Decrease number of branch
1679 QString s=selection->getSelectString();
1685 part=s.section(",",-1);
1687 num=part.right(part.length() - 3);
1689 s=s.left (s.length() -num.length());
1692 num=QString ("%1").arg(num.toUInt()-1);
1696 // Try to select this one
1697 if (select (s)) return;
1699 // We have no direct precessor,
1700 // try to decrease the parental number in order to
1701 // find a precessor with same depth
1703 int d=selection->getDepth();
1708 while (!found && d>0)
1710 s=s.section (",",0,d-1);
1711 // replace substring of current depth in s with "1"
1712 part=s.section(",",-1);
1714 num=part.right(part.length() - 3);
1718 // decrease number of parent
1719 num=QString ("%1").arg(num.toUInt()-1);
1720 s=s.section (",",0,d-2) + ","+ typ+num;
1723 // Special case, look at orientation
1724 if (selection->getOrientation()==OrientRightOfCenter)
1725 num=QString ("%1").arg(num.toUInt()-1);
1727 num=QString ("%1").arg(num.toUInt()+1);
1732 // pad to oldDepth, select the last branch for each depth
1733 for (i=d;i<oldDepth;i++)
1737 if ( ((BranchObj*)(selection))->countBranches()>0)
1738 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)(selection))->countBranches()-1 );
1745 // try to select the freshly built string
1753 void MapEditor::selectUpperBranch()
1755 // Finish open lineEdits
1756 if (lineedit) finishedLineEditNoSave();
1760 if (typeid(*selection) == typeid(BranchObj))
1762 if (selection->getOrientation()==OrientRightOfCenter)
1765 if (selection->getDepth()==1)
1773 void MapEditor::selectLowerBranch()
1775 // Finish open lineEdits
1776 if (lineedit) finishedLineEditNoSave();
1780 if (typeid(*selection) == typeid(BranchObj))
1782 if (selection->getOrientation()==OrientRightOfCenter)
1785 if (selection->getDepth()==1)
1794 void MapEditor::selectLeftBranch()
1796 // Finish open lineEdits
1797 if (lineedit) finishedLineEditNoSave();
1803 if (typeid(*selection) == typeid(MapCenterObj))
1805 par= (BranchObj*) (selection);
1806 bo=par->getLastSelectedBranch();
1809 // Workaround for reselecting on left and right side
1810 if (bo->getOrientation()==OrientRightOfCenter)
1812 bo=par->getLastBranch();
1818 selection->select();
1820 ensureSelectionVisible();
1825 par=(BranchObj*)(selection->getParObj());
1826 if (selection->getOrientation()==OrientRightOfCenter)
1828 if (typeid(*selection) == typeid(BranchObj) ||
1829 typeid(*selection) == typeid(FloatImageObj))
1831 selection->unselect();
1833 selection->select();
1835 ensureSelectionVisible();
1839 if (typeid(*selection) == typeid(BranchObj) )
1841 bo=((BranchObj*)(selection))->getLastSelectedBranch();
1844 selection->unselect();
1846 selection->select();
1848 ensureSelectionVisible();
1856 void MapEditor::selectRightBranch()
1858 // Finish open lineEdits
1859 if (lineedit) finishedLineEditNoSave();
1866 if (typeid(*selection) == typeid(MapCenterObj))
1868 par= (BranchObj*) (selection);
1869 bo=par->getLastSelectedBranch();
1872 // Workaround for relecting on left and right side
1873 if (bo->getOrientation()==OrientLeftOfCenter)
1874 bo=par->getFirstBranch();
1879 selection->select();
1880 ensureSelectionVisible();
1885 par=(BranchObj*)(selection->getParObj());
1886 if (selection->getOrientation()==OrientLeftOfCenter)
1888 if (typeid(*selection) == typeid(BranchObj) ||
1889 typeid(*selection) == typeid(FloatImageObj))
1891 selection->unselect();
1893 selection->select();
1895 ensureSelectionVisible();
1899 if (typeid(*selection) == typeid(BranchObj) )
1901 bo=((BranchObj*)(selection))->getLastSelectedBranch();
1904 selection->unselect();
1906 selection->select();
1908 ensureSelectionVisible();
1916 void MapEditor::selectFirstBranch()
1918 // Finish open lineEdits
1919 if (lineedit) finishedLineEditNoSave();
1925 if (typeid(*selection) == typeid(BranchObj))
1927 bo1= (BranchObj*) (selection);
1928 par=(BranchObj*)(bo1->getParObj());
1929 bo2=par->getFirstBranch();
1933 selection->select();
1934 ensureSelectionVisible();
1941 void MapEditor::selectLastBranch()
1943 // Finish open lineEdits
1944 if (lineedit) finishedLineEditNoSave();
1950 if (typeid(*selection) == typeid(BranchObj))
1952 bo1= (BranchObj*) (selection);
1953 par=(BranchObj*)(bo1->getParObj());
1954 bo2=par->getLastBranch();
1958 selection->select();
1959 ensureSelectionVisible();
1966 void MapEditor::setColor(QColor c)
1971 void MapEditor::selectBackgroundColor()
1973 // Finish open lineEdits
1974 if (lineedit) finishedLineEditNoSave();
1976 QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
1977 if ( !col.isValid() ) return;
1978 setBackgroundColor( col );
1982 void MapEditor::setBackgroundColor(QColor c)
1984 mapCanvas->setBackgroundColor (c);
1987 QColor MapEditor::pickColor()
1991 if (typeid(*selection) == typeid(BranchObj) ||
1992 typeid(*selection) == typeid(MapCenterObj))
1994 BranchObj *bo=(BranchObj*)(selection);
1995 actColor=bo->getColor();
2001 void MapEditor::colorItem()
2005 if (typeid(*selection) == typeid(BranchObj) ||
2006 typeid(*selection) == typeid(MapCenterObj))
2009 saveState(PartOfMap,selection);
2010 BranchObj *bo=(BranchObj*)(selection);
2011 bo->setColor(actColor, false); // color links, color childs
2016 void MapEditor::colorBranch()
2020 if (typeid(*selection) == typeid(BranchObj) ||
2021 typeid(*selection) == typeid(MapCenterObj))
2024 saveState(PartOfMap,selection);
2025 BranchObj *bo=(BranchObj*)(selection);
2026 bo->setColor(actColor, true); // color links, color childs
2032 void MapEditor::toggleStandardFlag(QString f)
2037 saveState(PartOfMap,selection);
2038 ((BranchObj*)(selection))->toggleStandardFlag (f,actionSettingsUseFlagGroups);
2042 void MapEditor::setViewCenter()
2044 // transform to CanvasView Coord:
2045 QPoint p=worldMatrix().map(movingCenter);
2046 center ( p.x(), p.y());
2050 BranchObj* MapEditor::findText (QString s, bool cs)
2053 { // Nothing found or new find process
2055 // nothing found, start again
2057 itFind=mapCenter->first();
2059 bool searching=true;
2060 bool foundNote=false;
2061 while (searching && !EOFind)
2065 // Searching in Note
2066 if (itFind->getNote().contains(s,cs))
2068 if (selection!=itFind)
2070 if (selection) ((BranchObj*)(selection))->unselect();
2072 selection->select();
2074 ensureSelectionVisible();
2076 if (textEditor->findText(s,cs))
2082 // Searching in Heading
2083 if (searching && itFind->getHeading().contains (s,cs) )
2085 if (selection) ((BranchObj*)(selection))->unselect();
2087 selection->select();
2089 ensureSelectionVisible();
2095 itFind=itFind->next();
2096 if (!itFind) EOFind=true;
2102 return (BranchObj*)(selection);
2107 void MapEditor::findReset()
2108 { // Necessary if text to find changes during a find process
2113 void MapEditor::openURL()
2117 if (typeid(*selection) == typeid(BranchObj) ||
2118 typeid(*selection) == typeid(MapCenterObj))
2120 QString url=((BranchObj*)(selection))->getURL();
2122 QProcess *proc = new QProcess( this );
2124 #if !defined(Q_OS_MACX)
2125 proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL","konqueror" ));
2127 proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL",
2128 "/Applications/Safari.app/Contents/MacOS/Safari" ));
2131 proc->addArgument( url);
2133 if ( !proc->start() )
2135 if (mainWindow->settingsURL() )
2141 void MapEditor::editURL()
2143 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2144 typeid(*selection) == typeid(MapCenterObj)) )
2147 QString text = QInputDialog::getText(
2148 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2149 ((BranchObj*)(selection))->getURL(), &ok, this );
2152 // user entered something and pressed OK
2153 ((BranchObj*)(selection))->setURL (text);
2160 void MapEditor::editHeading2URL()
2162 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2163 typeid(*selection) == typeid(MapCenterObj)) )
2165 BranchObj *b=(BranchObj*)(selection);
2166 b->setURL (b->getHeading());
2172 void MapEditor::editBugzilla2URL()
2174 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2175 typeid(*selection) == typeid(MapCenterObj)) )
2177 BranchObj *b=(BranchObj*)(selection);
2178 b->setURL ("https://bugzilla.novell.com/show_bug.cgi?id="+b->getHeading());
2184 void MapEditor::editVymLink()
2186 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2187 typeid(*selection) == typeid(MapCenterObj)) )
2189 QFileDialog *fd=new QFileDialog( this,tr("VYM - Link to another map"));
2190 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
2191 fd->setCaption(tr("VYM - Link to another map"));
2192 if (! ((BranchObj*)(selection))->getVymLink().isEmpty() )
2193 fd->setSelection( ((BranchObj*)(selection))->getVymLink() );
2197 if ( fd->exec() == QDialog::Accepted )
2198 ((BranchObj*)(selection))->setVymLink (fd->selectedFile() );
2200 mapCenter->reposition();
2207 void MapEditor::deleteVymLink()
2209 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2210 typeid(*selection) == typeid(MapCenterObj)) )
2212 ((BranchObj*)(selection))->setVymLink ("" );
2214 mapCenter->reposition();
2221 QString MapEditor::getVymLink()
2223 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2224 typeid(*selection) == typeid(MapCenterObj)) )
2226 return ((BranchObj*)(selection))->getVymLink();
2232 void MapEditor::removeBranchHere()
2234 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2237 saveState(PartOfMap,selection->getParObj());
2238 QString sel=selection->getSelectString();
2239 BranchObj* bo=(BranchObj*)(selection);
2240 BranchObj* par=(BranchObj*)(bo->getParObj());
2242 par->removeBranchHere(bo);
2243 mapCenter->reposition();
2248 void MapEditor::removeChilds()
2250 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2253 saveState(PartOfMap,selection->getParObj());
2254 ((BranchObj*)(selection))->removeChilds();
2255 mapCenter->reposition();
2259 void MapEditor::editMapInfo()
2261 ExtraInfoDialog dia;
2262 dia.setMapName (getFileName() );
2263 dia.setAuthor (mapCenter->getAuthor() );
2264 dia.setComment(mapCenter->getComment() );
2269 QCanvasItemList l=canvas()->allItems();
2270 for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
2272 stats+=QString ("%1 items on canvas\n").arg (i,6);
2279 bo=mapCenter->first();
2282 if (!bo->getNote().isEmpty() ) n++;
2283 f+= bo->countFloatImages();
2285 xl+=bo->countXLinks();
2288 stats+=QString ("%1 branches\n").arg (b-1,6);
2289 stats+=QString ("%1 xLinks \n").arg (xl,6);
2290 stats+=QString ("%1 notes\n").arg (n,6);
2291 stats+=QString ("%1 images\n").arg (f,6);
2292 dia.setStats (stats);
2294 // Finally show dialog
2295 if (dia.exec() == QDialog::Accepted)
2297 mapCenter->setAuthor (dia.getAuthor() );
2298 mapCenter->setComment (dia.getComment() );
2303 void MapEditor::updateActions()
2306 if (getLinkColorHint()==HeadingColor)
2307 actionFormatLinkColorHint->setOn(true);
2309 actionFormatLinkColorHint->setOn(false);
2314 actionFormatLinkStyleLine->setOn(true);
2317 actionFormatLinkStyleParabel->setOn(true);
2320 actionFormatLinkStylePolyLine->setOn(true);
2322 case StylePolyParabel:
2323 actionFormatLinkStylePolyParabel->setOn(true);
2329 QPixmap pix( 16, 16 );
2330 pix.fill( mapCanvas->backgroundColor() );
2331 actionFormatBackColor->setIconSet( pix );
2332 pix.fill( defLinkColor );
2333 actionFormatLinkColor->setIconSet( pix );
2335 actionEditUndo->setEnabled( mapChanged );
2336 actionFileSave->setEnabled( mapUnsaved );
2340 if ( (typeid(*selection) == typeid(BranchObj)) ||
2341 (typeid(*selection) == typeid(MapCenterObj)) )
2343 BranchObj *bo=(BranchObj*)(selection);
2344 // Take care of links
2345 if (bo->countXLinks()==0)
2347 branchLinksContextMenu->clear();
2348 branchLinksContextMenu->insertItem ("No link available");
2349 branchLinksContextMenuDup->clear();
2350 branchLinksContextMenuDup->insertItem ("No link available");
2356 branchLinksContextMenu->clear();
2357 branchLinksContextMenuDup->clear();
2358 for (int i=0; i<=bo->countXLinks();i++)
2360 bot=bo->XLinkTargetAt(i);
2363 s=bot->getHeading();
2366 branchLinksContextMenu->insertItem (s);
2367 branchLinksContextMenuDup->insertItem (s);
2372 standardFlagsDefault->setEnabled (true);
2374 if ( bo->getURL().isEmpty() )
2375 actionEditOpenURL->setEnabled (false);
2377 actionEditOpenURL->setEnabled (true);
2379 if ( bo->getVymLink().isEmpty() )
2381 actionEditOpenVymLink->setEnabled (false);
2382 actionEditDeleteVymLink->setEnabled (false);
2385 actionEditOpenVymLink->setEnabled (true);
2386 actionEditDeleteVymLink->setEnabled (true);
2389 actionEditCopy->setEnabled (true);
2390 actionEditCut->setEnabled (true);
2391 if (clipboardME->getMapCenter()->countBranches()>0)
2392 actionEditPaste->setEnabled (true);
2394 actionEditPaste->setEnabled (false);
2395 for (a=actionListBranches.first();a;a=actionListBranches.next())
2396 a->setEnabled(true);
2397 actionEditDelete->setEnabled (true);
2398 actionEditToggleFloatExport->setEnabled (false);
2399 switch (selection->getFrameType())
2402 actionFormatFrameNone->setOn(true);
2405 actionFormatFrameRectangle->setOn(true);
2411 if ( (typeid(*selection) == typeid(FloatImageObj)) )
2413 standardFlagsDefault->setEnabled (false);
2415 actionEditOpenURL->setEnabled (false);
2416 actionEditOpenVymLink->setEnabled (false);
2417 actionEditDeleteVymLink->setEnabled (false);
2419 actionEditCopy->setEnabled (true);
2420 actionEditCut->setEnabled (true);
2421 actionEditPaste->setEnabled (false); //FIXME
2422 for (a=actionListBranches.first();a;a=actionListBranches.next())
2423 a->setEnabled(false);
2424 actionEditDelete->setEnabled (true);
2425 actionEditToggleFloatExport->setOn
2426 ( ((FloatImageObj*)(selection))->getFloatExport() );
2431 standardFlagsDefault->setEnabled (false);
2433 actionEditCopy->setEnabled (false);
2434 actionEditCut->setEnabled (false);
2435 actionEditPaste->setEnabled (false);
2436 for (a=actionListBranches.first();a;a=actionListBranches.next())
2437 a->setEnabled(false);
2439 actionEditOpenURL->setEnabled (false);
2440 actionEditOpenVymLink->setEnabled (false);
2441 actionEditDeleteVymLink->setEnabled (false);
2442 actionEditHeading2URL->setEnabled (false);
2443 actionEditDelete->setEnabled (false);
2444 actionEditToggleFloatExport->setEnabled (false);
2448 void MapEditor::setLinkStyle (LinkStyle ls)
2455 bo=mapCenter->first();
2459 bo->setLinkStyle(bo->getDefLinkStyle());
2462 mapCenter->reposition();
2465 LinkStyle MapEditor::getLinkStyle ()
2470 void MapEditor::setLinkColor(QColor c)
2476 void MapEditor::setLinkColorHint()
2478 // called from setLinkColorHint(lch) or at end of parse
2480 bo=mapCenter->first();
2488 void MapEditor::setLinkColorHint(LinkColorHint lch)
2494 void MapEditor::toggleLinkColorHint()
2496 if (linkcolorhint==HeadingColor)
2497 linkcolorhint=DefaultColor;
2499 linkcolorhint=HeadingColor;
2501 bo=mapCenter->first();
2509 LinkColorHint MapEditor::getLinkColorHint()
2511 return linkcolorhint;
2514 QColor MapEditor::getDefLinkColor()
2516 return defLinkColor;
2519 void MapEditor::setDefXLinkColor(QColor col)
2524 QColor MapEditor::getDefXLinkColor()
2526 return defXLinkColor;
2529 void MapEditor::setDefXLinkWidth (int w)
2534 int MapEditor::getDefXLinkWidth()
2536 return defXLinkWidth;
2539 void MapEditor::selectLinkColor()
2541 // Finish open lineEdits
2542 if (lineedit) finishedLineEditNoSave();
2544 QColor col = QColorDialog::getColor( defLinkColor, this );
2545 if ( !col.isValid() ) return;
2546 setLinkColor( col );
2550 void MapEditor::toggleScroll()
2552 if (selection && (typeid(*selection) == typeid(BranchObj)) )
2554 BranchObj *bo=((BranchObj*)(selection));
2555 if (bo->countBranches()==0) return;
2556 if (bo->getDepth()==0) return;
2558 saveState(PartOfMap,selection);
2565 void MapEditor::unScrollAll()
2568 bo=mapCenter->first();
2571 if (bo->isScrolled()) bo->toggleScroll();
2576 void MapEditor::loadFloatImage ()
2579 (typeid(*selection) == typeid(BranchObj)) ||
2580 (typeid(*selection) == typeid(MapCenterObj)) )
2582 BranchObj *bo=((BranchObj*)(selection));
2584 QFileDialog *fd=new QFileDialog( this,tr("vym - load image"));
2585 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2586 ImagePreview *p =new ImagePreview (fd);
2587 fd->setContentsPreviewEnabled( TRUE );
2588 fd->setContentsPreview( p, p );
2589 fd->setPreviewMode( QFileDialog::Contents );
2590 fd->setCaption(tr("vym - Load image"));
2591 fd->setDir (lastImageDir);
2595 if ( fd->exec() == QDialog::Accepted )
2598 saveState(PartOfMap,selection);
2599 QString fn=fd->selectedFile();
2600 lastImageDir=fn.left(fn.findRev ("/"));
2601 bo->addFloatImage();
2602 // FIXME check if load was successful
2603 bo->getLastFloatImage()->load(fn);
2604 bo->getLastFloatImage()->setOriginalFilename(fn);
2605 mapCenter->reposition();
2612 void MapEditor::saveFloatImage (int item)
2615 (typeid(*selection) == typeid(FloatImageObj)) )
2617 FloatImageObj *fio=((FloatImageObj*)(selection));
2618 const char* fmt = saveImageFormatMenu->text(item);
2620 QFileDialog *fd=new QFileDialog( this, tr("vym - save image as") + fmt);
2621 fd->addFilter ("PNG (*.png)");
2622 fd->addFilter ("BMP (*.bmp)");
2623 fd->addFilter ("XBM (*.xbm)");
2624 fd->addFilter ("JPG (*.jpg)");
2625 fd->addFilter ("XPM (*.xpm)");
2626 fd->addFilter ("GIF (*.gif)");
2627 fd->addFilter ("PNM (*.pnm)");
2628 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2629 fd->setCaption(tr("vym - Save image as ") + fmt);
2630 fd->setMode( QFileDialog::AnyFile );
2631 fd->setSelection (fio->getOriginalFilename());
2635 if ( fd->exec() == QDialog::Accepted )
2637 if (QFile (fd->selectedFile()).exists() )
2639 QMessageBox mb( "VYM",
2640 tr("The file ") + fd->selectedFile() +
2641 tr(" exists already. "
2642 "Do you want to overwrite it?"),
2643 QMessageBox::Warning,
2644 QMessageBox::Yes | QMessageBox::Default,
2645 QMessageBox::Cancel | QMessageBox::Escape,
2646 QMessageBox::QMessageBox::NoButton );
2648 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
2649 mb.setButtonText( QMessageBox::No, tr("Cancel"));
2652 case QMessageBox::Yes:
2655 case QMessageBox::Cancel:
2661 fio->save (fd->selectedFile(),fmt);
2666 void MapEditor::toggleFloatExport()
2669 (typeid(*selection) == typeid(FloatImageObj))||
2670 (typeid(*selection) == typeid(FloatObj)) )
2672 FloatImageObj *fio=((FloatImageObj*)(selection));
2673 fio->setFloatExport (actionEditToggleFloatExport->isOn() );
2677 void MapEditor::setFrame(const FrameType &t)
2680 (typeid(*selection) == typeid(BranchObj)) ||
2681 (typeid(*selection) == typeid(MapCenterObj)) )
2683 selection->setFrameType (t);
2684 mapCenter->reposition();
2685 selection->updateLink();
2689 void MapEditor::importDir(BranchObj *dst, QDir d)
2692 (typeid(*selection) == typeid(BranchObj)) ||
2693 (typeid(*selection) == typeid(MapCenterObj)) )
2697 // Traverse directories
2698 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
2699 const QFileInfoList *dirlist = d.entryInfoList();
2700 QFileInfoListIterator itdir( *dirlist );
2703 while ( (fi = itdir.current()) != 0 )
2705 if (fi->fileName() != "." && fi->fileName() != ".." )
2708 bo=dst->getLastBranch();
2709 bo->setHeading (fi->fileName() );
2710 bo->setColor (QColor("blue"),false);
2712 if ( !d.cd(fi->fileName()) )
2713 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory"));
2716 // Recursively add subdirs
2724 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
2725 const QFileInfoList *filelist = d.entryInfoList();
2726 QFileInfoListIterator itfile( *filelist );
2728 while ( (fi = itfile.current()) != 0 )
2731 bo=dst->getLastBranch();
2732 bo->setHeading (fi->fileName() );
2733 bo->setColor (QColor("black"),false);
2734 if (fi->fileName().right(4) == ".vym" )
2735 bo->setVymLink (fi->filePath());
2742 void MapEditor::importDir()
2745 (typeid(*selection) == typeid(BranchObj)) ||
2746 (typeid(*selection) == typeid(MapCenterObj)) )
2748 QFileDialog *fd=new QFileDialog( this,tr("VYM - Choose directory structur to import"));
2749 fd->setMode (QFileDialog::DirectoryOnly);
2750 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
2751 fd->setCaption(tr("VYM - Choose directory structur to import"));
2755 if ( fd->exec() == QDialog::Accepted )
2757 BranchObj *bo=((BranchObj*)(selection));
2758 importDir (bo,QDir(fd->selectedFile()) );
2759 mapCenter->reposition();
2766 void MapEditor::followXLink(int i)
2769 (typeid(*selection) == typeid(BranchObj)) ||
2770 (typeid(*selection) == typeid(MapCenterObj)) )
2772 BranchObj *bo=((BranchObj*)(selection))->XLinkTargetAt(i);
2775 selection->unselect();
2777 selection->select();
2778 ensureSelectionVisible();
2783 void MapEditor::editXLink(int i)
2786 (typeid(*selection) == typeid(BranchObj)) ||
2787 (typeid(*selection) == typeid(MapCenterObj)) )
2789 XLinkObj *xlo=((BranchObj*)(selection))->XLinkAt(i);
2792 EditXLinkDialog dia;
2794 dia.setSelection(selection);
2795 if (dia.exec() == QDialog::Accepted)
2797 if (dia.useSettingsGlobal() )
2799 setDefXLinkColor (xlo->getColor() );
2800 setDefXLinkWidth (xlo->getWidth() );
2802 if (dia.deleteXLink())
2803 ((BranchObj*)(selection))->deleteXLinkAt(i);
2812 void MapEditor::testFunction()
2814 cout << "MapEditor::testFunction() called\n";
2816 (typeid(*selection) == typeid(BranchObj)) )
2818 QString s=((BranchObj*)(selection))->getHeading();
2823 void MapEditor::parseTest(const QString &s)
2827 api.parseCommand (s,c,p);
2828 if (c==QString("moveBranchUp"))
2830 else if (c=="moveBranchDown")
2832 else if (c=="select")
2835 cout << "Don't know about command \""<<s<<"\".\n";
2838 void MapEditor::ensureSelectionVisible()
2842 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
2844 if (selection->getOrientation() == OrientLeftOfCenter)
2845 p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
2847 p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
2848 ensureVisible (p.x(), p.y() );
2853 void MapEditor::updateViewCenter()
2855 // Update movingCenter, so that we can zoom comfortably later
2856 QRect rc = QRect( contentsX(), contentsY(),
2857 visibleWidth(), visibleHeight() );
2858 QRect canvasRect = inverseWorldMatrix().mapRect(rc);
2859 movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
2860 movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
2863 void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e )
2865 // Lineedits are already closed by preceding
2866 // mouseEvent, we don't need to close here.
2868 QPoint p = inverseWorldMatrix().map(e->pos());
2869 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
2872 { // MapObj was found
2873 if (selection != lmo)
2875 // select the MapObj
2876 if (selection) selection->unselect();
2878 selection->select();
2884 if (typeid(*selection)==typeid(BranchObj) ||
2885 typeid(*selection)==typeid(MapCenterObj) )
2887 // Context Menu on branch or mapcenter
2889 branchContextMenu->popup(e->globalPos() );
2891 if (typeid(*selection)==typeid(FloatImageObj))
2893 // Context Menu on floatimage
2895 floatimageContextMenu->popup(e->globalPos() );
2899 { // No MapObj found, we are on the Canvas itself
2900 // Context Menu on Canvas
2902 canvasContextMenu->popup(e->globalPos() );
2906 void MapEditor::contentsMousePressEvent(QMouseEvent* e)
2908 // Finish open lineEdits
2909 if (lineedit) finishedLineEditNoSave();
2911 QPoint p = inverseWorldMatrix().map(e->pos());
2912 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
2914 // Special case: CTRL is pressed
2915 if (e->state() & QMouseEvent::ControlButton)
2917 if (actionModModeColor->isOn())
2919 if (e->state() & QMouseEvent::ControlButton)
2922 setCursor (pickColorCursor);
2926 if (actionModModeLink->isOn())
2928 BranchObj *bo_begin=NULL;
2930 bo_begin=(BranchObj*)(lmo);
2933 ((typeid(*selection) == typeid(BranchObj)) ||
2934 (typeid(*selection) == typeid(MapCenterObj))) )
2935 bo_begin=(BranchObj*)(selection);
2939 linkingObj_src=bo_begin;
2940 tmpXLink=new XLinkObj (mapCanvas);
2941 tmpXLink->setBegin (bo_begin);
2942 tmpXLink->setEnd (p);
2943 tmpXLink->setColor(defXLinkColor);
2944 tmpXLink->setWidth(defXLinkWidth);
2945 tmpXLink->updateXLink();
2946 tmpXLink->setVisibility (true);
2953 { // MapObj was found
2954 if (selection != lmo)
2956 // select the MapObj
2957 if (selection) selection->unselect();
2959 selection->select();
2965 // Check, if systemFlag clicked
2966 if (typeid(*selection)==typeid(BranchObj) ||
2967 typeid(*selection)==typeid(MapCenterObj) )
2969 QString foname=((BranchObj*)(selection))->getSystemFlagName(p);
2970 if (!foname.isEmpty())
2972 // Do not move, if systemFlag clicked
2976 if (foname=="vymLink")
2978 mainWindow->editOpenVymLink();
2979 // tabWidget may change, better return now
2980 // before segfaulting...
2984 mainWindow->windowToggleNoteEditor();
2988 // Left Button Move Branches
2989 if (e->button() == QMouseEvent::LeftButton )
2991 // If modMode==copy, then we want to "move" the _new_ object around
2992 // then we need the offset from p to the _old_ selection, because of tmp
2993 if (actionModModeCopy->isOn() &&
2994 e->state() & QMouseEvent::ControlButton)
2996 if (typeid(*selection)==typeid(BranchObj) )
2999 movingObj_start.setX( p.x() - selection->x() );
3000 movingObj_start.setY( p.y() - selection->y() );
3001 mapCenter->addBranch ((BranchObj*)(selection));
3003 selection=mapCenter->getLastBranch();
3004 selection->select();
3005 mapCenter->reposition();
3009 movingObj_start.setX( p.x() - selection->x() );
3010 movingObj_start.setY( p.y() - selection->y() );
3013 movingObj=selection;
3015 // Middle Button Toggle Scroll
3016 // (On Mac OS X this won't work, but we still have
3017 // a button in the toolbar)
3018 if (e->button() == QMouseEvent::MidButton )
3022 { // No MapObj found, we are on the Canvas itself
3023 // Left Button move Pos of CanvasView
3024 if (e->button() == QMouseEvent::LeftButton )
3026 movingObj=NULL; // move Content not Obj
3027 movingObj_start=e->globalPos();
3028 movingCont_start=QPoint (contentsX(), contentsY() );
3029 movingVec=QPoint(0,0);
3030 setCursor(handOpenCursor);
3035 void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
3037 QPoint p = inverseWorldMatrix().map(e->pos());
3039 // Move the selected MapObj
3040 if ( selection && movingObj)
3042 ensureVisible (p.x(),p.y());
3044 // Now move the selection, but add relative position
3045 // (movingObj_start) where selection was chosen with
3046 // mousepointer. (This avoids flickering resp. jumping
3047 // of selection back to absPos)
3049 LinkableMapObj *lmosel;
3050 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3052 // Check if we could link
3053 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3056 if (typeid(*selection) == typeid(FloatImageObj))
3060 FloatObj *fo=(FloatObj*)(selection);
3061 if (fo->getLinkStyle()==StyleUndef)
3063 fo->setLinkStyle(fo->getDefLinkStyle());
3064 fo->setLinkColor(fo->getParObj()->getLinkColor());
3066 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3070 // Relink float to new mapcenter or branch, if shift is pressed
3071 // Only relink, if selection really has a new parent
3072 if ( (e->state() & QMouseEvent::ShiftButton) && lmo &&
3073 ( (typeid(*lmo)==typeid(BranchObj)) ||
3074 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3075 ( lmo != fo->getParObj())
3078 if (typeid(*fo) == typeid(FloatImageObj))
3080 FloatImageObj *fio=(FloatImageObj*)(fo);
3081 ((BranchObj*)(lmo))->addFloatImage (fio);
3083 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
3084 fio=((BranchObj*)(lmo))->getLastFloatImage();
3087 selection=(LinkableMapObj*)(fio);
3088 selection->select();
3089 movingObj=(MapObj*)(fio);
3090 // setLinkStyle calls updateLink, only set it once
3091 if (fio->getLinkStyle()!=fio->getDefLinkStyle() )
3092 fio->setLinkStyle (fio->getDefLinkStyle());
3095 // TODO if (typeid(*selection) == typeid(FloatTextObj))
3097 } else // selection != a FloatObj
3099 if (lmosel->getDepth()==0)
3101 if (e->state() == (LeftButton | !ShiftButton))
3102 // If mapCenter is moved, move all the rest by default, too.
3103 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3105 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3108 if (lmosel->getDepth()==1)
3110 // depth==1, mainbranch
3112 saveState(PartOfMap,lmosel);
3113 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3117 if (lmosel->getOrientation() == OrientLeftOfCenter)
3118 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3119 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3120 p.y()-movingObj_start.y() );
3122 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3124 // reposition subbranch
3125 lmosel->reposition();
3126 //ensureSelectionVisible();
3128 if (lmo && (lmo!=selection) &&
3129 (typeid(*lmo) == typeid(BranchObj) ||
3130 (typeid(*lmo) == typeid(MapCenterObj) )
3133 if (e->state() & QMouseEvent::ControlButton)
3135 // Special case: CTRL to link below lmo
3136 lmosel->setParObjTmp (lmo,p,+1);
3138 else if (e->state() & QMouseEvent::ShiftButton)
3139 lmosel->setParObjTmp (lmo,p,-1);
3141 lmosel->setParObjTmp (lmo,p,0);
3144 lmosel->unsetParObjTmp();
3146 if (lmo &&(lmo==selection))
3147 // Could link to myself (happens sometimes...)
3148 lmosel->unsetParObjTmp();
3150 // no Obj under selection, go back to original Parent
3151 lmosel->unsetParObjTmp();
3156 } // no FloatImageObj
3160 } // selection && moving_obj
3162 // Draw a link from one branch to another
3165 tmpXLink->setEnd (p);
3166 tmpXLink->updateXLink();
3170 if (!movingObj && !pickingColor &&!drawingLink)
3172 QPoint p=e->globalPos();
3173 movingVec.setX(-p.x() + movingObj_start.x() );
3174 movingVec.setY(-p.y() + movingObj_start.y() );
3175 setContentsPos( movingCont_start.x() + movingVec.x(),
3176 movingCont_start.y() + movingVec.y());
3183 void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e)
3185 LinkableMapObj *dst;
3186 // Have we been picking color?
3190 setCursor (ArrowCursor);
3191 // Check if we are over another branch
3192 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3193 if (dst && selection)
3195 if (e->state() & QMouseEvent::ShiftButton)
3197 ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),false);
3198 ((BranchObj*)(selection))->setLinkColor ();
3202 ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),true);
3203 ((BranchObj*)(selection))->setLinkColor ();
3209 // Have we been drawing a link?
3213 // Check if we are over another branch
3214 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3215 if (dst && selection)
3217 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3218 tmpXLink->updateXLink();
3219 tmpXLink->activate();
3230 // Have we been moving something?
3231 if ( selection && movingObj )
3233 // Check if we are over another branch, but ignore
3234 // any found LMOs, which are FloatObjs
3235 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ),
3236 ((LinkableMapObj*)(selection)) );
3239 (typeid(*dst)!=typeid(BranchObj)&&typeid(*dst)!=typeid(MapCenterObj)))
3244 // Now check, if we have been moving a branch
3245 if (typeid(*selection) == typeid(BranchObj) )
3247 // save the position in case we link to mapcenter
3248 QPoint savePos=QPoint (selection->x(),selection->y() );
3250 // Reset the temporary drawn link to the original one
3251 ((LinkableMapObj*)(selection))->unsetParObjTmp();
3259 // remove the current selection, if we have no destination
3260 selection->unselect();
3261 ((BranchObj*)(selection->getParObj()))->removeBranch ((BranchObj*)(selection));
3264 selection=selectionLast;
3266 selection->select();
3273 // TODO we also could check, if dest and src are on same branch,
3274 // then it would be sufficient to saveState of this branch
3276 // Modifiers allow to insert above/below dst
3277 if (e->state() & QMouseEvent::ShiftButton)
3279 ((BranchObj*)(selection))->moveBranchTo
3282 ((BranchObj*)(dst))->getNum()
3284 //if (selection) selection->select();
3286 if (e->state() & QMouseEvent::ControlButton)
3288 ((BranchObj*)(selection))->moveBranchTo
3291 ((BranchObj*)(dst))->getNum()+1
3293 //if (selection) selection->select();
3296 ((BranchObj*)(selection))->moveBranchTo ((BranchObj*)(dst),-1);
3297 if (dst->getDepth()==0)
3298 ((BranchObj*)(selection))->move (savePos);
3301 // Draw the original link, before selection was moved around
3302 mapCenter->reposition();
3304 // Finally resize canvas, if needed
3309 // maybe we moved View: set old cursor
3310 setCursor (ArrowCursor);
3314 void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
3316 // Finish open lineEdits
3317 if (lineedit) finishedLineEditNoSave();
3319 if (e->button() == QMouseEvent::LeftButton )
3321 QPoint p = inverseWorldMatrix().map(e->pos());
3322 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3323 if (lmo) { // MapObj was found
3324 // First select the MapObj than edit heading
3325 if (selection) selection->unselect();
3327 selection->select();
3329 saveState(PartOfMap,selection);
3335 void MapEditor::resizeEvent (QResizeEvent* e)
3337 QCanvasView::resizeEvent( e );
3340 if (!fileName.isEmpty()) s=fileName;