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.command();
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=="colorBranch")
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(1))
521 QColor c=parser.parColor (ok,0);
522 if (ok) colorBranch (c);
524 } else if (com=="colorSubtree")
526 cout << "atom="<< atom.ascii()<<endl;
527 if (xelection.isEmpty())
529 parser.setError (Aborted,"Nothing selected");
532 parser.setError (Aborted,"Type of selection is not a branch");
533 } else if (parser.checkParamCount(1))
535 QColor c=parser.parColor (ok,0);
536 if (ok) colorSubtree (c);
538 } else if (com=="cut")
540 if (xelection.isEmpty())
542 parser.setError (Aborted,"Nothing selected");
543 } else if ( xelection.type()!=Branch &&
544 xelection.type()!=MapCenter &&
545 xelection.type()!=FloatImage )
547 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
548 } else if (parser.checkParamCount(0))
552 } else if (com=="delete")
554 if (xelection.isEmpty())
556 parser.setError (Aborted,"Nothing selected");
557 } else if (xelection.type() != Branch && xelection.type() != FloatImage )
559 parser.setError (Aborted,"Type of selection is wrong.");
560 } else if (parser.checkParamCount(0))
564 } else if (com=="deleteKeepChilds")
566 if (xelection.isEmpty())
568 parser.setError (Aborted,"Nothing selected");
571 parser.setError (Aborted,"Type of selection is not a branch");
572 } else if (parser.checkParamCount(0))
576 } else if (com=="deleteChilds")
578 if (xelection.isEmpty())
580 parser.setError (Aborted,"Nothing selected");
583 parser.setError (Aborted,"Type of selection is not a branch");
584 } else if (parser.checkParamCount(0))
588 } else if (com=="linkTo")
590 if (xelection.isEmpty())
592 parser.setError (Aborted,"Nothing selected");
595 if (parser.checkParamCount(4))
597 // 0 selectstring of parent
598 // 1 num in parent (for branches)
599 // 2,3 x,y of mainbranch or mapcenter
600 s=parser.parString(ok,0);
601 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
604 if (typeid(*dst) == typeid(BranchObj) )
606 // Get number in parent
607 x=parser.parInt (ok,1);
609 selb->linkTo ((BranchObj*)(dst),x);
610 } else if (typeid(*dst) == typeid(MapCenterObj) )
612 selb->linkTo ((BranchObj*)(dst),-1);
613 // Get coordinates of mainbranch
614 x=parser.parInt (ok,2);
617 y=parser.parInt (ok,3);
618 if (ok) selb->move (x,y);
623 } else if ( xelection.type() == FloatImage)
625 if (parser.checkParamCount(1))
627 // 0 selectstring of parent
628 s=parser.parString(ok,0);
629 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
632 if (typeid(*dst) == typeid(BranchObj) ||
633 typeid(*dst) == typeid(MapCenterObj))
634 linkTo (dst->getSelectString());
636 parser.setError (Aborted,"Destination is not a branch");
639 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
640 } else if (com=="loadImage")
642 if (xelection.isEmpty())
644 parser.setError (Aborted,"Nothing selected");
647 parser.setError (Aborted,"Type of selection is not a branch");
648 } else if (parser.checkParamCount(1))
650 s=parser.parString(ok,0);
651 if (ok) loadFloatImageInt (s);
653 } else if (com=="moveBranchUp")
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(0))
665 } else if (com=="moveBranchDown")
667 if (xelection.isEmpty() )
669 parser.setError (Aborted,"Nothing selected");
672 parser.setError (Aborted,"Type of selection is not a branch");
673 } else if (parser.checkParamCount(0))
677 } else if (com=="move")
679 if (xelection.isEmpty() )
681 parser.setError (Aborted,"Nothing selected");
682 } else if ( xelection.type()!=Branch &&
683 xelection.type()!=MapCenter &&
684 xelection.type()!=FloatImage )
686 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
687 } else if (parser.checkParamCount(2))
689 x=parser.parInt (ok,0);
692 y=parser.parInt (ok,1);
696 } else if (com=="moveRel")
698 if (xelection.isEmpty() )
700 parser.setError (Aborted,"Nothing selected");
701 } else if ( xelection.type()!=Branch &&
702 xelection.type()!=MapCenter &&
703 xelection.type()!=FloatImage )
705 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
706 } else if (parser.checkParamCount(2))
708 x=parser.parInt (ok,0);
711 y=parser.parInt (ok,1);
712 if (ok) moveRel (x,y);
715 } else if (com=="paste")
717 if (xelection.isEmpty() )
719 parser.setError (Aborted,"Nothing selected");
722 parser.setError (Aborted,"Type of selection is not a branch");
723 } else if (parser.checkParamCount(0))
727 } else if (com=="saveImage")
729 FloatImageObj *fio=xelection.getFloatImage();
732 parser.setError (Aborted,"Type of selection is not an image");
733 } else if (parser.checkParamCount(2))
735 s=parser.parString(ok,0);
738 t=parser.parString(ok,1);
739 if (ok) saveFloatImageInt (fio,t,s);
742 } else if (com=="scroll")
744 if (xelection.isEmpty() )
746 parser.setError (Aborted,"Nothing selected");
749 parser.setError (Aborted,"Type of selection is not a branch");
750 } else if (parser.checkParamCount(0))
752 if (!scrollBranch ())
753 parser.setError (Aborted,"Could not scroll branch");
755 } else if (com=="select")
757 if (parser.checkParamCount(1))
759 s=parser.parString(ok,0);
762 } else if (com=="selectLastBranch")
764 if (xelection.isEmpty() )
766 parser.setError (Aborted,"Nothing selected");
769 parser.setError (Aborted,"Type of selection is not a branch");
770 } else if (parser.checkParamCount(0))
772 BranchObj *bo=selb->getLastBranch();
774 parser.setError (Aborted,"Could not select last branch");
778 } else if (com=="selectLastImage")
780 if (xelection.isEmpty() )
782 parser.setError (Aborted,"Nothing selected");
785 parser.setError (Aborted,"Type of selection is not a branch");
786 } else if (parser.checkParamCount(0))
788 FloatImageObj *fio=selb->getLastFloatImage();
790 parser.setError (Aborted,"Could not select last image");
794 } else if (com=="setMapAuthor")
796 if (parser.checkParamCount(1))
798 s=parser.parString(ok,0);
799 if (ok) setMapAuthor (s);
801 } else if (com=="setMapComment")
803 if (parser.checkParamCount(1))
805 s=parser.parString(ok,0);
806 if (ok) setMapComment(s);
808 } else if (com=="setMapBackgroundColor")
810 if (xelection.isEmpty() )
812 parser.setError (Aborted,"Nothing selected");
813 } else if (! xelection.getBranch() )
815 parser.setError (Aborted,"Type of selection is not a branch");
816 } else if (parser.checkParamCount(1))
818 QColor c=parser.parColor (ok,0);
819 if (ok) setMapBackgroundColor (c);
821 } else if (com=="setMapDefLinkColor")
823 if (xelection.isEmpty() )
825 parser.setError (Aborted,"Nothing selected");
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) setMapDefLinkColor (c);
834 } else if (com=="setMapLinkStyle")
836 if (parser.checkParamCount(1))
838 s=parser.parString (ok,0);
839 if (ok) setMapLinkStyle(s);
841 } else if (com=="setHeading")
843 if (xelection.isEmpty() )
845 parser.setError (Aborted,"Nothing selected");
848 parser.setError (Aborted,"Type of selection is not a branch");
849 } else if (parser.checkParamCount(1))
851 s=parser.parString (ok,0);
855 } else if (com=="setHideExport")
857 if (xelection.isEmpty() )
859 parser.setError (Aborted,"Nothing selected");
862 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
863 //FIXME selb is never a floatimage!!
864 } else if (parser.checkParamCount(1))
866 b=parser.parBool(ok,0);
867 if (ok) setHideExport (b);
869 } else if (com=="setIncludeImagesHorizontally")
871 if (xelection.isEmpty() )
873 parser.setError (Aborted,"Nothing selected");
876 parser.setError (Aborted,"Type of selection is not a branch");
877 } else if (parser.checkParamCount(1))
879 b=parser.parBool(ok,0);
880 if (ok) setIncludeImagesHor(b);
882 } else if (com=="setIncludeImagesVertically")
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) setIncludeImagesVer(b);
895 } else if (com=="setSelectionColor")
897 if (parser.checkParamCount(1))
899 QColor c=parser.parColor (ok,0);
900 if (ok) setSelectionColorInt (c);
902 } else if (com=="setURL")
904 if (xelection.isEmpty() )
906 parser.setError (Aborted,"Nothing selected");
909 parser.setError (Aborted,"Type of selection is not a branch");
910 } else if (parser.checkParamCount(1))
912 s=parser.parString (ok,0);
913 if (ok) setURLInt(s);
915 } else if (com=="setVymLink")
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) setVymLinkInt(s);
929 else if (com=="setFlag")
931 if (xelection.isEmpty() )
933 parser.setError (Aborted,"Nothing selected");
936 parser.setError (Aborted,"Type of selection is not a branch");
937 } else if (parser.checkParamCount(1))
939 s=parser.parString(ok,0);
942 selb->activateStandardFlag(s);
943 selb->updateFlagsToolbar();
946 } else if (com=="setFrameType")
948 if (xelection.isEmpty() )
950 parser.setError (Aborted,"Nothing selected");
953 parser.setError (Aborted,"Type of selection is not a branch");
954 } else if (parser.checkParamCount(1))
956 s=parser.parString(ok,0);
960 } else if (com=="unscroll")
962 if (xelection.isEmpty() )
964 parser.setError (Aborted,"Nothing selected");
967 parser.setError (Aborted,"Type of selection is not a branch");
968 } else if (parser.checkParamCount(0))
970 if (!unscrollBranch ())
971 parser.setError (Aborted,"Could not unscroll branch");
973 } else if (com=="unsetFlag")
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->deactivateStandardFlag(s);
987 selb->updateFlagsToolbar();
991 parser.setError (Aborted,"Unknown command");
994 if (parser.errorLevel()==NoError)
997 mapCenter->reposition();
1001 // TODO Error handling
1002 qWarning("MapEditor::parseAtom: Error!");
1003 qWarning(parser.errorMessage());
1007 void MapEditor::runScript (QString script)
1009 // FIXME "atomize" script, currently each line holds one atom
1011 parser.setScript (script);
1016 bool MapEditor::isDefault()
1021 bool MapEditor::isUnsaved()
1026 bool MapEditor::hasChanged()
1031 void MapEditor::setChanged()
1039 void MapEditor::closeMap()
1041 // Unselect before disabling the toolbar actions
1042 if (!xelection.isEmpty() ) xelection.unselect();
1050 void MapEditor::setFilePath(QString fname)
1052 setFilePath (fname,fname);
1055 void MapEditor::setFilePath(QString fname, QString destname)
1057 if (fname.isEmpty() || fname=="")
1064 filePath=fname; // becomes absolute path
1065 fileName=fname; // gets stripped of path
1066 destPath=destname; // needed for vymlinks
1068 // If fname is not an absolute path, complete it
1069 filePath=QDir(fname).absPath();
1070 fileDir=filePath.left (1+filePath.findRev ("/"));
1072 // Set short name, too. Search from behind:
1073 int i=fileName.findRev("/");
1074 if (i>=0) fileName=fileName.remove (0,i+1);
1076 // Forget the .vym (or .xml) for name of map
1077 mapName=fileName.left(fileName.findRev(".",-1,true) );
1081 QString MapEditor::getFilePath()
1086 QString MapEditor::getFileName()
1091 QString MapEditor::getMapName()
1096 QString MapEditor::getDestPath()
1101 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1103 ErrorCode err=success;
1107 if (xelection.isEmpty() ) xelection.unselect();
1110 mapCenter->setMapEditor(this);
1111 // (map state is set later at end of load...)
1114 BranchObj *bo=xelection.getBranch();
1115 if (!bo) return aborted;
1116 if (lmode==ImportAdd)
1117 saveStateChangingPart(
1120 QString("addMapInsert (%1)").arg(fname),
1121 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1123 saveStateChangingPart(
1126 QString("addMapReplace(%1)").arg(fname),
1127 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1131 mapBuilderHandler handler;
1132 QFile file( fname );
1134 // I am paranoid: file should exist anyway
1135 // according to check in mainwindow.
1136 if (!file.exists() )
1138 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1139 tr("Couldn't open map " +fname)+".");
1143 blockReposition=true;
1144 QXmlInputSource source( file);
1145 QXmlSimpleReader reader;
1146 reader.setContentHandler( &handler );
1147 reader.setErrorHandler( &handler );
1148 handler.setMapEditor( this );
1149 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1150 handler.setInputFile (file.name());
1151 handler.setLoadMode (lmode);
1152 blockSaveState=true;
1153 bool ok = reader.parse( source );
1154 blockReposition=false;
1155 blockSaveState=false;
1159 mapCenter->reposition();
1169 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1170 tr( handler.errorProtocol() ) );
1172 // Still return "success": the map maybe at least
1173 // partially read by the parser
1180 int MapEditor::save (const SaveMode &savemode)
1184 // Create mapName and fileDir
1185 makeSubDirs (fileDir);
1189 fname=mapName+".xml";
1191 // use name given by user, even if he chooses .doc
1196 if (savemode==CompleteMap || xelection.isEmpty())
1197 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1199 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch()); //FIXME check selected FIO
1201 if (!saveStringToDisk(fileDir+fname,saveFile))
1214 void MapEditor::setZipped (bool z)
1219 bool MapEditor::saveZipped ()
1224 void MapEditor::print()
1228 printer = new QPrinter;
1229 printer->setColorMode (QPrinter::Color);
1230 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1231 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1232 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1235 QRectF totalBBox=mapCenter->getTotalBBox();
1237 // Try to set orientation automagically
1238 // Note: Interpretation of generated postscript is amibiguous, if
1239 // there are problems with landscape mode, see
1240 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1242 if (totalBBox.width()>totalBBox.height())
1243 // recommend landscape
1244 printer->setOrientation (QPrinter::Landscape);
1246 // recommend portrait
1247 printer->setOrientation (QPrinter::Portrait);
1249 if ( printer->setup(this) )
1250 // returns false, if printing is canceled
1252 QPainter pp(printer);
1254 pp.setRenderHint(QPainter::Antialiasing,true);
1256 // Don't print the visualisation of selection
1257 xelection.unselect();
1259 QRectF mapRect=totalBBox;
1260 QGraphicsRectItem *frame=NULL;
1264 // Print frame around map
1265 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1266 totalBBox.width()+20, totalBBox.height()+20);
1267 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1268 frame->setZValue(0);
1273 double paperAspect = (double)printer->width() / (double)printer->height();
1274 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1276 if (mapAspect>=paperAspect)
1278 // Fit horizontally to paper width
1279 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1280 viewBottom=(int)(printer->width()/mapAspect);
1283 // Fit vertically to paper height
1284 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1285 viewBottom=printer->height();
1290 // Print footer below map
1292 font.setPointSize(10);
1294 QRectF footerBox(0,viewBottom,printer->width(),15);
1295 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1296 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1300 QRectF (0,0,printer->width(),printer->height()-15),
1301 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1304 // Viewport has paper dimension
1305 if (frame) delete (frame);
1307 // Restore selection
1308 xelection.reselect();
1310 // Save settings in vymrc
1311 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1312 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1313 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1317 void MapEditor::setAntiAlias (bool b)
1319 setRenderHint(QPainter::Antialiasing,b);
1322 void MapEditor::setSmoothPixmap(bool b)
1324 setRenderHint(QPainter::SmoothPixmapTransform,b);
1327 QPixmap MapEditor::getPixmap()
1329 QRectF mapRect=mapCenter->getTotalBBox();
1330 QPixmap pix((int)mapRect.width(),(int)mapRect.height());
1333 pp.setRenderHints(renderHints());
1335 // Don't print the visualisation of selection
1336 xelection.unselect();
1338 mapScene->render ( &pp,
1339 QRectF(0,0,mapRect.width(),mapRect.height()),
1340 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1342 // mapScene->render(&pp); // draw scene to painter
1346 // Restore selection
1347 xelection.reselect();
1352 void MapEditor::setHideTmpMode (HideTmpMode mode)
1355 mapCenter->setHideTmp (hidemode);
1356 mapCenter->reposition();
1360 HideTmpMode MapEditor::getHideTmpMode()
1365 void MapEditor::exportImage(QString fn)
1367 setExportMode (true);
1368 QPixmap pix (getPixmap());
1369 pix.save(fn, "PNG");
1370 setExportMode (false);
1373 void MapEditor::setExportMode (bool b)
1375 // should be called before and after exports
1376 // depending on the settings
1377 if (b && settings.value("/export/useHideExport","yes")=="yes")
1378 setHideTmpMode (HideExport);
1380 setHideTmpMode (HideNone);
1383 void MapEditor::exportImage(QString fn, QString format)
1385 setExportMode (true);
1386 QPixmap pix (getPixmap());
1387 pix.save(fn, format);
1388 setExportMode (false);
1391 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1395 ex.setMapCenter(mapCenter);
1396 if (ex.setConfigFile(cf))
1398 setExportMode (true);
1399 ex.exportPresentation();
1400 setExportMode (false);
1406 void MapEditor::exportXML(const QString &dir)
1408 // Hide stuff during export, if settings want this
1409 setExportMode (true);
1411 // Create subdirectories
1414 // write to directory
1415 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1418 file.setName ( dir + "/"+mapName+".xml");
1419 if ( !file.open( QIODevice::WriteOnly ) )
1421 // This should neverever happen
1422 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1426 // Write it finally, and write in UTF8, no matter what
1427 QTextStream ts( &file );
1428 ts.setEncoding (QTextStream::UnicodeUTF8);
1432 // Now write image, too
1433 exportImage (dir+"/images/"+mapName+".png");
1435 setExportMode (false);
1438 void MapEditor::clear()
1440 xelection.unselect();
1444 void MapEditor::copy()
1446 LinkableMapObj *sel=xelection.single();
1449 // write to directory
1450 QString clipfile="part";
1451 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPointF(),sel ); // FIXME check FIO
1454 file.setName ( clipboardDir + "/"+clipfile+".xml");
1455 if ( !file.open( QIODevice::WriteOnly ) )
1457 // This should neverever happen
1458 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1462 // Write it finally, and write in UTF8, no matter what
1463 QTextStream ts( &file );
1464 ts.setEncoding (QTextStream::UnicodeUTF8);
1468 clipboardEmpty=false;
1473 void MapEditor::redo()
1475 blockSaveState=true;
1477 // Restore variables
1478 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1479 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1480 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1481 // Can we undo at all?
1482 if (redosAvail<1) return;
1485 if (undosAvail<stepsTotal) undosAvail++;
1487 if (curStep>stepsTotal) curStep=1;
1488 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1489 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1490 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1491 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1492 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1493 QString version=undoSet.readEntry ("/history/version");
1495 if (!checkVersion(version))
1496 QMessageBox::warning(0,tr("Warning"),
1497 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1500 // Find out current undo directory
1501 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1503 /* TODO remove testing
1505 cout << "ME::redo() begin\n";
1506 cout << " undosAvail="<<undosAvail<<endl;
1507 cout << " redosAvail="<<redosAvail<<endl;
1508 cout << " curStep="<<curStep<<endl;
1509 cout << " ---------------------------"<<endl;
1510 cout << " comment="<<comment.toStdString()<<endl;
1511 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1512 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1513 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1514 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1515 cout << " ---------------------------"<<endl<<endl;
1517 // select object before redo
1518 if (!redoSelection.isEmpty())
1519 select (redoSelection);
1522 parseAtom (redoCommand);
1523 mapCenter->reposition();
1525 blockSaveState=false;
1527 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1528 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1529 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1530 undoSet.writeSettings(histPath);
1532 mainWindow->updateHistory (undoSet);
1535 /* TODO remove testing
1536 cout << "ME::redo() end\n";
1537 cout << " undosAvail="<<undosAvail<<endl;
1538 cout << " redosAvail="<<redosAvail<<endl;
1539 cout << " curStep="<<curStep<<endl;
1540 cout << " ---------------------------"<<endl<<endl;
1546 bool MapEditor::isRedoAvailable()
1548 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1554 void MapEditor::undo()
1556 blockSaveState=true;
1558 // Restore variables
1559 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1560 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1561 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1563 // Can we undo at all?
1564 if (undosAvail<1) return;
1566 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1567 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1568 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1569 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1570 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1571 QString version=undoSet.readEntry ("/history/version");
1573 if (!checkVersion(version))
1574 QMessageBox::warning(0,tr("Warning"),
1575 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1577 // Find out current undo directory
1578 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1580 // select object before undo
1581 if (!undoSelection.isEmpty())
1582 select (undoSelection);
1586 cout << "ME::undo() begin\n";
1587 cout << " undosAvail="<<undosAvail<<endl;
1588 cout << " redosAvail="<<redosAvail<<endl;
1589 cout << " curStep="<<curStep<<endl;
1590 cout << " ---------------------------"<<endl;
1591 cout << " comment="<<comment.toStdString()<<endl;
1592 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1593 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1594 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1595 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1596 cout << " ---------------------------"<<endl<<endl;
1597 parseAtom (undoCommand);
1598 mapCenter->reposition();
1602 if (curStep<1) curStep=stepsTotal;
1606 blockSaveState=false;
1607 /* TODO remove testing
1608 cout << "ME::undo() end\n";
1609 cout << " undosAvail="<<undosAvail<<endl;
1610 cout << " redosAvail="<<redosAvail<<endl;
1611 cout << " curStep="<<curStep<<endl;
1612 cout << " ---------------------------"<<endl<<endl;
1615 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1616 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1617 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1618 undoSet.writeSettings(histPath);
1620 mainWindow->updateHistory (undoSet);
1623 ensureSelectionVisible();
1626 bool MapEditor::isUndoAvailable()
1628 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1634 void MapEditor::gotoHistoryStep (int i)
1636 // Restore variables
1637 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1638 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1640 if (i<0) i=undosAvail+redosAvail;
1642 // Clicking above current step makes us undo things
1645 for (int j=0; j<undosAvail-i; j++) undo();
1648 // Clicking below current step makes us redo things
1650 for (int j=undosAvail; j<i; j++) redo();
1652 // And ignore clicking the current row ;-)
1655 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1657 QString pathDir=path.left(path.findRev("/"));
1663 // We need to parse saved XML data
1664 mapBuilderHandler handler;
1665 QXmlInputSource source( file);
1666 QXmlSimpleReader reader;
1667 reader.setContentHandler( &handler );
1668 reader.setErrorHandler( &handler );
1669 handler.setMapEditor( this );
1670 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1671 if (undoSel.isEmpty())
1675 handler.setLoadMode (NewMap);
1679 handler.setLoadMode (ImportReplace);
1681 blockReposition=true;
1682 bool ok = reader.parse( source );
1683 blockReposition=false;
1686 // This should never ever happen
1687 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1688 handler.errorProtocol());
1691 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1694 void MapEditor::addMapInsertInt (const QString &path, int pos)
1696 BranchObj *sel=xelection.getBranch();
1699 QString pathDir=path.left(path.findRev("/"));
1705 // We need to parse saved XML data
1706 mapBuilderHandler handler;
1707 QXmlInputSource source( file);
1708 QXmlSimpleReader reader;
1709 reader.setContentHandler( &handler );
1710 reader.setErrorHandler( &handler );
1711 handler.setMapEditor( this );
1712 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1713 handler.setLoadMode (ImportAdd);
1714 blockReposition=true;
1715 bool ok = reader.parse( source );
1716 blockReposition=false;
1719 // This should never ever happen
1720 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1721 handler.errorProtocol());
1724 sel->getLastBranch()->linkTo (sel,pos);
1726 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1730 void MapEditor::pasteNoSave()
1732 load (clipboardDir+"/part.xml",ImportAdd);
1735 void MapEditor::cutNoSave()
1741 void MapEditor::paste() // FIXME no pasting of FIO ???
1743 BranchObj *sel=xelection.getBranch();
1747 saveStateChangingPart(
1751 QString("Paste to %1").arg( getName(sel))
1753 mapCenter->reposition();
1757 void MapEditor::cut()
1759 LinkableMapObj *sel=xelection.single();
1760 if ( sel && (xelection.type() == Branch ||
1761 xelection.type()==MapCenter ||
1762 xelection.type()==FloatImage))
1764 saveStateChangingPart(
1768 QString("Cut %1").arg(getName(sel ))
1772 mapCenter->reposition();
1776 void MapEditor::move(const int &x, const int &y)
1778 LinkableMapObj *sel=xelection.single();
1781 QString ps=qpointfToString (sel->getAbsPos());
1782 QString s=xelection.single()->getSelectString();
1785 s, "move "+qpointfToString (QPointF (x,y)),
1786 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
1787 sel->move(x,y); // FIXME xelection not moved automagically...
1788 mapCenter->reposition();
1794 void MapEditor::moveRel (const int &x, const int &y)
1796 LinkableMapObj *sel=xelection.single();
1799 QString ps=qpointfToString (sel->getRelPos());
1800 QString s=sel->getSelectString();
1803 s, "moveRel "+qpointfToString (QPointF (x,y)),
1804 QString("Move %1 to relativ position %2").arg(getName(sel)).arg(ps));
1805 ((OrnamentedObj*)sel)->move2RelPos (x,y);
1806 mapCenter->reposition();
1812 void MapEditor::moveBranchUp()
1814 BranchObj* bo=xelection.getBranch();
1818 if (!bo->canMoveBranchUp()) return;
1819 par=(BranchObj*)(bo->getParObj());
1820 xelection.unselect(); // FIXME needed?
1821 bo=par->moveBranchUp (bo); // bo will be the one below selection
1822 xelection.reselect();
1823 //saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1824 saveState (bo,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1825 mapCenter->reposition();
1828 ensureSelectionVisible();
1832 void MapEditor::moveBranchDown()
1834 BranchObj* bo=xelection.getBranch();
1838 if (!bo->canMoveBranchDown()) return;
1839 par=(BranchObj*)(bo->getParObj());
1840 xelection.unselect(); // FIXME needed?
1841 bo=par->moveBranchDown(bo); // bo will be the one above selection
1842 xelection.reselect();
1843 //saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1844 saveState(bo,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1845 mapCenter->reposition();
1848 ensureSelectionVisible();
1852 void MapEditor::linkTo(const QString &dstString) // FIXME needed? only for FIO ??
1854 FloatImageObj *fio=xelection.getFloatImage();
1857 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
1858 if (dst && (typeid(*dst)==typeid (BranchObj) ||
1859 typeid(*dst)==typeid (MapCenterObj)))
1861 LinkableMapObj *dstPar=dst->getParObj();
1862 QString parString=dstPar->getSelectString();
1863 QString fioPreSelectString=fio->getSelectString();
1864 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
1865 ((BranchObj*)(dst))->addFloatImage (fio);
1866 xelection.unselect();
1867 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
1868 fio=((BranchObj*)(dst))->getLastFloatImage();
1871 xelection.select(fio);
1873 fio->getSelectString(),
1874 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
1876 QString ("linkTo (\"%1\")").arg(dstString),
1877 QString ("Link floatimage to %1").arg(getName(dst)));
1882 QString MapEditor::getHeading(bool &ok, QPoint &p)
1884 BranchObj *bo=xelection.getBranch();
1888 p=mapFromScene(bo->getAbsPos());
1889 return bo->getHeading();
1895 void MapEditor::setHeading(const QString &s)
1897 BranchObj *sel=xelection.getBranch();
1902 "setHeading (\""+sel->getHeading()+"\")",
1904 "setHeading (\""+s+"\")",
1905 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
1906 sel->setHeading(s );
1907 mapCenter->reposition();
1909 ensureSelectionVisible();
1913 void MapEditor::setURLInt (const QString &s)
1915 // Internal function, no saveState needed
1916 BranchObj *bo=xelection.getBranch();
1920 mapCenter->reposition();
1922 ensureSelectionVisible();
1926 void MapEditor::setHeadingInt(const QString &s)
1928 BranchObj *bo=xelection.getBranch();
1932 mapCenter->reposition();
1934 ensureSelectionVisible();
1938 void MapEditor::setVymLinkInt (const QString &s)
1940 // Internal function, no saveState needed
1941 BranchObj *bo=xelection.getBranch();
1945 mapCenter->reposition();
1947 ensureSelectionVisible();
1951 BranchObj* MapEditor::addNewBranchInt(int num)
1953 // Depending on pos:
1954 // -3 insert in childs of parent above selection
1955 // -2 add branch to selection
1956 // -1 insert in childs of parent below selection
1957 // 0..n insert in childs of parent at pos
1958 BranchObj *newbo=NULL;
1959 BranchObj *bo=xelection.getBranch();
1964 // save scroll state. If scrolled, automatically select
1965 // new branch in order to tmp unscroll parent...
1966 return bo->addBranch();
1971 bo=(BranchObj*)bo->getParObj();
1975 bo=(BranchObj*)bo->getParObj();
1978 newbo=bo->insertBranch(num);
1983 BranchObj* MapEditor::addNewBranch(int pos)
1985 // Different meaning than num in addNewBranchInt!
1989 BranchObj *bo = xelection.getBranch();
1990 BranchObj *newbo=NULL;
1994 setCursor (Qt::ArrowCursor);
1996 newbo=addNewBranchInt (pos-2);
2004 QString ("addBranch (%1)").arg(pos-2),
2005 QString ("Add new branch to %1").arg(getName(bo)));
2007 mapCenter->reposition();
2015 BranchObj* MapEditor::addNewBranchBefore()
2017 BranchObj *newbo=NULL;
2018 BranchObj *bo = xelection.getBranch();
2019 if (bo && xelection.type()==Branch)
2020 // We accept no MapCenterObj here, so we _have_ a parent
2022 QPointF p=bo->getRelPos();
2025 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2027 // add below selection
2028 newbo=parbo->insertBranch(bo->getNum()+1);
2031 newbo->move2RelPos (p);
2033 // Move selection to new branch
2034 bo->linkTo (newbo,-1);
2036 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2037 QString ("Add branch before %1").arg(getName(bo)));
2039 mapCenter->reposition();
2046 void MapEditor::deleteSelection()
2048 BranchObj *bo = xelection.getBranch();
2049 if (bo && xelection.type()==Branch)
2051 BranchObj* par=(BranchObj*)(bo->getParObj());
2052 xelection.unselect();
2053 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2054 par->removeBranch(bo);
2055 xelection.select (par);
2056 ensureSelectionVisible();
2057 mapCenter->reposition();
2062 FloatImageObj *fio=xelection.getFloatImage();
2065 BranchObj* par=(BranchObj*)(fio->getParObj());
2066 saveStateChangingPart(
2070 QString("Delete %1").arg(getName(fio))
2072 xelection.unselect();
2073 par->removeFloatImage(fio);
2074 xelection.select (par);
2075 mapCenter->reposition();
2077 ensureSelectionVisible();
2082 LinkableMapObj* MapEditor::getSelection()
2084 return xelection.single();
2087 BranchObj* MapEditor::getSelectedBranch()
2089 return xelection.getBranch();
2092 FloatImageObj* MapEditor::getSelectedFloatImage()
2094 return xelection.getFloatImage();
2097 void MapEditor::unselect()
2099 xelection.unselect();
2102 void MapEditor::reselect()
2104 xelection.reselect();
2107 bool MapEditor::select (const QString &s)
2109 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2111 // Finally select the found object
2114 xelection.unselect();
2115 xelection.select(lmo);
2117 ensureSelectionVisible();
2123 QString MapEditor::getSelectString()
2125 return xelection.getSelectString();
2128 void MapEditor::selectInt (LinkableMapObj *lmo)
2130 if (lmo && xelection.single()!= lmo)
2132 xelection.select(lmo);
2137 void MapEditor::selectNextBranchInt()
2139 // Increase number of branch
2140 LinkableMapObj *sel=xelection.single();
2143 QString s=sel->getSelectString();
2149 part=s.section(",",-1);
2151 num=part.right(part.length() - 3);
2153 s=s.left (s.length() -num.length());
2156 num=QString ("%1").arg(num.toUInt()+1);
2160 // Try to select this one
2161 if (select (s)) return;
2163 // We have no direct successor,
2164 // try to increase the parental number in order to
2165 // find a successor with same depth
2167 int d=xelection.single()->getDepth();
2172 while (!found && d>0)
2174 s=s.section (",",0,d-1);
2175 // replace substring of current depth in s with "1"
2176 part=s.section(",",-1);
2178 num=part.right(part.length() - 3);
2182 // increase number of parent
2183 num=QString ("%1").arg(num.toUInt()+1);
2184 s=s.section (",",0,d-2) + ","+ typ+num;
2187 // Special case, look at orientation
2188 if (xelection.single()->getOrientation()==OrientRightOfCenter)
2189 num=QString ("%1").arg(num.toUInt()+1);
2191 num=QString ("%1").arg(num.toUInt()-1);
2196 // pad to oldDepth, select the first branch for each depth
2197 for (i=d;i<oldDepth;i++)
2202 if ( xelection.getBranch()->countBranches()>0)
2210 // try to select the freshly built string
2218 void MapEditor::selectPrevBranchInt()
2220 // Decrease number of branch
2221 BranchObj *bo=xelection.getBranch();
2224 QString s=bo->getSelectString();
2230 part=s.section(",",-1);
2232 num=part.right(part.length() - 3);
2234 s=s.left (s.length() -num.length());
2236 int n=num.toInt()-1;
2239 num=QString ("%1").arg(n);
2242 // Try to select this one
2243 if (n>=0 && select (s)) return;
2245 // We have no direct precessor,
2246 // try to decrease the parental number in order to
2247 // find a precessor with same depth
2249 int d=xelection.single()->getDepth();
2254 while (!found && d>0)
2256 s=s.section (",",0,d-1);
2257 // replace substring of current depth in s with "1"
2258 part=s.section(",",-1);
2260 num=part.right(part.length() - 3);
2264 // decrease number of parent
2265 num=QString ("%1").arg(num.toInt()-1);
2266 s=s.section (",",0,d-2) + ","+ typ+num;
2269 // Special case, look at orientation
2270 if (xelection.single()->getOrientation()==OrientRightOfCenter)
2271 num=QString ("%1").arg(num.toInt()-1);
2273 num=QString ("%1").arg(num.toInt()+1);
2278 // pad to oldDepth, select the last branch for each depth
2279 for (i=d;i<oldDepth;i++)
2283 if ( xelection.getBranch()->countBranches()>0)
2284 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2291 // try to select the freshly built string
2299 void MapEditor::selectUpperBranch()
2301 BranchObj *bo=xelection.getBranch();
2302 if (bo && xelection.type()==Branch)
2304 if (bo->getOrientation()==OrientRightOfCenter)
2305 selectPrevBranchInt();
2307 if (bo->getDepth()==1)
2308 selectNextBranchInt();
2310 selectPrevBranchInt();
2314 void MapEditor::selectLowerBranch()
2316 BranchObj *bo=xelection.getBranch();
2317 if (bo && xelection.type()==Branch)
2318 if (bo->getOrientation()==OrientRightOfCenter)
2319 selectNextBranchInt();
2321 if (bo->getDepth()==1)
2322 selectPrevBranchInt();
2324 selectNextBranchInt();
2328 void MapEditor::selectLeftBranch()
2332 LinkableMapObj *sel=xelection.single();
2335 if (xelection.type()== MapCenter)
2337 par=xelection.getBranch();
2338 bo=par->getLastSelectedBranch();
2341 // Workaround for reselecting on left and right side
2342 if (bo->getOrientation()==OrientRightOfCenter)
2343 bo=par->getLastBranch();
2346 bo=par->getLastBranch();
2347 xelection.select(bo);
2349 ensureSelectionVisible();
2354 par=(BranchObj*)(sel->getParObj());
2355 if (sel->getOrientation()==OrientRightOfCenter)
2357 if (xelection.type() == Branch ||
2358 xelection.type() == FloatImage)
2360 xelection.select(par);
2362 ensureSelectionVisible();
2366 if (xelection.type() == Branch )
2368 bo=xelection.getBranch()->getLastSelectedBranch();
2371 xelection.select(bo);
2373 ensureSelectionVisible();
2381 void MapEditor::selectRightBranch()
2385 LinkableMapObj *sel=xelection.single();
2388 if (xelection.type()==MapCenter)
2390 par=xelection.getBranch();
2391 bo=par->getLastSelectedBranch();
2394 // Workaround for reselecting on left and right side
2395 if (bo->getOrientation()==OrientLeftOfCenter)
2396 bo=par->getFirstBranch();
2399 xelection.select(bo);
2401 ensureSelectionVisible();
2406 par=(BranchObj*)(xelection.single()->getParObj());
2407 if (xelection.single()->getOrientation()==OrientLeftOfCenter)
2409 if (xelection.type() == Branch ||
2410 xelection.type() == FloatImage)
2412 xelection.select(par);
2414 ensureSelectionVisible();
2418 if (xelection.type() == Branch)
2420 bo=xelection.getBranch()->getLastSelectedBranch();
2423 xelection.select(bo);
2425 ensureSelectionVisible();
2433 void MapEditor::selectFirstBranch()
2435 BranchObj *bo1=xelection.getBranch();
2440 par=(BranchObj*)(bo1->getParObj());
2441 bo2=par->getFirstBranch();
2443 xelection.select(bo2);
2445 ensureSelectionVisible();
2450 void MapEditor::selectLastBranch()
2452 BranchObj *bo1=xelection.getBranch();
2457 par=(BranchObj*)(bo1->getParObj());
2458 bo2=par->getLastBranch();
2461 xelection.select(bo2);
2463 ensureSelectionVisible();
2468 void MapEditor::selectMapBackgroundImage ()
2470 Q3FileDialog *fd=new Q3FileDialog( this);
2471 fd->setMode (Q3FileDialog::ExistingFile);
2472 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2473 ImagePreview *p =new ImagePreview (fd);
2474 fd->setContentsPreviewEnabled( TRUE );
2475 fd->setContentsPreview( p, p );
2476 fd->setPreviewMode( Q3FileDialog::Contents );
2477 fd->setCaption(vymName+" - " +tr("Load background image"));
2478 fd->setDir (lastImageDir);
2481 if ( fd->exec() == QDialog::Accepted )
2483 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2484 lastImageDir=QDir (fd->dirPath());
2485 setMapBackgroundImage (fd->selectedFile());
2489 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
2491 QColor oldcol=mapScene->backgroundBrush().color();
2495 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2497 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2498 QString("Set background color of map to %1").arg(col.name()));
2501 brush.setTextureImage (QPixmap (fn));
2502 mapScene->setBackgroundBrush(brush);
2505 void MapEditor::selectMapBackgroundColor()
2507 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2508 if ( !col.isValid() ) return;
2509 setMapBackgroundColor( col );
2513 void MapEditor::setMapBackgroundColor(QColor col)
2515 QColor oldcol=mapScene->backgroundBrush().color();
2518 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
2520 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
2521 QString("Set background color of map to %1").arg(col.name()));
2522 mapScene->setBackgroundBrush(col);
2525 QColor MapEditor::getMapBackgroundColor()
2527 return mapScene->backgroundBrush().color();
2530 QColor MapEditor::getCurrentHeadingColor()
2532 BranchObj *bo=xelection.getBranch();
2533 if (bo) return bo->getColor();
2535 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2539 void MapEditor::colorBranch (QColor c)
2541 BranchObj *bo=xelection.getBranch();
2546 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
2548 QString ("colorBranch (\"%1\")").arg(c.name()),
2549 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2551 bo->setColor(c); // color branch
2555 void MapEditor::colorSubtree (QColor c)
2557 BranchObj *bo=xelection.getBranch();
2560 saveStateChangingPart(
2563 QString ("colorSubtree (\"%1\")").arg(c.name()),
2564 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2566 bo->setColorSubtree (c); // color links, color childs
2571 void MapEditor::toggleStandardFlag(QString f)
2573 BranchObj *bo=xelection.getBranch();
2577 if (bo->isSetStandardFlag(f))
2589 QString("%1 (\"%2\")").arg(u).arg(f),
2591 QString("%1 (\"%2\")").arg(r).arg(f),
2592 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2593 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2599 BranchObj* MapEditor::findText (QString s, bool cs)
2601 QTextDocument::FindFlags flags=0;
2602 if (cs) flags=QTextDocument::FindCaseSensitively;
2605 { // Nothing found or new find process
2607 // nothing found, start again
2609 itFind=mapCenter->first();
2611 bool searching=true;
2612 bool foundNote=false;
2613 while (searching && !EOFind)
2617 // Searching in Note
2618 if (itFind->getNote().contains(s,cs))
2620 if (xelection.single()!=itFind)
2622 xelection.select(itFind);
2623 ensureSelectionVisible();
2625 if (textEditor->findText(s,flags))
2631 // Searching in Heading
2632 if (searching && itFind->getHeading().contains (s,cs) )
2634 xelection.select(itFind);
2635 ensureSelectionVisible();
2641 itFind=itFind->next();
2642 if (!itFind) EOFind=true;
2646 return xelection.getBranch();
2651 void MapEditor::findReset()
2652 { // Necessary if text to find changes during a find process
2656 void MapEditor::setURL(const QString &url)
2658 BranchObj *bo=xelection.getBranch();
2661 QString oldurl=bo->getURL();
2665 QString ("setURL (\"%1\")").arg(oldurl),
2667 QString ("setURL (\"%1\")").arg(url),
2668 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2674 void MapEditor::editURL()
2676 BranchObj *bo=xelection.getBranch();
2680 QString text = QInputDialog::getText(
2681 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2682 bo->getURL(), &ok, this );
2684 // user entered something and pressed OK
2689 QString MapEditor::getURL()
2691 BranchObj *bo=xelection.getBranch();
2693 return bo->getURL();
2698 QStringList MapEditor::getURLs()
2701 BranchObj *bo=xelection.getBranch();
2707 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2715 void MapEditor::editHeading2URL()
2717 BranchObj *bo=xelection.getBranch();
2719 setURL (bo->getHeading());
2722 void MapEditor::editBugzilla2URL()
2724 BranchObj *bo=xelection.getBranch();
2727 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2732 void MapEditor::editFATE2URL()
2734 BranchObj *bo=xelection.getBranch();
2737 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2740 "setURL (\""+bo->getURL()+"\")",
2742 "setURL (\""+url+"\")",
2743 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2750 void MapEditor::editVymLink()
2752 BranchObj *bo=xelection.getBranch();
2755 QStringList filters;
2756 filters <<"VYM map (*.vym)";
2757 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2758 fd->setFilters (filters);
2759 fd->setCaption(vymName+" - " +tr("Link to another map"));
2760 fd->setDirectory (lastFileDir);
2761 if (! bo->getVymLink().isEmpty() )
2762 fd->selectFile( bo->getVymLink() );
2766 if ( fd->exec() == QDialog::Accepted )
2768 lastFileDir=QDir (fd->directory().path());
2771 "setVymLink (\""+bo->getVymLink()+"\")",
2773 "setVymLink (\""+fd->selectedFile()+"\")",
2774 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2776 bo->setVymLink (fd->selectedFile() );
2778 mapCenter->reposition();
2784 void MapEditor::deleteVymLink()
2786 BranchObj *bo=xelection.getBranch();
2791 "setVymLink (\""+bo->getVymLink()+"\")",
2793 "setVymLink (\"\")",
2794 QString("Unset vymlink of %1").arg(getName(bo))
2796 bo->setVymLink ("" );
2798 mapCenter->reposition();
2803 void MapEditor::setHideExport(bool b)
2805 BranchObj *bo=xelection.getBranch();
2808 bo->setHideInExport (b);
2809 QString u= b ? "false" : "true";
2810 QString r=!b ? "false" : "true";
2814 QString ("setHideExport (%1)").arg(u),
2816 QString ("setHideExport (%1)").arg(r),
2817 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
2820 mapCenter->reposition();
2825 void MapEditor::toggleHideExport()
2827 BranchObj *bo=xelection.getBranch();
2829 setHideExport ( !bo->hideInExport() );
2832 QString MapEditor::getVymLink()
2834 BranchObj *bo=xelection.getBranch();
2836 return bo->getVymLink();
2842 QStringList MapEditor::getVymLinks()
2845 BranchObj *bo=xelection.getBranch();
2851 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2859 void MapEditor::deleteKeepChilds()
2861 BranchObj *bo=xelection.getBranch();
2865 par=(BranchObj*)(bo->getParObj());
2866 QPointF p=bo->getRelPos();
2867 saveStateChangingPart(
2870 "deleteKeepChilds ()",
2871 QString("Remove %1 and keep its childs").arg(getName(bo))
2874 QString sel=bo->getSelectString();
2876 par->removeBranchHere(bo);
2877 mapCenter->reposition();
2879 xelection.getBranch()->move2RelPos (p);
2880 mapCenter->reposition();
2884 void MapEditor::deleteChilds()
2886 BranchObj *bo=xelection.getBranch();
2889 saveStateChangingPart(
2893 QString( "Remove childs of branch %1").arg(getName(bo))
2896 mapCenter->reposition();
2900 void MapEditor::editMapInfo()
2902 ExtraInfoDialog dia;
2903 dia.setMapName (getFileName() );
2904 dia.setAuthor (mapCenter->getAuthor() );
2905 dia.setComment(mapCenter->getComment() );
2909 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
2916 bo=mapCenter->first();
2919 if (!bo->getNote().isEmpty() ) n++;
2920 f+= bo->countFloatImages();
2922 xl+=bo->countXLinks();
2925 stats+=QString ("%1 branches\n").arg (b-1,6);
2926 stats+=QString ("%1 xLinks \n").arg (xl,6);
2927 stats+=QString ("%1 notes\n").arg (n,6);
2928 stats+=QString ("%1 images\n").arg (f,6);
2929 dia.setStats (stats);
2931 // Finally show dialog
2932 if (dia.exec() == QDialog::Accepted)
2934 setMapAuthor (dia.getAuthor() );
2935 setMapComment (dia.getComment() );
2939 void MapEditor::ensureSelectionVisible()
2941 LinkableMapObj *lmo=xelection.single();
2942 if (lmo) ensureVisible (lmo->getBBox() );
2946 void MapEditor::updateSelection()
2948 // Tell selection to update geometries
2952 void MapEditor::updateActions()
2954 // Tell mainwindow to update states of actions
2955 mainWindow->updateActions();
2956 // TODO maybe don't update if blockReposition is set
2959 void MapEditor::updateNoteFlag()
2962 BranchObj *bo=xelection.getBranch();
2965 bo->updateNoteFlag();
2966 mainWindow->updateActions();
2970 void MapEditor::setMapAuthor (const QString &s)
2974 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
2976 QString ("setMapAuthor (\"%1\")").arg(s),
2977 QString ("Set author of map to \"%1\"").arg(s)
2979 mapCenter->setAuthor (s);
2982 void MapEditor::setMapComment (const QString &s)
2986 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
2988 QString ("setMapComment (\"%1\")").arg(s),
2989 QString ("Set comment of map")
2991 mapCenter->setComment (s);
2994 void MapEditor::setMapLinkStyle (const QString & s)
2996 saveStateChangingPart (
2999 QString("setMapLinkStyle (\"%1\")").arg(s),
3000 QString("Set map link style (\"%1\")").arg(s)
3004 linkstyle=StyleLine;
3005 else if (s=="StyleParabel")
3006 linkstyle=StyleParabel;
3007 else if (s=="StylePolyLine")
3008 linkstyle=StylePolyLine;
3010 linkstyle=StylePolyParabel;
3013 bo=mapCenter->first();
3017 bo->setLinkStyle(bo->getDefLinkStyle());
3020 mapCenter->reposition();
3023 LinkStyle MapEditor::getMapLinkStyle ()
3028 void MapEditor::setMapDefLinkColor(QColor c)
3034 void MapEditor::setMapLinkColorHintInt()
3036 // called from setMapLinkColorHint(lch) or at end of parse
3038 bo=mapCenter->first();
3046 void MapEditor::setMapLinkColorHint(LinkColorHint lch)
3049 setMapLinkColorHintInt();
3052 void MapEditor::toggleMapLinkColorHint()
3054 if (linkcolorhint==HeadingColor)
3055 linkcolorhint=DefaultColor;
3057 linkcolorhint=HeadingColor;
3059 bo=mapCenter->first();
3067 LinkColorHint MapEditor::getMapLinkColorHint()
3069 return linkcolorhint;
3072 QColor MapEditor::getMapDefLinkColor()
3074 return defLinkColor;
3077 void MapEditor::setMapDefXLinkColor(QColor col)
3082 QColor MapEditor::getMapDefXLinkColor()
3084 return defXLinkColor;
3087 void MapEditor::setMapDefXLinkWidth (int w)
3092 int MapEditor::getMapDefXLinkWidth()
3094 return defXLinkWidth;
3097 void MapEditor::selectMapLinkColor()
3099 QColor col = QColorDialog::getColor( defLinkColor, this );
3100 if ( !col.isValid() ) return;
3103 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3105 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3106 QString("Set link color to %1").arg(col.name())
3108 setMapDefLinkColor( col );
3111 void MapEditor::selectMapSelectionColor()
3113 QColor col = QColorDialog::getColor( defLinkColor, this );
3114 setSelectionColor (col);
3117 void MapEditor::setSelectionColorInt (QColor col)
3119 if ( !col.isValid() ) return;
3120 xelection.setColor (col);
3123 void MapEditor::setSelectionColor(QColor col)
3125 if ( !col.isValid() ) return;
3128 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3130 QString("setSelectionColor (%1)").arg(col.name()),
3131 QString("Set color of selection box to %1").arg(col.name())
3133 setSelectionColorInt (col);
3136 QColor MapEditor::getSelectionColor()
3138 return xelection.getColor();
3141 bool MapEditor::scrollBranch()
3143 BranchObj *bo=xelection.getBranch();
3146 if (bo->isScrolled()) return false;
3147 if (bo->countBranches()==0) return false;
3148 if (bo->getDepth()==0) return false;
3154 QString ("%1 ()").arg(u),
3156 QString ("%1 ()").arg(r),
3157 QString ("%1 %2").arg(r).arg(getName(bo))
3166 bool MapEditor::unscrollBranch()
3168 BranchObj *bo=xelection.getBranch();
3171 if (!bo->isScrolled()) return false;
3172 if (bo->countBranches()==0) return false;
3173 if (bo->getDepth()==0) return false;
3179 QString ("%1 ()").arg(u),
3181 QString ("%1 ()").arg(r),
3182 QString ("%1 %2").arg(r).arg(getName(bo))
3191 void MapEditor::toggleScroll()
3193 BranchObj *bo=xelection.getBranch();
3194 if (xelection.type()==Branch )
3196 if (bo->isScrolled())
3203 void MapEditor::unscrollChilds() // FIXME saveState missing
3205 BranchObj *bo=xelection.getBranch();
3211 if (bo->isScrolled()) bo->toggleScroll();
3217 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3219 BranchObj *bo=xelection.getBranch();
3223 bo->addFloatImage();
3224 fio=bo->getLastFloatImage();
3226 mapCenter->reposition();
3233 void MapEditor::loadFloatImage ()
3235 BranchObj *bo=xelection.getBranch();
3239 Q3FileDialog *fd=new Q3FileDialog( this);
3240 fd->setMode (Q3FileDialog::ExistingFiles);
3241 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3242 ImagePreview *p =new ImagePreview (fd);
3243 fd->setContentsPreviewEnabled( TRUE );
3244 fd->setContentsPreview( p, p );
3245 fd->setPreviewMode( Q3FileDialog::Contents );
3246 fd->setCaption(vymName+" - " +tr("Load image"));
3247 fd->setDir (lastImageDir);
3250 if ( fd->exec() == QDialog::Accepted )
3252 // FIXME loadFIO in QT4 use: lastImageDir=fd->directory();
3253 lastImageDir=QDir (fd->dirPath());
3256 for (int j=0; j<fd->selectedFiles().count(); j++)
3258 s=fd->selectedFiles().at(j);
3259 fio=loadFloatImageInt (s);
3262 (LinkableMapObj*)fio,
3265 QString ("loadImage (%1)").arg(s ),
3266 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3269 // FIXME loadFIO error handling
3270 qWarning ("Failed to load "+s);
3278 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3280 fio->save (fn,type);
3283 void MapEditor::saveFloatImage ()
3285 FloatImageObj *fio=xelection.getFloatImage();
3288 QFileDialog *fd=new QFileDialog( this);
3289 fd->setFilters (imageIO.getFilters());
3290 fd->setCaption(vymName+" - " +tr("Save image"));
3291 fd->setFileMode( QFileDialog::AnyFile );
3292 fd->setDirectory (lastImageDir);
3293 // fd->setSelection (fio->getOriginalFilename());
3297 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3299 fn=fd->selectedFiles().at(0);
3300 if (QFile (fn).exists() )
3302 QMessageBox mb( vymName,
3303 tr("The file %1 exists already.\n"
3304 "Do you want to overwrite it?").arg(fn),
3305 QMessageBox::Warning,
3306 QMessageBox::Yes | QMessageBox::Default,
3307 QMessageBox::Cancel | QMessageBox::Escape,
3308 QMessageBox::QMessageBox::NoButton );
3310 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3311 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3314 case QMessageBox::Yes:
3317 case QMessageBox::Cancel:
3324 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3330 void MapEditor::setFrameType(const FrameType &t) // FIXME missing saveState
3332 BranchObj *bo=xelection.getBranch();
3335 bo->setFrameType (t);
3336 mapCenter->reposition();
3341 void MapEditor::setFrameType(const QString &s) // FIXME missing saveState
3343 BranchObj *bo=xelection.getBranch();
3346 bo->setFrameType (s);
3347 mapCenter->reposition();
3352 void MapEditor::setFramePenColor(const QColor &c) // FIXME missing saveState
3354 BranchObj *bo=xelection.getBranch();
3356 bo->setFramePenColor (c);
3359 void MapEditor::setFrameBrushColor(const QColor &c) // FIXME missing saveState
3361 BranchObj *bo=xelection.getBranch();
3363 bo->setFrameBrushColor (c);
3366 void MapEditor::setIncludeImagesVer(bool b)
3368 BranchObj *bo=xelection.getBranch();
3371 QString u= b ? "false" : "true";
3372 QString r=!b ? "false" : "true";
3376 QString("setIncludeImagesVertically (%1)").arg(u),
3378 QString("setIncludeImagesVertically (%1)").arg(r),
3379 QString("Include images vertically in %1").arg(getName(bo))
3381 bo->setIncludeImagesVer(b);
3382 mapCenter->reposition();
3386 void MapEditor::setIncludeImagesHor(bool b)
3388 BranchObj *bo=xelection.getBranch();
3391 QString u= b ? "false" : "true";
3392 QString r=!b ? "false" : "true";
3396 QString("setIncludeImagesHorizontally (%1)").arg(u),
3398 QString("setIncludeImagesHorizontally (%1)").arg(r),
3399 QString("Include images horizontally in %1").arg(getName(bo))
3401 bo->setIncludeImagesHor(b);
3402 mapCenter->reposition();
3406 void MapEditor::setHideLinkUnselected (bool b) // FIXME missing saveState
3408 LinkableMapObj *sel=xelection.single();
3410 (xelection.type() == Branch ||
3411 xelection.type() == MapCenter ||
3412 xelection.type() == FloatImage ))
3413 sel->setHideLinkUnselected(b);
3416 void MapEditor::importDirInt(BranchObj *dst, QDir d) // FIXME missing saveState
3418 BranchObj *bo=xelection.getBranch();
3421 // Traverse directories
3422 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3423 QFileInfoList list = d.entryInfoList();
3426 for (int i = 0; i < list.size(); ++i)
3429 if (fi.fileName() != "." && fi.fileName() != ".." )
3432 bo=dst->getLastBranch();
3433 bo->setHeading (fi.fileName() );
3434 bo->setColor (QColor("blue"));
3436 if ( !d.cd(fi.fileName()) )
3437 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3440 // Recursively add subdirs
3441 importDirInt (bo,d);
3447 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3448 list = d.entryInfoList();
3450 for (int i = 0; i < list.size(); ++i)
3454 bo=dst->getLastBranch();
3455 bo->setHeading (fi.fileName() );
3456 bo->setColor (QColor("black"));
3457 if (fi.fileName().right(4) == ".vym" )
3458 bo->setVymLink (fi.filePath());
3463 void MapEditor::importDir()
3465 BranchObj *bo=xelection.getBranch();
3468 QStringList filters;
3469 filters <<"VYM map (*.vym)";
3470 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3471 fd->setMode (QFileDialog::DirectoryOnly);
3472 fd->setFilters (filters);
3473 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3477 if ( fd->exec() == QDialog::Accepted )
3479 importDirInt (bo,QDir(fd->selectedFile()) );
3480 mapCenter->reposition();
3486 void MapEditor::followXLink(int i)
3488 BranchObj *bo=xelection.getBranch();
3491 bo=bo->XLinkTargetAt(i);
3494 xelection.select(bo);
3495 ensureSelectionVisible();
3500 void MapEditor::editXLink(int i) // FIXME missing saveState
3502 BranchObj *bo=xelection.getBranch();
3505 XLinkObj *xlo=bo->XLinkAt(i);
3508 EditXLinkDialog dia;
3510 dia.setSelection(bo);
3511 if (dia.exec() == QDialog::Accepted)
3513 if (dia.useSettingsGlobal() )
3515 setMapDefXLinkColor (xlo->getColor() );
3516 setMapDefXLinkWidth (xlo->getWidth() );
3518 if (dia.deleteXLink())
3519 bo->deleteXLinkAt(i);
3525 void MapEditor::testFunction()
3527 // This is the playground
3532 dia.showCancelButton (true);
3533 dia.setText("This is a longer \nWarning");
3534 dia.setCaption("Warning: Flux problem");
3535 dia.setShowAgainName("mapeditor/testDialog");
3536 if (dia.exec()==QDialog::Accepted)
3537 cout << "accepted!\n";
3539 cout << "canceled!\n";
3543 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
3544 if (hidemode==HideNone)
3546 setHideTmpMode (HideExport);
3547 mapCenter->calcBBoxSizeWithChilds();
3548 QRectF totalBBox=mapCenter->getTotalBBox();
3549 QRectF mapRect=totalBBox;
3550 QCanvasRectangle *frame=NULL;
3552 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3554 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3555 totalBBox.width(), totalBBox.height());
3556 frame=new QCanvasRectangle (mapRect,mapScene);
3557 frame->setBrush (QColor(white));
3558 frame->setPen (QColor(black));
3559 frame->setZValue(0);
3564 setHideTmpMode (HideNone);
3566 cout <<" hidemode="<<hidemode<<endl;
3570 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3572 // Lineedits are already closed by preceding
3573 // mouseEvent, we don't need to close here.
3575 QPointF p = mapToScene(e->pos());
3576 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3579 { // MapObj was found
3580 if (xelection.single() != lmo)
3582 // select the MapObj
3583 xelection.select(lmo);
3586 if (xelection.getBranch() )
3588 // Context Menu on branch or mapcenter
3590 branchContextMenu->popup(e->globalPos() );
3593 if (xelection.getFloatImage() )
3595 // Context Menu on floatimage
3597 floatimageContextMenu->popup(e->globalPos() );
3601 { // No MapObj found, we are on the Canvas itself
3602 // Context Menu on scene
3604 canvasContextMenu->popup(e->globalPos() );
3609 void MapEditor::keyPressEvent(QKeyEvent* e)
3611 if (e->modifiers() & Qt::ControlModifier)
3613 switch (mainWindow->getModMode())
3616 setCursor (PickColorCursor);
3619 setCursor (CopyCursor);
3622 setCursor (XLinkCursor);
3625 setCursor (Qt::ArrowCursor);
3631 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3633 if (!(e->modifiers() & Qt::ControlModifier))
3634 setCursor (Qt::ArrowCursor);
3637 void MapEditor::mousePressEvent(QMouseEvent* e)
3639 // Ignore right clicks, these will go to context menus
3640 if (e->button() == Qt::RightButton )
3646 QPointF p = mapToScene(e->pos());
3647 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3651 //Take care of system flags _or_ modifier modes
3653 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3654 typeid(*lmo)==typeid(MapCenterObj) ))
3656 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3657 if (!foname.isEmpty())
3659 // systemFlag clicked
3663 if (e->state() & Qt::ControlModifier)
3664 mainWindow->editOpenURLTab();
3666 mainWindow->editOpenURL();
3668 else if (foname=="vymLink")
3670 mainWindow->editOpenVymLink();
3671 // tabWidget may change, better return now
3672 // before segfaulting...
3673 } else if (foname=="note")
3674 mainWindow->windowToggleNoteEditor();
3675 else if (foname=="hideInExport")
3682 // No system flag clicked, take care of modmodes (CTRL-Click)
3683 if (e->state() & Qt::ControlModifier)
3685 if (mainWindow->getModMode()==ModModeColor)
3688 setCursor (PickColorCursor);
3691 if (mainWindow->getModMode()==ModModeXLink)
3693 BranchObj *bo_begin=NULL;
3695 bo_begin=(BranchObj*)(lmo);
3697 if (xelection.getBranch() )
3698 bo_begin=xelection.getBranch();
3702 linkingObj_src=bo_begin;
3703 tmpXLink=new XLinkObj (mapScene);
3704 tmpXLink->setBegin (bo_begin);
3705 tmpXLink->setEnd (p);
3706 tmpXLink->setColor(defXLinkColor);
3707 tmpXLink->setWidth(defXLinkWidth);
3708 tmpXLink->updateXLink();
3709 tmpXLink->setVisibility (true);
3713 } // End of modmodes
3717 // Select the clicked object
3720 // Left Button Move Branches
3721 if (e->button() == Qt::LeftButton )
3723 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
3724 //movingObj_start.setY( p.y() - selection->y() );
3725 movingObj_start.setX( p.x() - lmo->x() );
3726 movingObj_start.setY( p.y() - lmo->y() );
3727 movingObj_orgPos.setX (lmo->x() );
3728 movingObj_orgPos.setY (lmo->y() );
3729 movingObj_orgRelPos=lmo->getRelPos();
3731 // If modMode==copy, then we want to "move" the _new_ object around
3732 // then we need the offset from p to the _old_ selection, because of tmp
3733 if (mainWindow->getModMode()==ModModeCopy &&
3734 e->state() & Qt::ControlModifier)
3736 if (xelection.type()==Branch)
3739 mapCenter->addBranch ((BranchObj*)xelection.single());
3741 xelection.select(mapCenter->getLastBranch());
3742 mapCenter->reposition();
3746 movingObj=xelection.single();
3748 // Middle Button Toggle Scroll
3749 // (On Mac OS X this won't work, but we still have
3750 // a button in the toolbar)
3751 if (e->button() == Qt::MidButton )
3756 { // No MapObj found, we are on the scene itself
3757 // Left Button move Pos of sceneView
3758 if (e->button() == Qt::LeftButton )
3760 movingObj=NULL; // move Content not Obj
3761 movingObj_start=e->globalPos();
3762 movingCont_start=QPointF (
3763 horizontalScrollBar()->value(),
3764 verticalScrollBar()->value());
3765 movingVec=QPointF(0,0);
3766 setCursor(HandOpenCursor);
3771 void MapEditor::mouseMoveEvent(QMouseEvent* e)
3773 QPointF p = mapToScene(e->pos());
3774 LinkableMapObj *lmosel=xelection.single();
3776 // Move the selected MapObj
3777 if ( lmosel && movingObj)
3779 // reset cursor if we are moving and don't copy
3780 if (mainWindow->getModMode()!=ModModeCopy)
3781 setCursor (Qt::ArrowCursor);
3783 // To avoid jumping of the sceneView, only
3784 // ensureSelectionVisible, if not tmp linked
3785 if (!lmosel->hasParObjTmp())
3786 ensureSelectionVisible ();
3788 // Now move the selection, but add relative position
3789 // (movingObj_start) where selection was chosen with
3790 // mousepointer. (This avoids flickering resp. jumping
3791 // of selection back to absPos)
3793 // Check if we could link
3794 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3797 FloatObj *fio=xelection.getFloatImage();
3800 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3802 fio->updateLink(); //no need for reposition, if we update link here
3805 // Relink float to new mapcenter or branch, if shift is pressed
3806 // Only relink, if selection really has a new parent
3807 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3808 ( (typeid(*lmo)==typeid(BranchObj)) ||
3809 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3810 ( lmo != fio->getParObj())
3813 if (typeid(*fio) == typeid(FloatImageObj) &&
3814 ( (typeid(*lmo)==typeid(BranchObj) ||
3815 typeid(*lmo)==typeid(MapCenterObj)) ))
3818 // Also save the move which was done so far
3819 QString pold=qpointfToString(movingObj_orgRelPos);
3820 QString pnow=qpointfToString(fio->getRelPos());
3826 QString("Move %1 to relativ position %2").arg(getName(fio)).arg(pnow));
3827 fio->getParObj()->requestReposition();
3828 mapCenter->reposition();
3830 linkTo (lmo->getSelectString());
3832 //movingObj_orgRelPos=lmosel->getRelPos();
3834 mapCenter->reposition();
3838 { // selection != a FloatObj
3839 if (lmosel->getDepth()==0)
3842 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3843 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3845 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3846 mapCenter->updateRelPositions();
3849 if (lmosel->getDepth()==1)
3852 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3853 lmosel->setRelPos();
3856 // Move ordinary branch
3857 if (lmosel->getOrientation() == OrientLeftOfCenter)
3858 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3859 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3860 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3862 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3865 // Maybe we can relink temporary?
3866 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
3867 (typeid(*lmo)==typeid(BranchObj) ||
3868 typeid(*lmo)==typeid(MapCenterObj)) )
3871 if (e->modifiers()==Qt::ControlModifier)
3873 // Special case: CTRL to link below lmo
3874 lmosel->setParObjTmp (lmo,p,+1);
3876 else if (e->modifiers()==Qt::ShiftModifier)
3877 lmosel->setParObjTmp (lmo,p,-1);
3879 lmosel->setParObjTmp (lmo,p,0);
3882 lmosel->unsetParObjTmp();
3884 // reposition subbranch
3885 lmosel->reposition();
3889 } // no FloatImageObj
3893 } // selection && moving_obj
3895 // Draw a link from one branch to another
3898 tmpXLink->setEnd (p);
3899 tmpXLink->updateXLink();
3903 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
3905 QPointF p=e->globalPos();
3906 movingVec.setX(-p.x() + movingObj_start.x() );
3907 movingVec.setY(-p.y() + movingObj_start.y() );
3908 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
3909 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
3914 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
3916 QPointF p = mapToScene(e->pos());
3917 LinkableMapObj *dst;
3918 LinkableMapObj *lmosel=xelection.single();
3919 // Have we been picking color?
3923 setCursor (Qt::ArrowCursor);
3924 // Check if we are over another branch
3925 dst=mapCenter->findMapObj(p, NULL);
3928 if (e->state() & Qt::ShiftModifier)
3929 colorBranch (((BranchObj*)(dst))->getColor());
3931 colorSubtree (((BranchObj*)(dst))->getColor());
3936 // Have we been drawing a link?
3940 // Check if we are over another branch
3941 dst=mapCenter->findMapObj(p, NULL);
3944 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3945 tmpXLink->updateXLink();
3946 tmpXLink->activate();
3947 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //FIXME undoCommand
3956 // Have we been moving something?
3957 if ( lmosel && movingObj )
3959 FloatImageObj *fo=xelection.getFloatImage();
3962 // Moved FloatObj. Maybe we need to reposition
3963 QString pold=qpointfToString(movingObj_orgRelPos);
3964 QString pnow=qpointfToString(fo->getRelPos());
3970 QString("Move %1 to relativ position %2").arg(getName(fo)).arg(pnow));
3972 fo->getParObj()->requestReposition();
3973 mapCenter->reposition();
3976 // Check if we are over another branch, but ignore
3977 // any found LMOs, which are FloatObjs
3978 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
3980 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3983 if (xelection.type() == MapCenter )
3984 { // FIXME The MapCenter was moved, no savestate yet
3987 if (xelection.type() == Branch )
3988 { // A branch was moved
3990 // save the position in case we link to mapcenter
3991 QPointF savePos=QPointF (lmosel->getAbsPos() );
3993 // Reset the temporary drawn link to the original one
3994 lmosel->unsetParObjTmp();
3996 // For Redo we may need to save original selection
3997 QString preSelStr=lmosel->getSelectString();
4002 BranchObj* bsel=xelection.getBranch();
4003 BranchObj* bdst=(BranchObj*)dst;
4005 QString preParStr=(bsel->getParObj())->getSelectString();
4006 QString preNum=QString::number (bsel->getNum(),10);
4007 QString preDstParStr;
4009 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4011 preDstParStr=dst->getParObj()->getSelectString();
4012 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4014 if (e->state() & Qt::ControlModifier && dst->getParObj())
4017 preDstParStr=dst->getParObj()->getSelectString();
4018 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4021 preDstParStr=dst->getSelectString();
4022 bsel->linkTo (bdst,-1);
4023 if (dst->getDepth()==0) bsel->move (savePos);
4025 QString postSelStr=lmosel->getSelectString();
4026 QString postNum=QString::number (bsel->getNum(),10);
4028 QString undoCom="linkTo (\""+
4029 preParStr+ "\"," + preNum +"," +
4030 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4032 QString redoCom="linkTo (\""+
4033 preDstParStr + "\"," + postNum + "," +
4034 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4039 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4041 if (lmosel->getDepth()==1)
4043 // The select string might be different _after_ moving around.
4044 // Therefor reposition and then use string of old selection, too
4045 mapCenter->reposition();
4047 QString ps=qpointfToString ( lmosel->getRelPos() );
4049 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4050 preSelStr, "moveRel "+ps,
4051 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4054 // Draw the original link, before selection was moved around
4055 mapCenter->reposition();
4058 // Finally resize scene, if needed
4062 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4065 // maybe we moved View: set old cursor
4066 setCursor (Qt::ArrowCursor);
4070 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4072 if (e->button() == Qt::LeftButton )
4074 QPointF p = mapToScene(e->pos());
4075 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4076 if (lmo) { // MapObj was found
4077 // First select the MapObj than edit heading
4078 xelection.select(lmo);
4079 mainWindow->editHeading();
4084 void MapEditor::resizeEvent (QResizeEvent* e)
4086 QGraphicsView::resizeEvent( e );
4089 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4091 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4092 // cerr << event->format(i) << endl;
4094 if (event->mimeData()->hasImage())
4095 event->acceptProposedAction();
4097 if (event->mimeData()->hasUrls())
4098 event->acceptProposedAction();
4101 void MapEditor::dragMoveEvent(QDragMoveEvent *event)
4105 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4110 void MapEditor::dropEvent(QDropEvent *event)
4112 BranchObj *sel=xelection.getBranch();
4116 if (event->mimeData()->hasImage())
4118 QVariant imageData = event->mimeData()->imageData();
4119 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4121 if (event->mimeData()->hasUrls())
4122 uris=event->mimeData()->urls();
4130 for (int i=0; i<uris.count();i++)
4132 // Workaround to avoid adding empty branches
4133 if (!uris.at(i).toString().isEmpty())
4135 bo=sel->addBranch();
4138 s=uris.at(i).toLocalFile();
4141 QString file = QDir::convertSeparators(s);
4142 heading = QFileInfo(file).baseName();
4144 if (file.endsWith(".vym", false))
4145 bo->setVymLink(file);
4147 bo->setURL(uris.at(i).toString());
4150 bo->setURL(uris.at(i).toString());
4153 if (!heading.isEmpty())
4154 bo->setHeading(heading);
4156 bo->setHeading(uris.at(i).toString());
4160 mapCenter->reposition();
4163 event->acceptProposedAction();
4167 void MapEditor::contentsDropEvent(QDropEvent *event)
4170 } else if (event->provides("application/x-moz-file-promise-url") &&
4171 event->provides("application/x-moz-nativeimage"))
4173 // Contains url to the img src in unicode16
4174 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4175 QString url = QString((const QChar*)d.data(),d.size()/2);
4179 } else if (event->provides ("text/uri-list"))
4180 { // Uris provided e.g. by konqueror
4181 Q3UriDrag::decode (event,uris);
4182 } else if (event->provides ("_NETSCAPE_URL"))
4183 { // Uris provided by Mozilla
4184 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4187 } else if (event->provides("text/html")) {
4189 // Handels text mime types
4190 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4191 QByteArray d = event->encodedData("text/html");
4194 text = QString((const QChar*)d.data(),d.size()/2);
4198 textEditor->setText(text);
4202 } else if (event->provides("text/plain")) {
4203 QByteArray d = event->encodedData("text/plain");
4206 text = QString((const QChar*)d.data(),d.size()/2);
4210 textEditor->setText(text);
4220 bool isUnicode16(const QByteArray &d)
4222 // TODO: make more precise check for unicode 16.
4223 // Guess unicode16 if any of second bytes are zero
4224 unsigned int length = max(0,d.size()-2)/2;
4225 for (unsigned int i = 0; i<length ; i++)
4226 if (d.at(i*2+1)==0) return true;
4230 void MapEditor::addFloatImageInt (const QPixmap &img)
4232 BranchObj *bo=xelection.getBranch();
4235 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4236 //QString fn=fd->selectedFile();
4237 //lastImageDir=fn.left(fn.findRev ("/"));
4238 FloatImageObj *fio=bo->addFloatImage();
4240 fio->setOriginalFilename("Image added by Drag and Drop");
4241 mapCenter->reposition();
4248 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4250 if (!imageBuffer) imageBuffer = new QBuffer();
4251 if (!imageBuffer->isOpen()) {
4252 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4254 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4258 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4260 if (nop->state()==Q3NetworkProtocol::StDone) {
4261 QPixmap img(imageBuffer->buffer());
4262 addFloatImageInt (img);
4266 imageBuffer->close();
4268 imageBuffer->close();
4275 void MapEditor::fetchImage(const QString &url)
4278 urlOperator->stop();
4279 disconnect(urlOperator);
4283 urlOperator = new Q3UrlOperator(url);
4284 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4285 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4287 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4288 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));