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>
18 #include <qdragobject.h>
19 #include <qurloperator.h>
20 #include <qnetworkprotocol.h>
31 #include "texteditor.h"
32 #include "linkablemapobj.h"
35 #include "mainwindow.h"
36 #include "extrainfodialog.h"
37 #include "editxlinkdialog.h"
40 #include "icons/flag-note.xpm"
41 #include "icons/flag-url.xpm"
42 #include "icons/flag-vymlink.xpm"
43 #include "icons/flag-scrolled-right.xpm"
44 #include "icons/flag-tmpUnscrolled-right.xpm"
45 #include "icons/flag-questionmark.xpm"
46 #include "icons/flag-exclamationmark.xpm"
47 #include "icons/flag-hook-green.xpm"
48 #include "icons/flag-cross-red.xpm"
49 #include "icons/flag-stopsign.xpm"
50 #include "icons/flag-smiley-good.xpm"
51 #include "icons/flag-smiley-sad.xpm"
52 #include "icons/flag-clock.xpm"
53 #include "icons/flag-lamp.xpm"
54 #include "icons/flag-arrow-up.xpm"
55 #include "icons/flag-arrow-down.xpm"
56 #include "icons/flag-thumb-up.xpm"
57 #include "icons/flag-thumb-down.xpm"
58 #include "icons/flag-heart.xpm"
59 #include "icons/flag-flash.xpm"
60 #include "icons/flag-lifebelt.xpm"
62 extern TextEditor *textEditor;
63 extern int statusbarTime;
64 extern Main *mainWindow;
65 extern QString tmpVymDir;
66 extern FlagRowObj *systemFlagsDefault;
67 extern FlagRowObj *standardFlagsDefault;
68 extern MapEditor *clipboardME;
70 extern QPtrList <QAction> actionListBranches;
72 extern QAction *actionFileSave;
73 extern QAction *actionEditUndo;
74 extern QAction *actionEditCopy;
75 extern QAction *actionEditCut;
76 extern QAction *actionEditPaste;
77 extern QAction *actionEditMoveUp;
78 extern QAction *actionEditMoveDown;
79 extern QAction *actionEditToggleScroll;
80 extern QAction *actionEditOpenURL;
81 extern QAction *actionEditURL;
82 extern QAction *actionEditHeading2URL;
83 extern QAction *actionEditBugzilla2URL;
84 extern QAction *actionEditOpenVymLink;
85 extern QAction *actionEditVymLink;
86 extern QAction *actionEditDeleteVymLink;
87 extern QAction *actionEditHeading;
88 extern QAction *actionEditDelete;
89 extern QAction *actionEditAddBranch;
90 extern QAction *actionEditAddBranchAbove;
91 extern QAction *actionEditAddBranchBelow;
92 extern QAction *actionEditRemoveBranchHere;
93 extern QAction *actionEditRemoveChilds;
94 extern QAction *actionEditImportAdd;
95 extern QAction *actionEditImportReplace;
96 extern QAction *actionEditSaveBranch;
97 extern QAction *actionEditSelectFirst;
98 extern QAction *actionEditSelectLast;
99 extern QAction *actionEditLoadImage;
100 extern QAction *actionEditToggleFloatExport;
102 extern QAction* actionFormatPickColor;
103 extern QAction* actionFormatColorBranch;
104 extern QAction* actionFormatColorSubtree;
105 extern QAction *actionFormatLinkColorHint;
106 extern QAction *actionFormatBackColor;
107 extern QAction *actionFormatLinkColor;
109 extern QActionGroup* actionGroupModModes;
110 extern QAction* actionModModeColor;
111 extern QAction* actionModModeLink;
112 extern QAction* actionModModeCopy;
114 extern QActionGroup *actionGroupFormatFrameTypes;
115 extern QAction *actionFormatFrameNone;
116 extern QAction *actionFormatFrameRectangle;
118 extern QActionGroup *actionGroupFormatLinkStyles;
119 extern QAction *actionFormatHideLinkUnselected;
120 extern QAction *actionFormatLinkStyleLine;
121 extern QAction *actionFormatLinkStyleParabel;
122 extern QAction *actionFormatLinkStylePolyLine;
123 extern QAction *actionFormatLinkStylePolyParabel;
125 extern QAction *actionViewToggleNoteEditor;
127 extern QAction *actionSettingsAutoedit;
128 extern QAction *actionSettingsAutoselectHeading;
129 extern QAction *actionSettingsAutoselectText;
130 extern QAction *actionSettingsPasteNewHeading;
131 extern QAction *actionSettingsUseFlagGroups;
133 extern QPopupMenu *branchContextMenu;
134 extern QPopupMenu *branchLinksContextMenu;
135 extern QPopupMenu *branchLinksContextMenuDup;
136 extern QPopupMenu *floatimageContextMenu;
137 extern QPopupMenu *saveImageFormatMenu;
138 extern QPopupMenu *exportImageFormatMenu;
139 extern QPopupMenu *canvasContextMenu;
141 extern Settings settings;
143 int MapEditor::mapNum=0; // make instance
145 ///////////////////////////////////////////////////////////////////////
146 ///////////////////////////////////////////////////////////////////////
147 MapEditor::MapEditor(
148 QWidget* parent, bool interactive, const char* name, WFlags f) :
149 QCanvasView(parent,name,f), urlOperator(0), imageBuffer(0)
151 //cout << "Constructor ME "<<this<<endl;
154 viewport()->setAcceptDrops(true);
156 mapCanvas = new QCanvas(1000,800);
157 mapCanvas->setAdvancePeriod(30);
159 setCanvas (mapCanvas);
161 // Always show scroll bars (automatic would flicker sometimes)
162 setVScrollBarMode ( QScrollView::AlwaysOn );
163 setHScrollBarMode ( QScrollView::AlwaysOn );
165 // Now create the _global_ system flags _once_:
166 // (Later all OrnamentedObj copy from this
167 // and set their own canvas)
168 if (!systemFlagsDefault)
170 systemFlagsDefault = new FlagRowObj (mapCanvas);
171 systemFlagsDefault->setVisibility (false);
172 systemFlagsDefault->setName ("systemFlagsDef");
174 FlagObj *fo = new FlagObj (mapCanvas);
175 fo->load(QPixmap(flag_note_xpm));
177 fo->setToolTip(tr("Note","Systemflag"));
178 systemFlagsDefault->addFlag (fo); // makes deep copy
180 fo->load(QPixmap(flag_url_xpm));
182 fo->setToolTip(tr("WWW Document (external)","Systemflag"));
183 systemFlagsDefault->addFlag (fo);
185 fo->load(QPixmap(flag_vymlink_xpm));
186 fo->setName("vymLink");
187 fo->setToolTip(tr("Link to another vym map","Systemflag"));
188 systemFlagsDefault->addFlag (fo);
190 fo->load(QPixmap(flag_scrolled_right_xpm));
191 fo->setName("scrolledright");
192 fo->setToolTip(tr("subtree is scrolled","Systemflag"));
193 systemFlagsDefault->addFlag (fo);
195 fo->load(QPixmap(flag_tmpUnscrolled_right_xpm));
196 fo->setName("tmpUnscrolledright");
197 fo->setToolTip(tr("subtree is temporary scrolled","Systemflag"));
198 systemFlagsDefault->addFlag (fo);
201 if (!standardFlagsDefault)
203 standardFlagsDefault = new FlagRowObj (mapCanvas);
204 standardFlagsDefault->setVisibility (false);
205 standardFlagsDefault->setName ("standardFlagsDef");
207 FlagObj *fo = new FlagObj (mapCanvas);
208 fo->load(QPixmap(flag_exclamationmark_xpm));
209 fo->setName ("exclamationmark");
210 fo->setGroup("standard-mark");
211 fo->setToolTip(tr("Take care!","Standardflag"));
212 standardFlagsDefault->addFlag (fo); // makes deep copy
214 fo->load(QPixmap(flag_questionmark_xpm));
215 fo->setName("questionmark");
216 fo->setGroup("standard-mark");
217 fo->setToolTip(tr("Really?","Standardflag"));
218 standardFlagsDefault->addFlag (fo);
220 fo->load(QPixmap(flag_hook_green_xpm));
221 fo->setName("hook-green");
222 fo->setGroup("standard-hook");
223 fo->setToolTip(tr("ok!","Standardflag"));
224 standardFlagsDefault->addFlag (fo);
226 fo->load(QPixmap(flag_cross_red_xpm));
227 fo->setName("cross-red");
228 fo->setGroup("standard-hook");
229 fo->setToolTip(tr("Not ok!","Standardflag"));
230 standardFlagsDefault->addFlag (fo);
232 fo->load(QPixmap(flag_stopsign_xpm));
233 fo->setName("stopsign");
234 fo->setToolTip(tr("This won't work!","Standardflag"));
235 standardFlagsDefault->addFlag (fo);
237 fo->load(QPixmap(flag_smiley_good_xpm));
238 fo->setName("smiley-good");
239 fo->setGroup("standard-smiley");
240 fo->setToolTip(tr("Good","Standardflag"));
241 standardFlagsDefault->addFlag (fo);
243 fo->load(QPixmap(flag_smiley_sad_xpm));
244 fo->setName("smiley-sad");
245 fo->setGroup("standard-smiley");
246 fo->setToolTip(tr("Bad","Standardflag"));
247 standardFlagsDefault->addFlag (fo);
249 fo->load(QPixmap(flag_clock_xpm));
250 fo->setName("clock");
251 fo->setToolTip(tr("Time critical","Standardflag"));
252 standardFlagsDefault->addFlag (fo);
254 fo->load(QPixmap(flag_lamp_xpm));
256 fo->setToolTip(tr("Idea!","Standardflag"));
257 standardFlagsDefault->addFlag (fo);
259 fo->load(QPixmap(flag_arrow_up_xpm));
260 fo->setName("arrow-up");
261 fo->setGroup("standard-arrow");
262 fo->setToolTip(tr("Important","Standardflag"));
263 standardFlagsDefault->addFlag (fo);
265 fo->load(QPixmap(flag_arrow_down_xpm));
266 fo->setName("arrow-down");
267 fo->setGroup("standard-arrow");
268 fo->setToolTip(tr("Unimportant","Standardflag"));
269 standardFlagsDefault->addFlag (fo);
271 fo->load(QPixmap(flag_thumb_up_xpm));
272 fo->setName("thumb-up");
273 fo->setGroup("standard-thumb");
274 fo->setToolTip(tr("I like this","Standardflag"));
275 standardFlagsDefault->addFlag (fo);
277 fo->load(QPixmap(flag_thumb_down_xpm));
278 fo->setName("thumb-down");
279 fo->setGroup("standard-thumb");
280 fo->setToolTip(tr("I like this","Standardflag"));
281 fo->setToolTip(tr("I do not like this","Standardflag"));
282 standardFlagsDefault->addFlag (fo);
284 fo->load(QPixmap(flag_heart_xpm));
285 fo->setName("heart");
286 fo->setToolTip(tr("I just love... ","Standardflag"));
287 standardFlagsDefault->addFlag (fo);
289 fo->load(QPixmap(flag_flash_xpm));
290 fo->setName("flash");
291 fo->setToolTip(tr("Dangerous","Standardflag"));
292 standardFlagsDefault->addFlag (fo);
294 fo->load(QPixmap(flag_lifebelt_xpm));
295 fo->setName("lifebelt");
296 fo->setToolTip(tr("This will help","Standardflag"));
297 standardFlagsDefault->addFlag (fo);
302 mapCenter = new MapCenterObj(mapCanvas);
303 mapCenter->setVisibility (true);
304 mapCenter->setMapEditor (this);
305 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
309 lineedit = new QLineEdit(this, "lineedit" );
310 connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEditNoSave() ) );
313 actColor=black; setColor (actColor);
314 defLinkColor=QColor (0,0,255);
315 defXLinkColor=QColor (180,180,180);
316 linkcolorhint=DefaultColor;
317 linkstyle=StylePolyParabel;
318 mapCanvas->setBackgroundColor (white);
320 // Create bitmap cursors, patform dependant
321 #if defined(Q_OS_MACX)
322 #include "icons/cursorhandopen16.xpm"
323 #include "icons/cursorcolorpicker16.xpm"
324 QBitmap cb( 16, 16, chandopen, TRUE );
325 QBitmap cm( 16, 16, chandopenmask, TRUE );
326 handOpenCursor=QCursor ( cb, cm );
327 // set hot spot to tip of picker
328 pickColorCursor=QCursor ( cursorcolorpicker_xpm, 1,15 );
330 #include "icons/cursorhandopen.xpm"
331 #include "icons/cursorcolorpicker.xpm"
333 QBitmap cb( 32, 32, chandopen, TRUE );
334 QBitmap cm( 32, 32, chandopenmask, TRUE );
335 handOpenCursor=QCursor ( cb, cm );
336 // set hot spot to tip of picker
337 pickColorCursor=QCursor ( cursorcolorpicker_xpm, 5,27 );
350 defXLinkColor=QColor (230,230,230);
361 undosTotal=settings.readNumEntry("/vym/mapeditor/undoLevels",50);
365 // Initialize find routine
372 blockReposition=false;
373 blockSaveState=false;
374 isInteractive=interactive;
376 // Create temporary files
379 // Initially set movingCentre
382 mapCenter->reposition(); // for positioning heading
385 MapEditor::~MapEditor()
387 if (imageBuffer) delete imageBuffer;
393 //cout <<"Destructor MapEditor\n";
396 //settings.writeEntry( "/vym/mapeditor/editmode/autoselect", );
400 QColor MapEditor::color()
405 QColor MapEditor::backgroundColor()
407 return mapCanvas->backgroundColor();
410 MapCenterObj* MapEditor::getMapCenter()
415 QCanvas* MapEditor::getCanvas()
420 void MapEditor::adjustCanvasSize()
422 // To adjust the canvas to map, viewport size and position, we have to
423 // do some coordinate magic...
425 // Get rectangle of (scroll-)view.
426 // We want to be in canvas coords, so
427 // we map. Important if view is zoomed...
428 QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(),
429 visibleWidth(), visibleHeight()) );
431 // Now we need the bounding box of view AND map to calc the correct canvas size.
432 // Why? Because if the map itself is moved out of view, the view has to be enlarged
433 // to avoid jumping aroung...
434 QRect map=mapCenter->getTotalBBox();
436 // right edge - left edge
437 int cw= max(map.x() + map.width(), view.x() + view.width()) - min(map.x(), view.x());
438 int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
441 if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) ||
442 !mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight())
445 // move the map on canvas (in order to not move it on screen) this is neccessary
446 // a) if topleft corner of canvas is left or above topleft corner of view and also left of
447 // above topleft corner of map. E.g. if map is completly inside view, but it would be possible
448 // to scroll to an empty area of canvas to the left.
449 // b) if topleft corner of map left of or above topleft of canvas
453 if (cw > mapCanvas->width() )
455 if (map.x()<0) dx=-map.x();
457 if (cw < mapCanvas->width() )
458 dx=-min (view.x(),map.x());
459 if (ch > mapCanvas->height() )
461 if (map.y()<0) dy=-map.y();
463 if (ch < mapCanvas->height() )
465 dy=-min (view.y(),map.y());
467 // We really have to resize now. Let's go...
468 mapCanvas->resize (cw,ch);
469 if ( (dx!=0) || (dy!=0) )
471 mapCenter->moveAllBy(dx,dy);
472 mapCenter->reposition();
474 // scroll the view (in order to not move map on screen)
480 bool MapEditor::isRepositionBlocked()
482 return blockReposition;
485 void MapEditor::makeTmpDirs()
487 // Create unique temporary directories
488 tmpMapDir=tmpVymDir+QString("/mapeditor-%1").arg(mapNum);
490 d.mkdir (tmpMapDir,true);
493 void MapEditor::delTmpDirs()
495 removeDir (QDir(tmpMapDir));
499 void MapEditor::makeSubDirs(const QString &s)
508 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, LinkableMapObj *saveSelection)
510 // tmpdir temporary directory to which data will be written
511 // prefix mapname, which will be appended to images etc.
512 // writeflags Only write flags for "real" save of map, not undo
513 // offset offset of bbox of whole map in canvas.
514 // Needed for XML export
515 // completeMap if false, only vympart will be written, without
532 ls="StylePolyParabel";
536 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
538 if (linkcolorhint==HeadingColor)
539 colhint=attribut("linkColorHint","HeadingColor");
541 QString mapAttr=attribut("version",__VYM_VERSION__);
543 mapAttr+= attribut("author",mapCenter->getAuthor()) +
544 attribut("comment",mapCenter->getComment()) +
545 attribut("date",mapCenter->getDate()) +
546 attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
547 attribut("linkStyle", ls ) +
548 attribut("linkColor", defLinkColor.name() ) +
549 attribut("defXLinkColor", defXLinkColor.name() ) +
550 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
552 s+=beginElement("vymmap",mapAttr);
555 // Find the used flags while traversing the tree
556 standardFlagsDefault->resetUsedCounter();
558 // Build xml recursivly
560 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
563 if ( typeid(*saveSelection) == typeid(BranchObj) )
564 s+=((BranchObj*)(saveSelection))->saveToDir(tmpdir,prefix,offset);
566 if (selection && typeid(*selection)==typeid(BranchObj))
567 // This is used if selected branch is saved from mainwindow
568 s+=((BranchObj*)selection)->saveToDir(tmpdir,prefix,offset);
571 // Save local settings
572 s+=settings.getXMLData (destPath);
575 if (selection && !saveSelection )
576 s+=valueElement("select",selection->getSelectString());
579 s+=endElement("vymmap");
582 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
586 void MapEditor::saveState()
589 saveState (CompleteMap,"",NULL,"",NULL);
592 void MapEditor::saveState(LinkableMapObj *undoSel)
594 // save the given part of the map
595 saveState (PartOfMap,"",undoSel,"",NULL);
598 void MapEditor::saveState(const QString &uc, const QString &rc)
600 // selection does not change during action,
601 // so just save commands for undo and redo
602 LinkableMapObj *unsel;
607 saveState (UndoCommand,uc,unsel,rc,unsel);
610 void MapEditor::saveState(const QString & uncom, LinkableMapObj *unsel)
612 saveState (UndoCommand,uncom,unsel,"FIXME-redoCom",NULL);
615 void MapEditor::saveState(const SaveMode &savemode, const QString &undoCom, LinkableMapObj *undoSel, const QString &redoCom, LinkableMapObj *redoSel)
619 if (blockSaveState) return;
621 /* TODO remove after testing
622 cout << "ME::saveState() begin\n"<<endl;
623 cout << " undosTotal="<<undosTotal<<endl;
624 cout << " undosAvail="<<undosAvail<<endl;
625 cout << " undoNum="<<undoNum<<endl;
626 cout << " ---------------------------"<<endl;
630 // Find out current undo directory
631 if (undosAvail<undosTotal) undosAvail++;
633 if (undoNum>undosTotal) undoNum=1;
636 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(undoNum));
637 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
639 // Create bakMapDir if not available
642 makeSubDirs (bakMapDir);
644 // Save current selection
645 QString redoSelection="";
647 redoSelection=redoSel->getSelectString();
649 // Save the object, which should be undone
650 QString undoSelection="";
652 undoSelection=undoSel->getSelectString();
654 // Save depending on how much needs to be saved
655 QString undoCommand="";
656 if (savemode==UndoCommand)
661 else if (savemode==PartOfMap && undoSel)
663 undoCommand="undoPart (\""+ undoSelection+"\",\""+bakMapPath+"\")";
664 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),undoSel);
667 undoCommand="undoMap (\""+bakMapPath+"\")";
668 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),NULL);
671 if (!backupXML.isEmpty())
672 // Write XML Data to disk
673 saveStringToDisk (QString(bakMapPath),backupXML);
676 set.setEntry (QString("undoCommand"),undoCommand);
677 set.setEntry (QString("undoSelection"),undoSelection);
678 set.setEntry (QString("redoCommand"),redoCom);
679 set.setEntry (QString("redoSelection"),redoSelection);
680 set.writeSettings(QString(bakMapDir+"/commands"));
682 /* TODO remove after testing
683 cout << " into="<< bakMapDir<<endl;
684 cout << " undosAvail="<<undosAvail<<endl;
685 cout << " undoNum="<<undoNum<<endl;
686 cout << " ---------------------------"<<endl;
687 cout << " undoCom="<<undoCommand<<endl;
688 cout << " undoSel="<<undoSelection<<endl;
689 cout << " ---------------------------"<<endl;
690 cout << " redoCom="<<redoCom<<endl;
691 cout << " redoSel="<<redoSelection<<endl;
692 cout << " ---------------------------"<<endl<<endl;
696 void MapEditor::parseAtom(const QString &atom)
703 // Split string s into command and parameters
704 api.parseCommand (atom);
705 QString com=api.command();
708 if (com=="moveBranchUp")
710 else if (com=="moveBranchDown")
712 else if (com=="move")
714 if (api.checkParamCount(2) && selection )
724 else if (com=="linkBranchToPos")
726 if (selection && typeid(*selection) == typeid(BranchObj) )
728 if (api.checkParamCount(4))
730 s=api.parString(ok,0);
731 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
734 if (typeid(*dst) == typeid(BranchObj) )
736 // Get number in parent
739 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),x);
740 } else if (typeid(*dst) == typeid(MapCenterObj) )
742 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),-1);
743 // Get coordinates of mainbranch
748 if (ok) ((BranchObj*)selection)->move (x,y);
754 } else if (com=="setHeading")
756 if (api.checkParamCount(1))
758 s=api.parString (ok,0);
759 if (ok) setHeading (s);
761 } else if (com=="setURL")
763 if (api.checkParamCount(1))
765 s=api.parString (ok,0);
768 } else if (com=="setVymLink")
770 if (api.checkParamCount(1))
772 s=api.parString (ok,0);
773 if (ok) setVymLink(s);
776 // Internal commands, used for undo etc.
777 else if (com==QString("undoMap"))
779 if (api.checkParamCount(1))
780 undoXML("",api.parString (ok,0));
781 } else if (com==QString("undoPart"))
783 if (api.checkParamCount(2))
785 s=api.parString (ok,0);
786 t=api.parString (ok,1);
789 } else if (com=="select")
790 if (api.checkParamCount(1))
792 s=api.parString(ok,0);
797 api.setError ("Unknown command in: "+atom);
798 cout << "ME::parse api should have error now...\n";
804 cout << "MapEditor::parseAtom: Error!\n";
805 cout << " "<<api.errorDesc()<<endl;
810 void MapEditor::finishedLineEditNoSave()
812 // This is called by finishedLineEdit or any MapEditor method,
813 // which wants to assure, that lineedits finish, before e.g. a branch is
816 // After calling LineEdit and using the clipboard, the
817 // focus is not any longer on the main widget, we
818 // have to restore it using parentWidget()->setFocus()
822 editingBO->setHeading(lineedit->text() );
824 lineedit->releaseKeyboard();
826 parentWidget()->setFocus();
827 mapCenter->reposition();
829 ensureSelectionVisible();
834 bool MapEditor::isDefault()
839 bool MapEditor::isUnsaved()
844 bool MapEditor::hasChanged()
849 void MapEditor::setChanged()
854 actionEditUndo->setEnabled (true);
855 actionFileSave->setEnabled (true);
859 void MapEditor::closeMap()
861 // Finish open lineEdits
862 if (lineedit) finishedLineEditNoSave();
864 // Unselect before disabling the toolbar actions
865 if (selection) selection->unselect();
873 void MapEditor::setFilePath(QString fname)
875 setFilePath (fname,fname);
878 void MapEditor::setFilePath(QString fname, QString destname)
887 filePath=fname; // becomes absolute path
888 fileName=fname; // gets stripped of path
889 destPath=destname; // needed for vymlinks
891 // If fname is not an absolute path, complete it
892 filePath=QDir(fname).absPath();
893 fileDir=filePath.left (1+filePath.findRev ("/"));
895 // Set short name, too. Search from behind:
896 int i=fileName.findRev("/");
897 if (i>=0) fileName=fileName.remove (0,i+1);
899 // Forget the .vym (or .xml) for name of map
900 mapName=fileName.left(fileName.findRev(".",-1,true) );
904 QString MapEditor::getFilePath()
909 QString MapEditor::getFileName()
914 QString MapEditor::getMapName()
919 QString MapEditor::getDestPath()
924 int MapEditor::load (QString &fname, const LoadMode &lmode)
926 // Finish open lineEdits
927 if (lineedit) finishedLineEditNoSave();
933 if (selection) selection->unselect();
936 mapCenter->setMapEditor(this);
937 // (map state is set later at end of load...)
940 saveState(selection);
944 mapBuilderHandler handler;
947 // I am paranoid: file should exist anyway
948 // according to check in mainwindow.
951 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
952 tr("Couldn't open map " +fname)+".");
956 blockReposition=true;
957 QXmlInputSource source( file);
958 QXmlSimpleReader reader;
959 reader.setContentHandler( &handler );
960 reader.setErrorHandler( &handler );
961 handler.setMapEditor( this );
962 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
963 handler.setLoadMode (lmode);
965 bool ok = reader.parse( source );
966 blockReposition=false;
967 blockSaveState=false;
971 mapCenter->reposition();
981 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
982 tr( handler.errorProtocol() ) );
984 // Still return "success": the map maybe at least
985 // partially read by the parser
992 int MapEditor::save (const SaveMode &savemode)
994 // Finish open lineEdits
995 if (lineedit) finishedLineEditNoSave();
999 // The SaveMode UndoCommand is not supported here
1000 if (savemode==UndoCommand) return 1;
1002 // Create mapName and fileDir
1003 makeSubDirs (fileDir);
1007 fname=mapName+".xml";
1009 // use name given by user, even if he chooses .doc
1014 if (savemode==CompleteMap || selection==NULL)
1015 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),NULL);
1017 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),selection);
1019 if (!saveStringToDisk(fileDir+fname,saveFile))
1026 actionFileSave->setEnabled(false);
1032 void MapEditor::setZipped (bool z)
1037 bool MapEditor::saveZipped ()
1042 void MapEditor::print()
1044 // Finish open lineEdits
1045 if (lineedit) finishedLineEditNoSave();
1049 printer = new QPrinter;
1050 printer->setColorMode (QPrinter::Color);
1051 printer->setPrinterName (settings.readEntry("/vym/mainwindow/printerName",printer->printerName()));
1054 QRect totalBBox=mapCenter->getTotalBBox();
1056 // Try to set orientation automagically
1057 // Note: Interpretation of generated postscript is amibiguous, if
1058 // there are problems with landscape mode, see
1059 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1061 if (totalBBox.width()>totalBBox.height())
1062 // recommend landscape
1063 printer->setOrientation (QPrinter::Landscape);
1065 // recommend portrait
1066 printer->setOrientation (QPrinter::Portrait);
1068 if ( printer->setup(this) )
1069 // returns false, if printing is canceled
1071 QPainter pp(printer);
1073 // Don't print the visualisation of selection
1074 LinkableMapObj *oldselection=NULL;
1077 oldselection=selection;
1078 selection->unselect();
1081 // Handle sizes of map and paper:
1083 // setWindow defines which part of the canvas will be transformed
1084 // setViewport defines area on paper in device coordinates (dpi)
1085 // e.g. (0,50,700,700) is upper part on A4
1086 // see also /usr/lib/qt3/doc/html/coordsys.html
1088 QPaintDeviceMetrics metrics (printer);
1090 double paperAspect = (double)metrics.width() / (double)metrics.height();
1091 double mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
1093 QRect mapRect=totalBBox;
1094 QCanvasRectangle *frame=NULL;
1095 QCanvasText *footerFN=NULL;
1096 QCanvasText *footerDate=NULL;
1097 if (printFrame || printFooter)
1102 // Print frame around map
1103 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1104 totalBBox.width()+20, totalBBox.height()+20);
1105 frame=new QCanvasRectangle (mapRect,mapCanvas);
1106 frame->setBrush (QColor(white));
1107 frame->setPen (QColor(black));
1111 /* TODO remove after testing
1112 QCanvasLine *l=new QCanvasLine (mapCanvas);
1113 l->setPoints (0,0,mapRect.width(),mapRect.height());
1114 l->setPen (QPen(QColor(black), 1));
1121 // Print footer below map
1123 font.setPointSize(10);
1124 footerFN=new QCanvasText (mapCanvas);
1125 footerFN->setText ("VYM - " + fileName);
1126 footerFN->setFont(font);
1127 footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
1128 footerFN->setZ(Z_TEXT);
1130 footerDate=new QCanvasText (mapCanvas);
1131 footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
1132 footerDate->setFont(font);
1133 footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
1134 footerDate->setZ(Z_TEXT);
1137 pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()+20);
1140 pp.setWindow (mapRect);
1143 if (mapAspect>=paperAspect)
1145 // Fit horizontally to paper width
1146 pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );
1149 // Fit vertically to paper height
1150 pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());
1153 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to printer
1155 // Delete Frame and footer
1159 delete (footerDate);
1161 if (frame) delete (frame);
1163 // Restore selection
1166 selection=oldselection;
1167 selection->select();
1170 // Save settings in vymrc
1171 settings.writeEntry("/vym/mainwindow/printerName",printer->printerName());
1175 QPixmap MapEditor::getPixmap()
1177 QRect mapRect=mapCenter->getTotalBBox();
1178 QPixmap pix (mapRect.size());
1181 // Don't print the visualisation of selection
1182 LinkableMapObj *oldselection=NULL;
1185 oldselection=selection;
1186 selection->unselect();
1189 pp.setWindow (mapRect);
1191 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to painter
1194 // Restore selection
1197 selection=oldselection;
1198 selection->select();
1204 void MapEditor::exportImage(QString fn)
1206 // Finish open lineEdits
1207 if (lineedit) finishedLineEditNoSave();
1209 QPixmap pix (getPixmap());
1210 pix.save(fn, "PNG");
1213 void MapEditor::exportImage(QString fn, int item)
1215 // Finish open lineEdits
1216 if (lineedit) finishedLineEditNoSave();
1218 QPixmap pix (getPixmap());
1219 pix.save(fn, exportImageFormatMenu->text(item) );
1222 void MapEditor::exportASCII()
1224 // TODO still experimental
1226 ex.setMapCenter(mapCenter);
1228 QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (ASCII)"));
1229 fd->addFilter ("TXT (*.txt)");
1230 fd->setCaption("VYM - Export (ASCII) (still experimental)");
1231 fd->setMode( QFileDialog::AnyFile );
1234 if ( fd->exec() == QDialog::Accepted )
1236 if (QFile (fd->selectedFile()).exists() )
1238 QMessageBox mb( "VYM",
1239 tr("The file %1 exists already.\nDo you want to overwrite it?").arg(fd->selectedFile()),
1240 QMessageBox::Warning,
1241 QMessageBox::Yes | QMessageBox::Default,
1242 QMessageBox::Cancel | QMessageBox::Escape,
1243 QMessageBox::NoButton );
1245 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
1246 mb.setButtonText( QMessageBox::No, tr("Cancel"));
1250 case QMessageBox::Yes:
1253 case QMessageBox::Cancel:
1254 // return, do nothing
1259 ex.setPath (fd->selectedFile() );
1264 void MapEditor::exportLaTeX()
1266 // TODO still experimental
1267 QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (LaTex)"));
1268 fd->addFilter ("TEX (*.tex)");
1269 fd->setCaption("VYM - Export (LaTex) (still experimental)");
1270 fd->setMode( QFileDialog::AnyFile );
1273 if ( fd->exec() == QDialog::Accepted )
1275 if (QFile (fd->selectedFile()).exists() )
1277 QMessageBox mb( "VYM",
1278 tr("The file ") + fd->selectedFile() +
1279 tr(" exists already. Do you want to overwrite it?"),
1280 QMessageBox::Warning,
1281 QMessageBox::Yes | QMessageBox::Default,
1282 QMessageBox::Cancel | QMessageBox::Escape,
1283 QMessageBox::NoButton );
1285 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
1286 mb.setButtonText( QMessageBox::No, tr("Cancel"));
1290 case QMessageBox::Yes:
1293 case QMessageBox::Cancel:
1300 ex.setPath (fd->selectedFile() );
1301 ex.setMapCenter(mapCenter);
1306 void MapEditor::exportOOPresentation()
1308 // TODO still experimental
1310 QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (Open Office 1.3.x Presentation)"));
1311 fd->addFilter ("Open Office 1.3.x presentation (*.sxi)");
1312 fd->setCaption("VYM - Export (Open Office 1.3.x presentation) (still experimental)");
1313 fd->setMode( QFileDialog::AnyFile );
1316 if ( fd->exec() == QDialog::Accepted )
1318 if (QFile (fd->selectedFile()).exists() )
1320 QMessageBox mb( "VYM",
1321 tr("The file ") + fd->selectedFile() +
1322 tr(" exists already. Do you want to overwrite it?"),
1323 QMessageBox::Warning,
1324 QMessageBox::Yes | QMessageBox::Default,
1325 QMessageBox::Cancel | QMessageBox::Escape,
1326 QMessageBox::NoButton );
1328 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
1329 mb.setButtonText( QMessageBox::No, tr("Cancel"));
1333 case QMessageBox::Yes:
1336 case QMessageBox::Cancel:
1344 //ex.setPath (fd->selectedFile() );
1345 ex.setMapCenter(mapCenter);
1346 ex.exportOOPresentation();
1352 void MapEditor::exportXML(const QString &dir)
1354 // Create subdirectories
1357 // write to directory
1358 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1361 file.setName ( dir + "/"+mapName+".xml");
1362 if ( !file.open( IO_WriteOnly ) )
1364 // This should neverever happen
1365 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1369 // Write it finally, and write in UTF8, no matter what
1370 QTextStream ts( &file );
1371 ts.setEncoding (QTextStream::UnicodeUTF8);
1375 // Now write image, too
1376 exportImage (dir+"/images/"+mapName+".png");
1379 void MapEditor::clear()
1383 selection->unselect();
1390 void MapEditor::copy()
1392 // Finish open lineEdits
1393 if (lineedit) finishedLineEditNoSave();
1397 if (typeid(*selection) == typeid(BranchObj) )
1401 clipboardME->clear();
1402 clipboardME->getMapCenter()->addBranch();
1403 to=clipboardME->getMapCenter()->getLastBranch();
1406 from=(BranchObj*)selection;
1409 // keep position relative to parent
1410 to->move2RelPos ( from->getRelPos());
1412 // select data in clipboard
1413 // clipboardME->select ("bo:0");
1415 // repositioning makes testing nicer,
1416 // but is not needed usually:
1417 if (clipboardME->isVisible())
1418 clipboardME->getMapCenter()->reposition();
1420 clipboardME->hide();
1423 /* FIXME rewrite this using import/export
1424 Currently there is a bug which would erase note, if
1425 branchobj in clipboard is selected...
1426 if (typeid(*selection) == typeid(FloatImageObj) )
1429 FloatImageObj* from;
1430 clipboardME->clear();
1431 clipboardME->getMapCenter()->addFloatImage();
1432 to=clipboardME->getMapCenter()->getLastFloatImage();
1435 from=(FloatImageObj*)selection;
1438 // select data in clipboard
1439 clipboardME->select ("fi:0");
1441 // repositioning makes testing nicer,
1442 // but is not needed usually:
1443 if (clipboardME->isVisible())
1444 clipboardME->getMapCenter()->reposition();
1446 clipboardME->hide();
1453 void MapEditor::redo()
1455 // Finish open lineEdits
1456 if (lineedit) finishedLineEditNoSave();
1458 blockSaveState=true;
1460 // Find out current undo directory
1461 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(undoNum));
1463 // Restore variables
1464 QString undoCommand;
1465 QString undoSelection;
1466 QString redoCommand;
1467 QString redoSelection;
1469 set.readSettings(QString(bakMapDir+"/commands"));
1470 undoCommand=set.readEntry ("undoCommand");
1471 undoSelection=set.readEntry ("undoSelection");
1472 redoCommand=set.readEntry ("redoCommand");
1473 redoSelection=set.readEntry ("redoSelection");
1475 // select object before redo
1476 if (!redoSelection.isEmpty())
1477 select (redoSelection);
1479 /* TODO remove testing
1480 cout << "ME::redo() begin\n";
1481 cout << " undosTotal="<<undosTotal<<endl;
1482 cout << " undosAvail="<<undosAvail<<endl;
1483 cout << " undoNum="<<undoNum<<endl;
1484 cout << " ---------------------------"<<endl;
1485 cout << " undoCom="<<undoCommand<<endl;
1486 cout << " undoSel="<<undoSelection<<endl;
1487 cout << " ---------------------------"<<endl;
1488 cout << " redoCom="<<redoCommand<<endl;
1489 cout << " redoSel="<<redoSelection<<endl;
1490 cout << " ---------------------------"<<endl;
1492 parseAtom (undoCommand);
1493 mapCenter->reposition();
1495 //if (!redoSelection.isEmpty())
1496 // select (redoSelection);
1500 // Undo not longer available now
1501 actionEditUndo->setEnabled (false);
1503 undoNum--; if (undoNum<1) undoNum=undosTotal;
1505 blockSaveState=false;
1506 /* TODO remove testing
1507 cout << "ME::redo() end\n";
1508 cout << " undosAvail="<<undosAvail<<endl;
1509 cout << " undoNum="<<undoNum<<endl;
1510 cout << " ---------------------------"<<endl<<endl;
1514 void MapEditor::undo()
1516 // Finish open lineEdits
1517 if (lineedit) finishedLineEditNoSave();
1519 blockSaveState=true;
1521 // Find out current undo directory
1522 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(undoNum));
1524 // Restore variables
1525 QString undoCommand;
1526 QString undoSelection;
1527 QString redoCommand;
1528 QString redoSelection;
1530 set.readSettings(QString(bakMapDir+"/commands"));
1531 undoCommand= set.readEntry ("undoCommand");
1532 undoSelection=set.readEntry ("undoSelection");
1533 redoCommand= set.readEntry ("redoCommand");
1534 redoSelection=set.readEntry ("redoSelection");
1536 // select object before undo
1537 if (!undoSelection.isEmpty())
1538 select (undoSelection);
1541 cout << "ME::undo() begin\n";
1542 cout << " undosTotal="<<undosTotal<<endl;
1543 cout << " undosAvail="<<undosAvail<<endl;
1544 cout << " undoNum="<<undoNum<<endl;
1545 cout << " ---------------------------"<<endl;
1546 cout << " undoCom="<<undoCommand<<endl;
1547 cout << " undoSel="<<undoSelection<<endl;
1548 cout << " ---------------------------"<<endl;
1549 cout << " redoCom="<<redoCommand<<endl;
1550 cout << " redoSel="<<redoSelection<<endl;
1551 cout << " ---------------------------"<<endl;
1553 parseAtom (undoCommand);
1554 mapCenter->reposition();
1556 //if (!redoSelection.isEmpty())
1557 // select (redoSelection);
1561 // Undo not longer available now
1562 actionEditUndo->setEnabled (false);
1564 undoNum--; if (undoNum<1) undoNum=undosTotal;
1566 blockSaveState=false;
1567 /* TODO remove testing
1568 cout << "ME::undo() end\n";
1569 cout << " undosAvail="<<undosAvail<<endl;
1570 cout << " undoNum="<<undoNum<<endl;
1571 cout << " ---------------------------"<<endl<<endl;
1575 void MapEditor::undoXML(const QString &undoSel, const QString &bakMapPath)
1577 QString bakMapDir=bakMapPath.left(bakMapPath.findRev("/"));
1579 QFile file (bakMapPath);
1583 // We need to parse saved XML data
1584 mapBuilderHandler handler;
1585 QXmlInputSource source( file);
1586 QXmlSimpleReader reader;
1587 reader.setContentHandler( &handler );
1588 reader.setErrorHandler( &handler );
1589 handler.setMapEditor( this );
1590 handler.setTmpDir ( bakMapDir ); // needed to load files with rel. path
1591 if (undoSel.isEmpty())
1595 handler.setLoadMode (NewMap);
1599 handler.setLoadMode (ImportReplace);
1601 blockReposition=true;
1602 bool ok = reader.parse( source );
1603 blockReposition=false;
1606 // This should never ever happen
1607 QMessageBox::critical( 0, tr( "Critical Parse Error by reading backupFile" ),
1608 tr( handler.errorProtocol() )+" in "+bakMapDir );
1612 QMessageBox::critical( 0, tr( "Critical Error" ),
1613 tr("Temporary directory %1 used for undo is gone. \n"
1614 "I will create a new one, but at the moment no undo is available.\n"
1615 "Maybe you want to reload your original data.\n\n"
1616 "Sorry for any inconveniences.").arg(bakMapDir) );
1621 LinkableMapObj* MapEditor::pasteNoSave()
1623 // Finish open lineEdits
1624 if (lineedit) finishedLineEditNoSave();
1626 clipboardME->select ("bo:0");
1627 LinkableMapObj *fromLMO=clipboardME->getSelection();
1628 LinkableMapObj *returnLMO=NULL;
1630 if (selection && fromLMO)
1632 if (typeid(*fromLMO) == typeid(BranchObj) )
1634 if (typeid(*selection) == typeid(MapCenterObj))
1636 returnLMO=mapCenter->addBranch( (BranchObj*)(fromLMO) );
1637 ((BranchObj*)(returnLMO))->move2RelPos(normalise(fromLMO->getRelPos() ) );
1639 if (typeid(*selection) == typeid(BranchObj))
1640 returnLMO=((BranchObj*)selection)->addBranch((BranchObj*)(fromLMO) );
1643 if (typeid(*fromLMO) == typeid(FloatImageObj) &&
1644 (typeid(*selection) == typeid (BranchObj) ||
1645 typeid(*selection)==typeid(MapCenterObj)) )
1646 returnLMO=((BranchObj*) selection)->addFloatImage ((FloatImageObj*)(fromLMO));
1652 void MapEditor::cutNoSave()
1654 // Finish open lineEdits
1655 if (lineedit) finishedLineEditNoSave();
1659 if (selection != NULL) {
1660 if (typeid(*selection) == typeid(BranchObj) )
1662 bo=(BranchObj*)selection;
1663 par=(BranchObj*)(bo->getParObj());
1666 par->removeBranch(bo);
1668 selection->select();
1670 if (typeid(*selection) == typeid(FloatImageObj) )
1672 FloatImageObj* fio=(FloatImageObj*)selection;
1673 par=(BranchObj*)(fio->getParObj());
1676 par->removeFloatImage(fio);
1678 selection->select();
1683 void MapEditor::paste()
1685 saveState(selection);
1687 mapCenter->reposition();
1691 void MapEditor::cut()
1693 saveState(selection->getParObj());
1696 mapCenter->reposition();
1700 void MapEditor::move(const int &x, const int &y)
1702 // TODO no saveState, because this is only internal at undo so far
1703 if (selection) selection->move(x,y);
1704 if (typeid(*selection) == typeid(FloatImageObj))
1705 ((FloatImageObj*)selection)->setRelPos();
1708 void MapEditor::moveBranchUp()
1710 // Finish open lineEdits
1711 if (lineedit) finishedLineEditNoSave();
1715 if (typeid(*selection) == typeid(BranchObj) )
1717 bo=(BranchObj*)selection;
1718 par=(BranchObj*)(bo->getParObj());
1719 selection->unselect();
1720 selection=par->moveBranchUp (bo);
1721 selection->select();
1722 saveState("moveBranchDown ()",bo);
1723 mapCenter->reposition();
1724 ensureSelectionVisible();
1728 void MapEditor::moveBranchDown()
1730 // Finish open lineEdits
1731 if (lineedit) finishedLineEditNoSave();
1735 if (typeid(*selection) == typeid(BranchObj) )
1737 bo=(BranchObj*)selection;
1738 par=(BranchObj*)(bo->getParObj());
1739 selection->unselect();
1740 selection=par->moveBranchDown(bo);
1741 selection->select();
1742 saveState("moveBranchUp ()",bo);
1743 mapCenter->reposition();
1744 ensureSelectionVisible();
1748 void MapEditor::editHeading()
1750 // Finish open lineEdits
1751 if (lineedit) finishedLineEditNoSave();
1754 (typeid(*selection) == typeid(BranchObj) ||
1755 typeid(*selection) == typeid(MapCenterObj) ) )
1757 editingBO=(BranchObj*)selection;
1758 saveState("setHeading (\""+((BranchObj*)selection)->getHeading()+"\")",editingBO );
1760 ensureSelectionVisible();
1761 QPoint p = worldMatrix().map(QPoint (editingBO->x(),editingBO->y()));
1762 lineedit->setGeometry(p.x()-contentsX(),p.y()-contentsY(),200,25);
1763 QString s=editingBO->getHeading();
1764 lineedit->setText(s);
1765 lineedit->setCursorPosition(1);
1766 if (actionSettingsAutoselectText->isOn() && !s.isEmpty() && actionSettingsPasteNewHeading->isOn() )
1767 lineedit->selectAll();
1769 lineedit->grabKeyboard();
1770 lineedit->setFocus();
1774 void MapEditor::setHeading(const QString &s)
1776 // Internal function, no saveState needed
1778 (typeid(*selection) == typeid(BranchObj) ||
1779 typeid(*selection) == typeid(MapCenterObj) ) )
1781 ((BranchObj*)selection)->setHeading(s);
1782 mapCenter->reposition();
1784 ensureSelectionVisible();
1788 void MapEditor::setURL (const QString &s)
1790 // Internal function, no saveState needed
1792 (typeid(*selection) == typeid(BranchObj) ||
1793 typeid(*selection) == typeid(MapCenterObj) ) )
1795 ((BranchObj*)selection)->setURL(s);
1796 mapCenter->reposition();
1798 ensureSelectionVisible();
1802 void MapEditor::setVymLink (const QString &s)
1804 // Internal function, no saveState needed
1806 (typeid(*selection) == typeid(BranchObj) ||
1807 typeid(*selection) == typeid(MapCenterObj) ) )
1809 ((BranchObj*)selection)->setVymLink(s);
1810 mapCenter->reposition();
1812 ensureSelectionVisible();
1816 void MapEditor::addNewBranch(int pos)
1818 // Finish open lineEdits
1819 if (lineedit) finishedLineEditNoSave();
1822 (typeid(*selection) == typeid(BranchObj) ||
1823 typeid(*selection) == typeid(MapCenterObj) ) )
1825 saveState(selection); //TODO undoCommand
1827 BranchObj* bo1 = (BranchObj*) selection;
1828 bool wasScrolled=false;
1829 BranchObj *newbo=NULL;
1832 // save scroll state. If scrolled, automatically select
1833 // new branch in order to tmp unscroll parent...
1834 wasScrolled=bo1->isScrolled();
1835 newbo=bo1->addBranch();
1838 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1842 // add above selection
1843 newbo=parbo->insertBranch(bo1->getNum());
1845 // add below selection
1846 newbo=parbo->insertBranch(bo1->getNum()+1);
1848 // This should not happen...
1853 LinkableMapObj *oldselection=selection;
1855 mapCenter->reposition();
1857 if (actionSettingsAutoedit->isOn() ||
1858 actionSettingsAutoselectHeading->isOn() )
1860 selection->unselect();
1862 selection->select();
1863 if (actionSettingsPasteNewHeading->isOn() )
1865 BranchObj *bo2= (BranchObj*)selection;
1866 bo2->setHeading("");
1868 if (actionSettingsAutoedit->isOn() )
1870 if (!actionSettingsAutoselectHeading->isOn()
1873 selection->unselect();
1874 selection=oldselection;
1875 selection->select();
1882 void MapEditor::addNewBranchHere()
1884 // Finish open lineEdits
1885 if (lineedit) finishedLineEditNoSave();
1888 (typeid(*selection) == typeid(BranchObj) ) )
1890 saveState(selection);
1892 BranchObj* bo1 = (BranchObj*) selection;
1893 bool wasScrolled=false;
1894 BranchObj *newbo=NULL;
1895 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1898 // add below selection
1899 newbo=parbo->insertBranch(bo1->getNum()+1);
1902 LinkableMapObj *oldselection=selection;
1903 ((BranchObj*)selection)->moveBranchTo (newbo,-1);
1905 mapCenter->reposition();
1907 if (actionSettingsAutoedit->isOn() ||
1908 actionSettingsAutoselectHeading->isOn() )
1910 selection->unselect();
1912 selection->select();
1913 if (actionSettingsPasteNewHeading->isOn() )
1915 BranchObj *bo2= (BranchObj*)selection;
1916 bo2->setHeading("");
1918 if (actionSettingsAutoedit->isOn() )
1920 if (!actionSettingsAutoselectHeading->isOn()
1923 selection->unselect();
1924 selection=oldselection;
1925 selection->select();
1931 void MapEditor::deleteSelection()
1933 // Finish open lineEdits
1934 if (lineedit) finishedLineEditNoSave();
1936 if (selection && typeid(*selection) ==typeid(BranchObj) )
1938 if (selection->getDepth()>1)
1939 // Normal branch, save parent with childs
1940 saveState(selection->getParObj());
1942 // Mainbranch, save whole map
1943 // TODO Better would be to insert mainbranch again at pos
1944 // But undoCommand is missing right now
1946 BranchObj* bo=dynamic_cast <BranchObj*> (selection);
1947 BranchObj* par=(BranchObj*)(bo->getParObj());
1950 par->removeBranch(bo);
1952 selection->select();
1953 ensureSelectionVisible();
1954 mapCenter->reposition();
1957 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
1959 saveState(selection->getParObj());
1960 FloatImageObj* fio=dynamic_cast <FloatImageObj*> (selection);
1961 BranchObj* par=(BranchObj*)(fio->getParObj());
1964 par->removeFloatImage(fio);
1966 selection->select();
1967 ensureSelectionVisible();
1968 mapCenter->reposition();
1973 LinkableMapObj* MapEditor::getSelection()
1978 bool MapEditor::select (const QString &s)
1980 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
1982 // Finally select the found object
1985 if (selection) unselect();
1987 selection->select();
1989 ensureSelectionVisible();
1995 void MapEditor::unselect()
1999 selectionLast=selection;
2000 selection->unselect();
2005 void MapEditor::reselect()
2009 selection=selectionLast;
2010 selection->select();
2015 void MapEditor::selectNextBranch()
2017 // Increase number of branch
2020 QString s=selection->getSelectString();
2026 part=s.section(",",-1);
2028 num=part.right(part.length() - 3);
2030 s=s.left (s.length() -num.length());
2033 num=QString ("%1").arg(num.toUInt()+1);
2037 // Try to select this one
2038 if (select (s)) return;
2040 // We have no direct successor,
2041 // try to increase the parental number in order to
2042 // find a successor with same depth
2044 int d=selection->getDepth();
2049 while (!found && d>0)
2051 s=s.section (",",0,d-1);
2052 // replace substring of current depth in s with "1"
2053 part=s.section(",",-1);
2055 num=part.right(part.length() - 3);
2059 // increase number of parent
2060 num=QString ("%1").arg(num.toUInt()+1);
2061 s=s.section (",",0,d-2) + ","+ typ+num;
2064 // Special case, look at orientation
2065 if (selection->getOrientation()==OrientRightOfCenter)
2066 num=QString ("%1").arg(num.toUInt()+1);
2068 num=QString ("%1").arg(num.toUInt()-1);
2073 // pad to oldDepth, select the first branch for each depth
2074 for (i=d;i<oldDepth;i++)
2079 if ( ((BranchObj*)selection)->countBranches()>0)
2087 // try to select the freshly built string
2095 void MapEditor::selectPrevBranch()
2097 // Decrease number of branch
2100 QString s=selection->getSelectString();
2106 part=s.section(",",-1);
2108 num=part.right(part.length() - 3);
2110 s=s.left (s.length() -num.length());
2113 num=QString ("%1").arg(num.toUInt()-1);
2117 // Try to select this one
2118 if (select (s)) return;
2120 // We have no direct precessor,
2121 // try to decrease the parental number in order to
2122 // find a precessor with same depth
2124 int d=selection->getDepth();
2129 while (!found && d>0)
2131 s=s.section (",",0,d-1);
2132 // replace substring of current depth in s with "1"
2133 part=s.section(",",-1);
2135 num=part.right(part.length() - 3);
2139 // decrease number of parent
2140 num=QString ("%1").arg(num.toUInt()-1);
2141 s=s.section (",",0,d-2) + ","+ typ+num;
2144 // Special case, look at orientation
2145 if (selection->getOrientation()==OrientRightOfCenter)
2146 num=QString ("%1").arg(num.toUInt()-1);
2148 num=QString ("%1").arg(num.toUInt()+1);
2153 // pad to oldDepth, select the last branch for each depth
2154 for (i=d;i<oldDepth;i++)
2158 if ( ((BranchObj*)selection)->countBranches()>0)
2159 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
2166 // try to select the freshly built string
2174 void MapEditor::selectUpperBranch()
2176 // Finish open lineEdits
2177 if (lineedit) finishedLineEditNoSave();
2181 if (typeid(*selection) == typeid(BranchObj))
2183 if (selection->getOrientation()==OrientRightOfCenter)
2186 if (selection->getDepth()==1)
2194 void MapEditor::selectLowerBranch()
2196 // Finish open lineEdits
2197 if (lineedit) finishedLineEditNoSave();
2201 if (typeid(*selection) == typeid(BranchObj))
2203 if (selection->getOrientation()==OrientRightOfCenter)
2206 if (selection->getDepth()==1)
2215 void MapEditor::selectLeftBranch()
2217 // Finish open lineEdits
2218 if (lineedit) finishedLineEditNoSave();
2224 if (typeid(*selection) == typeid(MapCenterObj))
2226 par= (BranchObj*) selection;
2227 bo=par->getLastSelectedBranch();
2230 // Workaround for reselecting on left and right side
2231 if (bo->getOrientation()==OrientRightOfCenter)
2233 bo=par->getLastBranch();
2239 selection->select();
2241 ensureSelectionVisible();
2246 par=(BranchObj*)(selection->getParObj());
2247 if (selection->getOrientation()==OrientRightOfCenter)
2249 if (typeid(*selection) == typeid(BranchObj) ||
2250 typeid(*selection) == typeid(FloatImageObj))
2252 selection->unselect();
2254 selection->select();
2256 ensureSelectionVisible();
2260 if (typeid(*selection) == typeid(BranchObj) )
2262 bo=((BranchObj*)selection)->getLastSelectedBranch();
2265 selection->unselect();
2267 selection->select();
2269 ensureSelectionVisible();
2277 void MapEditor::selectRightBranch()
2279 // Finish open lineEdits
2280 if (lineedit) finishedLineEditNoSave();
2287 if (typeid(*selection) == typeid(MapCenterObj))
2289 par= (BranchObj*) selection;
2290 bo=par->getLastSelectedBranch();
2293 // Workaround for relecting on left and right side
2294 if (bo->getOrientation()==OrientLeftOfCenter)
2295 bo=par->getFirstBranch();
2300 selection->select();
2301 ensureSelectionVisible();
2306 par=(BranchObj*)(selection->getParObj());
2307 if (selection->getOrientation()==OrientLeftOfCenter)
2309 if (typeid(*selection) == typeid(BranchObj) ||
2310 typeid(*selection) == typeid(FloatImageObj))
2312 selection->unselect();
2314 selection->select();
2316 ensureSelectionVisible();
2320 if (typeid(*selection) == typeid(BranchObj) )
2322 bo=((BranchObj*)selection)->getLastSelectedBranch();
2325 selection->unselect();
2327 selection->select();
2329 ensureSelectionVisible();
2337 void MapEditor::selectFirstBranch()
2339 // Finish open lineEdits
2340 if (lineedit) finishedLineEditNoSave();
2346 if (typeid(*selection) == typeid(BranchObj))
2348 bo1= (BranchObj*) selection;
2349 par=(BranchObj*)(bo1->getParObj());
2350 bo2=par->getFirstBranch();
2354 selection->select();
2355 ensureSelectionVisible();
2362 void MapEditor::selectLastBranch()
2364 // Finish open lineEdits
2365 if (lineedit) finishedLineEditNoSave();
2371 if (typeid(*selection) == typeid(BranchObj))
2373 bo1= (BranchObj*) selection;
2374 par=(BranchObj*)(bo1->getParObj());
2375 bo2=par->getLastBranch();
2379 selection->select();
2380 ensureSelectionVisible();
2387 void MapEditor::setColor(QColor c)
2392 void MapEditor::selectBackgroundColor()
2394 // Finish open lineEdits
2395 if (lineedit) finishedLineEditNoSave();
2397 QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
2398 if ( !col.isValid() ) return;
2399 setBackgroundColor( col );
2403 void MapEditor::setBackgroundColor(QColor c)
2405 mapCanvas->setBackgroundColor (c);
2408 QColor MapEditor::pickColor()
2412 if (typeid(*selection) == typeid(BranchObj) ||
2413 typeid(*selection) == typeid(MapCenterObj))
2415 BranchObj *bo=(BranchObj*)selection;
2416 actColor=bo->getColor();
2422 void MapEditor::colorItem()
2426 if (typeid(*selection) == typeid(BranchObj) ||
2427 typeid(*selection) == typeid(MapCenterObj))
2429 saveState(selection); //TODO undoCommand
2430 BranchObj *bo=(BranchObj*)selection;
2431 bo->setColor(actColor, false); // color links, color childs
2436 void MapEditor::colorBranch()
2440 if (typeid(*selection) == typeid(BranchObj) ||
2441 typeid(*selection) == typeid(MapCenterObj))
2443 saveState(selection);
2444 BranchObj *bo=(BranchObj*)selection;
2445 bo->setColor(actColor, true); // color links, color childs
2451 void MapEditor::toggleStandardFlag(QString f)
2455 saveState(selection);// TODO undoCommand
2456 ((BranchObj*)selection)->toggleStandardFlag (f,actionSettingsUseFlagGroups);
2460 void MapEditor::setViewCenter()
2462 // transform to CanvasView Coord:
2463 QPoint p=worldMatrix().map(movingCenter);
2464 center ( p.x(), p.y());
2468 BranchObj* MapEditor::findText (QString s, bool cs)
2471 { // Nothing found or new find process
2473 // nothing found, start again
2475 itFind=mapCenter->first();
2477 bool searching=true;
2478 bool foundNote=false;
2479 while (searching && !EOFind)
2483 // Searching in Note
2484 if (itFind->getNote().contains(s,cs))
2486 if (selection!=itFind)
2488 if (selection) ((BranchObj*)selection)->unselect();
2490 selection->select();
2492 ensureSelectionVisible();
2494 if (textEditor->findText(s,cs))
2500 // Searching in Heading
2501 if (searching && itFind->getHeading().contains (s,cs) )
2503 if (selection) ((BranchObj*)selection)->unselect();
2505 selection->select();
2507 ensureSelectionVisible();
2513 itFind=itFind->next();
2514 if (!itFind) EOFind=true;
2520 return (BranchObj*)selection;
2525 void MapEditor::findReset()
2526 { // Necessary if text to find changes during a find process
2531 void MapEditor::openURL()
2535 if (typeid(*selection) == typeid(BranchObj) ||
2536 typeid(*selection) == typeid(MapCenterObj))
2538 QString url=((BranchObj*)selection)->getURL();
2540 QProcess *proc = new QProcess( this );
2542 proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL" ));
2543 proc->addArgument( url);
2545 if ( !proc->start() )
2547 if (mainWindow->settingsURL() )
2553 void MapEditor::editURL()
2555 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2556 typeid(*selection) == typeid(MapCenterObj)) )
2559 BranchObj *bo=(BranchObj*)selection;
2560 QString text = QInputDialog::getText(
2561 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2562 bo->getURL(), &ok, this );
2565 // user entered something and pressed OK
2566 saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+text+"\")");
2573 void MapEditor::editHeading2URL()
2575 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2576 typeid(*selection) == typeid(MapCenterObj)) )
2578 BranchObj *bo=(BranchObj*)selection;
2579 saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+bo->getHeading()+"\")");
2580 bo->setURL (bo->getHeading());
2585 void MapEditor::editBugzilla2URL()
2587 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2588 typeid(*selection) == typeid(MapCenterObj)) )
2590 BranchObj *bo=(BranchObj*)selection;
2591 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2592 saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+url+"\")");
2598 void MapEditor::editVymLink()
2600 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2601 typeid(*selection) == typeid(MapCenterObj)) )
2603 BranchObj *bo=(BranchObj*)selection;
2604 QFileDialog *fd=new QFileDialog( this,tr("VYM - Link to another map"));
2605 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
2606 fd->setCaption(tr("VYM - Link to another map"));
2607 if (! bo->getVymLink().isEmpty() )
2608 fd->setSelection( bo->getVymLink() );
2612 if ( fd->exec() == QDialog::Accepted )
2614 saveState("setVymLink (\""+bo->getVymLink()+"\")","setVymLink (\""+fd->selectedFile()+"\")");
2615 bo->setVymLink (fd->selectedFile() );
2617 mapCenter->reposition();
2624 void MapEditor::deleteVymLink()
2626 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2627 typeid(*selection) == typeid(MapCenterObj)) )
2629 BranchObj *bo=(BranchObj*)selection;
2630 saveState("setVymLink (\""+bo->getVymLink()+"\")","setVymLink (\"\")");
2631 bo->setVymLink ("" );
2633 mapCenter->reposition();
2639 QString MapEditor::getVymLink()
2641 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2642 typeid(*selection) == typeid(MapCenterObj)) )
2644 return ((BranchObj*)selection)->getVymLink();
2650 void MapEditor::removeBranchHere()
2652 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2654 BranchObj* bo=(BranchObj*)selection;
2655 BranchObj* par=(BranchObj*)(bo->getParObj());
2656 if (bo->getDepth()==1)
2659 saveState(selection->getParObj()); // TODO undoCommand
2660 QString sel=selection->getSelectString();
2662 par->removeBranchHere(bo);
2663 mapCenter->reposition();
2668 void MapEditor::removeChilds()
2670 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2672 saveState(selection->getParObj());
2673 ((BranchObj*)selection)->removeChilds();
2674 mapCenter->reposition();
2678 void MapEditor::editMapInfo()
2680 ExtraInfoDialog dia;
2681 dia.setMapName (getFileName() );
2682 dia.setAuthor (mapCenter->getAuthor() );
2683 dia.setComment(mapCenter->getComment() );
2688 QCanvasItemList l=canvas()->allItems();
2689 for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
2691 stats+=QString ("%1 items on canvas\n").arg (i,6);
2698 bo=mapCenter->first();
2701 if (!bo->getNote().isEmpty() ) n++;
2702 f+= bo->countFloatImages();
2704 xl+=bo->countXLinks();
2707 stats+=QString ("%1 branches\n").arg (b-1,6);
2708 stats+=QString ("%1 xLinks \n").arg (xl,6);
2709 stats+=QString ("%1 notes\n").arg (n,6);
2710 stats+=QString ("%1 images\n").arg (f,6);
2711 dia.setStats (stats);
2713 // Finally show dialog
2714 if (dia.exec() == QDialog::Accepted)
2716 saveState(); //TODO undoCommand
2717 mapCenter->setAuthor (dia.getAuthor() );
2718 mapCenter->setComment (dia.getComment() );
2722 void MapEditor::updateActions()
2725 if (getLinkColorHint()==HeadingColor)
2726 actionFormatLinkColorHint->setOn(true);
2728 actionFormatLinkColorHint->setOn(false);
2733 actionFormatLinkStyleLine->setOn(true);
2736 actionFormatLinkStyleParabel->setOn(true);
2739 actionFormatLinkStylePolyLine->setOn(true);
2741 case StylePolyParabel:
2742 actionFormatLinkStylePolyParabel->setOn(true);
2748 QPixmap pix( 16, 16 );
2749 pix.fill( mapCanvas->backgroundColor() );
2750 actionFormatBackColor->setIconSet( pix );
2751 pix.fill( defLinkColor );
2752 actionFormatLinkColor->setIconSet( pix );
2754 actionEditUndo->setEnabled( mapChanged );
2755 actionFileSave->setEnabled( mapUnsaved );
2759 if ( (typeid(*selection) == typeid(BranchObj)) ||
2760 (typeid(*selection) == typeid(MapCenterObj)) )
2762 BranchObj *bo=(BranchObj*)selection;
2763 // Take care of links
2764 if (bo->countXLinks()==0)
2766 branchLinksContextMenu->clear();
2767 branchLinksContextMenu->insertItem ("No xLink available");
2768 branchLinksContextMenuDup->clear();
2769 branchLinksContextMenuDup->insertItem ("No xLink available");
2775 branchLinksContextMenu->clear();
2776 branchLinksContextMenuDup->clear();
2777 for (int i=0; i<=bo->countXLinks();i++)
2779 bot=bo->XLinkTargetAt(i);
2782 s=bot->getHeading();
2785 branchLinksContextMenu->insertItem (s);
2786 branchLinksContextMenuDup->insertItem (s);
2791 standardFlagsDefault->setEnabled (true);
2793 if ( bo->getURL().isEmpty() )
2794 actionEditOpenURL->setEnabled (false);
2796 actionEditOpenURL->setEnabled (true);
2798 if ( bo->getVymLink().isEmpty() )
2800 actionEditOpenVymLink->setEnabled (false);
2801 actionEditDeleteVymLink->setEnabled (false);
2804 actionEditOpenVymLink->setEnabled (true);
2805 actionEditDeleteVymLink->setEnabled (true);
2808 actionEditCopy->setEnabled (true);
2809 actionEditCut->setEnabled (true);
2810 if (clipboardME->getMapCenter()->countBranches()>0 || clipboardME->getMapCenter()->countFloatImages()>0)
2811 actionEditPaste->setEnabled (true);
2813 actionEditPaste->setEnabled (false);
2814 for (a=actionListBranches.first();a;a=actionListBranches.next())
2815 a->setEnabled(true);
2816 actionEditDelete->setEnabled (true);
2817 actionEditToggleFloatExport->setEnabled (false);
2818 switch (selection->getFrameType())
2821 actionFormatFrameNone->setOn(true);
2824 actionFormatFrameRectangle->setOn(true);
2829 actionFormatHideLinkUnselected->setOn
2830 ( selection->getHideLinkUnselected());
2832 if ( (typeid(*selection) == typeid(FloatImageObj)) )
2834 standardFlagsDefault->setEnabled (false);
2836 actionEditOpenURL->setEnabled (false);
2837 actionEditOpenVymLink->setEnabled (false);
2838 actionEditDeleteVymLink->setEnabled (false);
2840 actionEditCopy->setEnabled (true);
2841 actionEditCut->setEnabled (true);
2842 actionEditPaste->setEnabled (false); //FIXME
2843 for (a=actionListBranches.first();a;a=actionListBranches.next())
2844 a->setEnabled(false);
2845 actionEditDelete->setEnabled (true);
2846 actionEditToggleFloatExport->setOn
2847 ( ((FloatImageObj*)selection)->getFloatExport() );
2848 actionFormatHideLinkUnselected->setOn
2849 ( selection->getHideLinkUnselected());
2854 standardFlagsDefault->setEnabled (false);
2856 actionEditCopy->setEnabled (false);
2857 actionEditCut->setEnabled (false);
2858 actionEditPaste->setEnabled (false);
2859 for (a=actionListBranches.first();a;a=actionListBranches.next())
2860 a->setEnabled(false);
2862 actionEditOpenURL->setEnabled (false);
2863 actionEditOpenVymLink->setEnabled (false);
2864 actionEditDeleteVymLink->setEnabled (false);
2865 actionEditHeading2URL->setEnabled (false);
2866 actionEditDelete->setEnabled (false);
2867 actionEditToggleFloatExport->setEnabled (false);
2871 void MapEditor::updateNoteFlag()
2874 if ( (typeid(*selection) == typeid(BranchObj)) ||
2875 (typeid(*selection) == typeid(MapCenterObj)) )
2876 ((BranchObj*)selection)->updateNoteFlag();
2879 void MapEditor::setLinkStyle (LinkStyle ls)
2883 saveState(); // TODO undoCommand
2885 bo=mapCenter->first();
2889 bo->setLinkStyle(bo->getDefLinkStyle());
2892 mapCenter->reposition();
2895 LinkStyle MapEditor::getLinkStyle ()
2900 void MapEditor::setLinkColor(QColor c)
2906 void MapEditor::setLinkColorHint()
2908 // called from setLinkColorHint(lch) or at end of parse
2910 bo=mapCenter->first();
2918 void MapEditor::setLinkColorHint(LinkColorHint lch)
2924 void MapEditor::toggleLinkColorHint()
2926 if (linkcolorhint==HeadingColor)
2927 linkcolorhint=DefaultColor;
2929 linkcolorhint=HeadingColor;
2931 bo=mapCenter->first();
2939 LinkColorHint MapEditor::getLinkColorHint()
2941 return linkcolorhint;
2944 QColor MapEditor::getDefLinkColor()
2946 return defLinkColor;
2949 void MapEditor::setDefXLinkColor(QColor col)
2954 QColor MapEditor::getDefXLinkColor()
2956 return defXLinkColor;
2959 void MapEditor::setDefXLinkWidth (int w)
2964 int MapEditor::getDefXLinkWidth()
2966 return defXLinkWidth;
2969 void MapEditor::selectLinkColor()
2971 // Finish open lineEdits
2972 if (lineedit) finishedLineEditNoSave();
2974 QColor col = QColorDialog::getColor( defLinkColor, this );
2975 if ( !col.isValid() ) return;
2976 setLinkColor( col );
2977 saveState(); //TODO undoCommand
2981 void MapEditor::toggleScroll()
2983 if (selection && (typeid(*selection) == typeid(BranchObj)) )
2985 BranchObj *bo=((BranchObj*)selection);
2986 if (bo->countBranches()==0) return;
2987 if (bo->getDepth()==0) return;
2988 saveState(selection);
2995 void MapEditor::unScrollAll()
2998 bo=mapCenter->first();
3001 if (bo->isScrolled()) bo->toggleScroll();
3006 void MapEditor::loadFloatImage ()
3009 (typeid(*selection) == typeid(BranchObj)) ||
3010 (typeid(*selection) == typeid(MapCenterObj)) )
3012 BranchObj *bo=((BranchObj*)selection);
3014 QFileDialog *fd=new QFileDialog( this,tr("vym - load image"));
3015 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3016 ImagePreview *p =new ImagePreview (fd);
3017 fd->setContentsPreviewEnabled( TRUE );
3018 fd->setContentsPreview( p, p );
3019 fd->setPreviewMode( QFileDialog::Contents );
3020 fd->setCaption(tr("vym - Load image"));
3021 fd->setDir (lastImageDir);
3025 if ( fd->exec() == QDialog::Accepted )
3027 saveState(selection);
3028 QString fn=fd->selectedFile();
3029 lastImageDir=fn.left(fn.findRev ("/"));
3030 bo->addFloatImage();
3031 // TODO check if load was successful
3032 bo->getLastFloatImage()->load(fn);
3033 bo->getLastFloatImage()->setOriginalFilename(fn);
3034 mapCenter->reposition();
3041 void MapEditor::saveFloatImage (int item)
3044 (typeid(*selection) == typeid(FloatImageObj)) )
3046 FloatImageObj *fio=((FloatImageObj*)selection);
3047 const char* fmt = saveImageFormatMenu->text(item);
3049 QFileDialog *fd=new QFileDialog( this, tr("vym - save image as") + fmt);
3050 fd->addFilter ("PNG (*.png)");
3051 fd->addFilter ("BMP (*.bmp)");
3052 fd->addFilter ("XBM (*.xbm)");
3053 fd->addFilter ("JPG (*.jpg)");
3054 fd->addFilter ("XPM (*.xpm)");
3055 fd->addFilter ("GIF (*.gif)");
3056 fd->addFilter ("PNM (*.pnm)");
3057 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3058 fd->setCaption(tr("vym - Save image as %1").arg(fmt));
3059 fd->setMode( QFileDialog::AnyFile );
3060 fd->setSelection (fio->getOriginalFilename());
3064 if ( fd->exec() == QDialog::Accepted )
3066 if (QFile (fd->selectedFile()).exists() )
3068 QMessageBox mb( "VYM",
3069 tr("The file %1 exists already.\n"
3070 "Do you want to overwrite it?").arg(fd->selectedFile()),
3071 QMessageBox::Warning,
3072 QMessageBox::Yes | QMessageBox::Default,
3073 QMessageBox::Cancel | QMessageBox::Escape,
3074 QMessageBox::QMessageBox::NoButton );
3076 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3077 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3080 case QMessageBox::Yes:
3083 case QMessageBox::Cancel:
3089 fio->save (fd->selectedFile(),fmt);
3094 void MapEditor::toggleFloatExport()
3097 (typeid(*selection) == typeid(FloatImageObj))||
3098 (typeid(*selection) == typeid(FloatObj)) )
3100 FloatImageObj *fio=((FloatImageObj*)selection);
3101 fio->setFloatExport (actionEditToggleFloatExport->isOn() );
3105 void MapEditor::setFrame(const FrameType &t)
3108 (typeid(*selection) == typeid(BranchObj)) ||
3109 (typeid(*selection) == typeid(MapCenterObj)) )
3111 selection->setFrameType (t);
3112 mapCenter->reposition();
3113 selection->updateLink();
3117 void MapEditor::setHideLinkUnselected (bool b)
3120 (typeid(*selection) == typeid(BranchObj)) ||
3121 (typeid(*selection) == typeid(MapCenterObj)) ||
3122 (typeid(*selection) == typeid(FloatImageObj)) )
3123 selection->setHideLinkUnselected(b);
3126 void MapEditor::importDir(BranchObj *dst, QDir d)
3129 (typeid(*selection) == typeid(BranchObj)) ||
3130 (typeid(*selection) == typeid(MapCenterObj)) )
3134 // Traverse directories
3135 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3136 const QFileInfoList *dirlist = d.entryInfoList();
3137 QFileInfoListIterator itdir( *dirlist );
3140 while ( (fi = itdir.current()) != 0 )
3142 if (fi->fileName() != "." && fi->fileName() != ".." )
3145 bo=dst->getLastBranch();
3146 bo->setHeading (fi->fileName() );
3147 bo->setColor (QColor("blue"),false);
3149 if ( !d.cd(fi->fileName()) )
3150 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi->fileName()));
3153 // Recursively add subdirs
3161 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3162 const QFileInfoList *filelist = d.entryInfoList();
3163 QFileInfoListIterator itfile( *filelist );
3165 while ( (fi = itfile.current()) != 0 )
3168 bo=dst->getLastBranch();
3169 bo->setHeading (fi->fileName() );
3170 bo->setColor (QColor("black"),false);
3171 if (fi->fileName().right(4) == ".vym" )
3172 bo->setVymLink (fi->filePath());
3179 void MapEditor::importDir()
3182 (typeid(*selection) == typeid(BranchObj)) ||
3183 (typeid(*selection) == typeid(MapCenterObj)) )
3185 QFileDialog *fd=new QFileDialog( this,tr("VYM - Choose directory structur to import"));
3186 fd->setMode (QFileDialog::DirectoryOnly);
3187 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
3188 fd->setCaption(tr("VYM - Choose directory structur to import"));
3192 if ( fd->exec() == QDialog::Accepted )
3194 BranchObj *bo=((BranchObj*)selection);
3195 importDir (bo,QDir(fd->selectedFile()) );
3196 mapCenter->reposition();
3203 void MapEditor::followXLink(int i)
3206 (typeid(*selection) == typeid(BranchObj)) ||
3207 (typeid(*selection) == typeid(MapCenterObj)) )
3209 BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
3212 selection->unselect();
3214 selection->select();
3215 ensureSelectionVisible();
3220 void MapEditor::editXLink(int i)
3223 (typeid(*selection) == typeid(BranchObj)) ||
3224 (typeid(*selection) == typeid(MapCenterObj)) )
3226 XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
3229 EditXLinkDialog dia;
3231 dia.setSelection(selection);
3232 if (dia.exec() == QDialog::Accepted)
3234 if (dia.useSettingsGlobal() )
3236 setDefXLinkColor (xlo->getColor() );
3237 setDefXLinkWidth (xlo->getWidth() );
3239 if (dia.deleteXLink())
3240 ((BranchObj*)selection)->deleteXLinkAt(i);
3241 saveState(); //TODO undoCommand
3247 void MapEditor::testFunction()
3249 cout << "MapEditor::testFunction() called\n";
3254 void MapEditor::ensureSelectionVisible()
3258 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
3260 if (selection->getOrientation() == OrientLeftOfCenter)
3261 p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
3263 p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
3264 ensureVisible (p.x(), p.y() );
3269 void MapEditor::updateViewCenter()
3271 // Update movingCenter, so that we can zoom comfortably later
3272 QRect rc = QRect( contentsX(), contentsY(),
3273 visibleWidth(), visibleHeight() );
3274 QRect canvasRect = inverseWorldMatrix().mapRect(rc);
3275 movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
3276 movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
3279 void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e )
3281 // Lineedits are already closed by preceding
3282 // mouseEvent, we don't need to close here.
3284 QPoint p = inverseWorldMatrix().map(e->pos());
3285 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3288 { // MapObj was found
3289 if (selection != lmo)
3291 // select the MapObj
3292 if (selection) selection->unselect();
3294 selection->select();
3300 if (typeid(*selection)==typeid(BranchObj) ||
3301 typeid(*selection)==typeid(MapCenterObj) )
3303 // Context Menu on branch or mapcenter
3305 branchContextMenu->popup(e->globalPos() );
3307 if (typeid(*selection)==typeid(FloatImageObj))
3309 // Context Menu on floatimage
3311 floatimageContextMenu->popup(e->globalPos() );
3315 { // No MapObj found, we are on the Canvas itself
3316 // Context Menu on Canvas
3318 canvasContextMenu->popup(e->globalPos() );
3322 void MapEditor::contentsMousePressEvent(QMouseEvent* e)
3324 // Finish open lineEdits
3325 if (lineedit) finishedLineEditNoSave();
3327 QPoint p = inverseWorldMatrix().map(e->pos());
3328 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3330 // Special case: CTRL is pressed
3331 if (e->state() & QMouseEvent::ControlButton)
3333 if (actionModModeColor->isOn())
3335 if (e->state() & QMouseEvent::ControlButton)
3338 setCursor (pickColorCursor);
3342 if (actionModModeLink->isOn())
3344 BranchObj *bo_begin=NULL;
3346 bo_begin=(BranchObj*)(lmo);
3349 ((typeid(*selection) == typeid(BranchObj)) ||
3350 (typeid(*selection) == typeid(MapCenterObj))) )
3351 bo_begin=(BranchObj*)selection;
3355 linkingObj_src=bo_begin;
3356 tmpXLink=new XLinkObj (mapCanvas);
3357 tmpXLink->setBegin (bo_begin);
3358 tmpXLink->setEnd (p);
3359 tmpXLink->setColor(defXLinkColor);
3360 tmpXLink->setWidth(defXLinkWidth);
3361 tmpXLink->updateXLink();
3362 tmpXLink->setVisibility (true);
3369 { // MapObj was found
3370 if (selection != lmo)
3372 // select the MapObj
3373 if (selection) selection->unselect();
3375 selection->select();
3380 // Check, if systemFlag clicked
3381 if (typeid(*selection)==typeid(BranchObj) ||
3382 typeid(*selection)==typeid(MapCenterObj) )
3384 QString foname=((BranchObj*)selection)->getSystemFlagName(p);
3385 if (!foname.isEmpty())
3387 // Do not move, if systemFlag clicked
3391 if (foname=="vymLink")
3393 mainWindow->editOpenVymLink();
3394 // tabWidget may change, better return now
3395 // before segfaulting...
3399 mainWindow->windowToggleNoteEditor();
3403 // Left Button Move Branches
3404 if (e->button() == QMouseEvent::LeftButton )
3406 movingObj_start.setX( p.x() - selection->x() );
3407 movingObj_start.setY( p.y() - selection->y() );
3408 movingObj_orgPos.setX (lmo->x() );
3409 movingObj_orgPos.setY (lmo->y() );
3411 // If modMode==copy, then we want to "move" the _new_ object around
3412 // then we need the offset from p to the _old_ selection, because of tmp
3413 if (actionModModeCopy->isOn() &&
3414 e->state() & QMouseEvent::ControlButton)
3416 if (typeid(*selection)==typeid(BranchObj) )
3419 mapCenter->addBranch ((BranchObj*)selection);
3421 selection=mapCenter->getLastBranch();
3422 selection->select();
3423 mapCenter->reposition();
3426 movingObj=selection;
3428 // Middle Button Toggle Scroll
3429 // (On Mac OS X this won't work, but we still have
3430 // a button in the toolbar)
3431 if (e->button() == QMouseEvent::MidButton )
3435 { // No MapObj found, we are on the Canvas itself
3436 // Left Button move Pos of CanvasView
3437 if (e->button() == QMouseEvent::LeftButton )
3439 movingObj=NULL; // move Content not Obj
3440 movingObj_start=e->globalPos();
3441 movingCont_start=QPoint (contentsX(), contentsY() );
3442 movingVec=QPoint(0,0);
3443 setCursor(handOpenCursor);
3448 void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
3450 QPoint p = inverseWorldMatrix().map(e->pos());
3452 // Move the selected MapObj
3453 if ( selection && movingObj)
3455 // To avoid jumping of the CanvasView, only
3456 // ensureSelectionVisible, if not tmp linked
3457 if (!selection->hasParObjTmp())
3458 ensureSelectionVisible ();
3460 // Now move the selection, but add relative position
3461 // (movingObj_start) where selection was chosen with
3462 // mousepointer. (This avoids flickering resp. jumping
3463 // of selection back to absPos)
3465 LinkableMapObj *lmosel;
3466 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3468 // Check if we could link
3469 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3472 if (typeid(*selection) == typeid(FloatImageObj))
3474 FloatObj *fo=(FloatObj*)selection;
3475 saveState("move "+qpointToString(movingObj_orgPos),fo->getSelectString() );
3476 if (fo->getLinkStyle()==StyleUndef)
3478 fo->setLinkStyle(fo->getDefLinkStyle());
3479 fo->setLinkColor(fo->getParObj()->getLinkColor());
3481 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3485 // Relink float to new mapcenter or branch, if shift is pressed
3486 // Only relink, if selection really has a new parent
3487 if ( (e->state() & QMouseEvent::ShiftButton) && lmo &&
3488 ( (typeid(*lmo)==typeid(BranchObj)) ||
3489 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3490 ( lmo != fo->getParObj())
3493 if (typeid(*fo) == typeid(FloatImageObj))
3496 FloatImageObj *fio=(FloatImageObj*)(fo);
3497 ((BranchObj*)(lmo))->addFloatImage (fio);
3499 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
3500 fio=((BranchObj*)(lmo))->getLastFloatImage();
3503 selection=(LinkableMapObj*)(fio);
3504 selection->select();
3505 movingObj=(MapObj*)(fio);
3506 // setLinkStyle calls updateLink, only set it once
3507 if (fio->getLinkStyle()!=fio->getDefLinkStyle() )
3508 fio->setLinkStyle (fio->getDefLinkStyle());
3510 // TODO if (typeid(*selection) == typeid(FloatTextObj))
3512 } else // selection != a FloatObj
3514 if (lmosel->getDepth()==0)
3516 if (e->state() == (LeftButton | !ShiftButton))
3517 // If mapCenter is moved, move all the rest by default, too.
3518 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3520 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3523 if (lmosel->getDepth()==1)
3525 // depth==1, mainbranch
3526 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3530 if (lmosel->getOrientation() == OrientLeftOfCenter)
3531 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3532 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3533 p.y()-movingObj_start.y() );
3535 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3537 // reposition subbranch
3538 lmosel->reposition();
3539 //ensureSelectionVisible();
3541 if (lmo && (lmo!=selection) &&
3542 (typeid(*lmo) == typeid(BranchObj) ||
3543 (typeid(*lmo) == typeid(MapCenterObj) )
3546 if (e->state() & QMouseEvent::ControlButton)
3548 // Special case: CTRL to link below lmo
3549 lmosel->setParObjTmp (lmo,p,+1);
3551 else if (e->state() & QMouseEvent::ShiftButton)
3552 lmosel->setParObjTmp (lmo,p,-1);
3554 lmosel->setParObjTmp (lmo,p,0);
3557 lmosel->unsetParObjTmp();
3559 if (lmo &&(lmo==selection))
3560 // Could link to myself (happens sometimes...)
3561 lmosel->unsetParObjTmp();
3563 // no Obj under selection, go back to original Parent
3564 lmosel->unsetParObjTmp();
3569 } // no FloatImageObj
3573 } // selection && moving_obj
3575 // Draw a link from one branch to another
3578 tmpXLink->setEnd (p);
3579 tmpXLink->updateXLink();
3583 if (!movingObj && !pickingColor &&!drawingLink)
3585 QPoint p=e->globalPos();
3586 movingVec.setX(-p.x() + movingObj_start.x() );
3587 movingVec.setY(-p.y() + movingObj_start.y() );
3588 setContentsPos( movingCont_start.x() + movingVec.x(),
3589 movingCont_start.y() + movingVec.y());
3596 void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e)
3598 LinkableMapObj *dst;
3599 // Have we been picking color?
3603 setCursor (ArrowCursor);
3604 // Check if we are over another branch
3605 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3606 if (dst && selection)
3608 if (e->state() & QMouseEvent::ShiftButton)
3610 ((BranchObj*)selection)->setColor (((BranchObj*)(dst))->getColor(),false);
3611 ((BranchObj*)selection)->setLinkColor ();
3615 ((BranchObj*)selection)->setColor (((BranchObj*)(dst))->getColor(),true);
3616 ((BranchObj*)selection)->setLinkColor ();
3622 // Have we been drawing a link?
3626 // Check if we are over another branch
3627 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3628 if (dst && selection)
3630 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3631 tmpXLink->updateXLink();
3632 tmpXLink->activate();
3633 saveState(); //TODO undoCommand
3642 // Have we been moving something?
3643 if ( selection && movingObj )
3645 // Check if we are over another branch, but ignore
3646 // any found LMOs, which are FloatObjs
3647 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ),
3648 ((LinkableMapObj*)selection) );
3651 (typeid(*dst)!=typeid(BranchObj)&&typeid(*dst)!=typeid(MapCenterObj)))
3654 // Now check, if we have been moving a branch
3655 if (typeid(*selection) == typeid(BranchObj) )
3657 // save the position in case we link to mapcenter
3658 QPoint savePos=QPoint (selection->x(),selection->y() );
3660 // Reset the temporary drawn link to the original one
3661 ((LinkableMapObj*)selection)->unsetParObjTmp();
3667 BranchObj* bs=((BranchObj*)selection);
3668 QString undoCom="linkBranchToPos (\""+
3669 (bs->getParObj())->getSelectString()+
3671 QString("%1").arg(bs->getNum())+
3673 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+
3675 // TODO we also could check, if dest and src are on same branch,
3676 // then it would be sufficient to saveState of this branch
3678 // Modifiers allow to insert above/below dst
3679 if (e->state() & QMouseEvent::ShiftButton)
3681 bs->moveBranchTo ( (BranchObj*)(dst->getParObj()), ((BranchObj*)(dst))->getNum());
3683 if (e->state() & QMouseEvent::ControlButton)
3685 bs->moveBranchTo ( (BranchObj*)(dst->getParObj()), ((BranchObj*)(dst))->getNum()+1);
3688 bs->moveBranchTo ((BranchObj*)(dst),-1);
3689 if (dst->getDepth()==0)
3692 saveState (undoCom,bs->getSelectString() );
3694 if (selection->getDepth()==1)
3695 // If we have moved mainbranch only save endposition
3696 saveState("move "+qpointToString(movingObj_orgPos), selection->getSelectString() );
3698 // Draw the original link, before selection was moved around
3699 mapCenter->reposition();
3701 // Finally resize canvas, if needed
3706 // maybe we moved View: set old cursor
3707 setCursor (ArrowCursor);
3711 void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
3713 // Finish open lineEdits
3714 if (lineedit) finishedLineEditNoSave();
3716 if (e->button() == QMouseEvent::LeftButton )
3718 QPoint p = inverseWorldMatrix().map(e->pos());
3719 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3720 if (lmo) { // MapObj was found
3721 // First select the MapObj than edit heading
3722 if (selection) selection->unselect();
3724 selection->select();
3725 saveState(selection);
3731 void MapEditor::resizeEvent (QResizeEvent* e)
3733 QCanvasView::resizeEvent( e );
3736 if (!fileName.isEmpty()) s=fileName;
3740 void MapEditor::contentsDragEnterEvent(QDragEnterEvent *event)
3743 // for (unsigned int i=0;event->format(i);i++) // Debug mime type
3744 // cerr << event->format(i) << endl;
3747 (typeid(*selection) == typeid(BranchObj)) ||
3748 (typeid(*selection) == typeid(MapCenterObj))) {
3750 // If QImageDrag can decode mime type
3751 if (QImageDrag::canDecode(event)) {
3756 // If image are dragged from firefox
3757 if (event->provides("application/x-moz-file-promise-url") &&
3758 event->provides("application/x-moz-nativeimage")) {
3759 event->accept(true);
3763 // If QUriDrag can decode mime type
3764 if (QUriDrag::canDecode(event)) {
3769 // If Uri are dragged from firefox
3770 if (event->provides("_NETSCAPE_URL")){
3775 // If QTextDrag can decode mime type
3776 if (QTextDrag::canDecode(event)) {
3785 bool isUnicode16(const QByteArray &d)
3787 // TODO: make more precise check for unicode 16.
3788 // Guess unicode16 if any of second bytes are zero
3789 unsigned int length = max(0,d.size()-2)/2;
3790 for (unsigned int i = 0; i<length ; i++)
3791 if (d.at(i*2+1)==0) return true;
3795 void MapEditor::contentsDropEvent(QDropEvent *event)
3798 (typeid(*selection) == typeid(BranchObj)) ||
3799 (typeid(*selection) == typeid(MapCenterObj)))
3804 if (event->provides("image/png"))
3807 if (QImageDrag::decode(event, pix))
3815 } else if (event->provides("application/x-moz-file-promise-url") &&
3816 event->provides("application/x-moz-nativeimage"))
3818 // Contains url to the img src in unicode16
3819 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
3820 QString url = QString((const QChar*)d.data(),d.size()/2);
3824 } else if (event->provides ("text/uri-list"))
3825 { // Uris provided e.g. by konqueror
3826 QUriDrag::decode (event,uris);
3827 } else if (event->provides ("_NETSCAPE_URL"))
3828 { // Uris provided by Mozilla
3829 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
3832 } else if (event->provides("text/html")) {
3834 // Handels text mime types
3835 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
3836 QByteArray d = event->encodedData("text/html");
3839 text = QString((const QChar*)d.data(),d.size()/2);
3843 textEditor->setText(text);
3847 } else if (event->provides("text/plain")) {
3848 QByteArray d = event->encodedData("text/plain");
3851 text = QString((const QChar*)d.data(),d.size()/2);
3855 textEditor->setText(text);
3867 for (const char* u=uris.first(); u; u=uris.next())
3869 bo=((BranchObj*)selection)->addBranch();
3872 s=QUriDrag::uriToLocalFile(u);
3874 QString file = QDir::convertSeparators(s);
3875 heading = QFileInfo(file).baseName();
3877 if (file.endsWith(".vym", false))
3878 bo->setVymLink(file);
3887 bo->setHeading(heading);
3897 saveState(); //TODO undo Command
3898 mapCenter->reposition();
3905 void MapEditor::addFloatImage(const QPixmap &img)
3908 (typeid(*selection) == typeid(BranchObj)) ||
3909 (typeid(*selection) == typeid(MapCenterObj)) )
3911 BranchObj *bo=((BranchObj*)selection);
3912 saveState(selection);
3913 //QString fn=fd->selectedFile();
3914 //lastImageDir=fn.left(fn.findRev ("/"));
3915 bo->addFloatImage();
3916 // FIXME check if load was successful
3917 bo->getLastFloatImage()->load(img);
3918 //bo->getLastFloatImage()->setOriginalFilename(fn);
3919 mapCenter->reposition();
3926 void MapEditor::imageDataFetched(const QByteArray &a, QNetworkOperation */*nop*/)
3928 if (!imageBuffer) imageBuffer = new QBuffer();
3929 if (!imageBuffer->isOpen()) {
3930 imageBuffer->open(IO_WriteOnly | IO_Append);
3932 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
3936 void MapEditor::imageDataFinished(QNetworkOperation *nop)
3938 if (nop->state()==QNetworkProtocol::StDone) {
3939 QPixmap img(imageBuffer->buffer());
3944 imageBuffer->close();
3946 imageBuffer->close();
3953 void MapEditor::fetchImage(const QString &url)
3956 urlOperator->stop();
3957 disconnect(urlOperator);
3961 urlOperator = new QUrlOperator(url);
3962 connect(urlOperator, SIGNAL(finished(QNetworkOperation *)),
3963 this, SLOT(imageDataFinished(QNetworkOperation*)));
3965 connect(urlOperator, SIGNAL(data(const QByteArray &, QNetworkOperation *)),
3966 this, SLOT(imageDataFetched(const QByteArray &, QNetworkOperation *)));