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;
30 extern FlagRowObj *standardFlagsDefault;
32 extern QMenu* branchContextMenu;
33 extern QMenu* branchAddContextMenu;
34 extern QMenu* branchRemoveContextMenu;
35 extern QMenu* branchLinksContextMenu;
36 extern QMenu* branchXLinksContextMenuEdit;
37 extern QMenu* branchXLinksContextMenuFollow;
38 extern QMenu* floatimageContextMenu;
39 extern QMenu* canvasContextMenu;
42 extern Settings settings;
43 extern ImageIO imageIO;
45 extern QString vymName;
46 extern QString vymVersion;
48 extern QString iconPath;
49 extern QDir vymBaseDir;
50 extern QDir lastImageDir;
51 extern QDir lastFileDir;
53 int MapEditor::mapNum=0; // make instance
55 ///////////////////////////////////////////////////////////////////////
56 ///////////////////////////////////////////////////////////////////////
57 MapEditor::MapEditor( QWidget* parent) :
60 //cout << "Constructor ME "<<this<<endl;
64 mapScene= new QGraphicsScene(parent);
65 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
66 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
71 mapCenter = new MapCenterObj(mapScene);
72 mapCenter->setVisibility (true);
73 mapCenter->setMapEditor (this);
74 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
75 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
80 defLinkColor=QColor (0,0,255);
81 defXLinkColor=QColor (180,180,180);
82 linkcolorhint=DefaultColor;
83 linkstyle=StylePolyParabel;
85 // Create bitmap cursors, platform dependant
86 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
87 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
88 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
89 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
91 setFocusPolicy (Qt::StrongFocus);
100 xelection.setMapEditor (this);
101 xelection.unselect();
104 defXLinkColor=QColor (230,230,230);
112 fileName=tr("unnamed");
115 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
116 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
118 // Initialize find routine
125 blockReposition=false;
126 blockSaveState=false;
130 // Create temporary files
133 setAcceptDrops (true);
135 mapCenter->reposition(); // for positioning heading
139 MapEditor::~MapEditor()
141 //cout <<"Destructor MapEditor\n";
144 MapCenterObj* MapEditor::getMapCenter()
149 QGraphicsScene * MapEditor::getScene()
154 bool MapEditor::isRepositionBlocked()
156 return blockReposition;
159 QString MapEditor::getName (const LinkableMapObj *lmo)
162 if (!lmo) return QString("Error: NULL has no name!");
164 if ((typeid(*lmo) == typeid(BranchObj) ||
165 typeid(*lmo) == typeid(MapCenterObj)))
168 s=(((BranchObj*)lmo)->getHeading());
169 if (s=="") s="unnamed";
170 return QString("branch (%1)").arg(s);
171 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
173 if ((typeid(*lmo) == typeid(FloatImageObj) ))
174 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
175 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
176 return QString("Unknown type has no name!");
179 void MapEditor::makeTmpDirs()
181 // Create unique temporary directories
182 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
183 histPath=QDir::convertSeparators (tmpMapDir+"/history");
188 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
190 // tmpdir temporary directory to which data will be written
191 // prefix mapname, which will be appended to images etc.
192 // writeflags Only write flags for "real" save of map, not undo
193 // offset offset of bbox of whole map in scene.
194 // Needed for XML export
210 ls="StylePolyParabel";
214 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
216 if (linkcolorhint==HeadingColor)
217 colhint=attribut("linkColorHint","HeadingColor");
219 QString mapAttr=attribut("version",vymVersion);
220 if (!saveSel || saveSel==mapCenter)
221 mapAttr+= attribut("author",mapCenter->getAuthor()) +
222 attribut("comment",mapCenter->getComment()) +
223 attribut("date",mapCenter->getDate()) +
224 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
225 attribut("selectionColor", xelection.getColor().name() ) +
226 attribut("linkStyle", ls ) +
227 attribut("linkColor", defLinkColor.name() ) +
228 attribut("defXLinkColor", defXLinkColor.name() ) +
229 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
231 s+=beginElement("vymmap",mapAttr);
234 // Find the used flags while traversing the tree
235 standardFlagsDefault->resetUsedCounter();
237 // Reset the counters before saving
238 // TODO constr. of FIO creates lots of objects, better do this in some other way...
239 FloatImageObj (mapScene).resetSaveCounter();
241 // Build xml recursivly
242 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
243 // Save complete map, if saveSel not set
244 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
247 if ( typeid(*saveSel) == typeid(BranchObj) )
249 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
250 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
252 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
255 // Save local settings
256 s+=settings.getXMLData (destPath);
259 if (!xelection.isEmpty() && !saveSel )
260 s+=valueElement("select",xelection.getSelectString());
263 s+=endElement("vymmap");
266 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
270 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
272 // save the selected part of the map, Undo will replace part of map
273 QString undoSelection="";
275 undoSelection=undoSel->getSelectString();
277 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
278 QString redoSelection="";
280 redoSelection=undoSel->getSelectString();
282 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
285 saveState (PartOfMap,
286 undoSelection, "addMapReplace (\"PATH\")",
292 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
296 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
299 QString undoSelection=redoSel->getParObj()->getSelectString();
300 QString redoSelection=redoSel->getSelectString();
301 if (typeid(*redoSel) == typeid(BranchObj) )
303 // save the selected branch of the map, Undo will insert part of map
304 saveState (PartOfMap,
305 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
306 redoSelection, "delete ()",
313 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
315 // "Normal" savestate: save commands, selections and comment
316 // so just save commands for undo and redo
317 // and use current selection
319 QString redoSelection="";
320 if (redoSel) redoSelection=redoSel->getSelectString();
321 QString undoSelection="";
322 if (undoSel) undoSelection=undoSel->getSelectString();
324 saveState (UndoCommand,
331 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
333 // "Normal" savestate: save commands, selections and comment
334 // so just save commands for undo and redo
335 // and use current selection
336 saveState (UndoCommand,
344 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
348 if (blockSaveState) return;
350 /* TODO remove after testing
352 cout << "ME::saveState() "<<endl;
354 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
355 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
356 int curStep=undoSet.readNumEntry ("/history/curStep",0);
357 // Find out current undo directory
358 if (undosAvail<stepsTotal) undosAvail++;
360 if (curStep>stepsTotal) curStep=1;
362 QString backupXML="";
363 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
364 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
365 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
367 // Create bakMapDir if not available
370 makeSubDirs (bakMapDir);
372 // Save depending on how much needs to be saved
374 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPointF (),saveSel);
376 QString undoCommand="";
377 if (savemode==UndoCommand)
381 else if (savemode==PartOfMap )
384 undoCommand.replace ("PATH",bakMapPath);
387 if (!backupXML.isEmpty())
388 // Write XML Data to disk
389 saveStringToDisk (QString(bakMapPath),backupXML);
391 // We would have to save all actions in a tree, to keep track of
392 // possible redos after a action. Possible, but we are too lazy: forget about redos.
395 // Write the current state to disk
396 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
397 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
398 undoSet.setEntry ("/history/curStep",QString::number(curStep));
399 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
400 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
401 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
402 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
403 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
404 undoSet.setEntry (QString("/history/version"),vymVersion);
405 undoSet.writeSettings(histPath);
407 /* TODO remove after testing
409 //cout << " into="<< histPath.toStdString()<<endl;
410 cout << " stepsTotal="<<stepsTotal<<
411 ", undosAvail="<<undosAvail<<
412 ", redosAvail="<<redosAvail<<
413 ", curStep="<<curStep<<endl;
414 cout << " ---------------------------"<<endl;
415 cout << " comment="<<comment.toStdString()<<endl;
416 cout << " undoCom="<<undoCommand.toStdString()<<endl;
417 cout << " undoSel="<<undoSelection.toStdString()<<endl;
418 cout << " redoCom="<<redoCom.toStdString()<<endl;
419 cout << " redoSel="<<redoSelection.toStdString()<<endl;
420 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
421 cout << " ---------------------------"<<endl;
423 mainWindow->updateHistory (undoSet);
428 void MapEditor::parseAtom(const QString &atom)
430 BranchObj *selb=xelection.getBranch();
435 // Split string s into command and parameters
436 parser.parseAtom (atom);
437 QString com=parser.getCommand();
440 if (com=="addBranch")
442 if (xelection.isEmpty())
444 parser.setError (Aborted,"Nothing selected");
447 parser.setError (Aborted,"Type of selection is not a branch");
452 if (parser.checkParamCount(pl))
454 if (parser.paramCount()==0)
455 addNewBranchInt (-2);
458 y=parser.parInt (ok,0);
459 if (ok ) addNewBranchInt (y);
463 } else if (com=="addBranchBefore")
465 if (xelection.isEmpty())
467 parser.setError (Aborted,"Nothing selected");
470 parser.setError (Aborted,"Type of selection is not a branch");
473 if (parser.paramCount()==0)
475 addNewBranchBefore ();
478 } else if (com==QString("addMapReplace"))
480 if (xelection.isEmpty())
482 parser.setError (Aborted,"Nothing selected");
485 parser.setError (Aborted,"Type of selection is not a branch");
486 } else if (parser.checkParamCount(1))
488 //s=parser.parString (ok,0); // selection
489 t=parser.parString (ok,0); // path to map
490 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
491 addMapReplaceInt(selb->getSelectString(),t);
493 } else if (com==QString("addMapInsert"))
495 if (xelection.isEmpty())
497 parser.setError (Aborted,"Nothing selected");
500 parser.setError (Aborted,"Type of selection is not a branch");
503 if (parser.checkParamCount(2))
505 t=parser.parString (ok,0); // path to map
506 y=parser.parInt(ok,1); // position
507 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
508 addMapInsertInt(t,y);
511 } else if (com=="clearFlags")
513 if (xelection.isEmpty() )
515 parser.setError (Aborted,"Nothing selected");
518 parser.setError (Aborted,"Type of selection is not a branch");
519 } else if (parser.checkParamCount(0))
521 selb->clearStandardFlags();
522 selb->updateFlagsToolbar();
524 } else if (com=="colorBranch")
526 if (xelection.isEmpty())
528 parser.setError (Aborted,"Nothing selected");
531 parser.setError (Aborted,"Type of selection is not a branch");
532 } else if (parser.checkParamCount(1))
534 QColor c=parser.parColor (ok,0);
535 if (ok) colorBranch (c);
537 } else if (com=="colorSubtree")
539 cout << "atom="<< atom.ascii()<<endl;
540 if (xelection.isEmpty())
542 parser.setError (Aborted,"Nothing selected");
545 parser.setError (Aborted,"Type of selection is not a branch");
546 } else if (parser.checkParamCount(1))
548 QColor c=parser.parColor (ok,0);
549 if (ok) colorSubtree (c);
551 } else if (com=="cut")
553 if (xelection.isEmpty())
555 parser.setError (Aborted,"Nothing selected");
556 } else if ( xelection.type()!=Branch &&
557 xelection.type()!=MapCenter &&
558 xelection.type()!=FloatImage )
560 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
561 } else if (parser.checkParamCount(0))
565 } else if (com=="delete")
567 if (xelection.isEmpty())
569 parser.setError (Aborted,"Nothing selected");
570 } else if (xelection.type() != Branch && xelection.type() != FloatImage )
572 parser.setError (Aborted,"Type of selection is wrong.");
573 } else if (parser.checkParamCount(0))
577 } else if (com=="deleteKeepChilds")
579 if (xelection.isEmpty())
581 parser.setError (Aborted,"Nothing selected");
584 parser.setError (Aborted,"Type of selection is not a branch");
585 } else if (parser.checkParamCount(0))
589 } else if (com=="deleteChilds")
591 if (xelection.isEmpty())
593 parser.setError (Aborted,"Nothing selected");
596 parser.setError (Aborted,"Type of selection is not a branch");
597 } else if (parser.checkParamCount(0))
601 } else if (com=="linkTo")
603 if (xelection.isEmpty())
605 parser.setError (Aborted,"Nothing selected");
608 if (parser.checkParamCount(4))
610 // 0 selectstring of parent
611 // 1 num in parent (for branches)
612 // 2,3 x,y of mainbranch or mapcenter
613 s=parser.parString(ok,0);
614 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
617 if (typeid(*dst) == typeid(BranchObj) )
619 // Get number in parent
620 x=parser.parInt (ok,1);
622 selb->linkTo ((BranchObj*)(dst),x);
623 } else if (typeid(*dst) == typeid(MapCenterObj) )
625 selb->linkTo ((BranchObj*)(dst),-1);
626 // Get coordinates of mainbranch
627 x=parser.parInt (ok,2);
630 y=parser.parInt (ok,3);
631 if (ok) selb->move (x,y);
636 } else if ( xelection.type() == FloatImage)
638 if (parser.checkParamCount(1))
640 // 0 selectstring of parent
641 s=parser.parString(ok,0);
642 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
645 if (typeid(*dst) == typeid(BranchObj) ||
646 typeid(*dst) == typeid(MapCenterObj))
647 linkTo (dst->getSelectString());
649 parser.setError (Aborted,"Destination is not a branch");
652 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
653 } else if (com=="loadImage")
655 if (xelection.isEmpty())
657 parser.setError (Aborted,"Nothing selected");
660 parser.setError (Aborted,"Type of selection is not a branch");
661 } else if (parser.checkParamCount(1))
663 s=parser.parString(ok,0);
664 if (ok) loadFloatImageInt (s);
666 } else if (com=="moveBranchUp")
668 if (xelection.isEmpty() )
670 parser.setError (Aborted,"Nothing selected");
673 parser.setError (Aborted,"Type of selection is not a branch");
674 } else if (parser.checkParamCount(0))
678 } else if (com=="moveBranchDown")
680 if (xelection.isEmpty() )
682 parser.setError (Aborted,"Nothing selected");
685 parser.setError (Aborted,"Type of selection is not a branch");
686 } else if (parser.checkParamCount(0))
690 } else if (com=="move")
692 if (xelection.isEmpty() )
694 parser.setError (Aborted,"Nothing selected");
695 } else if ( xelection.type()!=Branch &&
696 xelection.type()!=MapCenter &&
697 xelection.type()!=FloatImage )
699 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
700 } else if (parser.checkParamCount(2))
702 x=parser.parInt (ok,0);
705 y=parser.parInt (ok,1);
709 } else if (com=="moveRel")
711 if (xelection.isEmpty() )
713 parser.setError (Aborted,"Nothing selected");
714 } else if ( xelection.type()!=Branch &&
715 xelection.type()!=MapCenter &&
716 xelection.type()!=FloatImage )
718 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
719 } else if (parser.checkParamCount(2))
721 x=parser.parInt (ok,0);
724 y=parser.parInt (ok,1);
725 if (ok) moveRel (x,y);
728 } else if (com=="paste")
730 if (xelection.isEmpty() )
732 parser.setError (Aborted,"Nothing selected");
735 parser.setError (Aborted,"Type of selection is not a branch");
736 } else if (parser.checkParamCount(0))
740 } else if (com=="saveImage")
742 FloatImageObj *fio=xelection.getFloatImage();
745 parser.setError (Aborted,"Type of selection is not an image");
746 } else if (parser.checkParamCount(2))
748 s=parser.parString(ok,0);
751 t=parser.parString(ok,1);
752 if (ok) saveFloatImageInt (fio,t,s);
755 } else if (com=="scroll")
757 if (xelection.isEmpty() )
759 parser.setError (Aborted,"Nothing selected");
762 parser.setError (Aborted,"Type of selection is not a branch");
763 } else if (parser.checkParamCount(0))
765 if (!scrollBranch ())
766 parser.setError (Aborted,"Could not scroll branch");
768 } else if (com=="select")
770 if (parser.checkParamCount(1))
772 s=parser.parString(ok,0);
775 } else if (com=="selectLastBranch")
777 if (xelection.isEmpty() )
779 parser.setError (Aborted,"Nothing selected");
782 parser.setError (Aborted,"Type of selection is not a branch");
783 } else if (parser.checkParamCount(0))
785 BranchObj *bo=selb->getLastBranch();
787 parser.setError (Aborted,"Could not select last branch");
791 } else if (com=="selectLastImage")
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 FloatImageObj *fio=selb->getLastFloatImage();
803 parser.setError (Aborted,"Could not select last image");
807 } else if (com=="setMapAuthor")
809 if (parser.checkParamCount(1))
811 s=parser.parString(ok,0);
812 if (ok) setMapAuthor (s);
814 } else if (com=="setMapComment")
816 if (parser.checkParamCount(1))
818 s=parser.parString(ok,0);
819 if (ok) setMapComment(s);
821 } else if (com=="setMapBackgroundColor")
823 if (xelection.isEmpty() )
825 parser.setError (Aborted,"Nothing selected");
826 } else if (! xelection.getBranch() )
828 parser.setError (Aborted,"Type of selection is not a branch");
829 } else if (parser.checkParamCount(1))
831 QColor c=parser.parColor (ok,0);
832 if (ok) setMapBackgroundColor (c);
834 } else if (com=="setMapDefLinkColor")
836 if (xelection.isEmpty() )
838 parser.setError (Aborted,"Nothing selected");
841 parser.setError (Aborted,"Type of selection is not a branch");
842 } else if (parser.checkParamCount(1))
844 QColor c=parser.parColor (ok,0);
845 if (ok) setMapDefLinkColor (c);
847 } else if (com=="setMapLinkStyle")
849 if (parser.checkParamCount(1))
851 s=parser.parString (ok,0);
852 if (ok) setMapLinkStyle(s);
854 } else if (com=="setHeading")
856 if (xelection.isEmpty() )
858 parser.setError (Aborted,"Nothing selected");
861 parser.setError (Aborted,"Type of selection is not a branch");
862 } else if (parser.checkParamCount(1))
864 s=parser.parString (ok,0);
868 } else if (com=="setHideExport")
870 if (xelection.isEmpty() )
872 parser.setError (Aborted,"Nothing selected");
875 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
876 //FIXME selb is never a floatimage!!
877 } else if (parser.checkParamCount(1))
879 b=parser.parBool(ok,0);
880 if (ok) setHideExport (b);
882 } else if (com=="setIncludeImagesHorizontally")
884 if (xelection.isEmpty() )
886 parser.setError (Aborted,"Nothing selected");
889 parser.setError (Aborted,"Type of selection is not a branch");
890 } else if (parser.checkParamCount(1))
892 b=parser.parBool(ok,0);
893 if (ok) setIncludeImagesHor(b);
895 } else if (com=="setIncludeImagesVertically")
897 if (xelection.isEmpty() )
899 parser.setError (Aborted,"Nothing selected");
902 parser.setError (Aborted,"Type of selection is not a branch");
903 } else if (parser.checkParamCount(1))
905 b=parser.parBool(ok,0);
906 if (ok) setIncludeImagesVer(b);
908 } else if (com=="setSelectionColor")
910 if (parser.checkParamCount(1))
912 QColor c=parser.parColor (ok,0);
913 if (ok) setSelectionColorInt (c);
915 } else if (com=="setURL")
917 if (xelection.isEmpty() )
919 parser.setError (Aborted,"Nothing selected");
922 parser.setError (Aborted,"Type of selection is not a branch");
923 } else if (parser.checkParamCount(1))
925 s=parser.parString (ok,0);
926 if (ok) setURLInt(s);
928 } else if (com=="setVymLink")
930 if (xelection.isEmpty() )
932 parser.setError (Aborted,"Nothing selected");
935 parser.setError (Aborted,"Type of selection is not a branch");
936 } else if (parser.checkParamCount(1))
938 s=parser.parString (ok,0);
939 if (ok) setVymLinkInt(s);
942 else if (com=="setFlag")
944 if (xelection.isEmpty() )
946 parser.setError (Aborted,"Nothing selected");
949 parser.setError (Aborted,"Type of selection is not a branch");
950 } else if (parser.checkParamCount(1))
952 s=parser.parString(ok,0);
955 selb->activateStandardFlag(s);
956 selb->updateFlagsToolbar();
959 } else if (com=="setFrameType")
961 if (xelection.isEmpty() )
963 parser.setError (Aborted,"Nothing selected");
966 parser.setError (Aborted,"Type of selection is not a branch");
967 } else if (parser.checkParamCount(1))
969 s=parser.parString(ok,0);
973 } else if (com=="toggleFlag")
975 if (xelection.isEmpty() )
977 parser.setError (Aborted,"Nothing selected");
980 parser.setError (Aborted,"Type of selection is not a branch");
981 } else if (parser.checkParamCount(1))
983 s=parser.parString(ok,0);
986 selb->toggleStandardFlag(s);
987 selb->updateFlagsToolbar();
990 } else if (com=="unscroll")
992 if (xelection.isEmpty() )
994 parser.setError (Aborted,"Nothing selected");
997 parser.setError (Aborted,"Type of selection is not a branch");
998 } else if (parser.checkParamCount(0))
1000 if (!unscrollBranch ())
1001 parser.setError (Aborted,"Could not unscroll branch");
1003 } else if (com=="unsetFlag")
1005 if (xelection.isEmpty() )
1007 parser.setError (Aborted,"Nothing selected");
1010 parser.setError (Aborted,"Type of selection is not a branch");
1011 } else if (parser.checkParamCount(1))
1013 s=parser.parString(ok,0);
1016 selb->deactivateStandardFlag(s);
1017 selb->updateFlagsToolbar();
1021 parser.setError (Aborted,"Unknown command");
1024 if (parser.errorLevel()==NoError)
1027 mapCenter->reposition();
1031 // TODO Error handling
1032 qWarning("MapEditor::parseAtom: Error!");
1033 qWarning(parser.errorMessage());
1037 void MapEditor::runScript (QString script)
1039 parser.setScript (script);
1041 while (parser.next() )
1042 parseAtom(parser.getAtom());
1045 bool MapEditor::isDefault()
1050 bool MapEditor::isUnsaved()
1055 bool MapEditor::hasChanged()
1060 void MapEditor::setChanged()
1068 void MapEditor::closeMap()
1070 // Unselect before disabling the toolbar actions
1071 if (!xelection.isEmpty() ) xelection.unselect();
1079 void MapEditor::setFilePath(QString fname)
1081 setFilePath (fname,fname);
1084 void MapEditor::setFilePath(QString fname, QString destname)
1086 if (fname.isEmpty() || fname=="")
1093 filePath=fname; // becomes absolute path
1094 fileName=fname; // gets stripped of path
1095 destPath=destname; // needed for vymlinks
1097 // If fname is not an absolute path, complete it
1098 filePath=QDir(fname).absPath();
1099 fileDir=filePath.left (1+filePath.findRev ("/"));
1101 // Set short name, too. Search from behind:
1102 int i=fileName.findRev("/");
1103 if (i>=0) fileName=fileName.remove (0,i+1);
1105 // Forget the .vym (or .xml) for name of map
1106 mapName=fileName.left(fileName.findRev(".",-1,true) );
1110 QString MapEditor::getFilePath()
1115 QString MapEditor::getFileName()
1120 QString MapEditor::getMapName()
1125 QString MapEditor::getDestPath()
1130 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1132 ErrorCode err=success;
1136 if (xelection.isEmpty() ) xelection.unselect();
1139 mapCenter->setMapEditor(this);
1140 // (map state is set later at end of load...)
1143 BranchObj *bo=xelection.getBranch();
1144 if (!bo) return aborted;
1145 if (lmode==ImportAdd)
1146 saveStateChangingPart(
1149 QString("addMapInsert (%1)").arg(fname),
1150 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1152 saveStateChangingPart(
1155 QString("addMapReplace(%1)").arg(fname),
1156 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1160 mapBuilderHandler handler;
1161 QFile file( fname );
1163 // I am paranoid: file should exist anyway
1164 // according to check in mainwindow.
1165 if (!file.exists() )
1167 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1168 tr("Couldn't open map " +fname)+".");
1172 blockReposition=true;
1173 QXmlInputSource source( file);
1174 QXmlSimpleReader reader;
1175 reader.setContentHandler( &handler );
1176 reader.setErrorHandler( &handler );
1177 handler.setMapEditor( this );
1178 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1179 handler.setInputFile (file.name());
1180 handler.setLoadMode (lmode);
1181 blockSaveState=true;
1182 bool ok = reader.parse( source );
1183 blockReposition=false;
1184 blockSaveState=false;
1188 mapCenter->reposition();
1198 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1199 tr( handler.errorProtocol() ) );
1201 // Still return "success": the map maybe at least
1202 // partially read by the parser
1209 int MapEditor::save (const SaveMode &savemode)
1213 // Create mapName and fileDir
1214 makeSubDirs (fileDir);
1218 fname=mapName+".xml";
1220 // use name given by user, even if he chooses .doc
1225 if (savemode==CompleteMap || xelection.isEmpty())
1226 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1228 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch()); //FIXME check selected FIO
1230 if (!saveStringToDisk(fileDir+fname,saveFile))
1243 void MapEditor::setZipped (bool z)
1248 bool MapEditor::saveZipped ()
1253 void MapEditor::print()
1257 printer = new QPrinter;
1258 printer->setColorMode (QPrinter::Color);
1259 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1260 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1261 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1264 QRectF totalBBox=mapCenter->getTotalBBox();
1266 // Try to set orientation automagically
1267 // Note: Interpretation of generated postscript is amibiguous, if
1268 // there are problems with landscape mode, see
1269 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1271 if (totalBBox.width()>totalBBox.height())
1272 // recommend landscape
1273 printer->setOrientation (QPrinter::Landscape);
1275 // recommend portrait
1276 printer->setOrientation (QPrinter::Portrait);
1278 if ( printer->setup(this) )
1279 // returns false, if printing is canceled
1281 QPainter pp(printer);
1283 pp.setRenderHint(QPainter::Antialiasing,true);
1285 // Don't print the visualisation of selection
1286 xelection.unselect();
1288 QRectF mapRect=totalBBox;
1289 QGraphicsRectItem *frame=NULL;
1293 // Print frame around map
1294 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1295 totalBBox.width()+20, totalBBox.height()+20);
1296 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1297 frame->setZValue(0);
1302 double paperAspect = (double)printer->width() / (double)printer->height();
1303 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1305 if (mapAspect>=paperAspect)
1307 // Fit horizontally to paper width
1308 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1309 viewBottom=(int)(printer->width()/mapAspect);
1312 // Fit vertically to paper height
1313 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1314 viewBottom=printer->height();
1319 // Print footer below map
1321 font.setPointSize(10);
1323 QRectF footerBox(0,viewBottom,printer->width(),15);
1324 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1325 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1329 QRectF (0,0,printer->width(),printer->height()-15),
1330 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1333 // Viewport has paper dimension
1334 if (frame) delete (frame);
1336 // Restore selection
1337 xelection.reselect();
1339 // Save settings in vymrc
1340 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1341 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1342 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1346 void MapEditor::setAntiAlias (bool b)
1348 setRenderHint(QPainter::Antialiasing,b);
1351 void MapEditor::setSmoothPixmap(bool b)
1353 setRenderHint(QPainter::SmoothPixmapTransform,b);
1356 QPixmap MapEditor::getPixmap()
1358 QRectF mapRect=mapCenter->getTotalBBox();
1359 QPixmap pix((int)mapRect.width(),(int)mapRect.height());
1362 pp.setRenderHints(renderHints());
1364 // Don't print the visualisation of selection
1365 xelection.unselect();
1367 mapScene->render ( &pp,
1368 QRectF(0,0,mapRect.width(),mapRect.height()),
1369 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1371 // mapScene->render(&pp); // draw scene to painter
1375 // Restore selection
1376 xelection.reselect();
1381 void MapEditor::setHideTmpMode (HideTmpMode mode)
1384 mapCenter->setHideTmp (hidemode);
1385 mapCenter->reposition();
1389 HideTmpMode MapEditor::getHideTmpMode()
1394 void MapEditor::exportImage(QString fn)
1396 setExportMode (true);
1397 QPixmap pix (getPixmap());
1398 pix.save(fn, "PNG");
1399 setExportMode (false);
1402 void MapEditor::setExportMode (bool b)
1404 // should be called before and after exports
1405 // depending on the settings
1406 if (b && settings.value("/export/useHideExport","yes")=="yes")
1407 setHideTmpMode (HideExport);
1409 setHideTmpMode (HideNone);
1412 void MapEditor::exportImage(QString fn, QString format)
1414 setExportMode (true);
1415 QPixmap pix (getPixmap());
1416 pix.save(fn, format);
1417 setExportMode (false);
1420 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1424 ex.setMapCenter(mapCenter);
1425 if (ex.setConfigFile(cf))
1427 setExportMode (true);
1428 ex.exportPresentation();
1429 setExportMode (false);
1435 void MapEditor::exportXML(const QString &dir)
1437 // Hide stuff during export, if settings want this
1438 setExportMode (true);
1440 // Create subdirectories
1443 // write to directory
1444 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1447 file.setName ( dir + "/"+mapName+".xml");
1448 if ( !file.open( QIODevice::WriteOnly ) )
1450 // This should neverever happen
1451 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1455 // Write it finally, and write in UTF8, no matter what
1456 QTextStream ts( &file );
1457 ts.setEncoding (QTextStream::UnicodeUTF8);
1461 // Now write image, too
1462 exportImage (dir+"/images/"+mapName+".png");
1464 setExportMode (false);
1467 void MapEditor::clear()
1469 xelection.unselect();
1473 void MapEditor::copy()
1475 LinkableMapObj *sel=xelection.single();
1478 // write to directory
1479 QString clipfile="part";
1480 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPointF(),sel ); // FIXME check FIO
1483 file.setName ( clipboardDir + "/"+clipfile+".xml");
1484 if ( !file.open( QIODevice::WriteOnly ) )
1486 // This should neverever happen
1487 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1491 // Write it finally, and write in UTF8, no matter what
1492 QTextStream ts( &file );
1493 ts.setEncoding (QTextStream::UnicodeUTF8);
1497 clipboardEmpty=false;
1502 void MapEditor::redo()
1504 blockSaveState=true;
1506 // Restore variables
1507 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1508 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1509 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1510 // Can we undo at all?
1511 if (redosAvail<1) return;
1514 if (undosAvail<stepsTotal) undosAvail++;
1516 if (curStep>stepsTotal) curStep=1;
1517 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1518 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1519 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1520 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1521 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1522 QString version=undoSet.readEntry ("/history/version");
1524 if (!checkVersion(version))
1525 QMessageBox::warning(0,tr("Warning"),
1526 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1529 // Find out current undo directory
1530 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1532 /* TODO remove testing
1534 cout << "ME::redo() begin\n";
1535 cout << " undosAvail="<<undosAvail<<endl;
1536 cout << " redosAvail="<<redosAvail<<endl;
1537 cout << " curStep="<<curStep<<endl;
1538 cout << " ---------------------------"<<endl;
1539 cout << " comment="<<comment.toStdString()<<endl;
1540 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1541 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1542 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1543 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1544 cout << " ---------------------------"<<endl<<endl;
1546 // select object before redo
1547 if (!redoSelection.isEmpty())
1548 select (redoSelection);
1551 parseAtom (redoCommand);
1552 mapCenter->reposition();
1554 blockSaveState=false;
1556 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1557 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1558 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1559 undoSet.writeSettings(histPath);
1561 mainWindow->updateHistory (undoSet);
1564 /* TODO remove testing
1565 cout << "ME::redo() end\n";
1566 cout << " undosAvail="<<undosAvail<<endl;
1567 cout << " redosAvail="<<redosAvail<<endl;
1568 cout << " curStep="<<curStep<<endl;
1569 cout << " ---------------------------"<<endl<<endl;
1575 bool MapEditor::isRedoAvailable()
1577 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1583 void MapEditor::undo()
1585 blockSaveState=true;
1587 // Restore variables
1588 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1589 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1590 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1592 // Can we undo at all?
1593 if (undosAvail<1) return;
1595 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1596 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1597 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1598 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1599 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1600 QString version=undoSet.readEntry ("/history/version");
1602 if (!checkVersion(version))
1603 QMessageBox::warning(0,tr("Warning"),
1604 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1606 // Find out current undo directory
1607 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1609 // select object before undo
1610 if (!undoSelection.isEmpty())
1611 select (undoSelection);
1615 cout << "ME::undo() begin\n";
1616 cout << " undosAvail="<<undosAvail<<endl;
1617 cout << " redosAvail="<<redosAvail<<endl;
1618 cout << " curStep="<<curStep<<endl;
1619 cout << " ---------------------------"<<endl;
1620 cout << " comment="<<comment.toStdString()<<endl;
1621 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1622 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1623 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1624 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1625 cout << " ---------------------------"<<endl<<endl;
1626 parseAtom (undoCommand);
1627 mapCenter->reposition();
1631 if (curStep<1) curStep=stepsTotal;
1635 blockSaveState=false;
1636 /* TODO remove testing
1637 cout << "ME::undo() end\n";
1638 cout << " undosAvail="<<undosAvail<<endl;
1639 cout << " redosAvail="<<redosAvail<<endl;
1640 cout << " curStep="<<curStep<<endl;
1641 cout << " ---------------------------"<<endl<<endl;
1644 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1645 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1646 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1647 undoSet.writeSettings(histPath);
1649 mainWindow->updateHistory (undoSet);
1652 ensureSelectionVisible();
1655 bool MapEditor::isUndoAvailable()
1657 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1663 void MapEditor::gotoHistoryStep (int i)
1665 // Restore variables
1666 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1667 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1669 if (i<0) i=undosAvail+redosAvail;
1671 // Clicking above current step makes us undo things
1674 for (int j=0; j<undosAvail-i; j++) undo();
1677 // Clicking below current step makes us redo things
1679 for (int j=undosAvail; j<i; j++) redo();
1681 // And ignore clicking the current row ;-)
1684 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1686 QString pathDir=path.left(path.findRev("/"));
1692 // We need to parse saved XML data
1693 mapBuilderHandler handler;
1694 QXmlInputSource source( file);
1695 QXmlSimpleReader reader;
1696 reader.setContentHandler( &handler );
1697 reader.setErrorHandler( &handler );
1698 handler.setMapEditor( this );
1699 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1700 if (undoSel.isEmpty())
1704 handler.setLoadMode (NewMap);
1708 handler.setLoadMode (ImportReplace);
1710 blockReposition=true;
1711 bool ok = reader.parse( source );
1712 blockReposition=false;
1715 // This should never ever happen
1716 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1717 handler.errorProtocol());
1720 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1723 void MapEditor::addMapInsertInt (const QString &path, int pos)
1725 BranchObj *sel=xelection.getBranch();
1728 QString pathDir=path.left(path.findRev("/"));
1734 // We need to parse saved XML data
1735 mapBuilderHandler handler;
1736 QXmlInputSource source( file);
1737 QXmlSimpleReader reader;
1738 reader.setContentHandler( &handler );
1739 reader.setErrorHandler( &handler );
1740 handler.setMapEditor( this );
1741 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1742 handler.setLoadMode (ImportAdd);
1743 blockReposition=true;
1744 bool ok = reader.parse( source );
1745 blockReposition=false;
1748 // This should never ever happen
1749 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1750 handler.errorProtocol());
1753 sel->getLastBranch()->linkTo (sel,pos);
1755 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1759 void MapEditor::pasteNoSave()
1761 load (clipboardDir+"/part.xml",ImportAdd);
1764 void MapEditor::cutNoSave()
1770 void MapEditor::paste() // FIXME no pasting of FIO ???
1772 BranchObj *sel=xelection.getBranch();
1776 saveStateChangingPart(
1780 QString("Paste to %1").arg( getName(sel))
1782 mapCenter->reposition();
1786 void MapEditor::cut()
1788 LinkableMapObj *sel=xelection.single();
1789 if ( sel && (xelection.type() == Branch ||
1790 xelection.type()==MapCenter ||
1791 xelection.type()==FloatImage))
1793 saveStateChangingPart(
1797 QString("Cut %1").arg(getName(sel ))
1801 mapCenter->reposition();
1805 void MapEditor::move(const int &x, const int &y)
1807 LinkableMapObj *sel=xelection.single();
1810 QString ps=qpointfToString (sel->getAbsPos());
1811 QString s=xelection.single()->getSelectString();
1814 s, "move "+qpointfToString (QPointF (x,y)),
1815 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
1816 sel->move(x,y); // FIXME xelection not moved automagically...
1817 mapCenter->reposition();
1823 void MapEditor::moveRel (const int &x, const int &y)
1825 LinkableMapObj *sel=xelection.single();
1828 QString ps=qpointfToString (sel->getRelPos());
1829 QString s=sel->getSelectString();
1832 s, "moveRel "+qpointfToString (QPointF (x,y)),
1833 QString("Move %1 to relativ position %2").arg(getName(sel)).arg(ps));
1834 ((OrnamentedObj*)sel)->move2RelPos (x,y);
1835 mapCenter->reposition();
1841 void MapEditor::moveBranchUp()
1843 BranchObj* bo=xelection.getBranch();
1847 if (!bo->canMoveBranchUp()) return;
1848 par=(BranchObj*)(bo->getParObj());
1849 xelection.unselect(); // FIXME needed?
1850 bo=par->moveBranchUp (bo); // bo will be the one below selection
1851 xelection.reselect();
1852 //saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1853 saveState (bo,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1854 mapCenter->reposition();
1857 ensureSelectionVisible();
1861 void MapEditor::moveBranchDown()
1863 BranchObj* bo=xelection.getBranch();
1867 if (!bo->canMoveBranchDown()) return;
1868 par=(BranchObj*)(bo->getParObj());
1869 xelection.unselect(); // FIXME needed?
1870 bo=par->moveBranchDown(bo); // bo will be the one above selection
1871 xelection.reselect();
1872 //saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1873 saveState(bo,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1874 mapCenter->reposition();
1877 ensureSelectionVisible();
1881 void MapEditor::linkTo(const QString &dstString) // FIXME needed? only for FIO ??
1883 FloatImageObj *fio=xelection.getFloatImage();
1886 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
1887 if (dst && (typeid(*dst)==typeid (BranchObj) ||
1888 typeid(*dst)==typeid (MapCenterObj)))
1890 LinkableMapObj *dstPar=dst->getParObj();
1891 QString parString=dstPar->getSelectString();
1892 QString fioPreSelectString=fio->getSelectString();
1893 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
1894 ((BranchObj*)(dst))->addFloatImage (fio);
1895 xelection.unselect();
1896 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
1897 fio=((BranchObj*)(dst))->getLastFloatImage();
1900 xelection.select(fio);
1902 fio->getSelectString(),
1903 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
1905 QString ("linkTo (\"%1\")").arg(dstString),
1906 QString ("Link floatimage to %1").arg(getName(dst)));
1911 QString MapEditor::getHeading(bool &ok, QPoint &p)
1913 BranchObj *bo=xelection.getBranch();
1917 p=mapFromScene(bo->getAbsPos());
1918 return bo->getHeading();
1924 void MapEditor::setHeading(const QString &s)
1926 BranchObj *sel=xelection.getBranch();
1931 "setHeading (\""+sel->getHeading()+"\")",
1933 "setHeading (\""+s+"\")",
1934 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
1935 sel->setHeading(s );
1936 mapCenter->reposition();
1938 ensureSelectionVisible();
1942 void MapEditor::setURLInt (const QString &s)
1944 // Internal function, no saveState needed
1945 BranchObj *bo=xelection.getBranch();
1949 mapCenter->reposition();
1951 ensureSelectionVisible();
1955 void MapEditor::setHeadingInt(const QString &s)
1957 BranchObj *bo=xelection.getBranch();
1961 mapCenter->reposition();
1963 ensureSelectionVisible();
1967 void MapEditor::setVymLinkInt (const QString &s)
1969 // Internal function, no saveState needed
1970 BranchObj *bo=xelection.getBranch();
1974 mapCenter->reposition();
1976 ensureSelectionVisible();
1980 BranchObj* MapEditor::addNewBranchInt(int num)
1982 // Depending on pos:
1983 // -3 insert in childs of parent above selection
1984 // -2 add branch to selection
1985 // -1 insert in childs of parent below selection
1986 // 0..n insert in childs of parent at pos
1987 BranchObj *newbo=NULL;
1988 BranchObj *bo=xelection.getBranch();
1993 // save scroll state. If scrolled, automatically select
1994 // new branch in order to tmp unscroll parent...
1995 return bo->addBranch();
2000 bo=(BranchObj*)bo->getParObj();
2004 bo=(BranchObj*)bo->getParObj();
2007 newbo=bo->insertBranch(num);
2012 BranchObj* MapEditor::addNewBranch(int pos)
2014 // Different meaning than num in addNewBranchInt!
2018 BranchObj *bo = xelection.getBranch();
2019 BranchObj *newbo=NULL;
2023 setCursor (Qt::ArrowCursor);
2025 newbo=addNewBranchInt (pos-2);
2033 QString ("addBranch (%1)").arg(pos-2),
2034 QString ("Add new branch to %1").arg(getName(bo)));
2036 mapCenter->reposition();
2044 BranchObj* MapEditor::addNewBranchBefore()
2046 BranchObj *newbo=NULL;
2047 BranchObj *bo = xelection.getBranch();
2048 if (bo && xelection.type()==Branch)
2049 // We accept no MapCenterObj here, so we _have_ a parent
2051 QPointF p=bo->getRelPos();
2054 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2056 // add below selection
2057 newbo=parbo->insertBranch(bo->getNum()+1);
2060 newbo->move2RelPos (p);
2062 // Move selection to new branch
2063 bo->linkTo (newbo,-1);
2065 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2066 QString ("Add branch before %1").arg(getName(bo)));
2068 mapCenter->reposition();
2075 void MapEditor::deleteSelection()
2077 BranchObj *bo = xelection.getBranch();
2078 if (bo && xelection.type()==Branch)
2080 BranchObj* par=(BranchObj*)(bo->getParObj());
2081 xelection.unselect();
2082 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2083 par->removeBranch(bo);
2084 xelection.select (par);
2085 ensureSelectionVisible();
2086 mapCenter->reposition();
2091 FloatImageObj *fio=xelection.getFloatImage();
2094 BranchObj* par=(BranchObj*)(fio->getParObj());
2095 saveStateChangingPart(
2099 QString("Delete %1").arg(getName(fio))
2101 xelection.unselect();
2102 par->removeFloatImage(fio);
2103 xelection.select (par);
2104 mapCenter->reposition();
2106 ensureSelectionVisible();
2111 LinkableMapObj* MapEditor::getSelection()
2113 return xelection.single();
2116 BranchObj* MapEditor::getSelectedBranch()
2118 return xelection.getBranch();
2121 FloatImageObj* MapEditor::getSelectedFloatImage()
2123 return xelection.getFloatImage();
2126 void MapEditor::unselect()
2128 xelection.unselect();
2131 void MapEditor::reselect()
2133 xelection.reselect();
2136 bool MapEditor::select (const QString &s)
2138 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2140 // Finally select the found object
2143 xelection.unselect();
2144 xelection.select(lmo);
2146 ensureSelectionVisible();
2152 QString MapEditor::getSelectString()
2154 return xelection.getSelectString();
2157 void MapEditor::selectInt (LinkableMapObj *lmo)
2159 if (lmo && xelection.single()!= lmo)
2161 xelection.select(lmo);
2166 void MapEditor::selectNextBranchInt()
2168 // Increase number of branch
2169 LinkableMapObj *sel=xelection.single();
2172 QString s=sel->getSelectString();
2178 part=s.section(",",-1);
2180 num=part.right(part.length() - 3);
2182 s=s.left (s.length() -num.length());
2185 num=QString ("%1").arg(num.toUInt()+1);
2189 // Try to select this one
2190 if (select (s)) return;
2192 // We have no direct successor,
2193 // try to increase the parental number in order to
2194 // find a successor with same depth
2196 int d=xelection.single()->getDepth();
2201 while (!found && d>0)
2203 s=s.section (",",0,d-1);
2204 // replace substring of current depth in s with "1"
2205 part=s.section(",",-1);
2207 num=part.right(part.length() - 3);
2211 // increase number of parent
2212 num=QString ("%1").arg(num.toUInt()+1);
2213 s=s.section (",",0,d-2) + ","+ typ+num;
2216 // Special case, look at orientation
2217 if (xelection.single()->getOrientation()==OrientRightOfCenter)
2218 num=QString ("%1").arg(num.toUInt()+1);
2220 num=QString ("%1").arg(num.toUInt()-1);
2225 // pad to oldDepth, select the first branch for each depth
2226 for (i=d;i<oldDepth;i++)
2231 if ( xelection.getBranch()->countBranches()>0)
2239 // try to select the freshly built string
2247 void MapEditor::selectPrevBranchInt()
2249 // Decrease number of branch
2250 BranchObj *bo=xelection.getBranch();
2253 QString s=bo->getSelectString();
2259 part=s.section(",",-1);
2261 num=part.right(part.length() - 3);
2263 s=s.left (s.length() -num.length());
2265 int n=num.toInt()-1;
2268 num=QString ("%1").arg(n);
2271 // Try to select this one
2272 if (n>=0 && select (s)) return;
2274 // We have no direct precessor,
2275 // try to decrease the parental number in order to
2276 // find a precessor with same depth
2278 int d=xelection.single()->getDepth();
2283 while (!found && d>0)
2285 s=s.section (",",0,d-1);
2286 // replace substring of current depth in s with "1"
2287 part=s.section(",",-1);
2289 num=part.right(part.length() - 3);
2293 // decrease number of parent
2294 num=QString ("%1").arg(num.toInt()-1);
2295 s=s.section (",",0,d-2) + ","+ typ+num;
2298 // Special case, look at orientation
2299 if (xelection.single()->getOrientation()==OrientRightOfCenter)
2300 num=QString ("%1").arg(num.toInt()-1);
2302 num=QString ("%1").arg(num.toInt()+1);
2307 // pad to oldDepth, select the last branch for each depth
2308 for (i=d;i<oldDepth;i++)
2312 if ( xelection.getBranch()->countBranches()>0)
2313 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2320 // try to select the freshly built string
2328 void MapEditor::selectUpperBranch()
2330 BranchObj *bo=xelection.getBranch();
2331 if (bo && xelection.type()==Branch)
2333 if (bo->getOrientation()==OrientRightOfCenter)
2334 selectPrevBranchInt();
2336 if (bo->getDepth()==1)
2337 selectNextBranchInt();
2339 selectPrevBranchInt();
2343 void MapEditor::selectLowerBranch()
2345 BranchObj *bo=xelection.getBranch();
2346 if (bo && xelection.type()==Branch)
2347 if (bo->getOrientation()==OrientRightOfCenter)
2348 selectNextBranchInt();
2350 if (bo->getDepth()==1)
2351 selectPrevBranchInt();
2353 selectNextBranchInt();
2357 void MapEditor::selectLeftBranch()
2361 LinkableMapObj *sel=xelection.single();
2364 if (xelection.type()== MapCenter)
2366 par=xelection.getBranch();
2367 bo=par->getLastSelectedBranch();
2370 // Workaround for reselecting on left and right side
2371 if (bo->getOrientation()==OrientRightOfCenter)
2372 bo=par->getLastBranch();
2375 bo=par->getLastBranch();
2376 xelection.select(bo);
2378 ensureSelectionVisible();
2383 par=(BranchObj*)(sel->getParObj());
2384 if (sel->getOrientation()==OrientRightOfCenter)
2386 if (xelection.type() == Branch ||
2387 xelection.type() == FloatImage)
2389 xelection.select(par);
2391 ensureSelectionVisible();
2395 if (xelection.type() == Branch )
2397 bo=xelection.getBranch()->getLastSelectedBranch();
2400 xelection.select(bo);
2402 ensureSelectionVisible();
2410 void MapEditor::selectRightBranch()
2414 LinkableMapObj *sel=xelection.single();
2417 if (xelection.type()==MapCenter)
2419 par=xelection.getBranch();
2420 bo=par->getLastSelectedBranch();
2423 // Workaround for reselecting on left and right side
2424 if (bo->getOrientation()==OrientLeftOfCenter)
2425 bo=par->getFirstBranch();
2428 xelection.select(bo);
2430 ensureSelectionVisible();
2435 par=(BranchObj*)(xelection.single()->getParObj());
2436 if (xelection.single()->getOrientation()==OrientLeftOfCenter)
2438 if (xelection.type() == Branch ||
2439 xelection.type() == FloatImage)
2441 xelection.select(par);
2443 ensureSelectionVisible();
2447 if (xelection.type() == Branch)
2449 bo=xelection.getBranch()->getLastSelectedBranch();
2452 xelection.select(bo);
2454 ensureSelectionVisible();
2462 void MapEditor::selectFirstBranch()
2464 BranchObj *bo1=xelection.getBranch();
2469 par=(BranchObj*)(bo1->getParObj());
2470 bo2=par->getFirstBranch();
2472 xelection.select(bo2);
2474 ensureSelectionVisible();
2479 void MapEditor::selectLastBranch()
2481 BranchObj *bo1=xelection.getBranch();
2486 par=(BranchObj*)(bo1->getParObj());
2487 bo2=par->getLastBranch();
2490 xelection.select(bo2);
2492 ensureSelectionVisible();
2497 void MapEditor::selectMapBackgroundImage ()
2499 Q3FileDialog *fd=new Q3FileDialog( this);
2500 fd->setMode (Q3FileDialog::ExistingFile);
2501 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2502 ImagePreview *p =new ImagePreview (fd);
2503 fd->setContentsPreviewEnabled( TRUE );
2504 fd->setContentsPreview( p, p );
2505 fd->setPreviewMode( Q3FileDialog::Contents );
2506 fd->setCaption(vymName+" - " +tr("Load background image"));
2507 fd->setDir (lastImageDir);
2510 if ( fd->exec() == QDialog::Accepted )
2512 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2513 lastImageDir=QDir (fd->dirPath());
2514 setMapBackgroundImage (fd->selectedFile());
2518 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
2520 QColor oldcol=mapScene->backgroundBrush().color();
2524 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2526 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2527 QString("Set background color of map to %1").arg(col.name()));
2530 brush.setTextureImage (QPixmap (fn));
2531 mapScene->setBackgroundBrush(brush);
2534 void MapEditor::selectMapBackgroundColor()
2536 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2537 if ( !col.isValid() ) return;
2538 setMapBackgroundColor( col );
2542 void MapEditor::setMapBackgroundColor(QColor col)
2544 QColor oldcol=mapScene->backgroundBrush().color();
2547 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
2549 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
2550 QString("Set background color of map to %1").arg(col.name()));
2551 mapScene->setBackgroundBrush(col);
2554 QColor MapEditor::getMapBackgroundColor()
2556 return mapScene->backgroundBrush().color();
2559 QColor MapEditor::getCurrentHeadingColor()
2561 BranchObj *bo=xelection.getBranch();
2562 if (bo) return bo->getColor();
2564 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2568 void MapEditor::colorBranch (QColor c)
2570 BranchObj *bo=xelection.getBranch();
2575 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
2577 QString ("colorBranch (\"%1\")").arg(c.name()),
2578 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2580 bo->setColor(c); // color branch
2584 void MapEditor::colorSubtree (QColor c)
2586 BranchObj *bo=xelection.getBranch();
2589 saveStateChangingPart(
2592 QString ("colorSubtree (\"%1\")").arg(c.name()),
2593 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2595 bo->setColorSubtree (c); // color links, color childs
2600 void MapEditor::toggleStandardFlag(QString f)
2602 BranchObj *bo=xelection.getBranch();
2606 if (bo->isSetStandardFlag(f))
2618 QString("%1 (\"%2\")").arg(u).arg(f),
2620 QString("%1 (\"%2\")").arg(r).arg(f),
2621 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2622 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2628 BranchObj* MapEditor::findText (QString s, bool cs)
2630 QTextDocument::FindFlags flags=0;
2631 if (cs) flags=QTextDocument::FindCaseSensitively;
2634 { // Nothing found or new find process
2636 // nothing found, start again
2638 itFind=mapCenter->first();
2640 bool searching=true;
2641 bool foundNote=false;
2642 while (searching && !EOFind)
2646 // Searching in Note
2647 if (itFind->getNote().contains(s,cs))
2649 if (xelection.single()!=itFind)
2651 xelection.select(itFind);
2652 ensureSelectionVisible();
2654 if (textEditor->findText(s,flags))
2660 // Searching in Heading
2661 if (searching && itFind->getHeading().contains (s,cs) )
2663 xelection.select(itFind);
2664 ensureSelectionVisible();
2670 itFind=itFind->next();
2671 if (!itFind) EOFind=true;
2675 return xelection.getBranch();
2680 void MapEditor::findReset()
2681 { // Necessary if text to find changes during a find process
2685 void MapEditor::setURL(const QString &url)
2687 BranchObj *bo=xelection.getBranch();
2690 QString oldurl=bo->getURL();
2694 QString ("setURL (\"%1\")").arg(oldurl),
2696 QString ("setURL (\"%1\")").arg(url),
2697 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2703 void MapEditor::editURL()
2705 BranchObj *bo=xelection.getBranch();
2709 QString text = QInputDialog::getText(
2710 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2711 bo->getURL(), &ok, this );
2713 // user entered something and pressed OK
2718 QString MapEditor::getURL()
2720 BranchObj *bo=xelection.getBranch();
2722 return bo->getURL();
2727 QStringList MapEditor::getURLs()
2730 BranchObj *bo=xelection.getBranch();
2736 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2744 void MapEditor::editHeading2URL()
2746 BranchObj *bo=xelection.getBranch();
2748 setURL (bo->getHeading());
2751 void MapEditor::editBugzilla2URL()
2753 BranchObj *bo=xelection.getBranch();
2756 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2761 void MapEditor::editFATE2URL()
2763 BranchObj *bo=xelection.getBranch();
2766 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2769 "setURL (\""+bo->getURL()+"\")",
2771 "setURL (\""+url+"\")",
2772 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2779 void MapEditor::editVymLink()
2781 BranchObj *bo=xelection.getBranch();
2784 QStringList filters;
2785 filters <<"VYM map (*.vym)";
2786 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2787 fd->setFilters (filters);
2788 fd->setCaption(vymName+" - " +tr("Link to another map"));
2789 fd->setDirectory (lastFileDir);
2790 if (! bo->getVymLink().isEmpty() )
2791 fd->selectFile( bo->getVymLink() );
2795 if ( fd->exec() == QDialog::Accepted )
2797 lastFileDir=QDir (fd->directory().path());
2800 "setVymLink (\""+bo->getVymLink()+"\")",
2802 "setVymLink (\""+fd->selectedFile()+"\")",
2803 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2805 bo->setVymLink (fd->selectedFile() );
2807 mapCenter->reposition();
2813 void MapEditor::deleteVymLink()
2815 BranchObj *bo=xelection.getBranch();
2820 "setVymLink (\""+bo->getVymLink()+"\")",
2822 "setVymLink (\"\")",
2823 QString("Unset vymlink of %1").arg(getName(bo))
2825 bo->setVymLink ("" );
2827 mapCenter->reposition();
2832 void MapEditor::setHideExport(bool b)
2834 BranchObj *bo=xelection.getBranch();
2837 bo->setHideInExport (b);
2838 QString u= b ? "false" : "true";
2839 QString r=!b ? "false" : "true";
2843 QString ("setHideExport (%1)").arg(u),
2845 QString ("setHideExport (%1)").arg(r),
2846 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
2849 mapCenter->reposition();
2854 void MapEditor::toggleHideExport()
2856 BranchObj *bo=xelection.getBranch();
2858 setHideExport ( !bo->hideInExport() );
2861 QString MapEditor::getVymLink()
2863 BranchObj *bo=xelection.getBranch();
2865 return bo->getVymLink();
2871 QStringList MapEditor::getVymLinks()
2874 BranchObj *bo=xelection.getBranch();
2880 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2888 void MapEditor::deleteKeepChilds()
2890 BranchObj *bo=xelection.getBranch();
2894 par=(BranchObj*)(bo->getParObj());
2895 QPointF p=bo->getRelPos();
2896 saveStateChangingPart(
2899 "deleteKeepChilds ()",
2900 QString("Remove %1 and keep its childs").arg(getName(bo))
2903 QString sel=bo->getSelectString();
2905 par->removeBranchHere(bo);
2906 mapCenter->reposition();
2908 xelection.getBranch()->move2RelPos (p);
2909 mapCenter->reposition();
2913 void MapEditor::deleteChilds()
2915 BranchObj *bo=xelection.getBranch();
2918 saveStateChangingPart(
2922 QString( "Remove childs of branch %1").arg(getName(bo))
2925 mapCenter->reposition();
2929 void MapEditor::editMapInfo()
2931 ExtraInfoDialog dia;
2932 dia.setMapName (getFileName() );
2933 dia.setAuthor (mapCenter->getAuthor() );
2934 dia.setComment(mapCenter->getComment() );
2938 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
2945 bo=mapCenter->first();
2948 if (!bo->getNote().isEmpty() ) n++;
2949 f+= bo->countFloatImages();
2951 xl+=bo->countXLinks();
2954 stats+=QString ("%1 branches\n").arg (b-1,6);
2955 stats+=QString ("%1 xLinks \n").arg (xl,6);
2956 stats+=QString ("%1 notes\n").arg (n,6);
2957 stats+=QString ("%1 images\n").arg (f,6);
2958 dia.setStats (stats);
2960 // Finally show dialog
2961 if (dia.exec() == QDialog::Accepted)
2963 setMapAuthor (dia.getAuthor() );
2964 setMapComment (dia.getComment() );
2968 void MapEditor::ensureSelectionVisible()
2970 LinkableMapObj *lmo=xelection.single();
2971 if (lmo) ensureVisible (lmo->getBBox() );
2975 void MapEditor::updateSelection()
2977 // Tell selection to update geometries
2981 void MapEditor::updateActions()
2983 // Tell mainwindow to update states of actions
2984 mainWindow->updateActions();
2985 // TODO maybe don't update if blockReposition is set
2988 void MapEditor::updateNoteFlag()
2991 BranchObj *bo=xelection.getBranch();
2994 bo->updateNoteFlag();
2995 mainWindow->updateActions();
2999 void MapEditor::setMapAuthor (const QString &s)
3003 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3005 QString ("setMapAuthor (\"%1\")").arg(s),
3006 QString ("Set author of map to \"%1\"").arg(s)
3008 mapCenter->setAuthor (s);
3011 void MapEditor::setMapComment (const QString &s)
3015 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3017 QString ("setMapComment (\"%1\")").arg(s),
3018 QString ("Set comment of map")
3020 mapCenter->setComment (s);
3023 void MapEditor::setMapLinkStyle (const QString & s)
3025 saveStateChangingPart (
3028 QString("setMapLinkStyle (\"%1\")").arg(s),
3029 QString("Set map link style (\"%1\")").arg(s)
3033 linkstyle=StyleLine;
3034 else if (s=="StyleParabel")
3035 linkstyle=StyleParabel;
3036 else if (s=="StylePolyLine")
3037 linkstyle=StylePolyLine;
3039 linkstyle=StylePolyParabel;
3042 bo=mapCenter->first();
3046 bo->setLinkStyle(bo->getDefLinkStyle());
3049 mapCenter->reposition();
3052 LinkStyle MapEditor::getMapLinkStyle ()
3057 void MapEditor::setMapDefLinkColor(QColor c)
3063 void MapEditor::setMapLinkColorHintInt()
3065 // called from setMapLinkColorHint(lch) or at end of parse
3067 bo=mapCenter->first();
3075 void MapEditor::setMapLinkColorHint(LinkColorHint lch)
3078 setMapLinkColorHintInt();
3081 void MapEditor::toggleMapLinkColorHint()
3083 if (linkcolorhint==HeadingColor)
3084 linkcolorhint=DefaultColor;
3086 linkcolorhint=HeadingColor;
3088 bo=mapCenter->first();
3096 LinkColorHint MapEditor::getMapLinkColorHint()
3098 return linkcolorhint;
3101 QColor MapEditor::getMapDefLinkColor()
3103 return defLinkColor;
3106 void MapEditor::setMapDefXLinkColor(QColor col)
3111 QColor MapEditor::getMapDefXLinkColor()
3113 return defXLinkColor;
3116 void MapEditor::setMapDefXLinkWidth (int w)
3121 int MapEditor::getMapDefXLinkWidth()
3123 return defXLinkWidth;
3126 void MapEditor::selectMapLinkColor()
3128 QColor col = QColorDialog::getColor( defLinkColor, this );
3129 if ( !col.isValid() ) return;
3132 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3134 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3135 QString("Set link color to %1").arg(col.name())
3137 setMapDefLinkColor( col );
3140 void MapEditor::selectMapSelectionColor()
3142 QColor col = QColorDialog::getColor( defLinkColor, this );
3143 setSelectionColor (col);
3146 void MapEditor::setSelectionColorInt (QColor col)
3148 if ( !col.isValid() ) return;
3149 xelection.setColor (col);
3152 void MapEditor::setSelectionColor(QColor col)
3154 if ( !col.isValid() ) return;
3157 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3159 QString("setSelectionColor (%1)").arg(col.name()),
3160 QString("Set color of selection box to %1").arg(col.name())
3162 setSelectionColorInt (col);
3165 QColor MapEditor::getSelectionColor()
3167 return xelection.getColor();
3170 bool MapEditor::scrollBranch()
3172 BranchObj *bo=xelection.getBranch();
3175 if (bo->isScrolled()) return false;
3176 if (bo->countBranches()==0) return false;
3177 if (bo->getDepth()==0) return false;
3183 QString ("%1 ()").arg(u),
3185 QString ("%1 ()").arg(r),
3186 QString ("%1 %2").arg(r).arg(getName(bo))
3195 bool MapEditor::unscrollBranch()
3197 BranchObj *bo=xelection.getBranch();
3200 if (!bo->isScrolled()) return false;
3201 if (bo->countBranches()==0) return false;
3202 if (bo->getDepth()==0) return false;
3208 QString ("%1 ()").arg(u),
3210 QString ("%1 ()").arg(r),
3211 QString ("%1 %2").arg(r).arg(getName(bo))
3220 void MapEditor::toggleScroll()
3222 BranchObj *bo=xelection.getBranch();
3223 if (xelection.type()==Branch )
3225 if (bo->isScrolled())
3232 void MapEditor::unscrollChilds() // FIXME saveState missing
3234 BranchObj *bo=xelection.getBranch();
3240 if (bo->isScrolled()) bo->toggleScroll();
3246 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3248 BranchObj *bo=xelection.getBranch();
3252 bo->addFloatImage();
3253 fio=bo->getLastFloatImage();
3255 mapCenter->reposition();
3262 void MapEditor::loadFloatImage ()
3264 BranchObj *bo=xelection.getBranch();
3268 Q3FileDialog *fd=new Q3FileDialog( this);
3269 fd->setMode (Q3FileDialog::ExistingFiles);
3270 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3271 ImagePreview *p =new ImagePreview (fd);
3272 fd->setContentsPreviewEnabled( TRUE );
3273 fd->setContentsPreview( p, p );
3274 fd->setPreviewMode( Q3FileDialog::Contents );
3275 fd->setCaption(vymName+" - " +tr("Load image"));
3276 fd->setDir (lastImageDir);
3279 if ( fd->exec() == QDialog::Accepted )
3281 // FIXME loadFIO in QT4 use: lastImageDir=fd->directory();
3282 lastImageDir=QDir (fd->dirPath());
3285 for (int j=0; j<fd->selectedFiles().count(); j++)
3287 s=fd->selectedFiles().at(j);
3288 fio=loadFloatImageInt (s);
3291 (LinkableMapObj*)fio,
3294 QString ("loadImage (%1)").arg(s ),
3295 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3298 // FIXME loadFIO error handling
3299 qWarning ("Failed to load "+s);
3307 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3309 fio->save (fn,type);
3312 void MapEditor::saveFloatImage ()
3314 FloatImageObj *fio=xelection.getFloatImage();
3317 QFileDialog *fd=new QFileDialog( this);
3318 fd->setFilters (imageIO.getFilters());
3319 fd->setCaption(vymName+" - " +tr("Save image"));
3320 fd->setFileMode( QFileDialog::AnyFile );
3321 fd->setDirectory (lastImageDir);
3322 // fd->setSelection (fio->getOriginalFilename());
3326 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3328 fn=fd->selectedFiles().at(0);
3329 if (QFile (fn).exists() )
3331 QMessageBox mb( vymName,
3332 tr("The file %1 exists already.\n"
3333 "Do you want to overwrite it?").arg(fn),
3334 QMessageBox::Warning,
3335 QMessageBox::Yes | QMessageBox::Default,
3336 QMessageBox::Cancel | QMessageBox::Escape,
3337 QMessageBox::QMessageBox::NoButton );
3339 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3340 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3343 case QMessageBox::Yes:
3346 case QMessageBox::Cancel:
3353 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3359 void MapEditor::setFrameType(const FrameType &t) // FIXME missing saveState
3361 BranchObj *bo=xelection.getBranch();
3364 bo->setFrameType (t);
3365 mapCenter->reposition();
3370 void MapEditor::setFrameType(const QString &s) // FIXME missing saveState
3372 BranchObj *bo=xelection.getBranch();
3375 bo->setFrameType (s);
3376 mapCenter->reposition();
3381 void MapEditor::setFramePenColor(const QColor &c) // FIXME missing saveState
3383 BranchObj *bo=xelection.getBranch();
3385 bo->setFramePenColor (c);
3388 void MapEditor::setFrameBrushColor(const QColor &c) // FIXME missing saveState
3390 BranchObj *bo=xelection.getBranch();
3392 bo->setFrameBrushColor (c);
3395 void MapEditor::setIncludeImagesVer(bool b)
3397 BranchObj *bo=xelection.getBranch();
3400 QString u= b ? "false" : "true";
3401 QString r=!b ? "false" : "true";
3405 QString("setIncludeImagesVertically (%1)").arg(u),
3407 QString("setIncludeImagesVertically (%1)").arg(r),
3408 QString("Include images vertically in %1").arg(getName(bo))
3410 bo->setIncludeImagesVer(b);
3411 mapCenter->reposition();
3415 void MapEditor::setIncludeImagesHor(bool b)
3417 BranchObj *bo=xelection.getBranch();
3420 QString u= b ? "false" : "true";
3421 QString r=!b ? "false" : "true";
3425 QString("setIncludeImagesHorizontally (%1)").arg(u),
3427 QString("setIncludeImagesHorizontally (%1)").arg(r),
3428 QString("Include images horizontally in %1").arg(getName(bo))
3430 bo->setIncludeImagesHor(b);
3431 mapCenter->reposition();
3435 void MapEditor::setHideLinkUnselected (bool b) // FIXME missing saveState
3437 LinkableMapObj *sel=xelection.single();
3439 (xelection.type() == Branch ||
3440 xelection.type() == MapCenter ||
3441 xelection.type() == FloatImage ))
3442 sel->setHideLinkUnselected(b);
3445 void MapEditor::importDirInt(BranchObj *dst, QDir d) // FIXME missing saveState
3447 BranchObj *bo=xelection.getBranch();
3450 // Traverse directories
3451 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3452 QFileInfoList list = d.entryInfoList();
3455 for (int i = 0; i < list.size(); ++i)
3458 if (fi.fileName() != "." && fi.fileName() != ".." )
3461 bo=dst->getLastBranch();
3462 bo->setHeading (fi.fileName() );
3463 bo->setColor (QColor("blue"));
3465 if ( !d.cd(fi.fileName()) )
3466 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3469 // Recursively add subdirs
3470 importDirInt (bo,d);
3476 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3477 list = d.entryInfoList();
3479 for (int i = 0; i < list.size(); ++i)
3483 bo=dst->getLastBranch();
3484 bo->setHeading (fi.fileName() );
3485 bo->setColor (QColor("black"));
3486 if (fi.fileName().right(4) == ".vym" )
3487 bo->setVymLink (fi.filePath());
3492 void MapEditor::importDir()
3494 BranchObj *bo=xelection.getBranch();
3497 QStringList filters;
3498 filters <<"VYM map (*.vym)";
3499 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3500 fd->setMode (QFileDialog::DirectoryOnly);
3501 fd->setFilters (filters);
3502 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3506 if ( fd->exec() == QDialog::Accepted )
3508 importDirInt (bo,QDir(fd->selectedFile()) );
3509 mapCenter->reposition();
3515 void MapEditor::followXLink(int i)
3517 BranchObj *bo=xelection.getBranch();
3520 bo=bo->XLinkTargetAt(i);
3523 xelection.select(bo);
3524 ensureSelectionVisible();
3529 void MapEditor::editXLink(int i) // FIXME missing saveState
3531 BranchObj *bo=xelection.getBranch();
3534 XLinkObj *xlo=bo->XLinkAt(i);
3537 EditXLinkDialog dia;
3539 dia.setSelection(bo);
3540 if (dia.exec() == QDialog::Accepted)
3542 if (dia.useSettingsGlobal() )
3544 setMapDefXLinkColor (xlo->getColor() );
3545 setMapDefXLinkWidth (xlo->getWidth() );
3547 if (dia.deleteXLink())
3548 bo->deleteXLinkAt(i);
3554 void MapEditor::testFunction()
3556 // This is the playground
3561 dia.showCancelButton (true);
3562 dia.setText("This is a longer \nWarning");
3563 dia.setCaption("Warning: Flux problem");
3564 dia.setShowAgainName("mapeditor/testDialog");
3565 if (dia.exec()==QDialog::Accepted)
3566 cout << "accepted!\n";
3568 cout << "canceled!\n";
3572 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
3573 if (hidemode==HideNone)
3575 setHideTmpMode (HideExport);
3576 mapCenter->calcBBoxSizeWithChilds();
3577 QRectF totalBBox=mapCenter->getTotalBBox();
3578 QRectF mapRect=totalBBox;
3579 QCanvasRectangle *frame=NULL;
3581 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3583 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3584 totalBBox.width(), totalBBox.height());
3585 frame=new QCanvasRectangle (mapRect,mapScene);
3586 frame->setBrush (QColor(white));
3587 frame->setPen (QColor(black));
3588 frame->setZValue(0);
3593 setHideTmpMode (HideNone);
3595 cout <<" hidemode="<<hidemode<<endl;
3599 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3601 // Lineedits are already closed by preceding
3602 // mouseEvent, we don't need to close here.
3604 QPointF p = mapToScene(e->pos());
3605 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3608 { // MapObj was found
3609 if (xelection.single() != lmo)
3611 // select the MapObj
3612 xelection.select(lmo);
3615 if (xelection.getBranch() )
3617 // Context Menu on branch or mapcenter
3619 branchContextMenu->popup(e->globalPos() );
3622 if (xelection.getFloatImage() )
3624 // Context Menu on floatimage
3626 floatimageContextMenu->popup(e->globalPos() );
3630 { // No MapObj found, we are on the Canvas itself
3631 // Context Menu on scene
3633 canvasContextMenu->popup(e->globalPos() );
3638 void MapEditor::keyPressEvent(QKeyEvent* e)
3640 if (e->modifiers() & Qt::ControlModifier)
3642 switch (mainWindow->getModMode())
3645 setCursor (PickColorCursor);
3648 setCursor (CopyCursor);
3651 setCursor (XLinkCursor);
3654 setCursor (Qt::ArrowCursor);
3660 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3662 if (!(e->modifiers() & Qt::ControlModifier))
3663 setCursor (Qt::ArrowCursor);
3666 void MapEditor::mousePressEvent(QMouseEvent* e)
3668 // Ignore right clicks, these will go to context menus
3669 if (e->button() == Qt::RightButton )
3675 QPointF p = mapToScene(e->pos());
3676 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3680 //Take care of system flags _or_ modifier modes
3682 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3683 typeid(*lmo)==typeid(MapCenterObj) ))
3685 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3686 if (!foname.isEmpty())
3688 // systemFlag clicked
3692 if (e->state() & Qt::ControlModifier)
3693 mainWindow->editOpenURLTab();
3695 mainWindow->editOpenURL();
3697 else if (foname=="vymLink")
3699 mainWindow->editOpenVymLink();
3700 // tabWidget may change, better return now
3701 // before segfaulting...
3702 } else if (foname=="note")
3703 mainWindow->windowToggleNoteEditor();
3704 else if (foname=="hideInExport")
3711 // No system flag clicked, take care of modmodes (CTRL-Click)
3712 if (e->state() & Qt::ControlModifier)
3714 if (mainWindow->getModMode()==ModModeColor)
3717 setCursor (PickColorCursor);
3720 if (mainWindow->getModMode()==ModModeXLink)
3722 BranchObj *bo_begin=NULL;
3724 bo_begin=(BranchObj*)(lmo);
3726 if (xelection.getBranch() )
3727 bo_begin=xelection.getBranch();
3731 linkingObj_src=bo_begin;
3732 tmpXLink=new XLinkObj (mapScene);
3733 tmpXLink->setBegin (bo_begin);
3734 tmpXLink->setEnd (p);
3735 tmpXLink->setColor(defXLinkColor);
3736 tmpXLink->setWidth(defXLinkWidth);
3737 tmpXLink->updateXLink();
3738 tmpXLink->setVisibility (true);
3742 } // End of modmodes
3746 // Select the clicked object
3749 // Left Button Move Branches
3750 if (e->button() == Qt::LeftButton )
3752 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
3753 //movingObj_start.setY( p.y() - selection->y() );
3754 movingObj_start.setX( p.x() - lmo->x() );
3755 movingObj_start.setY( p.y() - lmo->y() );
3756 movingObj_orgPos.setX (lmo->x() );
3757 movingObj_orgPos.setY (lmo->y() );
3758 movingObj_orgRelPos=lmo->getRelPos();
3760 // If modMode==copy, then we want to "move" the _new_ object around
3761 // then we need the offset from p to the _old_ selection, because of tmp
3762 if (mainWindow->getModMode()==ModModeCopy &&
3763 e->state() & Qt::ControlModifier)
3765 if (xelection.type()==Branch)
3768 mapCenter->addBranch ((BranchObj*)xelection.single());
3770 xelection.select(mapCenter->getLastBranch());
3771 mapCenter->reposition();
3775 movingObj=xelection.single();
3777 // Middle Button Toggle Scroll
3778 // (On Mac OS X this won't work, but we still have
3779 // a button in the toolbar)
3780 if (e->button() == Qt::MidButton )
3785 { // No MapObj found, we are on the scene itself
3786 // Left Button move Pos of sceneView
3787 if (e->button() == Qt::LeftButton )
3789 movingObj=NULL; // move Content not Obj
3790 movingObj_start=e->globalPos();
3791 movingCont_start=QPointF (
3792 horizontalScrollBar()->value(),
3793 verticalScrollBar()->value());
3794 movingVec=QPointF(0,0);
3795 setCursor(HandOpenCursor);
3800 void MapEditor::mouseMoveEvent(QMouseEvent* e)
3802 QPointF p = mapToScene(e->pos());
3803 LinkableMapObj *lmosel=xelection.single();
3805 // Move the selected MapObj
3806 if ( lmosel && movingObj)
3808 // reset cursor if we are moving and don't copy
3809 if (mainWindow->getModMode()!=ModModeCopy)
3810 setCursor (Qt::ArrowCursor);
3812 // To avoid jumping of the sceneView, only
3813 // ensureSelectionVisible, if not tmp linked
3814 if (!lmosel->hasParObjTmp())
3815 ensureSelectionVisible ();
3817 // Now move the selection, but add relative position
3818 // (movingObj_start) where selection was chosen with
3819 // mousepointer. (This avoids flickering resp. jumping
3820 // of selection back to absPos)
3822 // Check if we could link
3823 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3826 FloatObj *fio=xelection.getFloatImage();
3829 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3831 fio->updateLink(); //no need for reposition, if we update link here
3834 // Relink float to new mapcenter or branch, if shift is pressed
3835 // Only relink, if selection really has a new parent
3836 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3837 ( (typeid(*lmo)==typeid(BranchObj)) ||
3838 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3839 ( lmo != fio->getParObj())
3842 if (typeid(*fio) == typeid(FloatImageObj) &&
3843 ( (typeid(*lmo)==typeid(BranchObj) ||
3844 typeid(*lmo)==typeid(MapCenterObj)) ))
3847 // Also save the move which was done so far
3848 QString pold=qpointfToString(movingObj_orgRelPos);
3849 QString pnow=qpointfToString(fio->getRelPos());
3855 QString("Move %1 to relativ position %2").arg(getName(fio)).arg(pnow));
3856 fio->getParObj()->requestReposition();
3857 mapCenter->reposition();
3859 linkTo (lmo->getSelectString());
3861 //movingObj_orgRelPos=lmosel->getRelPos();
3863 mapCenter->reposition();
3867 { // selection != a FloatObj
3868 if (lmosel->getDepth()==0)
3871 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3872 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3874 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3875 mapCenter->updateRelPositions();
3878 if (lmosel->getDepth()==1)
3881 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3882 lmosel->setRelPos();
3885 // Move ordinary branch
3886 if (lmosel->getOrientation() == OrientLeftOfCenter)
3887 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3888 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3889 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3891 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3894 // Maybe we can relink temporary?
3895 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
3896 (typeid(*lmo)==typeid(BranchObj) ||
3897 typeid(*lmo)==typeid(MapCenterObj)) )
3900 if (e->modifiers()==Qt::ControlModifier)
3902 // Special case: CTRL to link below lmo
3903 lmosel->setParObjTmp (lmo,p,+1);
3905 else if (e->modifiers()==Qt::ShiftModifier)
3906 lmosel->setParObjTmp (lmo,p,-1);
3908 lmosel->setParObjTmp (lmo,p,0);
3911 lmosel->unsetParObjTmp();
3913 // reposition subbranch
3914 lmosel->reposition();
3918 } // no FloatImageObj
3922 } // selection && moving_obj
3924 // Draw a link from one branch to another
3927 tmpXLink->setEnd (p);
3928 tmpXLink->updateXLink();
3932 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
3934 QPointF p=e->globalPos();
3935 movingVec.setX(-p.x() + movingObj_start.x() );
3936 movingVec.setY(-p.y() + movingObj_start.y() );
3937 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
3938 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
3943 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
3945 QPointF p = mapToScene(e->pos());
3946 LinkableMapObj *dst;
3947 LinkableMapObj *lmosel=xelection.single();
3948 // Have we been picking color?
3952 setCursor (Qt::ArrowCursor);
3953 // Check if we are over another branch
3954 dst=mapCenter->findMapObj(p, NULL);
3957 if (e->state() & Qt::ShiftModifier)
3958 colorBranch (((BranchObj*)(dst))->getColor());
3960 colorSubtree (((BranchObj*)(dst))->getColor());
3965 // Have we been drawing a link?
3969 // Check if we are over another branch
3970 dst=mapCenter->findMapObj(p, NULL);
3973 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3974 tmpXLink->updateXLink();
3975 tmpXLink->activate();
3976 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //FIXME undoCommand
3985 // Have we been moving something?
3986 if ( lmosel && movingObj )
3988 FloatImageObj *fo=xelection.getFloatImage();
3991 // Moved FloatObj. Maybe we need to reposition
3992 QString pold=qpointfToString(movingObj_orgRelPos);
3993 QString pnow=qpointfToString(fo->getRelPos());
3999 QString("Move %1 to relativ position %2").arg(getName(fo)).arg(pnow));
4001 fo->getParObj()->requestReposition();
4002 mapCenter->reposition();
4005 // Check if we are over another branch, but ignore
4006 // any found LMOs, which are FloatObjs
4007 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
4009 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4012 if (xelection.type() == MapCenter )
4013 { // FIXME The MapCenter was moved, no savestate yet
4016 if (xelection.type() == Branch )
4017 { // A branch was moved
4019 // save the position in case we link to mapcenter
4020 QPointF savePos=QPointF (lmosel->getAbsPos() );
4022 // Reset the temporary drawn link to the original one
4023 lmosel->unsetParObjTmp();
4025 // For Redo we may need to save original selection
4026 QString preSelStr=lmosel->getSelectString();
4031 BranchObj* bsel=xelection.getBranch();
4032 BranchObj* bdst=(BranchObj*)dst;
4034 QString preParStr=(bsel->getParObj())->getSelectString();
4035 QString preNum=QString::number (bsel->getNum(),10);
4036 QString preDstParStr;
4038 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4040 preDstParStr=dst->getParObj()->getSelectString();
4041 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4043 if (e->state() & Qt::ControlModifier && dst->getParObj())
4046 preDstParStr=dst->getParObj()->getSelectString();
4047 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4050 preDstParStr=dst->getSelectString();
4051 bsel->linkTo (bdst,-1);
4052 if (dst->getDepth()==0) bsel->move (savePos);
4054 QString postSelStr=lmosel->getSelectString();
4055 QString postNum=QString::number (bsel->getNum(),10);
4057 QString undoCom="linkTo (\""+
4058 preParStr+ "\"," + preNum +"," +
4059 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4061 QString redoCom="linkTo (\""+
4062 preDstParStr + "\"," + postNum + "," +
4063 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4068 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4070 if (lmosel->getDepth()==1)
4072 // The select string might be different _after_ moving around.
4073 // Therefor reposition and then use string of old selection, too
4074 mapCenter->reposition();
4076 QString ps=qpointfToString ( lmosel->getRelPos() );
4078 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4079 preSelStr, "moveRel "+ps,
4080 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4083 // Draw the original link, before selection was moved around
4084 mapCenter->reposition();
4087 // Finally resize scene, if needed
4091 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4094 // maybe we moved View: set old cursor
4095 setCursor (Qt::ArrowCursor);
4099 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4101 if (e->button() == Qt::LeftButton )
4103 QPointF p = mapToScene(e->pos());
4104 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4105 if (lmo) { // MapObj was found
4106 // First select the MapObj than edit heading
4107 xelection.select(lmo);
4108 mainWindow->editHeading();
4113 void MapEditor::resizeEvent (QResizeEvent* e)
4115 QGraphicsView::resizeEvent( e );
4118 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4120 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4121 // cerr << event->format(i) << endl;
4123 if (event->mimeData()->hasImage())
4124 event->acceptProposedAction();
4126 if (event->mimeData()->hasUrls())
4127 event->acceptProposedAction();
4130 void MapEditor::dragMoveEvent(QDragMoveEvent *event)
4134 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4139 void MapEditor::dropEvent(QDropEvent *event)
4141 BranchObj *sel=xelection.getBranch();
4145 if (event->mimeData()->hasImage())
4147 QVariant imageData = event->mimeData()->imageData();
4148 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4150 if (event->mimeData()->hasUrls())
4151 uris=event->mimeData()->urls();
4159 for (int i=0; i<uris.count();i++)
4161 // Workaround to avoid adding empty branches
4162 if (!uris.at(i).toString().isEmpty())
4164 bo=sel->addBranch();
4167 s=uris.at(i).toLocalFile();
4170 QString file = QDir::convertSeparators(s);
4171 heading = QFileInfo(file).baseName();
4173 if (file.endsWith(".vym", false))
4174 bo->setVymLink(file);
4176 bo->setURL(uris.at(i).toString());
4179 bo->setURL(uris.at(i).toString());
4182 if (!heading.isEmpty())
4183 bo->setHeading(heading);
4185 bo->setHeading(uris.at(i).toString());
4189 mapCenter->reposition();
4192 event->acceptProposedAction();
4196 void MapEditor::contentsDropEvent(QDropEvent *event)
4199 } else if (event->provides("application/x-moz-file-promise-url") &&
4200 event->provides("application/x-moz-nativeimage"))
4202 // Contains url to the img src in unicode16
4203 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4204 QString url = QString((const QChar*)d.data(),d.size()/2);
4208 } else if (event->provides ("text/uri-list"))
4209 { // Uris provided e.g. by konqueror
4210 Q3UriDrag::decode (event,uris);
4211 } else if (event->provides ("_NETSCAPE_URL"))
4212 { // Uris provided by Mozilla
4213 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4216 } else if (event->provides("text/html")) {
4218 // Handels text mime types
4219 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4220 QByteArray d = event->encodedData("text/html");
4223 text = QString((const QChar*)d.data(),d.size()/2);
4227 textEditor->setText(text);
4231 } else if (event->provides("text/plain")) {
4232 QByteArray d = event->encodedData("text/plain");
4235 text = QString((const QChar*)d.data(),d.size()/2);
4239 textEditor->setText(text);
4249 bool isUnicode16(const QByteArray &d)
4251 // TODO: make more precise check for unicode 16.
4252 // Guess unicode16 if any of second bytes are zero
4253 unsigned int length = max(0,d.size()-2)/2;
4254 for (unsigned int i = 0; i<length ; i++)
4255 if (d.at(i*2+1)==0) return true;
4259 void MapEditor::addFloatImageInt (const QPixmap &img)
4261 BranchObj *bo=xelection.getBranch();
4264 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4265 //QString fn=fd->selectedFile();
4266 //lastImageDir=fn.left(fn.findRev ("/"));
4267 FloatImageObj *fio=bo->addFloatImage();
4269 fio->setOriginalFilename("Image added by Drag and Drop");
4270 mapCenter->reposition();
4277 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4279 if (!imageBuffer) imageBuffer = new QBuffer();
4280 if (!imageBuffer->isOpen()) {
4281 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4283 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4287 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4289 if (nop->state()==Q3NetworkProtocol::StDone) {
4290 QPixmap img(imageBuffer->buffer());
4291 addFloatImageInt (img);
4295 imageBuffer->close();
4297 imageBuffer->close();
4304 void MapEditor::fetchImage(const QString &url)
4307 urlOperator->stop();
4308 disconnect(urlOperator);
4312 urlOperator = new Q3UrlOperator(url);
4313 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4314 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4316 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4317 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));