3 #include <q3filedialog.h>
12 #include "editxlinkdialog.h"
14 #include "extrainfodialog.h"
16 #include "linkablemapobj.h"
17 #include "mainwindow.h"
19 #include "texteditor.h"
20 #include "warningdialog.h"
24 extern TextEditor *textEditor;
25 extern int statusbarTime;
26 extern Main *mainWindow;
27 extern QString tmpVymDir;
28 extern QString clipboardDir;
29 extern bool clipboardEmpty;
31 extern FlagRowObj *standardFlagsDefault;
33 extern QMenu* branchContextMenu;
34 extern QMenu* branchAddContextMenu;
35 extern QMenu* branchRemoveContextMenu;
36 extern QMenu* branchLinksContextMenu;
37 extern QMenu* branchXLinksContextMenuEdit;
38 extern QMenu* branchXLinksContextMenuFollow;
39 extern QMenu* floatimageContextMenu;
40 extern QMenu* canvasContextMenu;
43 extern Settings settings;
44 extern ImageIO imageIO;
46 extern QString vymName;
47 extern QString vymVersion;
49 extern QString iconPath;
50 extern QDir vymBaseDir;
51 extern QDir lastImageDir;
52 extern QDir lastFileDir;
54 int MapEditor::mapNum=0; // make instance
56 ///////////////////////////////////////////////////////////////////////
57 ///////////////////////////////////////////////////////////////////////
58 MapEditor::MapEditor( QWidget* parent) :
61 //cout << "Constructor ME "<<this<<endl;
65 mapScene= new QGraphicsScene(parent);
66 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
67 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
72 mapCenter = new MapCenterObj(mapScene);
73 mapCenter->setVisibility (true);
74 mapCenter->setMapEditor (this);
75 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
76 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
81 defLinkColor=QColor (0,0,255);
82 defXLinkColor=QColor (180,180,180);
83 linkcolorhint=LinkableMapObj::DefaultColor;
84 linkstyle=LinkableMapObj::PolyParabel;
86 // Create bitmap cursors, platform dependant
87 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
88 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
89 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
90 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
92 setFocusPolicy (Qt::StrongFocus);
101 xelection.setMapEditor (this);
102 xelection.unselect();
105 defXLinkColor=QColor (230,230,230);
113 fileName=tr("unnamed");
116 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
117 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
119 // Initialize find routine
126 blockReposition=false;
127 blockSaveState=false;
129 hidemode=BranchObj::HideNone;
131 // Create temporary files
134 setAcceptDrops (true);
136 mapCenter->reposition(); // for positioning heading
140 //timerId = startTimer(100);
143 autosaveTimer=new QTimer (this);
144 connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
147 MapEditor::~MapEditor()
149 //cout <<"Destructor MapEditor\n";
150 autosaveTimer->stop();
153 MapCenterObj* MapEditor::getMapCenter()
158 QGraphicsScene * MapEditor::getScene()
163 bool MapEditor::isRepositionBlocked()
165 return blockReposition;
168 void MapEditor::setSaveStateBlocked(bool b)
173 QString MapEditor::getName (const LinkableMapObj *lmo)
176 if (!lmo) return QString("Error: NULL has no name!");
178 if ((typeid(*lmo) == typeid(BranchObj) ||
179 typeid(*lmo) == typeid(MapCenterObj)))
182 s=(((BranchObj*)lmo)->getHeading());
183 if (s=="") s="unnamed";
184 return QString("branch (%1)").arg(s);
185 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
187 if ((typeid(*lmo) == typeid(FloatImageObj) ))
188 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
189 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
190 return QString("Unknown type has no name!");
193 void MapEditor::makeTmpDirs()
195 // Create unique temporary directories
196 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
197 histPath=QDir::convertSeparators (tmpMapDir+"/history");
202 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
204 // tmpdir temporary directory to which data will be written
205 // prefix mapname, which will be appended to images etc.
206 // writeflags Only write flags for "real" save of map, not undo
207 // offset offset of bbox of whole map in scene.
208 // Needed for XML export
214 case LinkableMapObj::Line:
217 case LinkableMapObj::Parabel:
220 case LinkableMapObj::PolyLine:
224 ls="StylePolyParabel";
228 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
230 if (linkcolorhint==LinkableMapObj::HeadingColor)
231 colhint=attribut("linkColorHint","HeadingColor");
233 QString mapAttr=attribut("version",vymVersion);
234 if (!saveSel || saveSel==mapCenter)
235 mapAttr+= attribut("author",mapCenter->getAuthor()) +
236 attribut("comment",mapCenter->getComment()) +
237 attribut("date",mapCenter->getDate()) +
238 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
239 attribut("selectionColor", xelection.getColor().name() ) +
240 attribut("linkStyle", ls ) +
241 attribut("linkColor", defLinkColor.name() ) +
242 attribut("defXLinkColor", defXLinkColor.name() ) +
243 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
245 s+=beginElement("vymmap",mapAttr);
248 // Find the used flags while traversing the tree
249 standardFlagsDefault->resetUsedCounter();
251 // Reset the counters before saving
252 // TODO constr. of FIO creates lots of objects, better do this in some other way...
253 FloatImageObj (mapScene).resetSaveCounter();
255 // Build xml recursivly
256 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
257 // Save complete map, if saveSel not set
258 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
261 if ( typeid(*saveSel) == typeid(BranchObj) )
263 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
264 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
266 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
269 // Save local settings
270 s+=settings.getXMLData (destPath);
273 if (!xelection.isEmpty() && !saveSel )
274 s+=valueElement("select",xelection.getSelectString());
277 s+=endElement("vymmap");
280 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
284 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
288 if (blockSaveState) return;
290 /* TODO remove after testing
292 if (debug) cout << "ME::saveState() for "<<mapName.ascii()<<endl;
294 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
295 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
296 int curStep=undoSet.readNumEntry ("/history/curStep",0);
297 // Find out current undo directory
298 if (undosAvail<stepsTotal) undosAvail++;
300 if (curStep>stepsTotal) curStep=1;
302 QString backupXML="";
303 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
304 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
305 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
307 // Create bakMapDir if not available
310 makeSubDirs (bakMapDir);
312 // Save depending on how much needs to be saved
314 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPointF (),saveSel);
316 QString undoCommand="";
317 if (savemode==UndoCommand)
321 else if (savemode==PartOfMap )
324 undoCommand.replace ("PATH",bakMapPath);
327 if (!backupXML.isEmpty())
328 // Write XML Data to disk
329 saveStringToDisk (QString(bakMapPath),backupXML);
331 // We would have to save all actions in a tree, to keep track of
332 // possible redos after a action. Possible, but we are too lazy: forget about redos.
335 // Write the current state to disk
336 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
337 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
338 undoSet.setEntry ("/history/curStep",QString::number(curStep));
339 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
340 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
341 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
342 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
343 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
344 undoSet.setEntry (QString("/history/version"),vymVersion);
345 undoSet.writeSettings(histPath);
349 // TODO remove after testing
350 //cout << " into="<< histPath.toStdString()<<endl;
351 cout << " stepsTotal="<<stepsTotal<<
352 ", undosAvail="<<undosAvail<<
353 ", redosAvail="<<redosAvail<<
354 ", curStep="<<curStep<<endl;
355 cout << " ---------------------------"<<endl;
356 cout << " comment="<<comment.toStdString()<<endl;
357 cout << " undoCom="<<undoCommand.toStdString()<<endl;
358 cout << " undoSel="<<undoSelection.toStdString()<<endl;
359 cout << " redoCom="<<redoCom.toStdString()<<endl;
360 cout << " redoSel="<<redoSelection.toStdString()<<endl;
361 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
362 cout << " ---------------------------"<<endl;
365 mainWindow->updateHistory (undoSet);
371 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
373 // save the selected part of the map, Undo will replace part of map
374 QString undoSelection="";
376 undoSelection=undoSel->getSelectString();
378 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
379 QString redoSelection="";
381 redoSelection=undoSel->getSelectString();
383 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
386 saveState (PartOfMap,
387 undoSelection, "addMapReplace (\"PATH\")",
393 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
397 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
400 QString undoSelection=redoSel->getParObj()->getSelectString();
401 QString redoSelection=redoSel->getSelectString();
402 if (typeid(*redoSel) == typeid(BranchObj) )
404 // save the selected branch of the map, Undo will insert part of map
405 saveState (PartOfMap,
406 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
407 redoSelection, "delete ()",
414 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
416 // "Normal" savestate: save commands, selections and comment
417 // so just save commands for undo and redo
418 // and use current selection
420 QString redoSelection="";
421 if (redoSel) redoSelection=redoSel->getSelectString();
422 QString undoSelection="";
423 if (undoSel) undoSelection=undoSel->getSelectString();
425 saveState (UndoCommand,
432 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
434 // "Normal" savestate: save commands, selections and comment
435 // so just save commands for undo and redo
436 // and use current selection
437 saveState (UndoCommand,
445 void MapEditor::parseAtom(const QString &atom)
447 BranchObj *selb=xelection.getBranch();
452 // Split string s into command and parameters
453 parser.parseAtom (atom);
454 QString com=parser.getCommand();
457 if (com=="addBranch")
459 if (xelection.isEmpty())
461 parser.setError (Aborted,"Nothing selected");
464 parser.setError (Aborted,"Type of selection is not a branch");
469 if (parser.checkParamCount(pl))
471 if (parser.paramCount()==0)
472 addNewBranchInt (-2);
475 y=parser.parInt (ok,0);
476 if (ok ) addNewBranchInt (y);
480 } else if (com=="addBranchBefore")
482 if (xelection.isEmpty())
484 parser.setError (Aborted,"Nothing selected");
487 parser.setError (Aborted,"Type of selection is not a branch");
490 if (parser.paramCount()==0)
492 addNewBranchBefore ();
495 } else if (com==QString("addMapReplace"))
497 if (xelection.isEmpty())
499 parser.setError (Aborted,"Nothing selected");
502 parser.setError (Aborted,"Type of selection is not a branch");
503 } else if (parser.checkParamCount(1))
505 //s=parser.parString (ok,0); // selection
506 t=parser.parString (ok,0); // path to map
507 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
508 addMapReplaceInt(selb->getSelectString(),t);
510 } else if (com==QString("addMapInsert"))
512 if (xelection.isEmpty())
514 parser.setError (Aborted,"Nothing selected");
517 parser.setError (Aborted,"Type of selection is not a branch");
520 if (parser.checkParamCount(2))
522 t=parser.parString (ok,0); // path to map
523 y=parser.parInt(ok,1); // position
524 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
525 addMapInsertInt(t,y);
528 } else if (com=="clearFlags")
530 if (xelection.isEmpty() )
532 parser.setError (Aborted,"Nothing selected");
535 parser.setError (Aborted,"Type of selection is not a branch");
536 } else if (parser.checkParamCount(0))
538 selb->clearStandardFlags();
539 selb->updateFlagsToolbar();
541 } else if (com=="colorBranch")
543 if (xelection.isEmpty())
545 parser.setError (Aborted,"Nothing selected");
548 parser.setError (Aborted,"Type of selection is not a branch");
549 } else if (parser.checkParamCount(1))
551 QColor c=parser.parColor (ok,0);
552 if (ok) colorBranch (c);
554 } else if (com=="colorSubtree")
556 if (xelection.isEmpty())
558 parser.setError (Aborted,"Nothing selected");
561 parser.setError (Aborted,"Type of selection is not a branch");
562 } else if (parser.checkParamCount(1))
564 QColor c=parser.parColor (ok,0);
565 if (ok) colorSubtree (c);
567 } else if (com=="cut")
569 if (xelection.isEmpty())
571 parser.setError (Aborted,"Nothing selected");
572 } else if ( xelection.type()!=Branch &&
573 xelection.type()!=MapCenter &&
574 xelection.type()!=FloatImage )
576 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
577 } else if (parser.checkParamCount(0))
581 } else if (com=="delete")
583 if (xelection.isEmpty())
585 parser.setError (Aborted,"Nothing selected");
586 } else if (xelection.type() != Branch && xelection.type() != FloatImage )
588 parser.setError (Aborted,"Type of selection is wrong.");
589 } else if (parser.checkParamCount(0))
593 } else if (com=="deleteKeepChilds")
595 if (xelection.isEmpty())
597 parser.setError (Aborted,"Nothing selected");
600 parser.setError (Aborted,"Type of selection is not a branch");
601 } else if (parser.checkParamCount(0))
605 } else if (com=="deleteChilds")
607 if (xelection.isEmpty())
609 parser.setError (Aborted,"Nothing selected");
612 parser.setError (Aborted,"Type of selection is not a branch");
613 } else if (parser.checkParamCount(0))
617 } else if (com=="linkTo")
619 if (xelection.isEmpty())
621 parser.setError (Aborted,"Nothing selected");
624 if (parser.checkParamCount(4))
626 // 0 selectstring of parent
627 // 1 num in parent (for branches)
628 // 2,3 x,y of mainbranch or mapcenter
629 s=parser.parString(ok,0);
630 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
633 if (typeid(*dst) == typeid(BranchObj) )
635 // Get number in parent
636 x=parser.parInt (ok,1);
638 selb->linkTo ((BranchObj*)(dst),x);
639 } else if (typeid(*dst) == typeid(MapCenterObj) )
641 selb->linkTo ((BranchObj*)(dst),-1);
642 // Get coordinates of mainbranch
643 x=parser.parInt (ok,2);
646 y=parser.parInt (ok,3);
647 if (ok) selb->move (x,y);
652 } else if ( xelection.type() == FloatImage)
654 if (parser.checkParamCount(1))
656 // 0 selectstring of parent
657 s=parser.parString(ok,0);
658 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
661 if (typeid(*dst) == typeid(BranchObj) ||
662 typeid(*dst) == typeid(MapCenterObj))
663 linkTo (dst->getSelectString());
665 parser.setError (Aborted,"Destination is not a branch");
668 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
669 } else if (com=="loadImage")
671 if (xelection.isEmpty())
673 parser.setError (Aborted,"Nothing selected");
676 parser.setError (Aborted,"Type of selection is not a branch");
677 } else if (parser.checkParamCount(1))
679 s=parser.parString(ok,0);
680 if (ok) loadFloatImageInt (s);
682 } else if (com=="moveBranchUp")
684 if (xelection.isEmpty() )
686 parser.setError (Aborted,"Nothing selected");
689 parser.setError (Aborted,"Type of selection is not a branch");
690 } else if (parser.checkParamCount(0))
694 } else if (com=="moveBranchDown")
696 if (xelection.isEmpty() )
698 parser.setError (Aborted,"Nothing selected");
701 parser.setError (Aborted,"Type of selection is not a branch");
702 } else if (parser.checkParamCount(0))
706 } else if (com=="move")
708 if (xelection.isEmpty() )
710 parser.setError (Aborted,"Nothing selected");
711 } else if ( xelection.type()!=Branch &&
712 xelection.type()!=MapCenter &&
713 xelection.type()!=FloatImage )
715 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
716 } else if (parser.checkParamCount(2))
718 x=parser.parInt (ok,0);
721 y=parser.parInt (ok,1);
725 } else if (com=="moveRel")
727 if (xelection.isEmpty() )
729 parser.setError (Aborted,"Nothing selected");
730 } else if ( xelection.type()!=Branch &&
731 xelection.type()!=MapCenter &&
732 xelection.type()!=FloatImage )
734 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
735 } else if (parser.checkParamCount(2))
737 x=parser.parInt (ok,0);
740 y=parser.parInt (ok,1);
741 if (ok) moveRel (x,y);
744 } else if (com=="paste")
746 if (xelection.isEmpty() )
748 parser.setError (Aborted,"Nothing selected");
751 parser.setError (Aborted,"Type of selection is not a branch");
752 } else if (parser.checkParamCount(0))
756 } else if (com=="saveImage")
758 FloatImageObj *fio=xelection.getFloatImage();
761 parser.setError (Aborted,"Type of selection is not an image");
762 } else if (parser.checkParamCount(2))
764 s=parser.parString(ok,0);
767 t=parser.parString(ok,1);
768 if (ok) saveFloatImageInt (fio,t,s);
771 } else if (com=="scroll")
773 if (xelection.isEmpty() )
775 parser.setError (Aborted,"Nothing selected");
778 parser.setError (Aborted,"Type of selection is not a branch");
779 } else if (parser.checkParamCount(0))
781 if (!scrollBranch (selb))
782 parser.setError (Aborted,"Could not scroll branch");
784 } else if (com=="select")
786 if (parser.checkParamCount(1))
788 s=parser.parString(ok,0);
791 } else if (com=="selectLastBranch")
793 if (xelection.isEmpty() )
795 parser.setError (Aborted,"Nothing selected");
798 parser.setError (Aborted,"Type of selection is not a branch");
799 } else if (parser.checkParamCount(0))
801 BranchObj *bo=selb->getLastBranch();
803 parser.setError (Aborted,"Could not select last branch");
807 } else if (com=="selectLastImage")
809 if (xelection.isEmpty() )
811 parser.setError (Aborted,"Nothing selected");
814 parser.setError (Aborted,"Type of selection is not a branch");
815 } else if (parser.checkParamCount(0))
817 FloatImageObj *fio=selb->getLastFloatImage();
819 parser.setError (Aborted,"Could not select last image");
823 } else if (com=="setFrameType")
825 if ( xelection.type()!=Branch && xelection.type()!= MapCenter && xelection.type()!=FloatImage)
827 parser.setError (Aborted,"Type of selection does not allow setting frame type");
829 else if (parser.checkParamCount(1))
831 s=parser.parString(ok,0);
832 if (ok) setFrameType (s);
834 } else if (com=="setFramePenColor")
836 if ( xelection.type()!=Branch && xelection.type()!= MapCenter && xelection.type()!=FloatImage)
838 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
840 else if (parser.checkParamCount(1))
842 QColor c=parser.parColor(ok,0);
843 if (ok) setFramePenColor (c);
845 } else if (com=="setFrameBrushColor")
847 if ( xelection.type()!=Branch && xelection.type()!= MapCenter && xelection.type()!=FloatImage)
849 parser.setError (Aborted,"Type of selection does not allow setting brush color");
851 else if (parser.checkParamCount(1))
853 QColor c=parser.parColor(ok,0);
854 if (ok) setFrameBrushColor (c);
856 } else if (com=="setFramePadding")
858 if ( xelection.type()!=Branch && xelection.type()!= MapCenter && xelection.type()!=FloatImage)
860 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
862 else if (parser.checkParamCount(1))
864 x=parser.parInt(ok,0);
865 if (ok) setFramePadding(x);
867 } else if (com=="setFrameBorderWidth")
869 if ( xelection.type()!=Branch && xelection.type()!= MapCenter && xelection.type()!=FloatImage)
871 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
873 else if (parser.checkParamCount(1))
875 x=parser.parInt(ok,0);
876 if (ok) setFrameBorderWidth (x);
878 } else if (com=="setMapAuthor")
880 if (parser.checkParamCount(1))
882 s=parser.parString(ok,0);
883 if (ok) setMapAuthor (s);
885 } else if (com=="setMapComment")
887 if (parser.checkParamCount(1))
889 s=parser.parString(ok,0);
890 if (ok) setMapComment(s);
892 } else if (com=="setMapBackgroundColor")
894 if (xelection.isEmpty() )
896 parser.setError (Aborted,"Nothing selected");
897 } else if (! xelection.getBranch() )
899 parser.setError (Aborted,"Type of selection is not a branch");
900 } else if (parser.checkParamCount(1))
902 QColor c=parser.parColor (ok,0);
903 if (ok) setMapBackgroundColor (c);
905 } else if (com=="setMapDefLinkColor")
907 if (xelection.isEmpty() )
909 parser.setError (Aborted,"Nothing selected");
912 parser.setError (Aborted,"Type of selection is not a branch");
913 } else if (parser.checkParamCount(1))
915 QColor c=parser.parColor (ok,0);
916 if (ok) setMapDefLinkColor (c);
918 } else if (com=="setMapLinkStyle")
920 if (parser.checkParamCount(1))
922 s=parser.parString (ok,0);
923 if (ok) setMapLinkStyle(s);
925 } else if (com=="setHeading")
927 if (xelection.isEmpty() )
929 parser.setError (Aborted,"Nothing selected");
932 parser.setError (Aborted,"Type of selection is not a branch");
933 } else if (parser.checkParamCount(1))
935 s=parser.parString (ok,0);
939 } else if (com=="setHideExport")
941 if (xelection.isEmpty() )
943 parser.setError (Aborted,"Nothing selected");
944 } else if (xelection.type()!=Branch && xelection.type() != MapCenter &&xelection.type()!=FloatImage)
946 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
947 } else if (parser.checkParamCount(1))
949 b=parser.parBool(ok,0);
950 if (ok) setHideExport (b);
952 } else if (com=="setIncludeImagesHorizontally")
954 if (xelection.isEmpty() )
956 parser.setError (Aborted,"Nothing selected");
959 parser.setError (Aborted,"Type of selection is not a branch");
960 } else if (parser.checkParamCount(1))
962 b=parser.parBool(ok,0);
963 if (ok) setIncludeImagesHor(b);
965 } else if (com=="setIncludeImagesVertically")
967 if (xelection.isEmpty() )
969 parser.setError (Aborted,"Nothing selected");
972 parser.setError (Aborted,"Type of selection is not a branch");
973 } else if (parser.checkParamCount(1))
975 b=parser.parBool(ok,0);
976 if (ok) setIncludeImagesVer(b);
978 } else if (com=="setSelectionColor")
980 if (parser.checkParamCount(1))
982 QColor c=parser.parColor (ok,0);
983 if (ok) setSelectionColorInt (c);
985 } else if (com=="setURL")
987 if (xelection.isEmpty() )
989 parser.setError (Aborted,"Nothing selected");
992 parser.setError (Aborted,"Type of selection is not a branch");
993 } else if (parser.checkParamCount(1))
995 s=parser.parString (ok,0);
996 if (ok) setURLInt(s);
998 } else if (com=="setVymLink")
1000 if (xelection.isEmpty() )
1002 parser.setError (Aborted,"Nothing selected");
1005 parser.setError (Aborted,"Type of selection is not a branch");
1006 } else if (parser.checkParamCount(1))
1008 s=parser.parString (ok,0);
1009 if (ok) setVymLinkInt(s);
1012 else if (com=="setFlag")
1014 if (xelection.isEmpty() )
1016 parser.setError (Aborted,"Nothing selected");
1019 parser.setError (Aborted,"Type of selection is not a branch");
1020 } else if (parser.checkParamCount(1))
1022 s=parser.parString(ok,0);
1025 selb->activateStandardFlag(s);
1026 selb->updateFlagsToolbar();
1029 } else if (com=="setFrameType")
1031 if (xelection.isEmpty() )
1033 parser.setError (Aborted,"Nothing selected");
1036 parser.setError (Aborted,"Type of selection is not a branch");
1037 } else if (parser.checkParamCount(1))
1039 s=parser.parString(ok,0);
1043 } else if (com=="toggleFlag")
1045 if (xelection.isEmpty() )
1047 parser.setError (Aborted,"Nothing selected");
1050 parser.setError (Aborted,"Type of selection is not a branch");
1051 } else if (parser.checkParamCount(1))
1053 s=parser.parString(ok,0);
1056 selb->toggleStandardFlag(s);
1057 selb->updateFlagsToolbar();
1060 } else if (com=="unscroll")
1062 if (xelection.isEmpty() )
1064 parser.setError (Aborted,"Nothing selected");
1067 parser.setError (Aborted,"Type of selection is not a branch");
1068 } else if (parser.checkParamCount(0))
1070 if (!unscrollBranch (selb))
1071 parser.setError (Aborted,"Could not unscroll branch");
1073 } else if (com=="unscrollChilds")
1075 if (xelection.isEmpty() )
1077 parser.setError (Aborted,"Nothing selected");
1080 parser.setError (Aborted,"Type of selection is not a branch");
1081 } else if (parser.checkParamCount(0))
1085 } else if (com=="unsetFlag")
1087 if (xelection.isEmpty() )
1089 parser.setError (Aborted,"Nothing selected");
1092 parser.setError (Aborted,"Type of selection is not a branch");
1093 } else if (parser.checkParamCount(1))
1095 s=parser.parString(ok,0);
1098 selb->deactivateStandardFlag(s);
1099 selb->updateFlagsToolbar();
1103 parser.setError (Aborted,"Unknown command");
1106 if (parser.errorLevel()==NoError)
1109 mapCenter->reposition();
1113 // TODO Error handling
1114 qWarning("MapEditor::parseAtom: Error!");
1115 qWarning(parser.errorMessage());
1119 void MapEditor::runScript (QString script)
1121 parser.setScript (script);
1123 while (parser.next() )
1124 parseAtom(parser.getAtom());
1127 bool MapEditor::isDefault()
1132 bool MapEditor::hasChanged()
1137 void MapEditor::setChanged()
1140 autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
1148 void MapEditor::closeMap()
1150 // Unselect before disabling the toolbar actions
1151 if (!xelection.isEmpty() ) xelection.unselect();
1159 void MapEditor::setFilePath(QString fpath, QString destname)
1161 if (fpath.isEmpty() || fpath=="")
1168 filePath=fpath; // becomes absolute path
1169 fileName=fpath; // gets stripped of path
1170 destPath=destname; // needed for vymlinks
1172 // If fpath is not an absolute path, complete it
1173 filePath=QDir(fpath).absPath();
1174 fileDir=filePath.left (1+filePath.findRev ("/"));
1176 // Set short name, too. Search from behind:
1177 int i=fileName.findRev("/");
1178 if (i>=0) fileName=fileName.remove (0,i+1);
1180 // Forget the .vym (or .xml) for name of map
1181 mapName=fileName.left(fileName.findRev(".",-1,true) );
1185 void MapEditor::setFilePath(QString fpath)
1187 setFilePath (fpath,fpath);
1190 QString MapEditor::getFilePath()
1195 QString MapEditor::getFileName()
1200 QString MapEditor::getMapName()
1205 QString MapEditor::getDestPath()
1210 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1212 ErrorCode err=success;
1216 if (xelection.isEmpty() ) xelection.unselect();
1219 mapCenter->setMapEditor(this);
1220 // (map state is set later at end of load...)
1223 BranchObj *bo=xelection.getBranch();
1224 if (!bo) return aborted;
1225 if (lmode==ImportAdd)
1226 saveStateChangingPart(
1229 QString("addMapInsert (%1)").arg(fname),
1230 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1232 saveStateChangingPart(
1235 QString("addMapReplace(%1)").arg(fname),
1236 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1240 mapBuilderHandler handler;
1241 QFile file( fname );
1243 // I am paranoid: file should exist anyway
1244 // according to check in mainwindow.
1245 if (!file.exists() )
1247 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1248 tr("Couldn't open map " +fname)+".");
1252 bool blockSaveStateOrg=blockSaveState;
1253 blockReposition=true;
1254 blockSaveState=true;
1255 QXmlInputSource source( file);
1256 QXmlSimpleReader reader;
1257 reader.setContentHandler( &handler );
1258 reader.setErrorHandler( &handler );
1259 handler.setMapEditor( this );
1260 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1261 handler.setInputFile (file.name());
1262 handler.setLoadMode (lmode);
1263 bool ok = reader.parse( source );
1264 blockReposition=false;
1265 blockSaveState=blockSaveStateOrg;
1269 mapCenter->reposition();
1276 autosaveTimer->stop();
1280 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1281 tr( handler.errorProtocol() ) );
1283 // Still return "success": the map maybe at least
1284 // partially read by the parser
1291 int MapEditor::save (const SaveMode &savemode)
1295 // Create mapName and fileDir
1296 makeSubDirs (fileDir);
1300 fname=mapName+".xml";
1302 // use name given by user, even if he chooses .doc
1307 if (savemode==CompleteMap || xelection.isEmpty())
1308 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1310 //save () FIXME check FIO
1311 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());
1313 if (!saveStringToDisk(fileDir+fname,saveFile))
1320 autosaveTimer->stop();
1327 void MapEditor::setZipped (bool z)
1332 bool MapEditor::saveZipped ()
1337 void MapEditor::print()
1341 printer = new QPrinter;
1342 printer->setColorMode (QPrinter::Color);
1343 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1344 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1345 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1348 QRectF totalBBox=mapCenter->getTotalBBox();
1350 // Try to set orientation automagically
1351 // Note: Interpretation of generated postscript is amibiguous, if
1352 // there are problems with landscape mode, see
1353 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1355 if (totalBBox.width()>totalBBox.height())
1356 // recommend landscape
1357 printer->setOrientation (QPrinter::Landscape);
1359 // recommend portrait
1360 printer->setOrientation (QPrinter::Portrait);
1362 if ( printer->setup(this) )
1363 // returns false, if printing is canceled
1365 QPainter pp(printer);
1367 pp.setRenderHint(QPainter::Antialiasing,true);
1369 // Don't print the visualisation of selection
1370 xelection.unselect();
1372 QRectF mapRect=totalBBox;
1373 QGraphicsRectItem *frame=NULL;
1377 // Print frame around map
1378 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1379 totalBBox.width()+20, totalBBox.height()+20);
1380 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1381 frame->setZValue(0);
1386 double paperAspect = (double)printer->width() / (double)printer->height();
1387 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1389 if (mapAspect>=paperAspect)
1391 // Fit horizontally to paper width
1392 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1393 viewBottom=(int)(printer->width()/mapAspect);
1396 // Fit vertically to paper height
1397 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1398 viewBottom=printer->height();
1403 // Print footer below map
1405 font.setPointSize(10);
1407 QRectF footerBox(0,viewBottom,printer->width(),15);
1408 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1409 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1413 QRectF (0,0,printer->width(),printer->height()-15),
1414 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1417 // Viewport has paper dimension
1418 if (frame) delete (frame);
1420 // Restore selection
1421 xelection.reselect();
1423 // Save settings in vymrc
1424 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1425 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1426 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1430 void MapEditor::setAntiAlias (bool b)
1432 setRenderHint(QPainter::Antialiasing,b);
1435 void MapEditor::setSmoothPixmap(bool b)
1437 setRenderHint(QPainter::SmoothPixmapTransform,b);
1440 QPixmap MapEditor::getPixmap()
1442 QRectF mapRect=mapCenter->getTotalBBox();
1443 QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+2);
1446 pp.setRenderHints(renderHints());
1448 // Don't print the visualisation of selection
1449 xelection.unselect();
1451 mapScene->render ( &pp,
1452 QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1453 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1455 // Restore selection
1456 xelection.reselect();
1461 void MapEditor::setHideTmpMode (BranchObj::HideTmpMode mode)
1464 mapCenter->setHideTmp (hidemode);
1465 mapCenter->reposition();
1469 BranchObj::HideTmpMode MapEditor::getHideTmpMode()
1474 void MapEditor::exportImage(QString fn)
1476 setExportMode (true);
1477 QPixmap pix (getPixmap());
1478 pix.save(fn, "PNG");
1479 setExportMode (false);
1482 void MapEditor::setExportMode (bool b)
1484 // should be called before and after exports
1485 // depending on the settings
1486 if (b && settings.value("/export/useHideExport","yes")=="yes")
1487 setHideTmpMode (BranchObj::HideExport);
1489 setHideTmpMode (BranchObj::HideNone);
1492 void MapEditor::exportImage(QString fn, QString format)
1494 setExportMode (true);
1495 QPixmap pix (getPixmap());
1496 pix.save(fn, format);
1497 setExportMode (false);
1500 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1504 ex.setMapCenter(mapCenter);
1505 if (ex.setConfigFile(cf))
1507 setExportMode (true);
1508 ex.exportPresentation();
1509 setExportMode (false);
1515 void MapEditor::exportXML(const QString &dir)
1517 // Hide stuff during export, if settings want this
1518 setExportMode (true);
1520 // Create subdirectories
1523 // write to directory
1524 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1527 file.setName ( dir + "/"+mapName+".xml");
1528 if ( !file.open( QIODevice::WriteOnly ) )
1530 // This should neverever happen
1531 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1535 // Write it finally, and write in UTF8, no matter what
1536 QTextStream ts( &file );
1537 ts.setEncoding (QTextStream::UnicodeUTF8);
1541 // Now write image, too
1542 exportImage (dir+"/images/"+mapName+".png");
1544 setExportMode (false);
1547 void MapEditor::clear()
1549 xelection.unselect();
1553 void MapEditor::copy()
1555 LinkableMapObj *sel=xelection.single();
1558 // write to directory
1559 QString clipfile="part";
1560 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPointF(),sel ); // FIXME check FIO
1563 file.setName ( clipboardDir + "/"+clipfile+".xml");
1564 if ( !file.open( QIODevice::WriteOnly ) )
1566 // This should neverever happen
1567 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1571 // Write it finally, and write in UTF8, no matter what
1572 QTextStream ts( &file );
1573 ts.setEncoding (QTextStream::UnicodeUTF8);
1577 clipboardEmpty=false;
1582 void MapEditor::redo()
1584 // Restore variables
1585 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1586 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1587 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1588 // Can we undo at all?
1589 if (redosAvail<1) return;
1591 bool blockSaveStateOrg=blockSaveState;
1592 blockSaveState=true;
1596 if (undosAvail<stepsTotal) undosAvail++;
1598 if (curStep>stepsTotal) curStep=1;
1599 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1600 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1601 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1602 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1603 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1604 QString version=undoSet.readEntry ("/history/version");
1606 if (!checkVersion(version))
1607 QMessageBox::warning(0,tr("Warning"),
1608 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1611 // Find out current undo directory
1612 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1616 cout << "ME::redo() begin\n";
1617 cout << " undosAvail="<<undosAvail<<endl;
1618 cout << " redosAvail="<<redosAvail<<endl;
1619 cout << " curStep="<<curStep<<endl;
1620 cout << " ---------------------------"<<endl;
1621 cout << " comment="<<comment.toStdString()<<endl;
1622 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1623 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1624 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1625 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1626 cout << " ---------------------------"<<endl<<endl;
1629 // select object before redo
1630 if (!redoSelection.isEmpty())
1631 select (redoSelection);
1634 parseAtom (redoCommand);
1635 mapCenter->reposition();
1637 blockSaveState=blockSaveStateOrg;
1639 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1640 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1641 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1642 undoSet.writeSettings(histPath);
1644 mainWindow->updateHistory (undoSet);
1647 /* TODO remove testing
1648 cout << "ME::redo() end\n";
1649 cout << " undosAvail="<<undosAvail<<endl;
1650 cout << " redosAvail="<<redosAvail<<endl;
1651 cout << " curStep="<<curStep<<endl;
1652 cout << " ---------------------------"<<endl<<endl;
1658 bool MapEditor::isRedoAvailable()
1660 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1666 void MapEditor::undo()
1668 // Restore variables
1669 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1670 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1671 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1673 // Can we undo at all?
1674 if (undosAvail<1) return;
1676 bool blockSaveStateOrg=blockSaveState;
1677 blockSaveState=true;
1679 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1680 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1681 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1682 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1683 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1684 QString version=undoSet.readEntry ("/history/version");
1686 if (!checkVersion(version))
1687 QMessageBox::warning(0,tr("Warning"),
1688 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1690 // Find out current undo directory
1691 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1693 // select object before undo
1694 if (!undoSelection.isEmpty())
1695 select (undoSelection);
1699 cout << "ME::undo() begin\n";
1700 cout << " undosAvail="<<undosAvail<<endl;
1701 cout << " redosAvail="<<redosAvail<<endl;
1702 cout << " curStep="<<curStep<<endl;
1703 cout << " ---------------------------"<<endl;
1704 cout << " comment="<<comment.toStdString()<<endl;
1705 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1706 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1707 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1708 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1709 cout << " ---------------------------"<<endl<<endl;
1711 parseAtom (undoCommand);
1712 mapCenter->reposition();
1716 if (curStep<1) curStep=stepsTotal;
1720 blockSaveState=blockSaveStateOrg;
1721 /* TODO remove testing
1722 cout << "ME::undo() end\n";
1723 cout << " undosAvail="<<undosAvail<<endl;
1724 cout << " redosAvail="<<redosAvail<<endl;
1725 cout << " curStep="<<curStep<<endl;
1726 cout << " ---------------------------"<<endl<<endl;
1729 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1730 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1731 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1732 undoSet.writeSettings(histPath);
1734 mainWindow->updateHistory (undoSet);
1737 ensureSelectionVisible();
1740 bool MapEditor::isUndoAvailable()
1742 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1748 void MapEditor::gotoHistoryStep (int i)
1750 // Restore variables
1751 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1752 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1754 if (i<0) i=undosAvail+redosAvail;
1756 // Clicking above current step makes us undo things
1759 for (int j=0; j<undosAvail-i; j++) undo();
1762 // Clicking below current step makes us redo things
1764 for (int j=undosAvail; j<i; j++) redo();
1766 // And ignore clicking the current row ;-)
1769 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1771 QString pathDir=path.left(path.findRev("/"));
1777 // We need to parse saved XML data
1778 mapBuilderHandler handler;
1779 QXmlInputSource source( file);
1780 QXmlSimpleReader reader;
1781 reader.setContentHandler( &handler );
1782 reader.setErrorHandler( &handler );
1783 handler.setMapEditor( this );
1784 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1785 if (undoSel.isEmpty())
1789 handler.setLoadMode (NewMap);
1793 handler.setLoadMode (ImportReplace);
1795 blockReposition=true;
1796 bool ok = reader.parse( source );
1797 blockReposition=false;
1800 // This should never ever happen
1801 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1802 handler.errorProtocol());
1805 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1808 void MapEditor::addMapInsertInt (const QString &path, int pos)
1810 BranchObj *sel=xelection.getBranch();
1813 QString pathDir=path.left(path.findRev("/"));
1819 // We need to parse saved XML data
1820 mapBuilderHandler handler;
1821 QXmlInputSource source( file);
1822 QXmlSimpleReader reader;
1823 reader.setContentHandler( &handler );
1824 reader.setErrorHandler( &handler );
1825 handler.setMapEditor( this );
1826 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1827 handler.setLoadMode (ImportAdd);
1828 blockReposition=true;
1829 bool ok = reader.parse( source );
1830 blockReposition=false;
1833 // This should never ever happen
1834 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1835 handler.errorProtocol());
1838 sel->getLastBranch()->linkTo (sel,pos);
1840 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1844 void MapEditor::pasteNoSave()
1846 load (clipboardDir+"/part.xml",ImportAdd);
1849 void MapEditor::cutNoSave()
1855 void MapEditor::paste() // FIXME no pasting of FIO ???
1857 BranchObj *sel=xelection.getBranch();
1861 saveStateChangingPart(
1865 QString("Paste to %1").arg( getName(sel))
1867 mapCenter->reposition();
1871 void MapEditor::cut()
1873 LinkableMapObj *sel=xelection.single();
1874 if ( sel && (xelection.type() == Branch ||
1875 xelection.type()==MapCenter ||
1876 xelection.type()==FloatImage))
1878 saveStateChangingPart(
1882 QString("Cut %1").arg(getName(sel ))
1886 mapCenter->reposition();
1890 void MapEditor::move(const int &x, const int &y)
1892 LinkableMapObj *sel=xelection.single();
1895 QString ps=qpointfToString (sel->getAbsPos());
1896 QString s=xelection.single()->getSelectString();
1899 s, "move "+qpointfToString (QPointF (x,y)),
1900 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
1902 mapCenter->reposition();
1908 void MapEditor::moveRel (const int &x, const int &y)
1910 LinkableMapObj *sel=xelection.single();
1913 QString ps=qpointfToString (sel->getRelPos());
1914 QString s=sel->getSelectString();
1917 s, "moveRel "+qpointfToString (QPointF (x,y)),
1918 QString("Move %1 to relativ position %2").arg(getName(sel)).arg(ps));
1919 ((OrnamentedObj*)sel)->move2RelPos (x,y);
1920 mapCenter->reposition();
1926 void MapEditor::moveBranchUp()
1928 BranchObj* bo=xelection.getBranch();
1932 if (!bo->canMoveBranchUp()) return;
1933 par=(BranchObj*)(bo->getParObj());
1934 BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
1935 saveState (bo->getSelectString(),"moveBranchDown ()",obo->getSelectString(),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1936 mapCenter->reposition();
1939 ensureSelectionVisible();
1943 void MapEditor::moveBranchDown()
1945 BranchObj* bo=xelection.getBranch();
1949 if (!bo->canMoveBranchDown()) return;
1950 par=(BranchObj*)(bo->getParObj());
1951 BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
1952 saveState(bo->getSelectString(),"moveBranchUp ()",obo->getSelectString(),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1953 mapCenter->reposition();
1956 ensureSelectionVisible();
1960 void MapEditor::linkTo(const QString &dstString) // FIXME needed? only for FIO ??
1962 FloatImageObj *fio=xelection.getFloatImage();
1965 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
1966 if (dst && (typeid(*dst)==typeid (BranchObj) ||
1967 typeid(*dst)==typeid (MapCenterObj)))
1969 LinkableMapObj *dstPar=dst->getParObj();
1970 QString parString=dstPar->getSelectString();
1971 QString fioPreSelectString=fio->getSelectString();
1972 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
1973 ((BranchObj*)(dst))->addFloatImage (fio);
1974 xelection.unselect();
1975 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
1976 fio=((BranchObj*)(dst))->getLastFloatImage();
1979 xelection.select(fio);
1981 fio->getSelectString(),
1982 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
1984 QString ("linkTo (\"%1\")").arg(dstString),
1985 QString ("Link floatimage to %1").arg(getName(dst)));
1990 QString MapEditor::getHeading(bool &ok, QPoint &p)
1992 BranchObj *bo=xelection.getBranch();
1996 p=mapFromScene(bo->getAbsPos());
1997 return bo->getHeading();
2003 void MapEditor::setHeading(const QString &s)
2005 BranchObj *sel=xelection.getBranch();
2010 "setHeading (\""+sel->getHeading()+"\")",
2012 "setHeading (\""+s+"\")",
2013 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
2014 sel->setHeading(s );
2015 mapCenter->reposition();
2017 ensureSelectionVisible();
2021 void MapEditor::setURLInt (const QString &s)
2023 // Internal function, no saveState needed
2024 BranchObj *bo=xelection.getBranch();
2028 mapCenter->reposition();
2030 ensureSelectionVisible();
2034 void MapEditor::setHeadingInt(const QString &s)
2036 BranchObj *bo=xelection.getBranch();
2040 mapCenter->reposition();
2042 ensureSelectionVisible();
2046 void MapEditor::setVymLinkInt (const QString &s)
2048 // Internal function, no saveState needed
2049 BranchObj *bo=xelection.getBranch();
2053 mapCenter->reposition();
2055 ensureSelectionVisible();
2059 BranchObj* MapEditor::addNewBranchInt(int num)
2061 // Depending on pos:
2062 // -3 insert in childs of parent above selection
2063 // -2 add branch to selection
2064 // -1 insert in childs of parent below selection
2065 // 0..n insert in childs of parent at pos
2066 BranchObj *newbo=NULL;
2067 BranchObj *bo=xelection.getBranch();
2072 // save scroll state. If scrolled, automatically select
2073 // new branch in order to tmp unscroll parent...
2074 return bo->addBranch();
2079 bo=(BranchObj*)bo->getParObj();
2083 bo=(BranchObj*)bo->getParObj();
2086 newbo=bo->insertBranch(num);
2091 BranchObj* MapEditor::addNewBranch(int pos)
2093 // Different meaning than num in addNewBranchInt!
2097 BranchObj *bo = xelection.getBranch();
2098 BranchObj *newbo=NULL;
2102 setCursor (Qt::ArrowCursor);
2104 newbo=addNewBranchInt (pos-2);
2112 QString ("addBranch (%1)").arg(pos-2),
2113 QString ("Add new branch to %1").arg(getName(bo)));
2115 mapCenter->reposition();
2123 BranchObj* MapEditor::addNewBranchBefore()
2125 BranchObj *newbo=NULL;
2126 BranchObj *bo = xelection.getBranch();
2127 if (bo && xelection.type()==Branch)
2128 // We accept no MapCenterObj here, so we _have_ a parent
2130 QPointF p=bo->getRelPos();
2133 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2135 // add below selection
2136 newbo=parbo->insertBranch(bo->getNum()+1);
2139 newbo->move2RelPos (p);
2141 // Move selection to new branch
2142 bo->linkTo (newbo,-1);
2144 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2145 QString ("Add branch before %1").arg(getName(bo)));
2147 mapCenter->reposition();
2154 void MapEditor::deleteSelection()
2156 BranchObj *bo = xelection.getBranch();
2157 if (bo && xelection.type()==Branch)
2159 BranchObj* par=(BranchObj*)(bo->getParObj());
2160 xelection.unselect();
2161 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2162 par->removeBranch(bo);
2163 xelection.select (par);
2164 ensureSelectionVisible();
2165 mapCenter->reposition();
2170 FloatImageObj *fio=xelection.getFloatImage();
2173 BranchObj* par=(BranchObj*)(fio->getParObj());
2174 saveStateChangingPart(
2178 QString("Delete %1").arg(getName(fio))
2180 xelection.unselect();
2181 par->removeFloatImage(fio);
2182 xelection.select (par);
2183 mapCenter->reposition();
2185 ensureSelectionVisible();
2190 LinkableMapObj* MapEditor::getSelection()
2192 return xelection.single();
2195 BranchObj* MapEditor::getSelectedBranch()
2197 return xelection.getBranch();
2200 FloatImageObj* MapEditor::getSelectedFloatImage()
2202 return xelection.getFloatImage();
2205 void MapEditor::unselect()
2207 xelection.unselect();
2210 void MapEditor::reselect()
2212 xelection.reselect();
2215 bool MapEditor::select (const QString &s)
2217 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2219 // Finally select the found object
2222 xelection.unselect();
2223 xelection.select(lmo);
2225 ensureSelectionVisible();
2231 QString MapEditor::getSelectString()
2233 return xelection.getSelectString();
2236 void MapEditor::selectInt (LinkableMapObj *lmo)
2238 if (lmo && xelection.single()!= lmo)
2240 xelection.select(lmo);
2245 void MapEditor::selectNextBranchInt()
2247 // Increase number of branch
2248 LinkableMapObj *sel=xelection.single();
2251 QString s=sel->getSelectString();
2257 part=s.section(",",-1);
2259 num=part.right(part.length() - 3);
2261 s=s.left (s.length() -num.length());
2264 num=QString ("%1").arg(num.toUInt()+1);
2268 // Try to select this one
2269 if (select (s)) return;
2271 // We have no direct successor,
2272 // try to increase the parental number in order to
2273 // find a successor with same depth
2275 int d=xelection.single()->getDepth();
2280 while (!found && d>0)
2282 s=s.section (",",0,d-1);
2283 // replace substring of current depth in s with "1"
2284 part=s.section(",",-1);
2286 num=part.right(part.length() - 3);
2290 // increase number of parent
2291 num=QString ("%1").arg(num.toUInt()+1);
2292 s=s.section (",",0,d-2) + ","+ typ+num;
2295 // Special case, look at orientation
2296 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2297 num=QString ("%1").arg(num.toUInt()+1);
2299 num=QString ("%1").arg(num.toUInt()-1);
2304 // pad to oldDepth, select the first branch for each depth
2305 for (i=d;i<oldDepth;i++)
2310 if ( xelection.getBranch()->countBranches()>0)
2318 // try to select the freshly built string
2326 void MapEditor::selectPrevBranchInt()
2328 // Decrease number of branch
2329 BranchObj *bo=xelection.getBranch();
2332 QString s=bo->getSelectString();
2338 part=s.section(",",-1);
2340 num=part.right(part.length() - 3);
2342 s=s.left (s.length() -num.length());
2344 int n=num.toInt()-1;
2347 num=QString ("%1").arg(n);
2350 // Try to select this one
2351 if (n>=0 && select (s)) return;
2353 // We have no direct precessor,
2354 // try to decrease the parental number in order to
2355 // find a precessor with same depth
2357 int d=xelection.single()->getDepth();
2362 while (!found && d>0)
2364 s=s.section (",",0,d-1);
2365 // replace substring of current depth in s with "1"
2366 part=s.section(",",-1);
2368 num=part.right(part.length() - 3);
2372 // decrease number of parent
2373 num=QString ("%1").arg(num.toInt()-1);
2374 s=s.section (",",0,d-2) + ","+ typ+num;
2377 // Special case, look at orientation
2378 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2379 num=QString ("%1").arg(num.toInt()-1);
2381 num=QString ("%1").arg(num.toInt()+1);
2386 // pad to oldDepth, select the last branch for each depth
2387 for (i=d;i<oldDepth;i++)
2391 if ( xelection.getBranch()->countBranches()>0)
2392 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2399 // try to select the freshly built string
2407 void MapEditor::selectUpperBranch()
2409 BranchObj *bo=xelection.getBranch();
2410 if (bo && xelection.type()==Branch)
2412 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2413 selectPrevBranchInt();
2415 if (bo->getDepth()==1)
2416 selectNextBranchInt();
2418 selectPrevBranchInt();
2422 void MapEditor::selectLowerBranch()
2424 BranchObj *bo=xelection.getBranch();
2425 if (bo && xelection.type()==Branch)
2426 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2427 selectNextBranchInt();
2429 if (bo->getDepth()==1)
2430 selectPrevBranchInt();
2432 selectNextBranchInt();
2436 void MapEditor::selectLeftBranch()
2440 LinkableMapObj *sel=xelection.single();
2443 if (xelection.type()== MapCenter)
2445 par=xelection.getBranch();
2446 bo=par->getLastSelectedBranch();
2449 // Workaround for reselecting on left and right side
2450 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2451 bo=par->getLastBranch();
2454 bo=par->getLastBranch();
2455 xelection.select(bo);
2457 ensureSelectionVisible();
2462 par=(BranchObj*)(sel->getParObj());
2463 if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
2465 if (xelection.type() == Branch ||
2466 xelection.type() == FloatImage)
2468 xelection.select(par);
2470 ensureSelectionVisible();
2474 if (xelection.type() == Branch )
2476 bo=xelection.getBranch()->getLastSelectedBranch();
2479 xelection.select(bo);
2481 ensureSelectionVisible();
2489 void MapEditor::selectRightBranch()
2493 LinkableMapObj *sel=xelection.single();
2496 if (xelection.type()==MapCenter)
2498 par=xelection.getBranch();
2499 bo=par->getLastSelectedBranch();
2502 // Workaround for reselecting on left and right side
2503 if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
2504 bo=par->getFirstBranch();
2507 xelection.select(bo);
2509 ensureSelectionVisible();
2514 par=(BranchObj*)(xelection.single()->getParObj());
2515 if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
2517 if (xelection.type() == Branch ||
2518 xelection.type() == FloatImage)
2520 xelection.select(par);
2522 ensureSelectionVisible();
2526 if (xelection.type() == Branch)
2528 bo=xelection.getBranch()->getLastSelectedBranch();
2531 xelection.select(bo);
2533 ensureSelectionVisible();
2541 void MapEditor::selectFirstBranch()
2543 BranchObj *bo1=xelection.getBranch();
2548 par=(BranchObj*)(bo1->getParObj());
2549 bo2=par->getFirstBranch();
2551 xelection.select(bo2);
2553 ensureSelectionVisible();
2558 void MapEditor::selectLastBranch()
2560 BranchObj *bo1=xelection.getBranch();
2565 par=(BranchObj*)(bo1->getParObj());
2566 bo2=par->getLastBranch();
2569 xelection.select(bo2);
2571 ensureSelectionVisible();
2576 void MapEditor::selectMapBackgroundImage ()
2578 Q3FileDialog *fd=new Q3FileDialog( this);
2579 fd->setMode (Q3FileDialog::ExistingFile);
2580 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2581 ImagePreview *p =new ImagePreview (fd);
2582 fd->setContentsPreviewEnabled( TRUE );
2583 fd->setContentsPreview( p, p );
2584 fd->setPreviewMode( Q3FileDialog::Contents );
2585 fd->setCaption(vymName+" - " +tr("Load background image"));
2586 fd->setDir (lastImageDir);
2589 if ( fd->exec() == QDialog::Accepted )
2591 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2592 lastImageDir=QDir (fd->dirPath());
2593 setMapBackgroundImage (fd->selectedFile());
2597 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
2599 QColor oldcol=mapScene->backgroundBrush().color();
2603 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2605 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2606 QString("Set background color of map to %1").arg(col.name()));
2609 brush.setTextureImage (QPixmap (fn));
2610 mapScene->setBackgroundBrush(brush);
2613 void MapEditor::selectMapBackgroundColor()
2615 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2616 if ( !col.isValid() ) return;
2617 setMapBackgroundColor( col );
2621 void MapEditor::setMapBackgroundColor(QColor col)
2623 QColor oldcol=mapScene->backgroundBrush().color();
2626 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
2628 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
2629 QString("Set background color of map to %1").arg(col.name()));
2630 mapScene->setBackgroundBrush(col);
2633 QColor MapEditor::getMapBackgroundColor()
2635 return mapScene->backgroundBrush().color();
2638 QColor MapEditor::getCurrentHeadingColor()
2640 BranchObj *bo=xelection.getBranch();
2641 if (bo) return bo->getColor();
2643 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2647 void MapEditor::colorBranch (QColor c)
2649 BranchObj *bo=xelection.getBranch();
2654 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
2656 QString ("colorBranch (\"%1\")").arg(c.name()),
2657 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2659 bo->setColor(c); // color branch
2663 void MapEditor::colorSubtree (QColor c)
2665 BranchObj *bo=xelection.getBranch();
2668 saveStateChangingPart(
2671 QString ("colorSubtree (\"%1\")").arg(c.name()),
2672 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2674 bo->setColorSubtree (c); // color links, color childs
2679 void MapEditor::toggleStandardFlag(QString f)
2681 BranchObj *bo=xelection.getBranch();
2685 if (bo->isSetStandardFlag(f))
2697 QString("%1 (\"%2\")").arg(u).arg(f),
2699 QString("%1 (\"%2\")").arg(r).arg(f),
2700 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2701 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2707 BranchObj* MapEditor::findText (QString s, bool cs)
2709 QTextDocument::FindFlags flags=0;
2710 if (cs) flags=QTextDocument::FindCaseSensitively;
2713 { // Nothing found or new find process
2715 // nothing found, start again
2717 itFind=mapCenter->first();
2719 bool searching=true;
2720 bool foundNote=false;
2721 while (searching && !EOFind)
2725 // Searching in Note
2726 if (itFind->getNote().contains(s,cs))
2728 if (xelection.single()!=itFind)
2730 xelection.select(itFind);
2731 ensureSelectionVisible();
2733 if (textEditor->findText(s,flags))
2739 // Searching in Heading
2740 if (searching && itFind->getHeading().contains (s,cs) )
2742 xelection.select(itFind);
2743 ensureSelectionVisible();
2749 itFind=itFind->next();
2750 if (!itFind) EOFind=true;
2754 return xelection.getBranch();
2759 void MapEditor::findReset()
2760 { // Necessary if text to find changes during a find process
2764 void MapEditor::setURL(const QString &url)
2766 BranchObj *bo=xelection.getBranch();
2769 QString oldurl=bo->getURL();
2773 QString ("setURL (\"%1\")").arg(oldurl),
2775 QString ("setURL (\"%1\")").arg(url),
2776 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2782 void MapEditor::editURL()
2784 BranchObj *bo=xelection.getBranch();
2788 QString text = QInputDialog::getText(
2789 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2790 bo->getURL(), &ok, this );
2792 // user entered something and pressed OK
2797 QString MapEditor::getURL()
2799 BranchObj *bo=xelection.getBranch();
2801 return bo->getURL();
2806 QStringList MapEditor::getURLs()
2809 BranchObj *bo=xelection.getBranch();
2815 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2823 void MapEditor::editHeading2URL()
2825 BranchObj *bo=xelection.getBranch();
2827 setURL (bo->getHeading());
2830 void MapEditor::editBugzilla2URL()
2832 BranchObj *bo=xelection.getBranch();
2835 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2840 void MapEditor::editFATE2URL()
2842 BranchObj *bo=xelection.getBranch();
2845 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2848 "setURL (\""+bo->getURL()+"\")",
2850 "setURL (\""+url+"\")",
2851 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2858 void MapEditor::editVymLink()
2860 BranchObj *bo=xelection.getBranch();
2863 QStringList filters;
2864 filters <<"VYM map (*.vym)";
2865 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2866 fd->setFilters (filters);
2867 fd->setCaption(vymName+" - " +tr("Link to another map"));
2868 fd->setDirectory (lastFileDir);
2869 if (! bo->getVymLink().isEmpty() )
2870 fd->selectFile( bo->getVymLink() );
2874 if ( fd->exec() == QDialog::Accepted )
2876 lastFileDir=QDir (fd->directory().path());
2879 "setVymLink (\""+bo->getVymLink()+"\")",
2881 "setVymLink (\""+fd->selectedFile()+"\")",
2882 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2884 bo->setVymLink (fd->selectedFile() );
2886 mapCenter->reposition();
2892 void MapEditor::deleteVymLink()
2894 BranchObj *bo=xelection.getBranch();
2899 "setVymLink (\""+bo->getVymLink()+"\")",
2901 "setVymLink (\"\")",
2902 QString("Unset vymlink of %1").arg(getName(bo))
2904 bo->setVymLink ("" );
2906 mapCenter->reposition();
2911 void MapEditor::setHideExport(bool b)
2913 BranchObj *bo=xelection.getBranch();
2916 bo->setHideInExport (b);
2917 QString u= b ? "false" : "true";
2918 QString r=!b ? "false" : "true";
2922 QString ("setHideExport (%1)").arg(u),
2924 QString ("setHideExport (%1)").arg(r),
2925 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
2928 mapCenter->reposition();
2933 void MapEditor::toggleHideExport()
2935 BranchObj *bo=xelection.getBranch();
2937 setHideExport ( !bo->hideInExport() );
2940 QString MapEditor::getVymLink()
2942 BranchObj *bo=xelection.getBranch();
2944 return bo->getVymLink();
2950 QStringList MapEditor::getVymLinks()
2953 BranchObj *bo=xelection.getBranch();
2959 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2967 void MapEditor::deleteKeepChilds()
2969 BranchObj *bo=xelection.getBranch();
2973 par=(BranchObj*)(bo->getParObj());
2974 QPointF p=bo->getRelPos();
2975 saveStateChangingPart(
2978 "deleteKeepChilds ()",
2979 QString("Remove %1 and keep its childs").arg(getName(bo))
2982 QString sel=bo->getSelectString();
2984 par->removeBranchHere(bo);
2985 mapCenter->reposition();
2987 xelection.getBranch()->move2RelPos (p);
2988 mapCenter->reposition();
2992 void MapEditor::deleteChilds()
2994 BranchObj *bo=xelection.getBranch();
2997 saveStateChangingPart(
3001 QString( "Remove childs of branch %1").arg(getName(bo))
3004 mapCenter->reposition();
3008 void MapEditor::editMapInfo()
3010 ExtraInfoDialog dia;
3011 dia.setMapName (getFileName() );
3012 dia.setAuthor (mapCenter->getAuthor() );
3013 dia.setComment(mapCenter->getComment() );
3017 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
3024 bo=mapCenter->first();
3027 if (!bo->getNote().isEmpty() ) n++;
3028 f+= bo->countFloatImages();
3030 xl+=bo->countXLinks();
3033 stats+=QString ("%1 branches\n").arg (b-1,6);
3034 stats+=QString ("%1 xLinks \n").arg (xl,6);
3035 stats+=QString ("%1 notes\n").arg (n,6);
3036 stats+=QString ("%1 images\n").arg (f,6);
3037 dia.setStats (stats);
3039 // Finally show dialog
3040 if (dia.exec() == QDialog::Accepted)
3042 setMapAuthor (dia.getAuthor() );
3043 setMapComment (dia.getComment() );
3047 void MapEditor::ensureSelectionVisible()
3049 LinkableMapObj *lmo=xelection.single();
3050 if (lmo) ensureVisible (lmo->getBBox() );
3054 void MapEditor::updateSelection()
3056 // Tell selection to update geometries
3060 void MapEditor::updateActions()
3062 // Tell mainwindow to update states of actions
3063 mainWindow->updateActions();
3064 // TODO maybe don't update if blockReposition is set
3067 void MapEditor::updateNoteFlag()
3070 BranchObj *bo=xelection.getBranch();
3073 bo->updateNoteFlag();
3074 mainWindow->updateActions();
3078 void MapEditor::setMapAuthor (const QString &s)
3082 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3084 QString ("setMapAuthor (\"%1\")").arg(s),
3085 QString ("Set author of map to \"%1\"").arg(s)
3087 mapCenter->setAuthor (s);
3090 void MapEditor::setMapComment (const QString &s)
3094 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3096 QString ("setMapComment (\"%1\")").arg(s),
3097 QString ("Set comment of map")
3099 mapCenter->setComment (s);
3102 void MapEditor::setMapLinkStyle (const QString & s)
3104 saveStateChangingPart (
3107 QString("setMapLinkStyle (\"%1\")").arg(s),
3108 QString("Set map link style (\"%1\")").arg(s)
3112 linkstyle=LinkableMapObj::Line;
3113 else if (s=="StyleParabel")
3114 linkstyle=LinkableMapObj::Parabel;
3115 else if (s=="StylePolyLine")
3116 linkstyle=LinkableMapObj::PolyLine;
3118 linkstyle=LinkableMapObj::PolyParabel;
3121 bo=mapCenter->first();
3125 bo->setLinkStyle(bo->getDefLinkStyle());
3128 mapCenter->reposition();
3131 LinkableMapObj::Style MapEditor::getMapLinkStyle ()
3136 void MapEditor::setMapDefLinkColor(QColor c)
3142 void MapEditor::setMapLinkColorHintInt()
3144 // called from setMapLinkColorHint(lch) or at end of parse
3146 bo=mapCenter->first();
3154 void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
3157 setMapLinkColorHintInt();
3160 void MapEditor::toggleMapLinkColorHint()
3162 if (linkcolorhint==LinkableMapObj::HeadingColor)
3163 linkcolorhint=LinkableMapObj::DefaultColor;
3165 linkcolorhint=LinkableMapObj::HeadingColor;
3167 bo=mapCenter->first();
3175 LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
3177 return linkcolorhint;
3180 QColor MapEditor::getMapDefLinkColor()
3182 return defLinkColor;
3185 void MapEditor::setMapDefXLinkColor(QColor col)
3190 QColor MapEditor::getMapDefXLinkColor()
3192 return defXLinkColor;
3195 void MapEditor::setMapDefXLinkWidth (int w)
3200 int MapEditor::getMapDefXLinkWidth()
3202 return defXLinkWidth;
3205 void MapEditor::selectMapLinkColor()
3207 QColor col = QColorDialog::getColor( defLinkColor, this );
3208 if ( !col.isValid() ) return;
3211 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3213 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3214 QString("Set link color to %1").arg(col.name())
3216 setMapDefLinkColor( col );
3219 void MapEditor::selectMapSelectionColor()
3221 QColor col = QColorDialog::getColor( defLinkColor, this );
3222 setSelectionColor (col);
3225 void MapEditor::setSelectionColorInt (QColor col)
3227 if ( !col.isValid() ) return;
3228 xelection.setColor (col);
3231 void MapEditor::setSelectionColor(QColor col)
3233 if ( !col.isValid() ) return;
3236 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3238 QString("setSelectionColor (%1)").arg(col.name()),
3239 QString("Set color of selection box to %1").arg(col.name())
3241 setSelectionColorInt (col);
3244 QColor MapEditor::getSelectionColor()
3246 return xelection.getColor();
3249 bool MapEditor::scrollBranch(BranchObj *bo)
3253 if (bo->isScrolled()) return false;
3254 if (bo->countBranches()==0) return false;
3255 if (bo->getDepth()==0) return false;
3261 QString ("%1 ()").arg(u),
3263 QString ("%1 ()").arg(r),
3264 QString ("%1 %2").arg(r).arg(getName(bo))
3273 bool MapEditor::unscrollBranch(BranchObj *bo)
3277 if (!bo->isScrolled()) return false;
3278 if (bo->countBranches()==0) return false;
3279 if (bo->getDepth()==0) return false;
3285 QString ("%1 ()").arg(u),
3287 QString ("%1 ()").arg(r),
3288 QString ("%1 %2").arg(r).arg(getName(bo))
3297 void MapEditor::toggleScroll()
3299 BranchObj *bo=xelection.getBranch();
3300 if (xelection.type()==Branch )
3302 if (bo->isScrolled())
3303 unscrollBranch (bo);
3309 void MapEditor::unscrollChilds()
3311 BranchObj *bo=xelection.getBranch();
3317 if (bo->isScrolled()) unscrollBranch (bo);
3323 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3325 BranchObj *bo=xelection.getBranch();
3329 bo->addFloatImage();
3330 fio=bo->getLastFloatImage();
3332 mapCenter->reposition();
3339 void MapEditor::loadFloatImage ()
3341 BranchObj *bo=xelection.getBranch();
3345 Q3FileDialog *fd=new Q3FileDialog( this);
3346 fd->setMode (Q3FileDialog::ExistingFiles);
3347 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3348 ImagePreview *p =new ImagePreview (fd);
3349 fd->setContentsPreviewEnabled( TRUE );
3350 fd->setContentsPreview( p, p );
3351 fd->setPreviewMode( Q3FileDialog::Contents );
3352 fd->setCaption(vymName+" - " +tr("Load image"));
3353 fd->setDir (lastImageDir);
3356 if ( fd->exec() == QDialog::Accepted )
3358 // FIXME loadFIO in QT4 use: lastImageDir=fd->directory();
3359 lastImageDir=QDir (fd->dirPath());
3362 for (int j=0; j<fd->selectedFiles().count(); j++)
3364 s=fd->selectedFiles().at(j);
3365 fio=loadFloatImageInt (s);
3368 (LinkableMapObj*)fio,
3371 QString ("loadImage (%1)").arg(s ),
3372 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3375 // FIXME loadFIO error handling
3376 qWarning ("Failed to load "+s);
3384 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3386 fio->save (fn,type);
3389 void MapEditor::saveFloatImage ()
3391 FloatImageObj *fio=xelection.getFloatImage();
3394 QFileDialog *fd=new QFileDialog( this);
3395 fd->setFilters (imageIO.getFilters());
3396 fd->setCaption(vymName+" - " +tr("Save image"));
3397 fd->setFileMode( QFileDialog::AnyFile );
3398 fd->setDirectory (lastImageDir);
3399 // fd->setSelection (fio->getOriginalFilename());
3403 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3405 fn=fd->selectedFiles().at(0);
3406 if (QFile (fn).exists() )
3408 QMessageBox mb( vymName,
3409 tr("The file %1 exists already.\n"
3410 "Do you want to overwrite it?").arg(fn),
3411 QMessageBox::Warning,
3412 QMessageBox::Yes | QMessageBox::Default,
3413 QMessageBox::Cancel | QMessageBox::Escape,
3414 QMessageBox::QMessageBox::NoButton );
3416 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3417 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3420 case QMessageBox::Yes:
3423 case QMessageBox::Cancel:
3430 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3436 void MapEditor::setFrameType(const FrameObj::FrameType &t)
3438 BranchObj *bo=xelection.getBranch();
3441 QString s=bo->getFrameTypeName();
3442 bo->setFrameType (t);
3443 saveState (bo, QString("setFrameType (\"%1\")").arg(s),
3444 bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
3445 mapCenter->reposition();
3450 void MapEditor::setFrameType(const QString &s)
3452 BranchObj *bo=xelection.getBranch();
3455 saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
3456 bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
3457 bo->setFrameType (s);
3458 mapCenter->reposition();
3463 void MapEditor::setFramePenColor(const QColor &c)
3465 BranchObj *bo=xelection.getBranch();
3468 saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
3469 bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
3470 bo->setFramePenColor (c);
3474 void MapEditor::setFrameBrushColor(const QColor &c)
3476 BranchObj *bo=xelection.getBranch();
3479 saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
3480 bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
3481 bo->setFrameBrushColor (c);
3485 void MapEditor::setFramePadding (const int &i)
3487 BranchObj *bo=xelection.getBranch();
3490 saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
3491 bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
3492 bo->setFramePadding (i);
3493 mapCenter->reposition();
3498 void MapEditor::setFrameBorderWidth(const int &i)
3500 BranchObj *bo=xelection.getBranch();
3503 saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
3504 bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
3505 bo->setFrameBorderWidth (i);
3506 mapCenter->reposition();
3511 void MapEditor::setIncludeImagesVer(bool b)
3513 BranchObj *bo=xelection.getBranch();
3516 QString u= b ? "false" : "true";
3517 QString r=!b ? "false" : "true";
3521 QString("setIncludeImagesVertically (%1)").arg(u),
3523 QString("setIncludeImagesVertically (%1)").arg(r),
3524 QString("Include images vertically in %1").arg(getName(bo))
3526 bo->setIncludeImagesVer(b);
3527 mapCenter->reposition();
3531 void MapEditor::setIncludeImagesHor(bool b)
3533 BranchObj *bo=xelection.getBranch();
3536 QString u= b ? "false" : "true";
3537 QString r=!b ? "false" : "true";
3541 QString("setIncludeImagesHorizontally (%1)").arg(u),
3543 QString("setIncludeImagesHorizontally (%1)").arg(r),
3544 QString("Include images horizontally in %1").arg(getName(bo))
3546 bo->setIncludeImagesHor(b);
3547 mapCenter->reposition();
3551 void MapEditor::setHideLinkUnselected (bool b) // FIXME missing saveState
3553 LinkableMapObj *sel=xelection.single();
3555 (xelection.type() == Branch ||
3556 xelection.type() == MapCenter ||
3557 xelection.type() == FloatImage ))
3558 sel->setHideLinkUnselected(b);
3561 void MapEditor::importDirInt(BranchObj *dst, QDir d) // FIXME missing saveState
3563 BranchObj *bo=xelection.getBranch();
3566 // Traverse directories
3567 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3568 QFileInfoList list = d.entryInfoList();
3571 for (int i = 0; i < list.size(); ++i)
3574 if (fi.fileName() != "." && fi.fileName() != ".." )
3577 bo=dst->getLastBranch();
3578 bo->setHeading (fi.fileName() );
3579 bo->setColor (QColor("blue"));
3581 if ( !d.cd(fi.fileName()) )
3582 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3585 // Recursively add subdirs
3586 importDirInt (bo,d);
3592 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3593 list = d.entryInfoList();
3595 for (int i = 0; i < list.size(); ++i)
3599 bo=dst->getLastBranch();
3600 bo->setHeading (fi.fileName() );
3601 bo->setColor (QColor("black"));
3602 if (fi.fileName().right(4) == ".vym" )
3603 bo->setVymLink (fi.filePath());
3608 void MapEditor::importDir()
3610 BranchObj *bo=xelection.getBranch();
3613 QStringList filters;
3614 filters <<"VYM map (*.vym)";
3615 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3616 fd->setMode (QFileDialog::DirectoryOnly);
3617 fd->setFilters (filters);
3618 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3622 if ( fd->exec() == QDialog::Accepted )
3624 importDirInt (bo,QDir(fd->selectedFile()) );
3625 mapCenter->reposition();
3631 void MapEditor::followXLink(int i)
3633 BranchObj *bo=xelection.getBranch();
3636 bo=bo->XLinkTargetAt(i);
3639 xelection.select(bo);
3640 ensureSelectionVisible();
3645 void MapEditor::editXLink(int i) // FIXME missing saveState
3647 BranchObj *bo=xelection.getBranch();
3650 XLinkObj *xlo=bo->XLinkAt(i);
3653 EditXLinkDialog dia;
3655 dia.setSelection(bo);
3656 if (dia.exec() == QDialog::Accepted)
3658 if (dia.useSettingsGlobal() )
3660 setMapDefXLinkColor (xlo->getColor() );
3661 setMapDefXLinkWidth (xlo->getWidth() );
3663 if (dia.deleteXLink())
3664 bo->deleteXLinkAt(i);
3670 void MapEditor::testFunction()
3672 // This is the playground
3674 BranchObj *bo=xelection.getBranch();
3675 if (bo) animObjList.append( bo );
3679 dia.showCancelButton (true);
3680 dia.setText("This is a longer \nWarning");
3681 dia.setCaption("Warning: Flux problem");
3682 dia.setShowAgainName("mapeditor/testDialog");
3683 if (dia.exec()==QDialog::Accepted)
3684 cout << "accepted!\n";
3686 cout << "canceled!\n";
3690 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
3691 if (hidemode==HideNone)
3693 setHideTmpMode (HideExport);
3694 mapCenter->calcBBoxSizeWithChilds();
3695 QRectF totalBBox=mapCenter->getTotalBBox();
3696 QRectF mapRect=totalBBox;
3697 QCanvasRectangle *frame=NULL;
3699 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3701 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3702 totalBBox.width(), totalBBox.height());
3703 frame=new QCanvasRectangle (mapRect,mapScene);
3704 frame->setBrush (QColor(white));
3705 frame->setPen (QColor(black));
3706 frame->setZValue(0);
3711 setHideTmpMode (HideNone);
3713 cout <<" hidemode="<<hidemode<<endl;
3717 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3719 // Lineedits are already closed by preceding
3720 // mouseEvent, we don't need to close here.
3722 QPointF p = mapToScene(e->pos());
3723 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3726 { // MapObj was found
3727 if (xelection.single() != lmo)
3729 // select the MapObj
3730 xelection.select(lmo);
3733 if (xelection.getBranch() )
3735 // Context Menu on branch or mapcenter
3737 branchContextMenu->popup(e->globalPos() );
3740 if (xelection.getFloatImage() )
3742 // Context Menu on floatimage
3744 floatimageContextMenu->popup(e->globalPos() );
3748 { // No MapObj found, we are on the Canvas itself
3749 // Context Menu on scene
3751 canvasContextMenu->popup(e->globalPos() );
3756 void MapEditor::keyPressEvent(QKeyEvent* e)
3758 if (e->modifiers() & Qt::ControlModifier)
3760 switch (mainWindow->getModMode())
3762 case Main::ModModeColor:
3763 setCursor (PickColorCursor);
3765 case Main::ModModeCopy:
3766 setCursor (CopyCursor);
3768 case Main::ModModeXLink:
3769 setCursor (XLinkCursor);
3772 setCursor (Qt::ArrowCursor);
3778 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3780 if (!(e->modifiers() & Qt::ControlModifier))
3781 setCursor (Qt::ArrowCursor);
3784 void MapEditor::mousePressEvent(QMouseEvent* e)
3786 // Ignore right clicks, these will go to context menus
3787 if (e->button() == Qt::RightButton )
3793 QPointF p = mapToScene(e->pos());
3794 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3798 //Take care of system flags _or_ modifier modes
3800 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3801 typeid(*lmo)==typeid(MapCenterObj) ))
3803 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3804 if (!foname.isEmpty())
3806 // systemFlag clicked
3810 if (e->state() & Qt::ControlModifier)
3811 mainWindow->editOpenURLTab();
3813 mainWindow->editOpenURL();
3815 else if (foname=="vymLink")
3817 mainWindow->editOpenVymLink();
3818 // tabWidget may change, better return now
3819 // before segfaulting...
3820 } else if (foname=="note")
3821 mainWindow->windowToggleNoteEditor();
3822 else if (foname=="hideInExport")
3829 // No system flag clicked, take care of modmodes (CTRL-Click)
3830 if (e->state() & Qt::ControlModifier)
3832 if (mainWindow->getModMode()==Main::ModModeColor)
3835 setCursor (PickColorCursor);
3838 if (mainWindow->getModMode()==Main::ModModeXLink)
3840 BranchObj *bo_begin=NULL;
3842 bo_begin=(BranchObj*)(lmo);
3844 if (xelection.getBranch() )
3845 bo_begin=xelection.getBranch();
3849 linkingObj_src=bo_begin;
3850 tmpXLink=new XLinkObj (mapScene);
3851 tmpXLink->setBegin (bo_begin);
3852 tmpXLink->setEnd (p);
3853 tmpXLink->setColor(defXLinkColor);
3854 tmpXLink->setWidth(defXLinkWidth);
3855 tmpXLink->updateXLink();
3856 tmpXLink->setVisibility (true);
3860 } // End of modmodes
3864 // Select the clicked object
3867 // Left Button Move Branches
3868 if (e->button() == Qt::LeftButton )
3870 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
3871 //movingObj_start.setY( p.y() - selection->y() );
3872 movingObj_start.setX( p.x() - lmo->x() );
3873 movingObj_start.setY( p.y() - lmo->y() );
3874 movingObj_orgPos.setX (lmo->x() );
3875 movingObj_orgPos.setY (lmo->y() );
3876 movingObj_orgRelPos=lmo->getRelPos();
3878 // If modMode==copy, then we want to "move" the _new_ object around
3879 // then we need the offset from p to the _old_ selection, because of tmp
3880 if (mainWindow->getModMode()==Main::ModModeCopy &&
3881 e->state() & Qt::ControlModifier)
3883 if (xelection.type()==Branch)
3886 mapCenter->addBranch ((BranchObj*)xelection.single());
3888 xelection.select(mapCenter->getLastBranch());
3889 mapCenter->reposition();
3893 movingObj=xelection.single();
3895 // Middle Button Toggle Scroll
3896 // (On Mac OS X this won't work, but we still have
3897 // a button in the toolbar)
3898 if (e->button() == Qt::MidButton )
3903 { // No MapObj found, we are on the scene itself
3904 // Left Button move Pos of sceneView
3905 if (e->button() == Qt::LeftButton )
3907 movingObj=NULL; // move Content not Obj
3908 movingObj_start=e->globalPos();
3909 movingCont_start=QPointF (
3910 horizontalScrollBar()->value(),
3911 verticalScrollBar()->value());
3912 movingVec=QPointF(0,0);
3913 setCursor(HandOpenCursor);
3918 void MapEditor::mouseMoveEvent(QMouseEvent* e)
3920 QPointF p = mapToScene(e->pos());
3921 LinkableMapObj *lmosel=xelection.single();
3923 // Move the selected MapObj
3924 if ( lmosel && movingObj)
3926 // reset cursor if we are moving and don't copy
3927 if (mainWindow->getModMode()!=Main::ModModeCopy)
3928 setCursor (Qt::ArrowCursor);
3930 // To avoid jumping of the sceneView, only
3931 // ensureSelectionVisible, if not tmp linked
3932 if (!lmosel->hasParObjTmp())
3933 ensureSelectionVisible ();
3935 // Now move the selection, but add relative position
3936 // (movingObj_start) where selection was chosen with
3937 // mousepointer. (This avoids flickering resp. jumping
3938 // of selection back to absPos)
3940 // Check if we could link
3941 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3944 FloatObj *fio=xelection.getFloatImage();
3947 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3949 fio->updateLink(); //no need for reposition, if we update link here
3952 // Relink float to new mapcenter or branch, if shift is pressed
3953 // Only relink, if selection really has a new parent
3954 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3955 ( (typeid(*lmo)==typeid(BranchObj)) ||
3956 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3957 ( lmo != fio->getParObj())
3960 if (typeid(*fio) == typeid(FloatImageObj) &&
3961 ( (typeid(*lmo)==typeid(BranchObj) ||
3962 typeid(*lmo)==typeid(MapCenterObj)) ))
3965 // Also save the move which was done so far
3966 QString pold=qpointfToString(movingObj_orgRelPos);
3967 QString pnow=qpointfToString(fio->getRelPos());
3973 QString("Move %1 to relativ position %2").arg(getName(fio)).arg(pnow));
3974 fio->getParObj()->requestReposition();
3975 mapCenter->reposition();
3977 linkTo (lmo->getSelectString());
3979 //movingObj_orgRelPos=lmosel->getRelPos();
3981 mapCenter->reposition();
3985 { // selection != a FloatObj
3986 if (lmosel->getDepth()==0)
3989 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3990 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3992 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3993 mapCenter->updateRelPositions();
3996 if (lmosel->getDepth()==1)
3999 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4000 lmosel->setRelPos();
4003 // Move ordinary branch
4004 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
4005 // Add width of bbox here, otherwise alignRelTo will cause jumping around
4006 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
4007 p.y()-movingObj_start.y() +lmosel->getTopPad() );
4009 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
4012 // Maybe we can relink temporary?
4013 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
4014 (typeid(*lmo)==typeid(BranchObj) ||
4015 typeid(*lmo)==typeid(MapCenterObj)) )
4018 if (e->modifiers()==Qt::ControlModifier)
4020 // Special case: CTRL to link below lmo
4021 lmosel->setParObjTmp (lmo,p,+1);
4023 else if (e->modifiers()==Qt::ShiftModifier)
4024 lmosel->setParObjTmp (lmo,p,-1);
4026 lmosel->setParObjTmp (lmo,p,0);
4029 lmosel->unsetParObjTmp();
4031 // reposition subbranch
4032 lmosel->reposition();
4036 } // no FloatImageObj
4040 } // selection && moving_obj
4042 // Draw a link from one branch to another
4045 tmpXLink->setEnd (p);
4046 tmpXLink->updateXLink();
4050 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
4052 QPointF p=e->globalPos();
4053 movingVec.setX(-p.x() + movingObj_start.x() );
4054 movingVec.setY(-p.y() + movingObj_start.y() );
4055 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
4056 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
4061 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
4063 QPointF p = mapToScene(e->pos());
4064 LinkableMapObj *dst;
4065 LinkableMapObj *lmosel=xelection.single();
4066 // Have we been picking color?
4070 setCursor (Qt::ArrowCursor);
4071 // Check if we are over another branch
4072 dst=mapCenter->findMapObj(p, NULL);
4075 if (e->state() & Qt::ShiftModifier)
4076 colorBranch (((BranchObj*)(dst))->getColor());
4078 colorSubtree (((BranchObj*)(dst))->getColor());
4083 // Have we been drawing a link?
4084 if (drawingLink) //FIXME savestate missing
4087 // Check if we are over another branch
4088 dst=mapCenter->findMapObj(p, NULL);
4091 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
4092 tmpXLink->updateXLink();
4093 tmpXLink->activate();
4094 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );
4103 // Have we been moving something?
4104 if ( lmosel && movingObj )
4106 FloatImageObj *fo=xelection.getFloatImage();
4109 // Moved FloatObj. Maybe we need to reposition
4110 QString pold=qpointfToString(movingObj_orgRelPos);
4111 QString pnow=qpointfToString(fo->getRelPos());
4117 QString("Move %1 to relativ position %2").arg(getName(fo)).arg(pnow));
4119 fo->getParObj()->requestReposition();
4120 mapCenter->reposition();
4123 // Check if we are over another branch, but ignore
4124 // any found LMOs, which are FloatObjs
4125 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
4127 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4130 if (xelection.type() == MapCenter )
4131 { // FIXME The MapCenter was moved, no savestate yet
4134 if (xelection.type() == Branch )
4135 { // A branch was moved
4137 // save the position in case we link to mapcenter
4138 QPointF savePos=QPointF (lmosel->getAbsPos() );
4140 // Reset the temporary drawn link to the original one
4141 lmosel->unsetParObjTmp();
4143 // For Redo we may need to save original selection
4144 QString preSelStr=lmosel->getSelectString();
4149 BranchObj* bsel=xelection.getBranch();
4150 BranchObj* bdst=(BranchObj*)dst;
4152 QString preParStr=(bsel->getParObj())->getSelectString();
4153 QString preNum=QString::number (bsel->getNum(),10);
4154 QString preDstParStr;
4156 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4158 preDstParStr=dst->getParObj()->getSelectString();
4159 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4161 if (e->state() & Qt::ControlModifier && dst->getParObj())
4164 preDstParStr=dst->getParObj()->getSelectString();
4165 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4168 preDstParStr=dst->getSelectString();
4169 bsel->linkTo (bdst,-1);
4170 if (dst->getDepth()==0) bsel->move (savePos);
4172 QString postSelStr=lmosel->getSelectString();
4173 QString postNum=QString::number (bsel->getNum(),10);
4175 QString undoCom="linkTo (\""+
4176 preParStr+ "\"," + preNum +"," +
4177 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4179 QString redoCom="linkTo (\""+
4180 preDstParStr + "\"," + postNum + "," +
4181 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4186 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4188 if (lmosel->getDepth()==1)
4190 // The select string might be different _after_ moving around.
4191 // Therefor reposition and then use string of old selection, too
4192 mapCenter->reposition();
4194 QString ps=qpointfToString ( lmosel->getRelPos() );
4196 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4197 preSelStr, "moveRel "+ps,
4198 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4201 // Draw the original link, before selection was moved around
4202 mapCenter->reposition();
4205 // Finally resize scene, if needed
4209 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4212 // maybe we moved View: set old cursor
4213 setCursor (Qt::ArrowCursor);
4217 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4219 if (e->button() == Qt::LeftButton )
4221 QPointF p = mapToScene(e->pos());
4222 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4223 if (lmo) { // MapObj was found
4224 // First select the MapObj than edit heading
4225 xelection.select(lmo);
4226 mainWindow->editHeading();
4231 void MapEditor::resizeEvent (QResizeEvent* e)
4233 QGraphicsView::resizeEvent( e );
4236 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4238 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4239 // cerr << event->format(i) << endl;
4241 if (event->mimeData()->hasImage())
4242 event->acceptProposedAction();
4244 if (event->mimeData()->hasUrls())
4245 event->acceptProposedAction();
4248 void MapEditor::dragMoveEvent(QDragMoveEvent *event)
4252 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4257 void MapEditor::dropEvent(QDropEvent *event)
4259 BranchObj *sel=xelection.getBranch();
4263 if (event->mimeData()->hasImage())
4265 QVariant imageData = event->mimeData()->imageData();
4266 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4268 if (event->mimeData()->hasUrls())
4269 uris=event->mimeData()->urls();
4277 for (int i=0; i<uris.count();i++)
4279 // Workaround to avoid adding empty branches
4280 if (!uris.at(i).toString().isEmpty())
4282 bo=sel->addBranch();
4285 s=uris.at(i).toLocalFile();
4288 QString file = QDir::convertSeparators(s);
4289 heading = QFileInfo(file).baseName();
4291 if (file.endsWith(".vym", false))
4292 bo->setVymLink(file);
4294 bo->setURL(uris.at(i).toString());
4297 bo->setURL(uris.at(i).toString());
4300 if (!heading.isEmpty())
4301 bo->setHeading(heading);
4303 bo->setHeading(uris.at(i).toString());
4307 mapCenter->reposition();
4310 event->acceptProposedAction();
4313 void MapEditor::timerEvent(QTimerEvent *event) //FIXME testing
4317 cout << "ME::timerEvent\n";
4319 for (int i=0; i<animObjList.size(); ++i)
4321 animObjList.at(i)->animate();
4322 ((BranchObj*)animObjList.at(i))->move2RelPos (((BranchObj*)animObjList.at(i))->getRelPos() );
4324 mapCenter->reposition();
4327 void MapEditor::autosave()
4329 if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/used",true).toBool() )
4330 mainWindow->fileSave (this);
4334 /*FIXME not needed? void MapEditor::contentsDropEvent(QDropEvent *event)
4337 } else if (event->provides("application/x-moz-file-promise-url") &&
4338 event->provides("application/x-moz-nativeimage"))
4340 // Contains url to the img src in unicode16
4341 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4342 QString url = QString((const QChar*)d.data(),d.size()/2);
4346 } else if (event->provides ("text/uri-list"))
4347 { // Uris provided e.g. by konqueror
4348 Q3UriDrag::decode (event,uris);
4349 } else if (event->provides ("_NETSCAPE_URL"))
4350 { // Uris provided by Mozilla
4351 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4354 } else if (event->provides("text/html")) {
4356 // Handels text mime types
4357 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4358 QByteArray d = event->encodedData("text/html");
4361 text = QString((const QChar*)d.data(),d.size()/2);
4365 textEditor->setText(text);
4369 } else if (event->provides("text/plain")) {
4370 QByteArray d = event->encodedData("text/plain");
4373 text = QString((const QChar*)d.data(),d.size()/2);
4377 textEditor->setText(text);
4387 bool isUnicode16(const QByteArray &d)
4389 // TODO: make more precise check for unicode 16.
4390 // Guess unicode16 if any of second bytes are zero
4391 unsigned int length = max(0,d.size()-2)/2;
4392 for (unsigned int i = 0; i<length ; i++)
4393 if (d.at(i*2+1)==0) return true;
4397 void MapEditor::addFloatImageInt (const QPixmap &img)
4399 BranchObj *bo=xelection.getBranch();
4402 FloatImageObj *fio=bo->addFloatImage();
4404 fio->setOriginalFilename("Image added by Drag and Drop"); // FIXME savestate
4405 mapCenter->reposition();
4412 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4414 if (!imageBuffer) imageBuffer = new QBuffer();
4415 if (!imageBuffer->isOpen()) {
4416 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4418 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4422 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4424 if (nop->state()==Q3NetworkProtocol::StDone) {
4425 QPixmap img(imageBuffer->buffer());
4426 addFloatImageInt (img);
4430 imageBuffer->close();
4432 imageBuffer->close();
4439 void MapEditor::fetchImage(const QString &url)
4442 urlOperator->stop();
4443 disconnect(urlOperator);
4447 urlOperator = new Q3UrlOperator(url);
4448 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4449 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4451 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4452 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));