Spanish doc is found, if LANG is set. Fixed wrong position of floatimages
3 #include <q3dragobject.h>
4 #include <q3urloperator.h>
5 #include <q3networkprotocol.h>
6 #include <q3paintdevicemetrics.h>
7 #include <q3filedialog.h>
16 #include "editxlinkdialog.h"
18 #include "extrainfodialog.h"
20 #include "linkablemapobj.h"
21 #include "mainwindow.h"
23 #include "texteditor.h"
24 #include "warningdialog.h"
28 extern TextEditor *textEditor;
29 extern int statusbarTime;
30 extern Main *mainWindow;
31 extern QString tmpVymDir;
32 extern QString clipboardDir;
33 extern bool clipboardEmpty;
34 extern FlagRowObj *standardFlagsDefault;
36 extern QMenu* branchContextMenu;
37 extern QMenu* branchAddContextMenu;
38 extern QMenu* branchRemoveContextMenu;
39 extern QMenu* branchLinksContextMenu;
40 extern QMenu* branchXLinksContextMenuEdit;
41 extern QMenu* branchXLinksContextMenuFollow;
42 extern QMenu* floatimageContextMenu;
43 extern QMenu* saveImageFormatMenu;
44 extern QMenu* canvasContextMenu;
45 extern QMenu* lastMapsMenu;
46 extern QMenu* importMenu;
47 extern QMenu* exportMenu;
50 extern Settings settings;
51 extern ImageIO imageIO;
53 extern QString iconPath;
54 extern QDir vymBaseDir;
55 extern QDir lastImageDir;
57 int MapEditor::mapNum=0; // make instance
59 ///////////////////////////////////////////////////////////////////////
60 ///////////////////////////////////////////////////////////////////////
62 QWidget* parent, const char* name, Qt::WFlags f) :
63 Q3CanvasView(parent,name,f), urlOperator(0), imageBuffer(0)
65 //cout << "Constructor ME "<<this<<endl;
68 viewport()->setAcceptDrops(true);
70 mapCanvas = new Q3Canvas(width(),height());
71 mapCanvas->setAdvancePeriod(30);
72 mapCanvas->setBackgroundColor (Qt::white);
74 setCanvas (mapCanvas);
76 // Always show scroll bars (automatic would flicker sometimes)
77 setVScrollBarMode ( Q3ScrollView::AlwaysOn );
78 setHScrollBarMode ( Q3ScrollView::AlwaysOn );
80 mapCenter = new MapCenterObj(mapCanvas);
81 mapCenter->setVisibility (true);
82 mapCenter->setMapEditor (this);
83 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
84 mapCenter->move(mapCanvas->width()/2-mapCenter->width()/2,mapCanvas->height()/2-mapCenter->height()/2);
88 defLinkColor=QColor (0,0,255);
89 defXLinkColor=QColor (180,180,180);
90 linkcolorhint=DefaultColor;
91 linkstyle=StylePolyParabel;
93 // Create bitmap cursors, platform dependant
94 #if defined(Q_OS_MACX)
95 handOpenCursor=QCursor ( QPixmap(iconPath+"cursorhandopen16.png"),1,1 );
96 pickColorCursor=QCursor ( QPixmap (iconPath+"cursorcolorpicker16.png"), 1,15 );
98 handOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
99 pickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
111 xelection.setMapCenter (mapCenter);
114 defXLinkColor=QColor (230,230,230);
122 fileName=tr("unnamed");
125 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",50);
126 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
128 // Initialize find routine
135 blockReposition=false;
136 blockSaveState=false;
140 // Create temporary files
143 // Initially set movingCentre
146 mapCenter->reposition(); // for positioning heading
148 // Initialize history window;
149 historyWindow.setME(this);
150 historyWindow.setStepsTotal(stepsTotal);
151 historyWindow.update (undoSet);
154 MapEditor::~MapEditor()
156 if (imageBuffer) delete imageBuffer;
162 //cout <<"Destructor MapEditor\n";
165 QColor MapEditor::getBackgroundColor()
167 return mapCanvas->backgroundColor();
170 MapCenterObj* MapEditor::getMapCenter()
175 Q3Canvas* MapEditor::getCanvas()
180 void MapEditor::adjustCanvasSize()
182 // To adjust the canvas to map, viewport size and position, we have to
183 // do some coordinate magic...
185 // Get rectangle of (scroll-)view.
186 // We want to be in canvas coords, so
187 // we map. Important if view is zoomed...
188 QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(),
189 visibleWidth(), visibleHeight()) );
191 // Now we need the bounding box of view AND map to calc the correct canvas size.
192 // Why? Because if the map itself is moved out of view, the view has to be enlarged
193 // to avoid jumping aroung...
194 QRect map=mapCenter->getTotalBBox();
196 // right edge - left edge
197 int cw= max(map.x() + map.width(), view.x() + view.width()) - min(map.x(), view.x());
198 int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
201 if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) ||
202 !mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight())
205 // move the map on canvas (in order to not move it on screen) this is neccessary
206 // a) if topleft corner of canvas is left or above topleft corner of view and also left of
207 // above topleft corner of map. E.g. if map is completly inside view, but it would be possible
208 // to scroll to an empty area of canvas to the left.
209 // b) if topleft corner of map left of or above topleft of canvas
213 if (cw > mapCanvas->width() )
215 if (map.x()<0) dx=-map.x();
217 if (cw < mapCanvas->width() )
218 dx=-min (view.x(),map.x());
219 if (ch > mapCanvas->height() )
221 if (map.y()<0) dy=-map.y();
223 if (ch < mapCanvas->height() )
225 dy=-min (view.y(),map.y());
227 // We really have to resize now. Let's go...
228 mapCanvas->resize (cw,ch);
229 if ( (dx!=0) || (dy!=0) )
231 mapCenter->moveAllBy(dx,dy);
232 mapCenter->reposition();
233 // mapCenter->positionBBox(); // To move float
235 // scroll the view (in order to not move map on screen)
241 bool MapEditor::isRepositionBlocked()
243 return blockReposition;
246 QString MapEditor::getName (LinkableMapObj *lmo)
249 if (!lmo) return QString("Error: NULL has no name!");
251 if ((typeid(*lmo) == typeid(BranchObj) ||
252 typeid(*lmo) == typeid(MapCenterObj)))
255 s=(((BranchObj*)lmo)->getHeading());
256 if (s=="") s="unnamed";
257 return QString("branch (%1)").arg(s);
258 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
260 if ((typeid(*lmo) == typeid(FloatImageObj) ))
261 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
262 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
263 return QString("Unknown type has no name!");
266 void MapEditor::makeTmpDirs()
268 // Create unique temporary directories
269 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
270 histPath=QDir::convertSeparators (tmpMapDir+"/history");
275 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, LinkableMapObj *saveSel)
277 // tmpdir temporary directory to which data will be written
278 // prefix mapname, which will be appended to images etc.
279 // writeflags Only write flags for "real" save of map, not undo
280 // offset offset of bbox of whole map in canvas.
281 // Needed for XML export
297 ls="StylePolyParabel";
301 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
303 if (linkcolorhint==HeadingColor)
304 colhint=attribut("linkColorHint","HeadingColor");
306 QString mapAttr=attribut("version",__VYM_VERSION);
308 mapAttr+= attribut("author",mapCenter->getAuthor()) +
309 attribut("comment",mapCenter->getComment()) +
310 attribut("date",mapCenter->getDate()) +
311 attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
312 attribut("linkStyle", ls ) +
313 attribut("linkColor", defLinkColor.name() ) +
314 attribut("defXLinkColor", defXLinkColor.name() ) +
315 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
317 s+=beginElement("vymmap",mapAttr);
320 // Find the used flags while traversing the tree
321 standardFlagsDefault->resetUsedCounter();
323 // Reset the counters before saving
324 FloatImageObj (mapCanvas).resetSaveCounter();
326 // Build xml recursivly
328 // Save complete map, if saveSel not set
329 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
332 if ( typeid(*saveSel) == typeid(BranchObj) )
334 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
335 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
337 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
339 else if (selection && typeid(*selection)==typeid(BranchObj))
340 // Save selected branch is saved from mainwindow //FIXME maybe use "subtree" above?
341 s+=((BranchObj*)selection)->saveToDir(tmpdir,prefix,offset);
344 // Save local settings
345 s+=settings.getXMLData (destPath);
348 if (selection && !saveSel )
349 s+=valueElement("select",selection->getSelectString());
352 s+=endElement("vymmap");
355 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
359 void MapEditor::saveStateComplete(const QString &comment)
361 // Save complete map, Undo will replace whole map
362 saveState (CompleteMap,
369 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
371 // save the selected part of the map, Undo will replace part of map
372 QString undoSelection="";
374 undoSelection=undoSel->getSelectString();
376 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
377 QString redoSelection="";
379 redoSelection=undoSel->getSelectString();
381 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
384 saveState (PartOfMap,
391 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
395 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
398 QString undoSelection=redoSel->getParObj()->getSelectString();
399 QString redoSelection=redoSel->getSelectString();
400 if (typeid(*redoSel) == typeid(BranchObj) && redoSel->getDepth()>1 )
402 // save the selected branch of the map, Undo will insert part of map
403 saveState (PartOfMap,
404 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
405 redoSelection, "delete ()",
408 } else if (typeid(*redoSel) == typeid(BranchObj) )
410 // save the selected mainbranch of the map, Undo will insert part of map
411 saveState (PartOfMap,
412 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
413 redoSelection, "delete ()",
421 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
423 // "Normal" savestate: save commands, selections and comment
424 // so just save commands for undo and redo
425 // and use current selection
427 QString redoSelection="";
428 if (redoSel) redoSelection=redoSel->getSelectString();
429 QString undoSelection="";
430 if (undoSel) undoSelection=undoSel->getSelectString();
432 saveState (UndoCommand,
439 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
441 // "Normal" savestate: save commands, selections and comment
442 // so just save commands for undo and redo
443 // and use current selection
444 saveState (UndoCommand,
452 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
456 if (blockSaveState) return;
458 /* TODO remove after testing
460 cout << "ME::saveState() "<<endl;
462 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
463 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
464 int curStep=undoSet.readNumEntry ("/history/curStep",0);
465 // Find out current undo directory
466 if (undosAvail<stepsTotal) undosAvail++;
468 if (curStep>stepsTotal) curStep=1;
471 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
472 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
473 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
475 // Create bakMapDir if not available
478 makeSubDirs (bakMapDir);
480 // Save depending on how much needs to be saved
484 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),saveSel);
486 QString undoCommand="";
487 if (savemode==UndoCommand)
491 else if (savemode==PartOfMap )
494 undoCommand.replace ("PATH",bakMapPath);
497 undoCommand="undoMap (\""+bakMapPath+"\")";
499 if (!backupXML.isEmpty())
500 // Write XML Data to disk
501 saveStringToDisk (QString(bakMapPath),backupXML);
503 // We would have to save all actions in a tree, to keep track of
504 // possible redos after a action. Possible, but we are too lazy: forget about redos.
507 // Write the current state to disk
508 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
509 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
510 undoSet.setEntry ("/history/curStep",QString::number(curStep));
511 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
512 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
513 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
514 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
515 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
516 undoSet.setEntry (QString("/history/version"),__VYM_VERSION);
517 undoSet.writeSettings(histPath);
519 /* TODO remove after testing
521 //cout << " into="<< histPath.toStdString()<<endl;
522 cout << " stepsTotal="<<stepsTotal<<
523 ", undosAvail="<<undosAvail<<
524 ", redosAvail="<<redosAvail<<
525 ", curStep="<<curStep<<endl;
526 cout << " ---------------------------"<<endl;
527 cout << " comment="<<comment.toStdString()<<endl;
528 cout << " undoCom="<<undoCommand.toStdString()<<endl;
529 cout << " undoSel="<<undoSelection.toStdString()<<endl;
530 cout << " redoCom="<<redoCom.toStdString()<<endl;
531 cout << " redoSel="<<redoSelection.toStdString()<<endl;
532 cout << " ---------------------------"<<endl;
534 historyWindow.update (undoSet);
539 void MapEditor::parseAtom(const QString &atom)
546 // Split string s into command and parameters
547 api.parseInput (atom);
548 QString com=api.command();
551 if (com=="addBranch")
555 api.setError (Aborted,"Nothing selected");
556 } else if ( (typeid(*selection) != typeid(BranchObj) &&
557 typeid(*selection) != typeid(MapCenterObj)) )
559 api.setError (Aborted,"Type of selection is not a branch");
564 if (api.checkParamCount(pl))
566 if (api.paramCount()==0)
567 addNewBranchInt (-2);
571 if (ok ) addNewBranchInt (y);
575 } else if (com=="addBranchBefore")
579 api.setError (Aborted,"Nothing selected");
580 } else if ( (typeid(*selection) != typeid(BranchObj) &&
581 typeid(*selection) != typeid(MapCenterObj)) )
583 api.setError (Aborted,"Type of selection is not a branch");
586 if (api.paramCount()==0)
588 addNewBranchBefore ();
591 } else if (com==QString("addMapReplace"))
595 api.setError (Aborted,"Nothing selected");
596 } else if ( (typeid(*selection) != typeid(BranchObj) &&
597 typeid(*selection) != typeid(MapCenterObj)) )
599 api.setError (Aborted,"Type of selection is not a branch");
600 } else if (api.checkParamCount(2))
602 s=api.parString (ok,0); // selection
603 t=api.parString (ok,1); // path to map
604 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
605 addMapReplaceInt(s,t);
607 } else if (com==QString("addMapInsert"))
611 api.setError (Aborted,"Nothing selected");
612 } else if ( (typeid(*selection) != typeid(BranchObj) &&
613 typeid(*selection) != typeid(MapCenterObj)) )
615 api.setError (Aborted,"Type of selection is not a branch");
618 if (api.checkParamCount(2))
620 t=api.parString (ok,0); // path to map
621 y=api.parInt(ok,1); // position
622 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
623 addMapInsertInt(t,y);
626 } else if (com=="colorItem")
630 api.setError (Aborted,"Nothing selected");
631 } else if ( typeid(*selection) != typeid(BranchObj) &&
632 typeid(*selection) != typeid(MapCenterObj))
634 api.setError (Aborted,"Type of selection is not a branch");
635 } else if (api.checkParamCount(1))
637 QColor c=api.parColor (ok,0);
638 if (ok) colorItem (c);
640 } else if (com=="colorBranch")
644 api.setError (Aborted,"Nothing selected");
645 } else if ( typeid(*selection) != typeid(BranchObj) &&
646 typeid(*selection) != typeid(MapCenterObj))
648 api.setError (Aborted,"Type of selection is not a branch");
649 } else if (api.checkParamCount(1))
651 QColor c=api.parColor (ok,0);
652 if (ok) colorBranch (c);
654 } else if (com=="cut")
658 api.setError (Aborted,"Nothing selected");
659 } else if ( typeid(*selection) != typeid(BranchObj) &&
660 typeid(*selection) != typeid(MapCenterObj) &&
661 typeid(*selection) != typeid(FloatImageObj) )
663 api.setError (Aborted,"Type of selection is not a branch or floatimage");
664 } else if (api.checkParamCount(0))
668 } else if (com=="delete")
672 api.setError (Aborted,"Nothing selected");
673 } else if ( (typeid(*selection) != typeid(BranchObj) &&
674 typeid(*selection) != typeid(MapCenterObj)) )
676 api.setError (Aborted,"Type of selection is not a branch");
677 } else if (api.checkParamCount(0))
681 } else if (com=="deleteKeepChilds")
685 api.setError (Aborted,"Nothing selected");
686 } else if ( (typeid(*selection) != typeid(BranchObj) &&
687 typeid(*selection) != typeid(MapCenterObj)) )
689 api.setError (Aborted,"Type of selection is not a branch");
690 } else if (api.checkParamCount(0))
694 } else if (com=="deleteChilds")
698 api.setError (Aborted,"Nothing selected");
699 } else if ( (typeid(*selection) != typeid(BranchObj) &&
700 typeid(*selection) != typeid(MapCenterObj)) )
702 api.setError (Aborted,"Type of selection is not a branch");
703 } else if (api.checkParamCount(0))
707 } else if (com=="linkBranchToPos")
711 api.setError (Aborted,"Nothing selected");
712 } else if ( (typeid(*selection) != typeid(BranchObj) &&
713 typeid(*selection) != typeid(MapCenterObj)) )
715 api.setError (Aborted,"Type of selection is not a branch");
716 } else if (api.checkParamCount(4))
718 // 0 selectstring of parent
719 // 1 num in parent (for branches)
720 // 2,3 x,y of mainbranch or mapcenter
721 s=api.parString(ok,0);
722 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
725 if (typeid(*dst) == typeid(BranchObj) )
727 // Get number in parent
730 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),x);
731 } else if (typeid(*dst) == typeid(MapCenterObj) )
733 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),-1);
734 // Get coordinates of mainbranch
739 if (ok) ((BranchObj*)selection)->move (x,y);
744 } else if (com=="moveBranchUp")
748 api.setError (Aborted,"Nothing selected");
749 } else if ( (typeid(*selection) != typeid(BranchObj) &&
750 typeid(*selection) != typeid(MapCenterObj)) )
752 api.setError (Aborted,"Type of selection is not a branch");
753 } else if (api.checkParamCount(0))
757 } else if (com=="moveBranchDown")
761 api.setError (Aborted,"Nothing selected");
762 } else if ( (typeid(*selection) != typeid(BranchObj) &&
763 typeid(*selection) != typeid(MapCenterObj)) )
765 api.setError (Aborted,"Type of selection is not a branch");
766 } else if (api.checkParamCount(0))
770 } else if (com=="move")
774 api.setError (Aborted,"Nothing selected");
775 } else if ( typeid(*selection) != typeid(BranchObj) &&
776 typeid(*selection) != typeid(MapCenterObj) &&
777 typeid(*selection) != typeid(FloatImageObj) )
779 api.setError (Aborted,"Type of selection is not a branch or floatimage");
780 } else if (api.checkParamCount(2))
789 } else if (com=="moveRel")
793 api.setError (Aborted,"Nothing selected");
794 } else if ( typeid(*selection) != typeid(BranchObj) &&
795 typeid(*selection) != typeid(MapCenterObj) &&
796 typeid(*selection) != typeid(FloatImageObj) )
798 api.setError (Aborted,"Type of selection is not a branch or floatimage");
799 } else if (api.checkParamCount(2))
805 if (ok) moveRel (x,y);
808 } else if (com=="paste")
812 api.setError (Aborted,"Nothing selected");
813 } else if ( typeid(*selection) != typeid(BranchObj) &&
814 typeid(*selection) != typeid(MapCenterObj) )
816 api.setError (Aborted,"Type of selection is not a branch");
817 } else if (api.checkParamCount(0))
821 } else if (com=="setHeading")
825 api.setError (Aborted,"Nothing selected");
826 } else if ( (typeid(*selection) != typeid(BranchObj) &&
827 typeid(*selection) != typeid(MapCenterObj)) )
829 api.setError (Aborted,"Type of selection is not a branch");
830 } else if (api.checkParamCount(1))
832 s=api.parString (ok,0);
836 } else if (com=="setHideExport")
840 api.setError (Aborted,"Nothing selected");
841 } else if ( typeid(*selection) != typeid(BranchObj) &&
842 typeid(*selection) != typeid(FloatImageObj) )
844 api.setError (Aborted,"Type of selection is not a branch or floatimage");
845 } else if (api.checkParamCount(1))
848 if (ok) setHideExport (b);
850 } else if (com=="setURL")
854 api.setError (Aborted,"Nothing selected");
855 } else if ( (typeid(*selection) != typeid(BranchObj) &&
856 typeid(*selection) != typeid(MapCenterObj)) )
858 api.setError (Aborted,"Type of selection is not a branch");
859 } else if (api.checkParamCount(1))
861 s=api.parString (ok,0);
862 if (ok) setURLInt(s);
864 } else if (com=="setVymLink")
868 api.setError (Aborted,"Nothing selected");
869 } else if ( (typeid(*selection) != typeid(BranchObj) &&
870 typeid(*selection) != typeid(MapCenterObj)) )
872 api.setError (Aborted,"Type of selection is not a branch");
873 } else if (api.checkParamCount(1))
875 s=api.parString (ok,0);
876 if (ok) setVymLinkInt(s);
879 else if (com=="setFlag")
883 api.setError (Aborted,"Nothing selected");
884 } else if ( (typeid(*selection) != typeid(BranchObj) &&
885 typeid(*selection) != typeid(MapCenterObj)) )
887 api.setError (Aborted,"Type of selection is not a branch");
888 } else if (api.checkParamCount(1))
890 s=api.parString(ok,0);
893 BranchObj* bo=(BranchObj*)selection;
894 bo->activateStandardFlag(s);
895 bo->updateFlagsToolbar();
899 else if (com=="unsetFlag")
903 api.setError (Aborted,"Nothing selected");
904 } else if ( (typeid(*selection) != typeid(BranchObj) &&
905 typeid(*selection) != typeid(MapCenterObj)) )
907 api.setError (Aborted,"Type of selection is not a branch");
908 } else if (api.checkParamCount(1))
910 s=api.parString(ok,0);
913 BranchObj* bo=(BranchObj*)selection;
914 bo->deactivateStandardFlag(s);
915 bo->updateFlagsToolbar();
919 } else if (com==QString("undoMap"))
921 if (api.checkParamCount(1))
922 addMapReplaceInt("",api.parString (ok,0));
923 } else if (com=="select")
925 if (api.checkParamCount(1))
927 s=api.parString(ok,0);
933 api.setError (Aborted,"Unknown command");
937 if (api.errorLevel()==NoError)
941 // TODO Error handling
942 qWarning("MapEditor::parseAtom: Error!");
943 qWarning(api.errorMessage());
947 void MapEditor::toggleHistoryWindow()
949 if (historyWindow.isVisible())
950 historyWindow.hide();
952 historyWindow.show();
956 bool MapEditor::isDefault()
961 bool MapEditor::isUnsaved()
966 bool MapEditor::hasChanged()
971 void MapEditor::setChanged()
979 void MapEditor::closeMap()
981 // Unselect before disabling the toolbar actions
982 if (selection) selection->unselect();
990 void MapEditor::setFilePath(QString fname)
992 setFilePath (fname,fname);
995 void MapEditor::setFilePath(QString fname, QString destname)
997 if (fname.isEmpty() || fname=="")
1004 filePath=fname; // becomes absolute path
1005 fileName=fname; // gets stripped of path
1006 destPath=destname; // needed for vymlinks
1008 // If fname is not an absolute path, complete it
1009 filePath=QDir(fname).absPath();
1010 fileDir=filePath.left (1+filePath.findRev ("/"));
1012 // Set short name, too. Search from behind:
1013 int i=fileName.findRev("/");
1014 if (i>=0) fileName=fileName.remove (0,i+1);
1016 // Forget the .vym (or .xml) for name of map
1017 mapName=fileName.left(fileName.findRev(".",-1,true) );
1019 // Adjust history window
1020 historyWindow.setCaption (__VYM " - " +tr("History for ")+fileName);
1024 QString MapEditor::getFilePath()
1029 QString MapEditor::getFileName()
1034 QString MapEditor::getMapName()
1039 QString MapEditor::getDestPath()
1044 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1046 ErrorCode err=success;
1050 if (selection) selection->unselect();
1053 mapCenter->setMapEditor(this);
1054 // (map state is set later at end of load...)
1057 if (!selection || (typeid(*selection) != typeid(BranchObj) &&
1058 typeid(*selection) != typeid (MapCenterObj)))
1060 BranchObj *bo=(BranchObj*)selection;
1061 if (lmode==ImportAdd)
1062 saveStateChangingPart(
1065 QString("addMapInsert (%1)").arg(fname),
1066 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1068 saveStateChangingPart(
1071 QString("addMapReplace(%1)").arg(fname),
1072 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1076 mapBuilderHandler handler;
1077 QFile file( fname );
1079 // I am paranoid: file should exist anyway
1080 // according to check in mainwindow.
1081 if (!file.exists() )
1083 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1084 tr("Couldn't open map " +fname)+".");
1088 blockReposition=true;
1089 QXmlInputSource source( file);
1090 QXmlSimpleReader reader;
1091 reader.setContentHandler( &handler );
1092 reader.setErrorHandler( &handler );
1093 handler.setMapEditor( this );
1094 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1095 handler.setInputFile (file.name());
1096 handler.setLoadMode (lmode);
1097 blockSaveState=true;
1098 bool ok = reader.parse( source );
1099 blockReposition=false;
1100 blockSaveState=false;
1104 mapCenter->reposition();
1114 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1115 tr( handler.errorProtocol() ) );
1117 // Still return "success": the map maybe at least
1118 // partially read by the parser
1125 int MapEditor::save (const SaveMode &savemode)
1129 // The SaveMode UndoCommand is not supported here
1130 if (savemode==UndoCommand) return 1;
1132 // Create mapName and fileDir
1133 makeSubDirs (fileDir);
1137 fname=mapName+".xml";
1139 // use name given by user, even if he chooses .doc
1144 if (savemode==CompleteMap || selection==NULL)
1145 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),NULL);
1147 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),selection);
1149 if (!saveStringToDisk(fileDir+fname,saveFile))
1162 void MapEditor::setZipped (bool z)
1167 bool MapEditor::saveZipped ()
1172 void MapEditor::print()
1176 printer = new QPrinter;
1177 printer->setColorMode (QPrinter::Color);
1178 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1181 QRect totalBBox=mapCenter->getTotalBBox();
1183 // Try to set orientation automagically
1184 // Note: Interpretation of generated postscript is amibiguous, if
1185 // there are problems with landscape mode, see
1186 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1188 if (totalBBox.width()>totalBBox.height())
1189 // recommend landscape
1190 printer->setOrientation (QPrinter::Landscape);
1192 // recommend portrait
1193 printer->setOrientation (QPrinter::Portrait);
1195 if ( printer->setup(this) )
1196 // returns false, if printing is canceled
1198 QPainter pp(printer);
1200 // Don't print the visualisation of selection
1201 LinkableMapObj *oldselection=NULL;
1204 oldselection=selection;
1205 selection->unselect();
1208 // Handle sizes of map and paper:
1210 // setWindow defines which part of the canvas will be transformed
1211 // setViewport defines area on paper in device coordinates (dpi)
1212 // e.g. (0,50,700,700) is upper part on A4
1213 // see also /usr/lib/qt3/doc/html/coordsys.html
1215 Q3PaintDeviceMetrics metrics (printer);
1217 double paperAspect = (double)metrics.width() / (double)metrics.height();
1218 double mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
1220 QRect mapRect=totalBBox;
1221 Q3CanvasRectangle *frame=NULL;
1222 Q3CanvasText *footerFN=NULL;
1223 Q3CanvasText *footerDate=NULL;
1224 if (printFrame || printFooter)
1229 // Print frame around map
1230 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1231 totalBBox.width()+20, totalBBox.height()+20);
1232 frame=new Q3CanvasRectangle (mapRect,mapCanvas);
1233 frame->setBrush (QColor(Qt::white));
1234 frame->setPen (QColor(Qt::black));
1238 /* TODO remove after testing
1239 QCanvasLine *l=new QCanvasLine (mapCanvas);
1240 l->setPoints (0,0,mapRect.width(),mapRect.height());
1241 l->setPen (QPen(QColor(black), 1));
1248 // Print footer below map
1250 font.setPointSize(10);
1251 footerFN=new Q3CanvasText (mapCanvas);
1252 footerFN->setText ("VYM - " + fileName);
1253 footerFN->setFont(font);
1254 footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
1255 footerFN->setZ(Z_TEXT);
1257 footerDate=new Q3CanvasText (mapCanvas);
1258 footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
1259 footerDate->setFont(font);
1260 footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
1261 footerDate->setZ(Z_TEXT);
1264 pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()+20);
1267 pp.setWindow (mapRect);
1270 if (mapAspect>=paperAspect)
1272 // Fit horizontally to paper width
1273 pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );
1276 // Fit vertically to paper height
1277 pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());
1280 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to printer
1282 // Delete Frame and footer
1286 delete (footerDate);
1288 if (frame) delete (frame);
1290 // Restore selection
1293 selection=oldselection;
1294 selection->select();
1297 // Save settings in vymrc
1298 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1302 QPixmap MapEditor::getPixmap()
1304 QRect mapRect=mapCenter->getTotalBBox();
1305 QPixmap pix (mapRect.size());
1308 // Don't print the visualisation of selection
1309 LinkableMapObj *oldselection=NULL;
1312 oldselection=selection;
1313 selection->unselect();
1316 pp.setWindow (mapRect);
1318 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to painter
1321 // Restore selection
1324 selection=oldselection;
1325 selection->select();
1331 void MapEditor::setHideTmpMode (HideTmpMode mode)
1334 mapCenter->setHideTmp (hidemode);
1335 mapCenter->reposition();
1340 HideTmpMode MapEditor::getHideTmpMode()
1345 void MapEditor::exportImage(QString fn)
1347 setExportMode (true);
1348 QPixmap pix (getPixmap());
1349 pix.save(fn, "PNG");
1350 setExportMode (false);
1353 void MapEditor::setExportMode (bool b)
1355 // should be called before and after exports
1356 // depending on the settings
1357 if (b && settings.value("/export/useHideExport","yes")=="yes")
1358 setHideTmpMode (HideExport);
1360 setHideTmpMode (HideNone);
1363 void MapEditor::exportImage(QString fn, QString format)
1365 setExportMode (true);
1366 QPixmap pix (getPixmap());
1367 pix.save(fn, format);
1368 setExportMode (false);
1371 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1375 ex.setMapCenter(mapCenter);
1376 if (ex.setConfigFile(cf))
1378 setExportMode (true);
1379 ex.exportPresentation();
1380 setExportMode (false);
1386 void MapEditor::exportXML(const QString &dir)
1388 // Hide stuff during export, if settings want this
1389 setExportMode (true);
1391 // Create subdirectories
1394 // write to directory
1395 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1398 file.setName ( dir + "/"+mapName+".xml");
1399 if ( !file.open( QIODevice::WriteOnly ) )
1401 // This should neverever happen
1402 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1406 // Write it finally, and write in UTF8, no matter what
1407 QTextStream ts( &file );
1408 ts.setEncoding (QTextStream::UnicodeUTF8);
1412 // Now write image, too
1413 exportImage (dir+"/images/"+mapName+".png");
1415 setExportMode (false);
1418 void MapEditor::clear()
1422 selection->unselect();
1429 void MapEditor::copy()
1433 // write to directory
1434 QString clipfile="part";
1435 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPoint(),selection);
1438 file.setName ( clipboardDir + "/"+clipfile+".xml");
1439 if ( !file.open( QIODevice::WriteOnly ) )
1441 // This should neverever happen
1442 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1446 // Write it finally, and write in UTF8, no matter what
1447 QTextStream ts( &file );
1448 ts.setEncoding (QTextStream::UnicodeUTF8);
1452 clipboardEmpty=false;
1457 void MapEditor::redo()
1459 blockSaveState=true;
1461 // Restore variables
1462 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1463 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1464 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1465 // Can we undo at all?
1466 if (redosAvail<1) return;
1469 if (undosAvail<stepsTotal) undosAvail++;
1471 if (curStep>stepsTotal) curStep=1;
1472 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1473 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1474 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1475 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1476 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1477 QString version=undoSet.readEntry ("/history/version");
1479 if (!checkVersion(version))
1480 QMessageBox::warning(0,tr("Warning"),
1481 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(__VYM_VERSION));
1484 // Find out current undo directory
1485 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1487 /* TODO remove testing
1489 cout << "ME::redo() begin\n";
1490 cout << " undosAvail="<<undosAvail<<endl;
1491 cout << " redosAvail="<<redosAvail<<endl;
1492 cout << " curStep="<<curStep<<endl;
1493 cout << " ---------------------------"<<endl;
1494 cout << " comment="<<comment.toStdString()<<endl;
1495 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1496 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1497 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1498 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1499 cout << " ---------------------------"<<endl<<endl;
1501 // select object before redo
1502 // FIXME better give up if no selection there...
1503 if (!redoSelection.isEmpty())
1504 select (redoSelection);
1507 parseAtom (redoCommand);
1508 mapCenter->reposition();
1510 blockSaveState=false;
1512 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1513 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1514 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1515 undoSet.writeSettings(histPath);
1517 historyWindow.update (undoSet);
1520 /* TODO remove testing
1522 cout << "ME::redo() end\n";
1523 cout << " undosAvail="<<undosAvail<<endl;
1524 cout << " redosAvail="<<redosAvail<<endl;
1525 cout << " curStep="<<curStep<<endl;
1526 cout << " ---------------------------"<<endl<<endl;
1531 bool MapEditor::isRedoAvailable()
1533 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1539 void MapEditor::undo()
1541 blockSaveState=true;
1543 // Restore variables
1544 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1545 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1546 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1548 // Can we undo at all?
1549 if (undosAvail<1) return;
1551 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1552 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1553 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1554 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1555 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1556 QString version=undoSet.readEntry ("/history/version");
1558 if (!checkVersion(version))
1559 QMessageBox::warning(0,tr("Warning"),
1560 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(__VYM_VERSION));
1562 // Find out current undo directory
1563 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1565 // select object before undo
1566 if (!undoSelection.isEmpty())
1567 select (undoSelection);
1571 cout << "ME::undo() begin\n";
1572 cout << " undosAvail="<<undosAvail<<endl;
1573 cout << " redosAvail="<<redosAvail<<endl;
1574 cout << " curStep="<<curStep<<endl;
1575 cout << " ---------------------------"<<endl;
1576 cout << " comment="<<comment.toStdString()<<endl;
1577 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1578 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1579 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1580 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1581 cout << " ---------------------------"<<endl<<endl;
1582 parseAtom (undoCommand);
1583 mapCenter->reposition();
1587 if (curStep<1) curStep=stepsTotal;
1591 blockSaveState=false;
1592 /* TODO remove testing
1594 cout << "ME::undo() end\n";
1595 cout << " undosAvail="<<undosAvail<<endl;
1596 cout << " redosAvail="<<redosAvail<<endl;
1597 cout << " curStep="<<curStep<<endl;
1598 cout << " ---------------------------"<<endl<<endl;
1600 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1601 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1602 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1603 undoSet.writeSettings(histPath);
1605 historyWindow.update (undoSet);
1609 bool MapEditor::isUndoAvailable()
1611 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1617 void MapEditor::gotoStep (int i)
1619 // Restore variables
1620 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1621 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1623 cout << "ME::goto "<<i<<endl;
1625 if (i<0) i=undosAvail+redosAvail;
1627 // Clicking above current step makes us undo things
1630 for (int j=0; j<undosAvail-i; j++) undo();
1633 // Clicking below current step makes us redo things
1635 for (int j=undosAvail; j<i; j++) redo();
1637 // And ignore clicking the current row ;-)
1640 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1642 QString pathDir=path.left(path.findRev("/"));
1648 // We need to parse saved XML data
1649 mapBuilderHandler handler;
1650 QXmlInputSource source( file);
1651 QXmlSimpleReader reader;
1652 reader.setContentHandler( &handler );
1653 reader.setErrorHandler( &handler );
1654 handler.setMapEditor( this );
1655 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1656 if (undoSel.isEmpty())
1660 handler.setLoadMode (NewMap);
1664 handler.setLoadMode (ImportReplace);
1666 blockReposition=true;
1667 bool ok = reader.parse( source );
1668 blockReposition=false;
1671 // This should never ever happen
1672 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1673 handler.errorProtocol());
1676 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1679 void MapEditor::addMapInsertInt (const QString &path, int pos)
1681 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1682 typeid(*selection) == typeid(MapCenterObj)))
1684 QString pathDir=path.left(path.findRev("/"));
1690 // We need to parse saved XML data
1691 mapBuilderHandler handler;
1692 QXmlInputSource source( file);
1693 QXmlSimpleReader reader;
1694 reader.setContentHandler( &handler );
1695 reader.setErrorHandler( &handler );
1696 handler.setMapEditor( this );
1697 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1698 handler.setLoadMode (ImportAdd);
1699 blockReposition=true;
1700 bool ok = reader.parse( source );
1701 blockReposition=false;
1704 // This should never ever happen
1705 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1706 handler.errorProtocol());
1708 if (selection!=mapCenter)
1709 ((BranchObj*)selection)->getLastBranch()->moveBranchTo ((BranchObj*)(selection),pos);
1711 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1715 void MapEditor::pasteNoSave()
1717 load (clipboardDir+"/part.xml",ImportAdd);
1720 void MapEditor::cutNoSave()
1726 void MapEditor::paste()
1728 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1729 typeid(*selection) == typeid(MapCenterObj)))
1732 saveStateChangingPart(
1736 QString("Paste to %1").arg( getName(selection))
1738 mapCenter->reposition();
1743 void MapEditor::cut()
1745 saveStateChangingPart(
1746 selection->getParObj(),
1749 QString("Cut %1").arg(getName(selection))
1753 mapCenter->reposition();
1757 void MapEditor::move(const int &x, const int &y)
1761 QString ps=qpointToString (selection->getAbsPos());
1762 QString s=selection->getSelectString();
1765 s, "move "+qpointToString (QPoint (x,y)),
1766 QString("Move %1 to %2").arg(getName(selection)).arg(ps));
1767 selection->move(x,y);
1768 mapCenter->reposition();
1774 void MapEditor::moveRel (const int &x, const int &y)
1776 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1777 typeid(*selection) == typeid(MapCenterObj) ||
1778 typeid(*selection) == typeid (FloatImageObj)))
1780 QString ps=qpointToString (selection->getRelPos());
1781 QString s=selection->getSelectString();
1784 s, "moveRel "+qpointToString (QPoint (x,y)),
1785 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(ps));
1786 ((OrnamentedObj*)selection)->move2RelPos (x,y);
1787 mapCenter->reposition();
1792 void MapEditor::moveBranchUp()
1796 if (typeid(*selection) == typeid(BranchObj) )
1798 bo=(BranchObj*)selection;
1799 if (!bo->canMoveBranchUp()) return;
1800 par=(BranchObj*)(bo->getParObj());
1801 selection->unselect();
1802 bo=par->moveBranchUp (bo); // bo will be the one below selection
1803 selection->select();
1804 saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1805 mapCenter->reposition();
1806 ensureSelectionVisible();
1810 void MapEditor::moveBranchDown()
1814 if (typeid(*selection) == typeid(BranchObj) )
1816 bo=(BranchObj*)selection;
1817 if (!bo->canMoveBranchDown()) return;
1818 par=(BranchObj*)(bo->getParObj());
1819 selection->unselect();
1820 bo=par->moveBranchDown(bo); // bo will be the one above selection
1821 selection->select();
1822 saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1823 mapCenter->reposition();
1824 ensureSelectionVisible();
1828 QString MapEditor::getHeading(bool &ok, QPoint &p)
1831 (typeid(*selection) == typeid(BranchObj) ||
1832 typeid(*selection) == typeid(MapCenterObj) ) )
1835 ensureSelectionVisible();
1836 p = ((BranchObj*)selection)->getAbsPos();
1837 p.setX (p.x() - contentsX());
1838 p.setY (p.y() - contentsY() + ((BranchObj*)selection)->height()/2);
1839 return ((BranchObj*)selection)->getHeading();
1845 void MapEditor::setHeading(const QString &s)
1848 (typeid(*selection) == typeid(BranchObj) ||
1849 typeid(*selection) == typeid(MapCenterObj) ) )
1851 editingBO=(BranchObj*)selection;
1854 "setHeading (\""+editingBO->getHeading()+"\")",
1856 "setHeading (\""+s+"\")",
1857 QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(s) );
1858 editingBO->setHeading(s );
1860 mapCenter->reposition();
1862 ensureSelectionVisible();
1866 void MapEditor::setURLInt (const QString &s)
1868 // Internal function, no saveState needed
1870 (typeid(*selection) == typeid(BranchObj) ||
1871 typeid(*selection) == typeid(MapCenterObj) ) )
1873 ((BranchObj*)selection)->setURL(s);
1874 mapCenter->reposition();
1876 ensureSelectionVisible();
1880 void MapEditor::setHeadingInt(const QString &s)
1883 (typeid(*selection) == typeid(BranchObj) ||
1884 typeid(*selection) == typeid(MapCenterObj) ) )
1886 ((BranchObj*)selection)->setHeading(s);
1887 mapCenter->reposition();
1889 ensureSelectionVisible();
1893 void MapEditor::setVymLinkInt (const QString &s)
1895 // Internal function, no saveState needed
1897 (typeid(*selection) == typeid(BranchObj) ||
1898 typeid(*selection) == typeid(MapCenterObj) ) )
1900 ((BranchObj*)selection)->setVymLink(s);
1901 mapCenter->reposition();
1903 ensureSelectionVisible();
1907 BranchObj* MapEditor::addNewBranchInt(int num)
1909 // Depending on pos:
1910 // -3 insert in childs of parent above selection
1911 // -2 add branch to selection
1912 // -1 insert in childs of parent below selection
1913 // 0..n insert in childs of parent at pos
1914 BranchObj *newbo=NULL;
1916 (typeid(*selection) == typeid(BranchObj) ||
1917 typeid(*selection) == typeid(MapCenterObj) ) )
1919 BranchObj* bo = (BranchObj*) selection;
1922 // save scroll state. If scrolled, automatically select
1923 // new branch in order to tmp unscroll parent...
1924 return bo->addBranch();
1929 bo=(BranchObj*)bo->getParObj();
1933 bo=(BranchObj*)bo->getParObj();
1936 newbo=bo->insertBranch(num);
1941 BranchObj* MapEditor::addNewBranch(int pos)
1943 // Different meaning than num in addNewBranchInt!
1947 BranchObj *bo = (BranchObj*) selection;
1948 BranchObj *newbo=NULL;
1951 (typeid(*selection) == typeid(BranchObj) ||
1952 typeid(*selection) == typeid(MapCenterObj) ) )
1954 newbo=addNewBranchInt (pos-2);
1959 selection, // FIXME sholdnt newbo be deleted here???
1962 QString ("addBranch (%1)").arg(pos-2),
1963 QString ("Add new branch to %1").arg(getName(bo)));
1965 mapCenter->reposition();
1973 BranchObj* MapEditor::addNewBranchBefore()
1975 BranchObj *newbo=NULL;
1977 (typeid(*selection) == typeid(BranchObj) ) )
1978 // We accept no MapCenterObj here, so we _have_ a parent
1980 BranchObj* bo = (BranchObj*) selection;
1981 QPoint p=bo->getRelPos();
1984 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1986 // add below selection
1987 newbo=parbo->insertBranch(bo->getNum()+1);
1990 newbo->move2RelPos (p);
1992 // Move selection to new branch
1993 ((BranchObj*)selection)->moveBranchTo (newbo,-1);
1995 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
1996 QString ("Add branch before %1").arg(getName(bo)));
1998 mapCenter->reposition();
2005 void MapEditor::deleteSelection()
2007 if (selection && typeid(*selection) ==typeid(BranchObj) )
2009 BranchObj* bo=(BranchObj*)selection;
2010 BranchObj* par=(BranchObj*)(bo->getParObj());
2012 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2014 par->removeBranch(bo);
2016 selection->select();
2017 ensureSelectionVisible();
2018 mapCenter->reposition();
2021 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
2023 FloatImageObj* fio=(FloatImageObj*)selection;
2024 BranchObj* par=(BranchObj*)(fio->getParObj());
2025 saveStateChangingPart(
2029 QString("Delete %1").arg(getName(fio))
2033 par->removeFloatImage(fio);
2035 selection->select();
2036 ensureSelectionVisible();
2037 mapCenter->reposition();
2042 LinkableMapObj* MapEditor::getSelection()
2047 void MapEditor::unselect()
2051 selectionLast=selection;
2052 selection->unselect();
2057 void MapEditor::reselect()
2061 selection=selectionLast;
2062 selection->select();
2067 bool MapEditor::select (const QString &s)
2069 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2071 // Finally select the found object
2074 if (selection) unselect();
2076 selection->select();
2078 ensureSelectionVisible();
2084 QString MapEditor::getSelectString()
2086 if (selection) return selection->getSelectString();
2090 void MapEditor::selectInt (LinkableMapObj *lmo)
2092 if (lmo && selection != lmo)
2094 // select the MapObj
2095 if (selection) selection->unselect();
2097 selection->select();
2103 void MapEditor::selectNextBranchInt()
2105 // Increase number of branch
2108 QString s=selection->getSelectString();
2114 part=s.section(",",-1);
2116 num=part.right(part.length() - 3);
2118 s=s.left (s.length() -num.length());
2121 num=QString ("%1").arg(num.toUInt()+1);
2125 // Try to select this one
2126 if (select (s)) return;
2128 // We have no direct successor,
2129 // try to increase the parental number in order to
2130 // find a successor with same depth
2132 int d=selection->getDepth();
2137 while (!found && d>0)
2139 s=s.section (",",0,d-1);
2140 // replace substring of current depth in s with "1"
2141 part=s.section(",",-1);
2143 num=part.right(part.length() - 3);
2147 // increase number of parent
2148 num=QString ("%1").arg(num.toUInt()+1);
2149 s=s.section (",",0,d-2) + ","+ typ+num;
2152 // Special case, look at orientation
2153 if (selection->getOrientation()==OrientRightOfCenter)
2154 num=QString ("%1").arg(num.toUInt()+1);
2156 num=QString ("%1").arg(num.toUInt()-1);
2161 // pad to oldDepth, select the first branch for each depth
2162 for (i=d;i<oldDepth;i++)
2167 if ( ((BranchObj*)selection)->countBranches()>0)
2175 // try to select the freshly built string
2183 void MapEditor::selectPrevBranchInt()
2185 // Decrease number of branch
2188 QString s=selection->getSelectString();
2194 part=s.section(",",-1);
2196 num=part.right(part.length() - 3);
2198 s=s.left (s.length() -num.length());
2201 num=QString ("%1").arg(num.toUInt()-1);
2205 // Try to select this one
2206 if (select (s)) return;
2208 // We have no direct precessor,
2209 // try to decrease the parental number in order to
2210 // find a precessor with same depth
2212 int d=selection->getDepth();
2217 while (!found && d>0)
2219 s=s.section (",",0,d-1);
2220 // replace substring of current depth in s with "1"
2221 part=s.section(",",-1);
2223 num=part.right(part.length() - 3);
2227 // decrease number of parent
2228 num=QString ("%1").arg(num.toUInt()-1);
2229 s=s.section (",",0,d-2) + ","+ typ+num;
2232 // Special case, look at orientation
2233 if (selection->getOrientation()==OrientRightOfCenter)
2234 num=QString ("%1").arg(num.toUInt()-1);
2236 num=QString ("%1").arg(num.toUInt()+1);
2241 // pad to oldDepth, select the last branch for each depth
2242 for (i=d;i<oldDepth;i++)
2246 if ( ((BranchObj*)selection)->countBranches()>0)
2247 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
2254 // try to select the freshly built string
2262 void MapEditor::selectUpperBranch()
2266 if (typeid(*selection) == typeid(BranchObj))
2268 if (selection->getOrientation()==OrientRightOfCenter)
2269 selectPrevBranchInt();
2271 if (selection->getDepth()==1)
2272 selectNextBranchInt();
2274 selectPrevBranchInt();
2279 void MapEditor::selectLowerBranch()
2283 if (typeid(*selection) == typeid(BranchObj))
2285 if (selection->getOrientation()==OrientRightOfCenter)
2286 selectNextBranchInt();
2288 if (selection->getDepth()==1)
2289 selectPrevBranchInt();
2291 selectNextBranchInt();
2297 void MapEditor::selectLeftBranch()
2303 if (typeid(*selection) == typeid(MapCenterObj))
2305 par= (BranchObj*) selection;
2306 bo=par->getLastSelectedBranch();
2309 // Workaround for reselecting on left and right side
2310 if (bo->getOrientation()==OrientRightOfCenter)
2312 bo=par->getLastBranch();
2318 selection->select();
2320 ensureSelectionVisible();
2325 par=(BranchObj*)(selection->getParObj());
2326 if (selection->getOrientation()==OrientRightOfCenter)
2328 if (typeid(*selection) == typeid(BranchObj) ||
2329 typeid(*selection) == typeid(FloatImageObj))
2331 selection->unselect();
2333 selection->select();
2335 ensureSelectionVisible();
2339 if (typeid(*selection) == typeid(BranchObj) )
2341 bo=((BranchObj*)selection)->getLastSelectedBranch();
2344 selection->unselect();
2346 selection->select();
2348 ensureSelectionVisible();
2356 void MapEditor::selectRightBranch()
2363 if (typeid(*selection) == typeid(MapCenterObj))
2365 par= (BranchObj*) selection;
2366 bo=par->getLastSelectedBranch();
2369 // Workaround for reselecting on left and right side
2370 if (bo->getOrientation()==OrientLeftOfCenter)
2371 bo=par->getFirstBranch();
2376 selection->select();
2377 ensureSelectionVisible();
2382 par=(BranchObj*)(selection->getParObj());
2383 if (selection->getOrientation()==OrientLeftOfCenter)
2385 if (typeid(*selection) == typeid(BranchObj) ||
2386 typeid(*selection) == typeid(FloatImageObj))
2388 selection->unselect();
2390 selection->select();
2392 ensureSelectionVisible();
2396 if (typeid(*selection) == typeid(BranchObj) )
2398 bo=((BranchObj*)selection)->getLastSelectedBranch();
2401 selection->unselect();
2403 selection->select();
2405 ensureSelectionVisible();
2413 void MapEditor::selectFirstBranch()
2419 if (typeid(*selection) == typeid(BranchObj))
2421 bo1= (BranchObj*) selection;
2422 par=(BranchObj*)(bo1->getParObj());
2423 bo2=par->getFirstBranch();
2427 selection->select();
2428 ensureSelectionVisible();
2435 void MapEditor::selectLastBranch()
2441 if (typeid(*selection) == typeid(BranchObj))
2443 bo1= (BranchObj*) selection;
2444 par=(BranchObj*)(bo1->getParObj());
2445 bo2=par->getLastBranch();
2449 selection->select();
2450 ensureSelectionVisible();
2457 void MapEditor::selectBackgroundColor()
2459 QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
2460 if ( !col.isValid() ) return;
2461 setBackgroundColor( col );
2463 saveStateComplete(QString("Set background color of map to %1").arg(col.name()));
2466 void MapEditor::setBackgroundColor(QColor c)
2468 mapCanvas->setBackgroundColor (c);
2471 QColor MapEditor::getCurrentHeadingColor()
2475 if (typeid(*selection) == typeid(BranchObj) ||
2476 typeid(*selection) == typeid(MapCenterObj))
2478 BranchObj *bo=(BranchObj*)selection;
2479 return bo->getColor();
2483 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2487 void MapEditor::colorItem(QColor c)
2491 if (typeid(*selection) == typeid(BranchObj) ||
2492 typeid(*selection) == typeid(MapCenterObj))
2494 BranchObj *bo=(BranchObj*)selection;
2495 saveStateChangingPart(
2498 QString ("colorItem (%1)").arg(c.name()),
2499 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2500 ); //TODO with complete API: undoCommand
2501 bo->setColor(c); // color branch
2506 void MapEditor::colorBranch(QColor c)
2510 if (typeid(*selection) == typeid(BranchObj) ||
2511 typeid(*selection) == typeid(MapCenterObj))
2513 BranchObj *bo=(BranchObj*)selection;
2514 saveStateChangingPart(
2517 QString ("colorBranch (%1)").arg(c.name()),
2518 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2520 bo->setColorChilds(c); // color links, color childs
2526 void MapEditor::toggleStandardFlag(QString f)
2530 if (typeid(*selection) == typeid(BranchObj) ||
2531 typeid(*selection) == typeid(MapCenterObj))
2533 BranchObj *bo=(BranchObj*)selection;
2535 if (bo->isSetStandardFlag(f))
2547 QString("%1 (\"%2\")").arg(u).arg(f),
2549 QString("%1 (\"%2\")").arg(r).arg(f),
2550 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2551 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2557 void MapEditor::setViewCenter()
2559 // transform to CanvasView Coord:
2560 QPoint p=worldMatrix().map(movingCenter);
2561 center ( p.x(), p.y());
2565 BranchObj* MapEditor::findText (QString s, bool cs)
2567 QTextDocument::FindFlags flags=0;
2568 if (cs) flags=QTextDocument::FindCaseSensitively;
2571 { // Nothing found or new find process
2573 // nothing found, start again
2575 itFind=mapCenter->first();
2577 bool searching=true;
2578 bool foundNote=false;
2579 while (searching && !EOFind)
2583 // Searching in Note
2584 if (itFind->getNote().contains(s,cs))
2586 if (selection!=itFind)
2588 if (selection) ((BranchObj*)selection)->unselect();
2590 selection->select();
2592 ensureSelectionVisible();
2594 if (textEditor->findText(s,flags))
2600 // Searching in Heading
2601 if (searching && itFind->getHeading().contains (s,cs) )
2603 if (selection) ((BranchObj*)selection)->unselect();
2605 selection->select();
2607 ensureSelectionVisible();
2613 itFind=itFind->next();
2614 if (!itFind) EOFind=true;
2620 return (BranchObj*)selection;
2625 void MapEditor::findReset()
2626 { // Necessary if text to find changes during a find process
2630 void MapEditor::setURL(const QString &url)
2632 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2633 typeid(*selection) == typeid(MapCenterObj)) )
2635 BranchObj *bo=(BranchObj*)selection;
2636 QString oldurl=bo->getURL();
2640 QString ("setURL (\"%1\")").arg(oldurl),
2642 QString ("setURL (\"%1\")").arg(url),
2643 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2649 void MapEditor::editURL()
2651 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2652 typeid(*selection) == typeid(MapCenterObj)) )
2655 BranchObj *bo=(BranchObj*)selection;
2656 QString text = QInputDialog::getText(
2657 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2658 bo->getURL(), &ok, this );
2660 // user entered something and pressed OK
2665 QString MapEditor::getURL()
2667 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2668 typeid(*selection) == typeid(MapCenterObj)) )
2669 return ((BranchObj*)selection)->getURL();
2674 QStringList MapEditor::getURLs()
2677 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2678 typeid(*selection) == typeid(MapCenterObj)) )
2680 BranchObj *bo=(BranchObj*)selection;
2684 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2692 void MapEditor::editHeading2URL()
2694 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2695 typeid(*selection) == typeid(MapCenterObj)) )
2696 setURL (((BranchObj*)selection)->getHeading());
2699 void MapEditor::editBugzilla2URL()
2701 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2702 typeid(*selection) == typeid(MapCenterObj)) )
2704 BranchObj *bo=(BranchObj*)selection;
2705 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2710 void MapEditor::editFATE2URL()
2712 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2713 typeid(*selection) == typeid(MapCenterObj)) )
2715 BranchObj *bo=(BranchObj*)selection;
2716 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2719 "setURL (\""+bo->getURL()+"\")",
2721 "setURL (\""+url+"\")",
2722 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2729 void MapEditor::editVymLink()
2731 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2732 typeid(*selection) == typeid(MapCenterObj)) )
2734 BranchObj *bo=(BranchObj*)selection;
2735 Q3FileDialog *fd=new Q3FileDialog( this,__VYM " - " +tr("Link to another map"));
2736 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
2737 fd->setCaption(__VYM " - " +tr("Link to another map"));
2738 if (! bo->getVymLink().isEmpty() )
2739 fd->setSelection( bo->getVymLink() );
2743 if ( fd->exec() == QDialog::Accepted )
2747 "setVymLink (\""+bo->getVymLink()+"\")",
2749 "setVymLink (\""+fd->selectedFile()+"\")",
2750 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2752 bo->setVymLink (fd->selectedFile() );
2754 mapCenter->reposition();
2761 void MapEditor::deleteVymLink()
2763 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2764 typeid(*selection) == typeid(MapCenterObj)) )
2766 BranchObj *bo=(BranchObj*)selection;
2769 "setVymLink (\""+bo->getVymLink()+"\")",
2771 "setVymLink (\"\")",
2772 QString("Unset vymlink of %1").arg(getName(bo))
2774 bo->setVymLink ("" );
2776 mapCenter->reposition();
2782 void MapEditor::setHideExport(bool b)
2784 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2785 typeid(*selection)==typeid(FloatImageObj)))
2787 OrnamentedObj *oo=(OrnamentedObj*)selection;
2788 oo->setHideInExport (b);
2789 QString u= b ? "false" : "true";
2790 QString r=!b ? "false" : "true";
2794 QString ("setHideExport (%1)").arg(u),
2796 QString ("setHideExport (%1)").arg(r),
2797 QString ("Set HideExport flag of %1 to %2").arg(getName(oo)).arg (r)
2800 mapCenter->reposition();
2806 void MapEditor::toggleHideExport()
2808 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2809 typeid(*selection)==typeid(FloatImageObj)))
2810 setHideExport ( !((OrnamentedObj*)selection)->hideInExport() );
2813 QString MapEditor::getVymLink()
2815 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2816 typeid(*selection) == typeid(MapCenterObj)) )
2818 return ((BranchObj*)selection)->getVymLink();
2824 QStringList MapEditor::getVymLinks()
2827 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2828 typeid(*selection) == typeid(MapCenterObj)) )
2830 BranchObj *bo=(BranchObj*)selection;
2834 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2842 void MapEditor::deleteKeepChilds()
2844 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2846 BranchObj* bo=(BranchObj*)selection;
2847 BranchObj* par=(BranchObj*)(bo->getParObj());
2848 QPoint p=bo->getRelPos();
2849 saveStateChangingPart(
2850 selection->getParObj(),
2852 "deleteKeepChilds ()",
2853 QString("Remove %1 and keep its childs").arg(getName(bo))
2856 QString sel=selection->getSelectString();
2858 par->removeBranchHere(bo);
2859 mapCenter->reposition();
2861 ((BranchObj*)selection)->move2RelPos (p);
2862 mapCenter->reposition();
2867 void MapEditor::deleteChilds()
2869 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2870 typeid(*selection)==typeid(MapCenterObj)))
2872 saveStateChangingPart(
2873 selection->getParObj(),
2876 QString( "Remove childs of branch %1").arg(getName(selection))
2878 ((BranchObj*)selection)->removeChilds();
2879 mapCenter->reposition();
2883 void MapEditor::editMapInfo()
2885 ExtraInfoDialog dia;
2886 dia.setMapName (getFileName() );
2887 dia.setAuthor (mapCenter->getAuthor() );
2888 dia.setComment(mapCenter->getComment() );
2893 Q3CanvasItemList l=canvas()->allItems();
2894 for (Q3CanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
2896 stats+=QString ("%1 items on canvas\n").arg (i,6);
2903 bo=mapCenter->first();
2906 if (!bo->getNote().isEmpty() ) n++;
2907 f+= bo->countFloatImages();
2909 xl+=bo->countXLinks();
2912 stats+=QString ("%1 branches\n").arg (b-1,6);
2913 stats+=QString ("%1 xLinks \n").arg (xl,6);
2914 stats+=QString ("%1 notes\n").arg (n,6);
2915 stats+=QString ("%1 images\n").arg (f,6);
2916 dia.setStats (stats);
2918 // Finally show dialog
2919 if (dia.exec() == QDialog::Accepted)
2921 saveStateComplete("Edit info about map"); //TODO undoCommand
2922 mapCenter->setAuthor (dia.getAuthor() );
2923 mapCenter->setComment (dia.getComment() );
2927 void MapEditor::updateActions()
2929 mainWindow->updateActions();
2930 // FIXME maybe don't update if blockReposition is set
2933 void MapEditor::updateNoteFlag()
2936 if ( (typeid(*selection) == typeid(BranchObj)) ||
2937 (typeid(*selection) == typeid(MapCenterObj)) )
2938 ((BranchObj*)selection)->updateNoteFlag();
2941 void MapEditor::setLinkStyle (LinkStyle ls)
2945 saveStateComplete("Set link style"); // TODO undoCommand
2947 bo=mapCenter->first();
2951 bo->setLinkStyle(bo->getDefLinkStyle());
2954 mapCenter->reposition();
2957 LinkStyle MapEditor::getLinkStyle ()
2962 void MapEditor::setLinkColor(QColor c)
2968 void MapEditor::setLinkColorHint()
2970 // called from setLinkColorHint(lch) or at end of parse
2972 bo=mapCenter->first();
2980 void MapEditor::setLinkColorHint(LinkColorHint lch)
2986 void MapEditor::toggleLinkColorHint()
2988 if (linkcolorhint==HeadingColor)
2989 linkcolorhint=DefaultColor;
2991 linkcolorhint=HeadingColor;
2993 bo=mapCenter->first();
3001 LinkColorHint MapEditor::getLinkColorHint()
3003 return linkcolorhint;
3006 QColor MapEditor::getDefLinkColor()
3008 return defLinkColor;
3011 void MapEditor::setDefXLinkColor(QColor col)
3016 QColor MapEditor::getDefXLinkColor()
3018 return defXLinkColor;
3021 void MapEditor::setDefXLinkWidth (int w)
3026 int MapEditor::getDefXLinkWidth()
3028 return defXLinkWidth;
3031 void MapEditor::selectLinkColor()
3033 QColor col = QColorDialog::getColor( defLinkColor, this );
3034 if ( !col.isValid() ) return;
3035 setLinkColor( col );
3036 saveStateComplete(QString("Set link color to %1").arg(col.name())); //TODO undoCommand
3040 void MapEditor::toggleScroll()
3042 if (selection && (typeid(*selection) == typeid(BranchObj)) )
3044 BranchObj *bo=((BranchObj*)selection);
3045 if (bo->countBranches()==0) return;
3046 if (bo->getDepth()==0) return;
3048 if (bo->isScrolled())
3060 QString ("%1 ()").arg(u),
3062 QString ("%1 ()").arg(r),
3063 QString ("%1 %2").arg(r).arg(getName(bo))
3071 void MapEditor::unScrollAll()
3074 bo=mapCenter->first();
3077 if (bo->isScrolled()) bo->toggleScroll();
3082 void MapEditor::loadFloatImage ()
3085 (typeid(*selection) == typeid(BranchObj)) ||
3086 (typeid(*selection) == typeid(MapCenterObj)) )
3088 BranchObj *bo=((BranchObj*)selection);
3090 Q3FileDialog *fd=new Q3FileDialog( this);
3091 fd->setMode (Q3FileDialog::ExistingFiles);
3092 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3093 ImagePreview *p =new ImagePreview (fd);
3094 fd->setContentsPreviewEnabled( TRUE );
3095 fd->setContentsPreview( p, p );
3096 fd->setPreviewMode( Q3FileDialog::Contents );
3097 fd->setCaption(__VYM " - " +tr("Load image"));
3098 fd->setDir (lastImageDir);
3102 if ( fd->exec() == QDialog::Accepted )
3104 // FIXME in QT4 use: lastImageDir=fd->directory();
3105 lastImageDir=QDir (fd->dirPath());
3106 QStringList flist = fd->selectedFiles();
3107 QStringList::Iterator it = flist.begin();
3109 while( it != flist.end() )
3112 bo->addFloatImage();
3113 fio=bo->getLastFloatImage();
3115 // FIXME check if load of fio was successful
3117 (LinkableMapObj*)fio,
3120 QString ("loadFloatImage (%1)").arg(*it),
3121 QString("Add floatimage %1 to %2").arg(*it).arg(getName(selection))
3123 bo->getLastFloatImage()->setOriginalFilename(fn);
3127 mapCenter->reposition();
3136 void MapEditor::saveFloatImage ()
3139 (typeid(*selection) == typeid(FloatImageObj)) )
3141 FloatImageObj *fio=((FloatImageObj*)selection);
3142 QFileDialog *fd=new QFileDialog( this);
3143 fd->setFilters (imageIO.getFilters());
3144 fd->setCaption(__VYM " - " +tr("Save image"));
3145 fd->setFileMode( QFileDialog::AnyFile );
3146 fd->setDirectory (lastImageDir);
3147 // fd->setSelection (fio->getOriginalFilename());
3151 if ( fd->exec() == QDialog::Accepted )
3153 if (QFile (fd->selectedFile()).exists() )
3155 QMessageBox mb( __VYM,
3156 tr("The file %1 exists already.\n"
3157 "Do you want to overwrite it?").arg(fd->selectedFile()),
3158 QMessageBox::Warning,
3159 QMessageBox::Yes | QMessageBox::Default,
3160 QMessageBox::Cancel | QMessageBox::Escape,
3161 QMessageBox::QMessageBox::NoButton );
3163 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3164 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3167 case QMessageBox::Yes:
3170 case QMessageBox::Cancel:
3177 fio->save (fd->selectedFile(),imageIO.getType (fd->selectedFilter() ) );
3183 void MapEditor::setFrame(const FrameType &t)
3186 (typeid(*selection) == typeid(BranchObj)) ||
3187 (typeid(*selection) == typeid(MapCenterObj)) )
3189 selection->setFrameType (t);
3190 mapCenter->reposition();
3191 selection->updateLink();
3195 void MapEditor::setIncludeImagesVer(bool b)
3198 (typeid(*selection) == typeid(BranchObj)) ||
3199 (typeid(*selection) == typeid(MapCenterObj)) )
3200 ((BranchObj*)selection)->setIncludeImagesVer(b);
3201 mapCenter->reposition();
3204 void MapEditor::setIncludeImagesHor(bool b)
3207 (typeid(*selection) == typeid(BranchObj)) ||
3208 (typeid(*selection) == typeid(MapCenterObj)) )
3209 ((BranchObj*)selection)->setIncludeImagesHor(b);
3210 mapCenter->reposition();
3213 void MapEditor::setHideLinkUnselected (bool b)
3216 (typeid(*selection) == typeid(BranchObj)) ||
3217 (typeid(*selection) == typeid(MapCenterObj)) ||
3218 (typeid(*selection) == typeid(FloatImageObj)) )
3219 selection->setHideLinkUnselected(b);
3222 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3225 (typeid(*selection) == typeid(BranchObj)) ||
3226 (typeid(*selection) == typeid(MapCenterObj)) )
3230 // Traverse directories
3231 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3232 QFileInfoList list = d.entryInfoList();
3235 for (int i = 0; i < list.size(); ++i)
3238 if (fi.fileName() != "." && fi.fileName() != ".." )
3241 bo=dst->getLastBranch();
3242 bo->setHeading (fi.fileName() );
3243 bo->setColor (QColor("blue"));
3245 if ( !d.cd(fi.fileName()) )
3246 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3249 // Recursively add subdirs
3250 importDirInt (bo,d);
3256 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3257 list = d.entryInfoList();
3259 for (int i = 0; i < list.size(); ++i)
3263 bo=dst->getLastBranch();
3264 bo->setHeading (fi.fileName() );
3265 bo->setColor (QColor("black"));
3266 if (fi.fileName().right(4) == ".vym" )
3267 bo->setVymLink (fi.filePath());
3272 void MapEditor::importDir()
3275 (typeid(*selection) == typeid(BranchObj)) ||
3276 (typeid(*selection) == typeid(MapCenterObj)) )
3278 Q3FileDialog *fd=new Q3FileDialog( this,__VYM " - " +tr("Choose directory structure to import"));
3279 fd->setMode (Q3FileDialog::DirectoryOnly);
3280 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
3281 fd->setCaption(__VYM " - " +tr("Choose directory structure to import"));
3285 if ( fd->exec() == QDialog::Accepted )
3287 BranchObj *bo=((BranchObj*)selection);
3288 importDirInt (bo,QDir(fd->selectedFile()) );
3289 mapCenter->reposition();
3296 void MapEditor::followXLink(int i)
3299 (typeid(*selection) == typeid(BranchObj)) ||
3300 (typeid(*selection) == typeid(MapCenterObj)) )
3302 BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
3305 selection->unselect();
3307 selection->select();
3308 ensureSelectionVisible();
3313 void MapEditor::editXLink(int i)
3316 (typeid(*selection) == typeid(BranchObj)) ||
3317 (typeid(*selection) == typeid(MapCenterObj)) )
3319 XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
3322 EditXLinkDialog dia;
3324 dia.setSelection(selection);
3325 if (dia.exec() == QDialog::Accepted)
3327 if (dia.useSettingsGlobal() )
3329 setDefXLinkColor (xlo->getColor() );
3330 setDefXLinkWidth (xlo->getWidth() );
3332 if (dia.deleteXLink())
3333 ((BranchObj*)selection)->deleteXLinkAt(i);
3334 saveStateComplete("Edit xLink"); //TODO undoCommand
3340 void MapEditor::testFunction()
3342 cout << "MapEditor::testFunction() called\n";
3345 (typeid(*selection) == typeid(BranchObj)) ||
3346 (typeid(*selection) == typeid(MapCenterObj)) )
3348 BranchObj* bo=(BranchObj*)selection;
3349 cout << bo->getHeading().ascii() <<" is scrolled: "<<bo->isScrolled()<<endl;
3354 dia.showCancelButton (true);
3355 dia.setText("This is a longer \nWarning");
3357 dia.setCaption("Warning: Flux problem");
3358 dia.setShowAgainName("/warnings/mapeditor");
3360 if (dia.exec()==QDialog::Accepted)
3361 cout << "accepted!\n";
3363 cout << "canceled!\n";
3366 /* Hide hidden stuff temporary, maybe add this as regular function somewhere
3367 if (hidemode==HideNone)
3369 setHideTmpMode (HideExport);
3370 mapCenter->calcBBoxSizeWithChilds();
3371 QRect totalBBox=mapCenter->getTotalBBox();
3372 QRect mapRect=totalBBox;
3373 QCanvasRectangle *frame=NULL;
3375 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3377 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3378 totalBBox.width(), totalBBox.height());
3379 frame=new QCanvasRectangle (mapRect,mapCanvas);
3380 frame->setBrush (QColor(white));
3381 frame->setPen (QColor(black));
3387 setHideTmpMode (HideNone);
3389 cout <<" hidemode="<<hidemode<<endl;
3393 void MapEditor::ensureSelectionVisible()
3397 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
3399 if (selection->getOrientation() == OrientLeftOfCenter)
3400 p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
3402 p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
3403 ensureVisible (p.x(), p.y() );
3408 void MapEditor::updateViewCenter()
3410 // Update movingCenter, so that we can zoom comfortably later
3411 QRect rc = QRect( contentsX(), contentsY(),
3412 visibleWidth(), visibleHeight() );
3413 QRect canvasRect = inverseWorldMatrix().mapRect(rc);
3414 movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
3415 movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
3418 void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e )
3420 // Lineedits are already closed by preceding
3421 // mouseEvent, we don't need to close here.
3423 QPoint p = inverseWorldMatrix().map(e->pos());
3424 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3427 { // MapObj was found
3428 if (selection != lmo)
3430 // select the MapObj
3431 if (selection) selection->unselect();
3433 selection->select();
3439 if (typeid(*selection)==typeid(BranchObj) ||
3440 typeid(*selection)==typeid(MapCenterObj) )
3442 // Context Menu on branch or mapcenter
3444 branchContextMenu->popup(e->globalPos() );
3446 if (typeid(*selection)==typeid(FloatImageObj))
3448 // Context Menu on floatimage
3450 floatimageContextMenu->popup(e->globalPos() );
3454 { // No MapObj found, we are on the Canvas itself
3455 // Context Menu on Canvas
3457 canvasContextMenu->popup(e->globalPos() );
3462 void MapEditor::contentsMousePressEvent(QMouseEvent* e)
3464 // Ignore right clicks, these will go to context menus
3465 if (e->button() == Qt::RightButton )
3471 QPoint p = inverseWorldMatrix().map(e->pos());
3472 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3476 //Take care of clickdesystem flags _or_ modifier modes
3478 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3479 typeid(*lmo)==typeid(MapCenterObj) ))
3481 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3482 if (!foname.isEmpty())
3484 // systemFlag clicked
3488 if (e->state() & Qt::ControlModifier)
3489 mainWindow->editOpenURLTab();
3491 mainWindow->editOpenURL();
3493 else if (foname=="vymLink")
3495 mainWindow->editOpenVymLink();
3496 // tabWidget may change, better return now
3497 // before segfaulting...
3498 } else if (foname=="note")
3499 mainWindow->windowToggleNoteEditor();
3500 else if (foname=="hideInExport")
3505 // No system flag clicked, take care of modmodes
3507 // Special case: CTRL is pressed
3508 if (e->state() & Qt::ControlModifier)
3510 if (mainWindow->getModMode()==ModModeColor)
3513 setCursor (pickColorCursor);
3516 if (mainWindow->getModMode()==ModModeXLink)
3518 BranchObj *bo_begin=NULL;
3520 bo_begin=(BranchObj*)(lmo);
3523 ((typeid(*selection) == typeid(BranchObj)) ||
3524 (typeid(*selection) == typeid(MapCenterObj))) )
3525 bo_begin=(BranchObj*)selection;
3529 linkingObj_src=bo_begin;
3530 tmpXLink=new XLinkObj (mapCanvas);
3531 tmpXLink->setBegin (bo_begin);
3532 tmpXLink->setEnd (p);
3533 tmpXLink->setColor(defXLinkColor);
3534 tmpXLink->setWidth(defXLinkWidth);
3535 tmpXLink->updateXLink();
3536 tmpXLink->setVisibility (true);
3544 // Left Button Move Branches
3545 if (e->button() == Qt::LeftButton )
3547 movingObj_start.setX( p.x() - selection->x() );
3548 movingObj_start.setY( p.y() - selection->y() );
3549 movingObj_orgPos.setX (lmo->x() );
3550 movingObj_orgPos.setY (lmo->y() );
3551 movingObj_orgRelPos=lmo->getRelPos();
3553 // If modMode==copy, then we want to "move" the _new_ object around
3554 // then we need the offset from p to the _old_ selection, because of tmp
3555 if (mainWindow->getModMode()==ModModeCopy &&
3556 e->state() & Qt::ControlModifier)
3558 if (typeid(*selection)==typeid(BranchObj) )
3561 mapCenter->addBranch ((BranchObj*)selection);
3563 selection=mapCenter->getLastBranch();
3564 selection->select();
3565 mapCenter->reposition();
3568 movingObj=selection;
3570 // Middle Button Toggle Scroll
3571 // (On Mac OS X this won't work, but we still have
3572 // a button in the toolbar)
3573 if (e->button() == Qt::MidButton )
3577 { // No MapObj found, we are on the Canvas itself
3578 // Left Button move Pos of CanvasView
3579 if (e->button() == Qt::LeftButton )
3581 movingObj=NULL; // move Content not Obj
3582 movingObj_start=e->globalPos();
3583 movingCont_start=QPoint (contentsX(), contentsY() );
3584 movingVec=QPoint(0,0);
3585 setCursor(handOpenCursor);
3590 void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
3592 QPoint p = inverseWorldMatrix().map(e->pos());
3594 // Move the selected MapObj
3595 if ( selection && movingObj)
3597 // To avoid jumping of the CanvasView, only
3598 // ensureSelectionVisible, if not tmp linked
3599 if (!selection->hasParObjTmp())
3600 ensureSelectionVisible ();
3602 // Now move the selection, but add relative position
3603 // (movingObj_start) where selection was chosen with
3604 // mousepointer. (This avoids flickering resp. jumping
3605 // of selection back to absPos)
3607 LinkableMapObj *lmosel;
3608 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3610 // Check if we could link
3611 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3614 if (typeid(*selection) == typeid(FloatImageObj))
3616 FloatObj *fo=(FloatObj*)selection;
3617 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3621 // Relink float to new mapcenter or branch, if shift is pressed
3622 // Only relink, if selection really has a new parent
3623 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3624 ( (typeid(*lmo)==typeid(BranchObj)) ||
3625 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3626 ( lmo != fo->getParObj())
3629 if (typeid(*fo) == typeid(FloatImageObj))
3632 saveStateComplete(QString("Relink %1 to %2").arg(getName(fo)).arg(getName(lmo) ) );
3633 FloatImageObj *fio=(FloatImageObj*)(fo);
3634 ((BranchObj*)(lmo))->addFloatImage (fio);
3636 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
3637 fio=((BranchObj*)(lmo))->getLastFloatImage();
3640 selection=(LinkableMapObj*)(fio);
3641 selection->select();
3642 movingObj=(MapObj*)(fio);
3646 { // selection != a FloatObj
3647 if (lmosel->getDepth()==0)
3650 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3651 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3653 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3654 mapCenter->updateRelPositions();
3657 if (lmosel->getDepth()==1)
3660 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3661 lmosel->setRelPos();
3664 // Move ordinary branch
3665 if (lmosel->getOrientation() == OrientLeftOfCenter)
3666 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3667 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3668 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3670 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3672 // reposition subbranch
3673 lmosel->reposition();
3675 if (lmo && (lmo!=selection) &&
3676 (typeid(*lmo) == typeid(BranchObj) ||
3677 (typeid(*lmo) == typeid(MapCenterObj) )
3680 if (e->modifiers()==Qt::ControlModifier)
3682 // Special case: CTRL to link below lmo
3683 lmosel->setParObjTmp (lmo,p,+1);
3685 else if (e->modifiers()==Qt::ShiftModifier)
3686 lmosel->setParObjTmp (lmo,p,-1);
3688 lmosel->setParObjTmp (lmo,p,0);
3691 lmosel->unsetParObjTmp();
3695 } // no FloatImageObj
3699 } // selection && moving_obj
3701 // Draw a link from one branch to another
3704 tmpXLink->setEnd (p);
3705 tmpXLink->updateXLink();
3709 if (!movingObj && !pickingColor &&!drawingLink)
3711 QPoint p=e->globalPos();
3712 movingVec.setX(-p.x() + movingObj_start.x() );
3713 movingVec.setY(-p.y() + movingObj_start.y() );
3714 setContentsPos( movingCont_start.x() + movingVec.x(),
3715 movingCont_start.y() + movingVec.y());
3722 void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e)
3724 LinkableMapObj *dst;
3725 // Have we been picking color?
3729 setCursor (Qt::ArrowCursor);
3730 // Check if we are over another branch
3731 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3732 if (dst && selection)
3734 if (e->state() & Qt::ShiftModifier)
3736 ((BranchObj*)selection)->setColor (((BranchObj*)(dst))->getColor());
3737 ((BranchObj*)selection)->setLinkColor ();
3741 ((BranchObj*)selection)->setColorChilds (((BranchObj*)(dst))->getColor());
3742 ((BranchObj*)selection)->setLinkColor ();
3748 // Have we been drawing a link?
3752 // Check if we are over another branch
3753 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3754 if (dst && selection)
3756 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3757 tmpXLink->updateXLink();
3758 tmpXLink->activate();
3759 saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //TODO undoCommand
3768 // Have we been moving something?
3769 if ( selection && movingObj )
3771 if(typeid(*selection)==typeid (FloatImageObj))
3773 // Moved FloatObj. Maybe we need to reposition
3774 FloatImageObj *fo=(FloatImageObj*)selection;
3775 QString pold=qpointToString(movingObj_orgRelPos);
3776 QString pnow=qpointToString(fo->getRelPos());
3782 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(pnow));
3784 // FIXME Why calling parObj here?
3785 selection->getParObj()->requestReposition();
3786 mapCenter->reposition();
3789 // Check if we are over another branch, but ignore
3790 // any found LMOs, which are FloatObjs
3791 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ),
3792 ((LinkableMapObj*)selection) );
3794 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3797 if (typeid(*selection) == typeid(MapCenterObj) )
3798 { // The MapCenter was moved
3799 cout << "FIXME missing savestate...\n";
3802 if (typeid(*selection) == typeid(BranchObj) )
3803 { // A branch was moved
3805 // save the position in case we link to mapcenter
3806 QPoint savePos=QPoint (selection->x(),selection->y() );
3808 // Reset the temporary drawn link to the original one
3809 ((LinkableMapObj*)selection)->unsetParObjTmp();
3811 // For Redo we may need to save original selection
3812 QString preSelStr=selection->getSelectString();
3817 BranchObj* bsel=(BranchObj*)selection;
3818 BranchObj* bdst=(BranchObj*)dst;
3820 QString preParStr=(bsel->getParObj())->getSelectString();
3821 QString preNum=QString::number (bsel->getNum(),10);
3822 QString preDstParStr;
3824 if (e->state() & Qt::ShiftModifier && dst->getParObj())
3826 preDstParStr=dst->getParObj()->getSelectString();
3827 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
3829 if (e->state() & Qt::ControlModifier && dst->getParObj())
3832 preDstParStr=dst->getParObj()->getSelectString();
3833 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
3836 preDstParStr=dst->getSelectString();
3837 bsel->moveBranchTo (bdst,-1);
3838 if (dst->getDepth()==0) bsel->move (savePos);
3840 QString postSelStr=selection->getSelectString();
3841 QString postNum=QString::number (bsel->getNum(),10);
3843 QString undoCom="linkBranchToPos (\""+
3844 preParStr+ "\"," + preNum +"," +
3845 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
3847 QString redoCom="linkBranchToPos (\""+
3848 preDstParStr + "\"," + postNum + "," +
3849 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
3854 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
3856 if (selection->getDepth()==1)
3858 // The select string might be different _after_ moving around.
3859 // Therefor reposition and then use string of old selection, too
3860 mapCenter->reposition();
3862 QString ps=qpointToString ( ((BranchObj*)selection)->getRelPos() );
3864 selection->getSelectString(), "moveRel "+qpointToString(movingObj_orgRelPos),
3865 preSelStr, "moveRel "+ps,
3866 QString("Move %1 to relative position %2").arg(getName(selection)).arg(ps));
3869 // Draw the original link, before selection was moved around
3870 mapCenter->reposition();
3872 // Finally resize canvas, if needed
3877 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
3880 // maybe we moved View: set old cursor
3881 setCursor (Qt::ArrowCursor);
3885 void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
3887 if (e->button() == Qt::LeftButton )
3889 QPoint p = inverseWorldMatrix().map(e->pos());
3890 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3891 if (lmo) { // MapObj was found
3892 // First select the MapObj than edit heading
3893 if (selection) selection->unselect();
3895 selection->select();
3896 mainWindow->editHeading();
3901 void MapEditor::resizeEvent (QResizeEvent* e)
3903 Q3CanvasView::resizeEvent( e );
3907 void MapEditor::contentsDragEnterEvent(QDragEnterEvent *event)
3910 // for (unsigned int i=0;event->format(i);i++) // Debug mime type
3911 // cerr << event->format(i) << endl;
3914 (typeid(*selection) == typeid(BranchObj)) ||
3915 (typeid(*selection) == typeid(MapCenterObj))) {
3917 // If QImageDrag can decode mime type
3918 if (Q3ImageDrag::canDecode(event)) {
3923 // If image are dragged from firefox
3924 if (event->provides("application/x-moz-file-promise-url") &&
3925 event->provides("application/x-moz-nativeimage")) {
3926 event->accept(true);
3930 // If QUriDrag can decode mime type
3931 if (Q3UriDrag::canDecode(event)) {
3936 // If Uri are dragged from firefox
3937 if (event->provides("_NETSCAPE_URL")){
3942 // If QTextDrag can decode mime type
3943 if (Q3TextDrag::canDecode(event)) {
3952 bool isUnicode16(const QByteArray &d)
3954 // TODO: make more precise check for unicode 16.
3955 // Guess unicode16 if any of second bytes are zero
3956 unsigned int length = max(0,d.size()-2)/2;
3957 for (unsigned int i = 0; i<length ; i++)
3958 if (d.at(i*2+1)==0) return true;
3962 void MapEditor::contentsDropEvent(QDropEvent *event)
3965 (typeid(*selection) == typeid(BranchObj)) ||
3966 (typeid(*selection) == typeid(MapCenterObj)))
3971 if (event->provides("image/png"))
3974 if (Q3ImageDrag::decode(event, pix))
3976 addFloatImageInt(pix);
3982 } else if (event->provides("application/x-moz-file-promise-url") &&
3983 event->provides("application/x-moz-nativeimage"))
3985 // Contains url to the img src in unicode16
3986 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
3987 QString url = QString((const QChar*)d.data(),d.size()/2);
3991 } else if (event->provides ("text/uri-list"))
3992 { // Uris provided e.g. by konqueror
3993 Q3UriDrag::decode (event,uris);
3994 } else if (event->provides ("_NETSCAPE_URL"))
3995 { // Uris provided by Mozilla
3996 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
3999 } else if (event->provides("text/html")) {
4001 // Handels text mime types
4002 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4003 QByteArray d = event->encodedData("text/html");
4006 text = QString((const QChar*)d.data(),d.size()/2);
4010 textEditor->setText(text);
4014 } else if (event->provides("text/plain")) {
4015 QByteArray d = event->encodedData("text/plain");
4018 text = QString((const QChar*)d.data(),d.size()/2);
4022 textEditor->setText(text);
4034 for (const char* u=uris.first(); u; u=uris.next())
4036 bo=((BranchObj*)selection)->addBranch();
4039 s=Q3UriDrag::uriToLocalFile(u);
4042 QString file = QDir::convertSeparators(s);
4043 heading = QFileInfo(file).baseName();
4045 if (file.endsWith(".vym", false))
4046 bo->setVymLink(file);
4055 if (!heading.isEmpty())
4056 bo->setHeading(heading);
4066 //FIXME saveState has to be called earlier for each of the drops...
4067 saveStateComplete("Drop Event"); //TODO undo Command
4068 mapCenter->reposition();
4075 void MapEditor::addFloatImageInt (const QPixmap &img)
4078 (typeid(*selection) == typeid(BranchObj)) ||
4079 (typeid(*selection) == typeid(MapCenterObj)) )
4081 BranchObj *bo=((BranchObj*)selection);
4082 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4083 //QString fn=fd->selectedFile();
4084 //lastImageDir=fn.left(fn.findRev ("/"));
4085 FloatImageObj *fio=bo->addFloatImage();
4087 fio->setOriginalFilename("Image added by Drag and Drop");
4088 mapCenter->reposition();
4095 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation */*nop*/)
4097 if (!imageBuffer) imageBuffer = new QBuffer();
4098 if (!imageBuffer->isOpen()) {
4099 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4101 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4105 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4107 if (nop->state()==Q3NetworkProtocol::StDone) {
4108 QPixmap img(imageBuffer->buffer());
4109 addFloatImageInt (img);
4113 imageBuffer->close();
4115 imageBuffer->close();
4122 void MapEditor::fetchImage(const QString &url)
4125 urlOperator->stop();
4126 disconnect(urlOperator);
4130 urlOperator = new Q3UrlOperator(url);
4131 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4132 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4134 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4135 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));