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.setMapCenter (mapCenter);
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("linkStyle", ls ) +
226 attribut("linkColor", defLinkColor.name() ) +
227 attribut("defXLinkColor", defXLinkColor.name() ) +
228 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
230 s+=beginElement("vymmap",mapAttr);
233 // Find the used flags while traversing the tree
234 standardFlagsDefault->resetUsedCounter();
236 // Reset the counters before saving
237 // TODO constr. of FIO creates lots of objects, better do this in some other way...
238 FloatImageObj (mapScene).resetSaveCounter();
240 // Build xml recursivly
241 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
242 // Save complete map, if saveSel not set
243 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
246 if ( typeid(*saveSel) == typeid(BranchObj) )
248 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
249 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
251 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
254 // Save local settings
255 s+=settings.getXMLData (destPath);
258 if (!xelection.isEmpty() && !saveSel )
259 s+=valueElement("select",xelection.getSelectString());
262 s+=endElement("vymmap");
265 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
269 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
271 // save the selected part of the map, Undo will replace part of map
272 QString undoSelection="";
274 undoSelection=undoSel->getSelectString();
276 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
277 QString redoSelection="";
279 redoSelection=undoSel->getSelectString();
281 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
284 saveState (PartOfMap,
285 undoSelection, "addMapReplace (\"PATH\")",
291 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
295 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
298 QString undoSelection=redoSel->getParObj()->getSelectString();
299 QString redoSelection=redoSel->getSelectString();
300 if (typeid(*redoSel) == typeid(BranchObj) )
302 // save the selected branch of the map, Undo will insert part of map
303 saveState (PartOfMap,
304 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
305 redoSelection, "delete ()",
312 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
314 // "Normal" savestate: save commands, selections and comment
315 // so just save commands for undo and redo
316 // and use current selection
318 QString redoSelection="";
319 if (redoSel) redoSelection=redoSel->getSelectString();
320 QString undoSelection="";
321 if (undoSel) undoSelection=undoSel->getSelectString();
323 saveState (UndoCommand,
330 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
332 // "Normal" savestate: save commands, selections and comment
333 // so just save commands for undo and redo
334 // and use current selection
335 saveState (UndoCommand,
343 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
347 if (blockSaveState) return;
349 /* TODO remove after testing
351 cout << "ME::saveState() "<<endl;
353 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
354 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
355 int curStep=undoSet.readNumEntry ("/history/curStep",0);
356 // Find out current undo directory
357 if (undosAvail<stepsTotal) undosAvail++;
359 if (curStep>stepsTotal) curStep=1;
361 QString backupXML="";
362 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
363 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
364 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
366 // Create bakMapDir if not available
369 makeSubDirs (bakMapDir);
371 // Save depending on how much needs to be saved
373 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPointF (),saveSel);
375 QString undoCommand="";
376 if (savemode==UndoCommand)
380 else if (savemode==PartOfMap )
383 undoCommand.replace ("PATH",bakMapPath);
386 if (!backupXML.isEmpty())
387 // Write XML Data to disk
388 saveStringToDisk (QString(bakMapPath),backupXML);
390 // We would have to save all actions in a tree, to keep track of
391 // possible redos after a action. Possible, but we are too lazy: forget about redos.
394 // Write the current state to disk
395 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
396 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
397 undoSet.setEntry ("/history/curStep",QString::number(curStep));
398 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
399 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
400 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
401 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
402 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
403 undoSet.setEntry (QString("/history/version"),vymVersion);
404 undoSet.writeSettings(histPath);
406 /* TODO remove after testing
408 //cout << " into="<< histPath.toStdString()<<endl;
409 cout << " stepsTotal="<<stepsTotal<<
410 ", undosAvail="<<undosAvail<<
411 ", redosAvail="<<redosAvail<<
412 ", curStep="<<curStep<<endl;
413 cout << " ---------------------------"<<endl;
414 cout << " comment="<<comment.toStdString()<<endl;
415 cout << " undoCom="<<undoCommand.toStdString()<<endl;
416 cout << " undoSel="<<undoSelection.toStdString()<<endl;
417 cout << " redoCom="<<redoCom.toStdString()<<endl;
418 cout << " redoSel="<<redoSelection.toStdString()<<endl;
419 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
420 cout << " ---------------------------"<<endl;
422 mainWindow->updateHistory (undoSet);
427 void MapEditor::parseAtom(const QString &atom)
429 BranchObj *selb=xelection.getBranch();
434 // Split string s into command and parameters
435 parser.parseAtom (atom);
436 QString com=parser.command();
439 if (com=="addBranch")
441 if (xelection.isEmpty())
443 parser.setError (Aborted,"Nothing selected");
446 parser.setError (Aborted,"Type of selection is not a branch");
451 if (parser.checkParamCount(pl))
453 if (parser.paramCount()==0)
454 addNewBranchInt (-2);
457 y=parser.parInt (ok,0);
458 if (ok ) addNewBranchInt (y);
462 } else if (com=="addBranchBefore")
464 if (xelection.isEmpty())
466 parser.setError (Aborted,"Nothing selected");
469 parser.setError (Aborted,"Type of selection is not a branch");
472 if (parser.paramCount()==0)
474 addNewBranchBefore ();
477 } else if (com==QString("addMapReplace"))
479 if (xelection.isEmpty())
481 parser.setError (Aborted,"Nothing selected");
484 parser.setError (Aborted,"Type of selection is not a branch");
485 } else if (parser.checkParamCount(1))
487 //s=parser.parString (ok,0); // selection
488 t=parser.parString (ok,0); // path to map
489 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
490 addMapReplaceInt(selb->getSelectString(),t);
492 } else if (com==QString("addMapInsert"))
494 if (xelection.isEmpty())
496 parser.setError (Aborted,"Nothing selected");
499 parser.setError (Aborted,"Type of selection is not a branch");
502 if (parser.checkParamCount(2))
504 t=parser.parString (ok,0); // path to map
505 y=parser.parInt(ok,1); // position
506 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
507 addMapInsertInt(t,y);
510 } else if (com=="colorBranch")
512 if (xelection.isEmpty())
514 parser.setError (Aborted,"Nothing selected");
517 parser.setError (Aborted,"Type of selection is not a branch");
518 } else if (parser.checkParamCount(1))
520 QColor c=parser.parColor (ok,0);
521 if (ok) colorBranch (c);
523 } else if (com=="colorSubtree")
525 if (xelection.isEmpty())
527 parser.setError (Aborted,"Nothing selected");
530 parser.setError (Aborted,"Type of selection is not a branch");
531 } else if (parser.checkParamCount(1))
533 QColor c=parser.parColor (ok,0);
534 if (ok) colorSubtree (c);
536 } else if (com=="cut")
538 if (xelection.isEmpty())
540 parser.setError (Aborted,"Nothing selected");
541 } else if ( xelection.type()!=Branch &&
542 xelection.type()!=MapCenter &&
543 xelection.type()!=FloatImage )
545 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
546 } else if (parser.checkParamCount(0))
550 } else if (com=="delete")
552 if (xelection.isEmpty())
554 parser.setError (Aborted,"Nothing selected");
555 } else if (xelection.type() != Branch && xelection.type() != FloatImage )
557 parser.setError (Aborted,"Type of selection is wrong.");
558 } else if (parser.checkParamCount(0))
562 } else if (com=="deleteKeepChilds")
564 if (xelection.isEmpty())
566 parser.setError (Aborted,"Nothing selected");
569 parser.setError (Aborted,"Type of selection is not a branch");
570 } else if (parser.checkParamCount(0))
574 } else if (com=="deleteChilds")
576 if (xelection.isEmpty())
578 parser.setError (Aborted,"Nothing selected");
581 parser.setError (Aborted,"Type of selection is not a branch");
582 } else if (parser.checkParamCount(0))
586 } else if (com=="linkTo")
588 if (xelection.isEmpty())
590 parser.setError (Aborted,"Nothing selected");
593 if (parser.checkParamCount(4))
595 // 0 selectstring of parent
596 // 1 num in parent (for branches)
597 // 2,3 x,y of mainbranch or mapcenter
598 s=parser.parString(ok,0);
599 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
602 if (typeid(*dst) == typeid(BranchObj) )
604 // Get number in parent
605 x=parser.parInt (ok,1);
607 selb->linkTo ((BranchObj*)(dst),x);
608 } else if (typeid(*dst) == typeid(MapCenterObj) )
610 selb->linkTo ((BranchObj*)(dst),-1);
611 // Get coordinates of mainbranch
612 x=parser.parInt (ok,2);
615 y=parser.parInt (ok,3);
616 if (ok) selb->move (x,y);
621 } else if ( xelection.type() == FloatImage)
623 if (parser.checkParamCount(1))
625 // 0 selectstring of parent
626 s=parser.parString(ok,0);
627 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
630 if (typeid(*dst) == typeid(BranchObj) ||
631 typeid(*dst) == typeid(MapCenterObj))
632 linkTo (dst->getSelectString());
634 parser.setError (Aborted,"Destination is not a branch");
637 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
638 } else if (com=="loadImage")
640 if (xelection.isEmpty())
642 parser.setError (Aborted,"Nothing selected");
645 parser.setError (Aborted,"Type of selection is not a branch");
646 } else if (parser.checkParamCount(1))
648 s=parser.parString(ok,0);
649 if (ok) loadFloatImageInt (s);
651 } else if (com=="moveBranchUp")
653 if (xelection.isEmpty() )
655 parser.setError (Aborted,"Nothing selected");
658 parser.setError (Aborted,"Type of selection is not a branch");
659 } else if (parser.checkParamCount(0))
663 } else if (com=="moveBranchDown")
665 if (xelection.isEmpty() )
667 parser.setError (Aborted,"Nothing selected");
670 parser.setError (Aborted,"Type of selection is not a branch");
671 } else if (parser.checkParamCount(0))
675 } else if (com=="move")
677 if (xelection.isEmpty() )
679 parser.setError (Aborted,"Nothing selected");
680 } else if ( xelection.type()!=Branch &&
681 xelection.type()!=MapCenter &&
682 xelection.type()!=FloatImage )
684 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
685 } else if (parser.checkParamCount(2))
687 x=parser.parInt (ok,0);
690 y=parser.parInt (ok,1);
694 } else if (com=="moveRel")
696 if (xelection.isEmpty() )
698 parser.setError (Aborted,"Nothing selected");
699 } else if ( xelection.type()!=Branch &&
700 xelection.type()!=MapCenter &&
701 xelection.type()!=FloatImage )
703 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
704 } else if (parser.checkParamCount(2))
706 x=parser.parInt (ok,0);
709 y=parser.parInt (ok,1);
710 if (ok) moveRel (x,y);
713 } else if (com=="paste")
715 if (xelection.isEmpty() )
717 parser.setError (Aborted,"Nothing selected");
720 parser.setError (Aborted,"Type of selection is not a branch");
721 } else if (parser.checkParamCount(0))
725 } else if (com=="saveImage")
727 FloatImageObj *fio=xelection.getFloatImage();
730 parser.setError (Aborted,"Type of selection is not an image");
731 } else if (parser.checkParamCount(2))
733 s=parser.parString(ok,0);
736 t=parser.parString(ok,1);
737 if (ok) saveFloatImageInt (fio,t,s);
740 } else if (com=="scroll")
742 if (xelection.isEmpty() )
744 parser.setError (Aborted,"Nothing selected");
747 parser.setError (Aborted,"Type of selection is not a branch");
748 } else if (parser.checkParamCount(0))
750 if (!scrollBranch ())
751 parser.setError (Aborted,"Could not scroll branch");
753 } else if (com=="select")
755 if (parser.checkParamCount(1))
757 s=parser.parString(ok,0);
760 } else if (com=="selectLastBranch")
762 if (xelection.isEmpty() )
764 parser.setError (Aborted,"Nothing selected");
767 parser.setError (Aborted,"Type of selection is not a branch");
768 } else if (parser.checkParamCount(0))
770 BranchObj *bo=selb->getLastBranch();
772 parser.setError (Aborted,"Could not select last branch");
776 } else if (com=="selectLastImage")
778 if (xelection.isEmpty() )
780 parser.setError (Aborted,"Nothing selected");
783 parser.setError (Aborted,"Type of selection is not a branch");
784 } else if (parser.checkParamCount(0))
786 FloatImageObj *fio=selb->getLastFloatImage();
788 parser.setError (Aborted,"Could not select last image");
792 } else if (com=="setMapAuthor")
794 if (parser.checkParamCount(1))
796 s=parser.parString(ok,0);
797 if (ok) setMapAuthor (s);
799 } else if (com=="setMapComment")
801 if (parser.checkParamCount(1))
803 s=parser.parString(ok,0);
804 if (ok) setMapComment(s);
806 } else if (com=="setMapBackgroundColor")
808 if (xelection.isEmpty() )
810 parser.setError (Aborted,"Nothing selected");
811 } else if (! xelection.getBranch() )
813 parser.setError (Aborted,"Type of selection is not a branch");
814 } else if (parser.checkParamCount(1))
816 QColor c=parser.parColor (ok,0);
817 if (ok) setMapBackgroundColor (c);
819 } else if (com=="setMapDefLinkColor")
821 if (xelection.isEmpty() )
823 parser.setError (Aborted,"Nothing selected");
826 parser.setError (Aborted,"Type of selection is not a branch");
827 } else if (parser.checkParamCount(1))
829 QColor c=parser.parColor (ok,0);
830 if (ok) setMapDefLinkColor (c);
832 } else if (com=="setMapLinkStyle")
834 if (parser.checkParamCount(1))
836 s=parser.parString (ok,0);
837 if (ok) setMapLinkStyle(s);
839 } else if (com=="setHeading")
841 if (xelection.isEmpty() )
843 parser.setError (Aborted,"Nothing selected");
846 parser.setError (Aborted,"Type of selection is not a branch");
847 } else if (parser.checkParamCount(1))
849 s=parser.parString (ok,0);
853 } else if (com=="setHideExport")
855 if (xelection.isEmpty() )
857 parser.setError (Aborted,"Nothing selected");
860 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
861 //FIXME selb is never a floatimage!!
862 } else if (parser.checkParamCount(1))
864 b=parser.parBool(ok,0);
865 if (ok) setHideExport (b);
867 } else if (com=="setIncludeImagesHorizontally")
869 if (xelection.isEmpty() )
871 parser.setError (Aborted,"Nothing selected");
874 parser.setError (Aborted,"Type of selection is not a branch");
875 } else if (parser.checkParamCount(1))
877 b=parser.parBool(ok,0);
878 if (ok) setIncludeImagesHor(b);
880 } else if (com=="setIncludeImagesVertically")
882 if (xelection.isEmpty() )
884 parser.setError (Aborted,"Nothing selected");
887 parser.setError (Aborted,"Type of selection is not a branch");
888 } else if (parser.checkParamCount(1))
890 b=parser.parBool(ok,0);
891 if (ok) setIncludeImagesVer(b);
893 } else if (com=="setURL")
895 if (xelection.isEmpty() )
897 parser.setError (Aborted,"Nothing selected");
900 parser.setError (Aborted,"Type of selection is not a branch");
901 } else if (parser.checkParamCount(1))
903 s=parser.parString (ok,0);
904 if (ok) setURLInt(s);
906 } else if (com=="setVymLink")
908 if (xelection.isEmpty() )
910 parser.setError (Aborted,"Nothing selected");
913 parser.setError (Aborted,"Type of selection is not a branch");
914 } else if (parser.checkParamCount(1))
916 s=parser.parString (ok,0);
917 if (ok) setVymLinkInt(s);
920 else if (com=="setFlag")
922 if (xelection.isEmpty() )
924 parser.setError (Aborted,"Nothing selected");
927 parser.setError (Aborted,"Type of selection is not a branch");
928 } else if (parser.checkParamCount(1))
930 s=parser.parString(ok,0);
933 selb->activateStandardFlag(s);
934 selb->updateFlagsToolbar();
937 } else if (com=="unscroll")
939 if (xelection.isEmpty() )
941 parser.setError (Aborted,"Nothing selected");
944 parser.setError (Aborted,"Type of selection is not a branch");
945 } else if (parser.checkParamCount(0))
947 if (!unscrollBranch ())
948 parser.setError (Aborted,"Could not unscroll branch");
950 } else if (com=="unsetFlag")
952 if (xelection.isEmpty() )
954 parser.setError (Aborted,"Nothing selected");
957 parser.setError (Aborted,"Type of selection is not a branch");
958 } else if (parser.checkParamCount(1))
960 s=parser.parString(ok,0);
963 selb->deactivateStandardFlag(s);
964 selb->updateFlagsToolbar();
968 parser.setError (Aborted,"Unknown command");
971 if (parser.errorLevel()==NoError)
974 mapCenter->reposition();
978 // TODO Error handling
979 qWarning("MapEditor::parseAtom: Error!");
980 qWarning(parser.errorMessage());
984 void MapEditor::runScript (QString script)
986 // TODO "atomize" script, currently each line holds one atom
988 QStringList list=script.split("\n");
991 for (int i=0; i<list.size(); i++)
997 if (pos>=0) l.truncate (pos);
999 // Try to ignore empty lines
1000 if (l.contains (QRegExp ("\\w")))
1006 bool MapEditor::isDefault()
1011 bool MapEditor::isUnsaved()
1016 bool MapEditor::hasChanged()
1021 void MapEditor::setChanged()
1029 void MapEditor::closeMap()
1031 // Unselect before disabling the toolbar actions
1032 if (!xelection.isEmpty() ) xelection.unselect();
1040 void MapEditor::setFilePath(QString fname)
1042 setFilePath (fname,fname);
1045 void MapEditor::setFilePath(QString fname, QString destname)
1047 if (fname.isEmpty() || fname=="")
1054 filePath=fname; // becomes absolute path
1055 fileName=fname; // gets stripped of path
1056 destPath=destname; // needed for vymlinks
1058 // If fname is not an absolute path, complete it
1059 filePath=QDir(fname).absPath();
1060 fileDir=filePath.left (1+filePath.findRev ("/"));
1062 // Set short name, too. Search from behind:
1063 int i=fileName.findRev("/");
1064 if (i>=0) fileName=fileName.remove (0,i+1);
1066 // Forget the .vym (or .xml) for name of map
1067 mapName=fileName.left(fileName.findRev(".",-1,true) );
1071 QString MapEditor::getFilePath()
1076 QString MapEditor::getFileName()
1081 QString MapEditor::getMapName()
1086 QString MapEditor::getDestPath()
1091 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1093 ErrorCode err=success;
1097 if (xelection.isEmpty() ) xelection.unselect();
1100 mapCenter->setMapEditor(this);
1101 // (map state is set later at end of load...)
1104 BranchObj *bo=xelection.getBranch();
1105 if (!bo) return aborted;
1106 if (lmode==ImportAdd)
1107 saveStateChangingPart(
1110 QString("addMapInsert (%1)").arg(fname),
1111 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1113 saveStateChangingPart(
1116 QString("addMapReplace(%1)").arg(fname),
1117 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1121 mapBuilderHandler handler;
1122 QFile file( fname );
1124 // I am paranoid: file should exist anyway
1125 // according to check in mainwindow.
1126 if (!file.exists() )
1128 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1129 tr("Couldn't open map " +fname)+".");
1133 blockReposition=true;
1134 QXmlInputSource source( file);
1135 QXmlSimpleReader reader;
1136 reader.setContentHandler( &handler );
1137 reader.setErrorHandler( &handler );
1138 handler.setMapEditor( this );
1139 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1140 handler.setInputFile (file.name());
1141 handler.setLoadMode (lmode);
1142 blockSaveState=true;
1143 bool ok = reader.parse( source );
1144 blockReposition=false;
1145 blockSaveState=false;
1149 mapCenter->reposition();
1158 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1159 tr( handler.errorProtocol() ) );
1161 // Still return "success": the map maybe at least
1162 // partially read by the parser
1169 int MapEditor::save (const SaveMode &savemode)
1173 // Create mapName and fileDir
1174 makeSubDirs (fileDir);
1178 fname=mapName+".xml";
1180 // use name given by user, even if he chooses .doc
1185 if (savemode==CompleteMap || xelection.isEmpty())
1186 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1188 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch()); //FIXME check selected FIO
1190 if (!saveStringToDisk(fileDir+fname,saveFile))
1203 void MapEditor::setZipped (bool z)
1208 bool MapEditor::saveZipped ()
1213 void MapEditor::print()
1217 printer = new QPrinter;
1218 printer->setColorMode (QPrinter::Color);
1219 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1220 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1221 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1224 // FIXME testing cout << "ME::print printProgram="<<printer->printProgram().ascii()<<endl;
1226 QRectF totalBBox=mapCenter->getTotalBBox();
1228 // Try to set orientation automagically
1229 // Note: Interpretation of generated postscript is amibiguous, if
1230 // there are problems with landscape mode, see
1231 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1233 if (totalBBox.width()>totalBBox.height())
1234 // recommend landscape
1235 printer->setOrientation (QPrinter::Landscape);
1237 // recommend portrait
1238 printer->setOrientation (QPrinter::Portrait);
1240 if ( printer->setup(this) )
1241 // returns false, if printing is canceled
1243 QPainter pp(printer);
1245 pp.setRenderHint(QPainter::Antialiasing,true);
1247 // Don't print the visualisation of selection
1248 xelection.unselect();
1250 QRectF mapRect=totalBBox;
1251 QGraphicsRectItem *frame=NULL;
1255 // Print frame around map
1256 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1257 totalBBox.width()+20, totalBBox.height()+20);
1258 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1259 frame->setZValue(0);
1264 double paperAspect = (double)printer->width() / (double)printer->height();
1265 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1267 if (mapAspect>=paperAspect)
1269 // Fit horizontally to paper width
1270 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1271 viewBottom=(int)(printer->width()/mapAspect);
1274 // Fit vertically to paper height
1275 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1276 viewBottom=printer->height();
1281 // Print footer below map
1283 font.setPointSize(10);
1285 QRectF footerBox(0,viewBottom,printer->width(),15);
1286 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1287 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1291 QRectF (0,0,printer->width(),printer->height()-15),
1292 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1295 // Viewport has paper dimension
1296 if (frame) delete (frame);
1298 // Restore selection
1299 xelection.reselect();
1301 // Save settings in vymrc
1302 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1303 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1304 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1308 void MapEditor::setAntiAlias (bool b)
1310 setRenderHint(QPainter::Antialiasing,b);
1313 void MapEditor::setSmoothPixmap(bool b)
1315 setRenderHint(QPainter::SmoothPixmapTransform,b);
1318 QPixmap MapEditor::getPixmap()
1320 QRectF mapRect=mapCenter->getTotalBBox();
1321 QPixmap pix((int)mapRect.width(),(int)mapRect.height());
1322 cout << "w.h="<<(int)mapRect.width()<<","<<(int)mapRect.height()<<endl;
1325 pp.setRenderHints(renderHints());
1327 // Don't print the visualisation of selection
1328 xelection.unselect();
1330 mapScene->render ( &pp,
1331 QRectF(0,0,mapRect.width(),mapRect.height()),
1332 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1334 // mapScene->render(&pp); // draw scene to painter
1338 // Restore selection
1339 xelection.reselect();
1344 void MapEditor::setHideTmpMode (HideTmpMode mode)
1347 mapCenter->setHideTmp (hidemode);
1348 mapCenter->reposition();
1352 HideTmpMode MapEditor::getHideTmpMode()
1357 void MapEditor::exportImage(QString fn)
1359 setExportMode (true);
1360 QPixmap pix (getPixmap());
1361 pix.save(fn, "PNG");
1362 setExportMode (false);
1365 void MapEditor::setExportMode (bool b)
1367 // should be called before and after exports
1368 // depending on the settings
1369 if (b && settings.value("/export/useHideExport","yes")=="yes")
1370 setHideTmpMode (HideExport);
1372 setHideTmpMode (HideNone);
1375 void MapEditor::exportImage(QString fn, QString format)
1377 setExportMode (true);
1378 QPixmap pix (getPixmap());
1379 pix.save(fn, format);
1380 setExportMode (false);
1383 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1387 ex.setMapCenter(mapCenter);
1388 if (ex.setConfigFile(cf))
1390 setExportMode (true);
1391 ex.exportPresentation();
1392 setExportMode (false);
1398 void MapEditor::exportXML(const QString &dir)
1400 // Hide stuff during export, if settings want this
1401 setExportMode (true);
1403 // Create subdirectories
1406 // write to directory
1407 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1410 file.setName ( dir + "/"+mapName+".xml");
1411 if ( !file.open( QIODevice::WriteOnly ) )
1413 // This should neverever happen
1414 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1418 // Write it finally, and write in UTF8, no matter what
1419 QTextStream ts( &file );
1420 ts.setEncoding (QTextStream::UnicodeUTF8);
1424 // Now write image, too
1425 exportImage (dir+"/images/"+mapName+".png");
1427 setExportMode (false);
1430 void MapEditor::clear()
1432 xelection.unselect();
1436 void MapEditor::copy()
1438 LinkableMapObj *sel=xelection.single();
1441 // write to directory
1442 QString clipfile="part";
1443 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPointF(),sel ); // FIXME check FIO
1446 file.setName ( clipboardDir + "/"+clipfile+".xml");
1447 if ( !file.open( QIODevice::WriteOnly ) )
1449 // This should neverever happen
1450 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1454 // Write it finally, and write in UTF8, no matter what
1455 QTextStream ts( &file );
1456 ts.setEncoding (QTextStream::UnicodeUTF8);
1460 clipboardEmpty=false;
1465 void MapEditor::redo()
1467 blockSaveState=true;
1469 // Restore variables
1470 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1471 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1472 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1473 // Can we undo at all?
1474 if (redosAvail<1) return;
1477 if (undosAvail<stepsTotal) undosAvail++;
1479 if (curStep>stepsTotal) curStep=1;
1480 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1481 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1482 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1483 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1484 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1485 QString version=undoSet.readEntry ("/history/version");
1487 if (!checkVersion(version))
1488 QMessageBox::warning(0,tr("Warning"),
1489 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1492 // Find out current undo directory
1493 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1495 /* TODO remove testing
1497 cout << "ME::redo() begin\n";
1498 cout << " undosAvail="<<undosAvail<<endl;
1499 cout << " redosAvail="<<redosAvail<<endl;
1500 cout << " curStep="<<curStep<<endl;
1501 cout << " ---------------------------"<<endl;
1502 cout << " comment="<<comment.toStdString()<<endl;
1503 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1504 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1505 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1506 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1507 cout << " ---------------------------"<<endl<<endl;
1509 // select object before redo
1510 if (!redoSelection.isEmpty())
1511 select (redoSelection);
1514 parseAtom (redoCommand);
1515 mapCenter->reposition();
1517 blockSaveState=false;
1519 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1520 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1521 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1522 undoSet.writeSettings(histPath);
1524 mainWindow->updateHistory (undoSet);
1527 /* TODO remove testing
1528 cout << "ME::redo() end\n";
1529 cout << " undosAvail="<<undosAvail<<endl;
1530 cout << " redosAvail="<<redosAvail<<endl;
1531 cout << " curStep="<<curStep<<endl;
1532 cout << " ---------------------------"<<endl<<endl;
1538 bool MapEditor::isRedoAvailable()
1540 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1546 void MapEditor::undo()
1548 blockSaveState=true;
1550 // Restore variables
1551 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1552 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1553 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1555 // Can we undo at all?
1556 if (undosAvail<1) return;
1558 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1559 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1560 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1561 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1562 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1563 QString version=undoSet.readEntry ("/history/version");
1565 if (!checkVersion(version))
1566 QMessageBox::warning(0,tr("Warning"),
1567 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1569 // Find out current undo directory
1570 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1572 // select object before undo
1573 if (!undoSelection.isEmpty())
1574 select (undoSelection);
1578 cout << "ME::undo() begin\n";
1579 cout << " undosAvail="<<undosAvail<<endl;
1580 cout << " redosAvail="<<redosAvail<<endl;
1581 cout << " curStep="<<curStep<<endl;
1582 cout << " ---------------------------"<<endl;
1583 cout << " comment="<<comment.toStdString()<<endl;
1584 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1585 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1586 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1587 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1588 cout << " ---------------------------"<<endl<<endl;
1589 parseAtom (undoCommand);
1590 mapCenter->reposition();
1594 if (curStep<1) curStep=stepsTotal;
1598 blockSaveState=false;
1599 /* TODO remove testing
1600 cout << "ME::undo() end\n";
1601 cout << " undosAvail="<<undosAvail<<endl;
1602 cout << " redosAvail="<<redosAvail<<endl;
1603 cout << " curStep="<<curStep<<endl;
1604 cout << " ---------------------------"<<endl<<endl;
1607 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1608 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1609 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1610 undoSet.writeSettings(histPath);
1612 mainWindow->updateHistory (undoSet);
1614 ensureSelectionVisible();
1617 bool MapEditor::isUndoAvailable()
1619 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1625 void MapEditor::gotoHistoryStep (int i)
1627 // Restore variables
1628 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1629 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1631 if (i<0) i=undosAvail+redosAvail;
1633 // Clicking above current step makes us undo things
1636 for (int j=0; j<undosAvail-i; j++) undo();
1639 // Clicking below current step makes us redo things
1641 for (int j=undosAvail; j<i; j++) redo();
1643 // And ignore clicking the current row ;-)
1646 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1648 QString pathDir=path.left(path.findRev("/"));
1654 // We need to parse saved XML data
1655 mapBuilderHandler handler;
1656 QXmlInputSource source( file);
1657 QXmlSimpleReader reader;
1658 reader.setContentHandler( &handler );
1659 reader.setErrorHandler( &handler );
1660 handler.setMapEditor( this );
1661 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1662 if (undoSel.isEmpty())
1666 handler.setLoadMode (NewMap);
1670 handler.setLoadMode (ImportReplace);
1672 blockReposition=true;
1673 bool ok = reader.parse( source );
1674 blockReposition=false;
1677 // This should never ever happen
1678 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1679 handler.errorProtocol());
1682 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1685 void MapEditor::addMapInsertInt (const QString &path, int pos)
1687 BranchObj *sel=xelection.getBranch();
1690 QString pathDir=path.left(path.findRev("/"));
1696 // We need to parse saved XML data
1697 mapBuilderHandler handler;
1698 QXmlInputSource source( file);
1699 QXmlSimpleReader reader;
1700 reader.setContentHandler( &handler );
1701 reader.setErrorHandler( &handler );
1702 handler.setMapEditor( this );
1703 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1704 handler.setLoadMode (ImportAdd);
1705 blockReposition=true;
1706 bool ok = reader.parse( source );
1707 blockReposition=false;
1710 // This should never ever happen
1711 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1712 handler.errorProtocol());
1715 sel->getLastBranch()->linkTo (sel,pos);
1717 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1721 void MapEditor::pasteNoSave()
1723 load (clipboardDir+"/part.xml",ImportAdd);
1726 void MapEditor::cutNoSave()
1732 void MapEditor::paste() // FIXME no pasting of FIO ???
1734 BranchObj *sel=xelection.getBranch();
1738 saveStateChangingPart(
1742 QString("Paste to %1").arg( getName(sel))
1744 mapCenter->reposition();
1748 void MapEditor::cut()
1750 LinkableMapObj *sel=xelection.single();
1751 if ( sel && (xelection.type() == Branch ||
1752 xelection.type()==MapCenter ||
1753 xelection.type()==FloatImage))
1755 saveStateChangingPart(
1759 QString("Cut %1").arg(getName(sel ))
1763 mapCenter->reposition();
1767 void MapEditor::move(const int &x, const int &y)
1769 LinkableMapObj *sel=xelection.single();
1772 QString ps=qpointfToString (sel->getAbsPos());
1773 QString s=xelection.single()->getSelectString();
1776 s, "move "+qpointfToString (QPointF (x,y)),
1777 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
1778 sel->move(x,y); // FIXME xelection not moved automagically...
1779 mapCenter->reposition();
1784 void MapEditor::moveRel (const int &x, const int &y)
1786 LinkableMapObj *sel=xelection.single();
1789 QString ps=qpointfToString (sel->getRelPos());
1790 QString s=sel->getSelectString();
1793 s, "moveRel "+qpointfToString (QPointF (x,y)),
1794 QString("Move %1 to relativ position %2").arg(getName(sel)).arg(ps));
1795 ((OrnamentedObj*)sel)->move2RelPos (x,y);
1796 mapCenter->reposition();
1801 void MapEditor::moveBranchUp()
1803 BranchObj* bo=xelection.getBranch();
1807 if (!bo->canMoveBranchUp()) return;
1808 par=(BranchObj*)(bo->getParObj());
1809 xelection.unselect(); // FIXME needed?
1810 bo=par->moveBranchUp (bo); // bo will be the one below selection
1811 xelection.reselect();
1812 //saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1813 saveState (bo,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1814 mapCenter->reposition();
1816 ensureSelectionVisible();
1820 void MapEditor::moveBranchDown()
1822 BranchObj* bo=xelection.getBranch();
1826 if (!bo->canMoveBranchDown()) return;
1827 par=(BranchObj*)(bo->getParObj());
1828 xelection.unselect(); // FIXME needed?
1829 bo=par->moveBranchDown(bo); // bo will be the one above selection
1830 xelection.reselect();
1831 //saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1832 saveState(bo,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1833 mapCenter->reposition();
1835 ensureSelectionVisible();
1839 void MapEditor::linkTo(const QString &dstString) // FIXME needed? only for FIO ??
1841 FloatImageObj *fio=xelection.getFloatImage();
1844 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
1845 if (dst && (typeid(*dst)==typeid (BranchObj) ||
1846 typeid(*dst)==typeid (MapCenterObj)))
1848 LinkableMapObj *dstPar=dst->getParObj();
1849 QString parString=dstPar->getSelectString();
1850 QString fioPreSelectString=fio->getSelectString();
1851 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
1852 ((BranchObj*)(dst))->addFloatImage (fio);
1853 xelection.unselect();
1854 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
1855 fio=((BranchObj*)(dst))->getLastFloatImage();
1858 xelection.select(fio);
1860 fio->getSelectString(),
1861 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
1863 QString ("linkTo (\"%1\")").arg(dstString),
1864 QString ("Link floatimage to %1").arg(getName(dst)));
1869 QString MapEditor::getHeading(bool &ok, QPoint &p)
1871 BranchObj *bo=xelection.getBranch();
1875 p=mapFromScene(bo->getAbsPos());
1876 return bo->getHeading();
1882 void MapEditor::setHeading(const QString &s)
1884 BranchObj *sel=xelection.getBranch();
1889 "setHeading (\""+sel->getHeading()+"\")",
1891 "setHeading (\""+s+"\")",
1892 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
1893 sel->setHeading(s );
1894 mapCenter->reposition();
1895 ensureSelectionVisible();
1899 void MapEditor::setURLInt (const QString &s)
1901 // Internal function, no saveState needed
1902 BranchObj *bo=xelection.getBranch();
1906 mapCenter->reposition();
1907 ensureSelectionVisible();
1911 void MapEditor::setHeadingInt(const QString &s)
1913 BranchObj *bo=xelection.getBranch();
1917 mapCenter->reposition();
1918 ensureSelectionVisible();
1922 void MapEditor::setVymLinkInt (const QString &s)
1924 // Internal function, no saveState needed
1925 BranchObj *bo=xelection.getBranch();
1929 mapCenter->reposition();
1930 ensureSelectionVisible();
1934 BranchObj* MapEditor::addNewBranchInt(int num)
1936 // Depending on pos:
1937 // -3 insert in childs of parent above selection
1938 // -2 add branch to selection
1939 // -1 insert in childs of parent below selection
1940 // 0..n insert in childs of parent at pos
1941 BranchObj *newbo=NULL;
1942 BranchObj *bo=xelection.getBranch();
1947 // save scroll state. If scrolled, automatically select
1948 // new branch in order to tmp unscroll parent...
1949 return bo->addBranch();
1954 bo=(BranchObj*)bo->getParObj();
1958 bo=(BranchObj*)bo->getParObj();
1961 newbo=bo->insertBranch(num);
1966 BranchObj* MapEditor::addNewBranch(int pos)
1968 // Different meaning than num in addNewBranchInt!
1972 BranchObj *bo = xelection.getBranch();
1973 BranchObj *newbo=NULL;
1977 setCursor (Qt::ArrowCursor);
1979 newbo=addNewBranchInt (pos-2);
1987 QString ("addBranch (%1)").arg(pos-2),
1988 QString ("Add new branch to %1").arg(getName(bo)));
1990 mapCenter->reposition();
1997 BranchObj* MapEditor::addNewBranchBefore()
1999 BranchObj *newbo=NULL;
2000 BranchObj *bo = xelection.getBranch();
2001 if (bo && xelection.type()==Branch)
2002 // We accept no MapCenterObj here, so we _have_ a parent
2004 QPointF p=bo->getRelPos();
2007 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2009 // add below selection
2010 newbo=parbo->insertBranch(bo->getNum()+1);
2013 newbo->move2RelPos (p);
2015 // Move selection to new branch
2016 bo->linkTo (newbo,-1);
2018 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2019 QString ("Add branch before %1").arg(getName(bo)));
2021 mapCenter->reposition();
2027 void MapEditor::deleteSelection()
2029 BranchObj *bo = xelection.getBranch();
2030 if (bo && xelection.type()==Branch)
2032 BranchObj* par=(BranchObj*)(bo->getParObj());
2033 xelection.unselect();
2034 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2035 par->removeBranch(bo);
2036 xelection.select (par);
2037 ensureSelectionVisible();
2038 mapCenter->reposition();
2042 FloatImageObj *fio=xelection.getFloatImage();
2045 BranchObj* par=(BranchObj*)(fio->getParObj());
2046 saveStateChangingPart(
2050 QString("Delete %1").arg(getName(fio))
2052 xelection.unselect();
2053 par->removeFloatImage(fio);
2054 xelection.select (par);
2055 ensureSelectionVisible();
2056 mapCenter->reposition();
2062 LinkableMapObj* MapEditor::getSelection()
2064 return xelection.single();
2067 void MapEditor::unselect()
2069 xelection.unselect();
2072 void MapEditor::reselect()
2074 xelection.reselect();
2077 bool MapEditor::select (const QString &s)
2079 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2081 // Finally select the found object
2084 xelection.unselect();
2085 xelection.select(lmo);
2086 ensureSelectionVisible();
2092 QString MapEditor::getSelectString()
2094 return xelection.getSelectString();
2097 void MapEditor::selectInt (LinkableMapObj *lmo)
2099 if (lmo && xelection.single()!= lmo)
2100 xelection.select(lmo);
2103 void MapEditor::selectNextBranchInt()
2105 // Increase number of branch
2106 LinkableMapObj *sel=xelection.single();
2109 QString s=sel->getSelectString();
2115 part=s.section(",",-1);
2117 num=part.right(part.length() - 3);
2119 s=s.left (s.length() -num.length());
2122 num=QString ("%1").arg(num.toUInt()+1);
2126 // Try to select this one
2127 if (select (s)) return;
2129 // We have no direct successor,
2130 // try to increase the parental number in order to
2131 // find a successor with same depth
2133 int d=xelection.single()->getDepth();
2138 while (!found && d>0)
2140 s=s.section (",",0,d-1);
2141 // replace substring of current depth in s with "1"
2142 part=s.section(",",-1);
2144 num=part.right(part.length() - 3);
2148 // increase number of parent
2149 num=QString ("%1").arg(num.toUInt()+1);
2150 s=s.section (",",0,d-2) + ","+ typ+num;
2153 // Special case, look at orientation
2154 if (xelection.single()->getOrientation()==OrientRightOfCenter)
2155 num=QString ("%1").arg(num.toUInt()+1);
2157 num=QString ("%1").arg(num.toUInt()-1);
2162 // pad to oldDepth, select the first branch for each depth
2163 for (i=d;i<oldDepth;i++)
2168 if ( xelection.getBranch()->countBranches()>0)
2176 // try to select the freshly built string
2184 void MapEditor::selectPrevBranchInt()
2186 // Decrease number of branch
2187 BranchObj *bo=xelection.getBranch();
2190 QString s=bo->getSelectString();
2196 part=s.section(",",-1);
2198 num=part.right(part.length() - 3);
2200 s=s.left (s.length() -num.length());
2202 int n=num.toInt()-1;
2205 num=QString ("%1").arg(n);
2208 // Try to select this one
2209 if (n>=0 && select (s)) return;
2211 // We have no direct precessor,
2212 // try to decrease the parental number in order to
2213 // find a precessor with same depth
2215 int d=xelection.single()->getDepth();
2220 while (!found && d>0)
2222 s=s.section (",",0,d-1);
2223 // replace substring of current depth in s with "1"
2224 part=s.section(",",-1);
2226 num=part.right(part.length() - 3);
2230 // decrease number of parent
2231 num=QString ("%1").arg(num.toInt()-1);
2232 s=s.section (",",0,d-2) + ","+ typ+num;
2235 // Special case, look at orientation
2236 if (xelection.single()->getOrientation()==OrientRightOfCenter)
2237 num=QString ("%1").arg(num.toInt()-1);
2239 num=QString ("%1").arg(num.toInt()+1);
2244 // pad to oldDepth, select the last branch for each depth
2245 for (i=d;i<oldDepth;i++)
2249 if ( xelection.getBranch()->countBranches()>0)
2250 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2257 // try to select the freshly built string
2265 void MapEditor::selectUpperBranch()
2267 BranchObj *bo=xelection.getBranch();
2268 if (bo && xelection.type()==Branch)
2270 if (bo->getOrientation()==OrientRightOfCenter)
2271 selectPrevBranchInt();
2273 if (bo->getDepth()==1)
2274 selectNextBranchInt();
2276 selectPrevBranchInt();
2280 void MapEditor::selectLowerBranch()
2282 BranchObj *bo=xelection.getBranch();
2283 if (bo && xelection.type()==Branch)
2284 if (bo->getOrientation()==OrientRightOfCenter)
2285 selectNextBranchInt();
2287 if (bo->getDepth()==1)
2288 selectPrevBranchInt();
2290 selectNextBranchInt();
2294 void MapEditor::selectLeftBranch()
2298 LinkableMapObj *sel=xelection.single();
2301 if (xelection.type()== MapCenter)
2303 par=xelection.getBranch();
2304 bo=par->getLastSelectedBranch();
2307 // Workaround for reselecting on left and right side
2308 if (bo->getOrientation()==OrientRightOfCenter)
2309 bo=par->getLastBranch();
2312 bo=par->getLastBranch();
2313 xelection.select(bo);
2314 ensureSelectionVisible();
2319 par=(BranchObj*)(sel->getParObj());
2320 if (sel->getOrientation()==OrientRightOfCenter)
2322 if (xelection.type() == Branch ||
2323 xelection.type() == FloatImage)
2325 xelection.select(par);
2326 ensureSelectionVisible();
2330 if (xelection.type() == Branch )
2332 bo=xelection.getBranch()->getLastSelectedBranch();
2335 xelection.select(bo);
2336 ensureSelectionVisible();
2344 void MapEditor::selectRightBranch()
2348 LinkableMapObj *sel=xelection.single();
2351 if (xelection.type()==MapCenter)
2353 par=xelection.getBranch();
2354 bo=par->getLastSelectedBranch();
2357 // Workaround for reselecting on left and right side
2358 if (bo->getOrientation()==OrientLeftOfCenter)
2359 bo=par->getFirstBranch();
2362 xelection.select(bo);
2363 ensureSelectionVisible();
2368 par=(BranchObj*)(xelection.single()->getParObj());
2369 if (xelection.single()->getOrientation()==OrientLeftOfCenter)
2371 if (xelection.type() == Branch ||
2372 xelection.type() == FloatImage)
2374 xelection.select(par);
2375 ensureSelectionVisible();
2379 if (xelection.type() == Branch)
2381 bo=xelection.getBranch()->getLastSelectedBranch();
2384 xelection.select(bo);
2385 ensureSelectionVisible();
2393 void MapEditor::selectFirstBranch()
2395 BranchObj *bo1=xelection.getBranch();
2400 par=(BranchObj*)(bo1->getParObj());
2401 bo2=par->getFirstBranch();
2403 xelection.select(bo2);
2404 ensureSelectionVisible();
2409 void MapEditor::selectLastBranch()
2411 BranchObj *bo1=xelection.getBranch();
2416 par=(BranchObj*)(bo1->getParObj());
2417 bo2=par->getLastBranch();
2420 xelection.select(bo2);
2421 ensureSelectionVisible();
2426 void MapEditor::selectMapBackgroundImage ()
2428 Q3FileDialog *fd=new Q3FileDialog( this);
2429 fd->setMode (Q3FileDialog::ExistingFile);
2430 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2431 ImagePreview *p =new ImagePreview (fd);
2432 fd->setContentsPreviewEnabled( TRUE );
2433 fd->setContentsPreview( p, p );
2434 fd->setPreviewMode( Q3FileDialog::Contents );
2435 fd->setCaption(vymName+" - " +tr("Load background image"));
2436 fd->setDir (lastImageDir);
2439 if ( fd->exec() == QDialog::Accepted )
2441 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2442 lastImageDir=QDir (fd->dirPath());
2443 setMapBackgroundImage (fd->selectedFile());
2447 void MapEditor::setMapBackgroundImage (const QString &fn)
2449 QColor oldcol=mapScene->backgroundBrush().color();
2453 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2455 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2456 QString("Set background color of map to %1").arg(col.name()));
2458 cout << "Trying to load "<<fn.ascii()<<endl;//FIXME
2460 brush.setTextureImage (QPixmap (fn));
2461 mapScene->setBackgroundBrush(brush);
2464 void MapEditor::selectMapBackgroundColor()
2466 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2467 if ( !col.isValid() ) return;
2468 setMapBackgroundColor( col );
2472 void MapEditor::setMapBackgroundColor(QColor col)
2474 QColor oldcol=mapScene->backgroundBrush().color();
2477 QString ("setMapBackgroundColor (%1)").arg(oldcol.name()),
2479 QString ("setMapBackgroundColor (%1)").arg(col.name()),
2480 QString("Set background color of map to %1").arg(col.name()));
2481 mapScene->setBackgroundBrush(col);
2484 QColor MapEditor::getMapBackgroundColor()
2486 return mapScene->backgroundBrush().color();
2489 QColor MapEditor::getCurrentHeadingColor()
2491 BranchObj *bo=xelection.getBranch();
2492 if (bo) return bo->getColor();
2494 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2498 void MapEditor::colorBranch (QColor c)
2500 BranchObj *bo=xelection.getBranch();
2505 QString ("colorBranch (%1)").arg(bo->getColor().name()),
2507 QString ("colorBranch (%1)").arg(c.name()),
2508 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2510 bo->setColor(c); // color branch
2514 void MapEditor::colorSubtree (QColor c)
2516 BranchObj *bo=xelection.getBranch();
2519 saveStateChangingPart(
2522 QString ("colorSubtree (%1)").arg(c.name()),
2523 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2525 bo->setColorSubtree (c); // color links, color childs
2530 void MapEditor::toggleStandardFlag(QString f)
2532 BranchObj *bo=xelection.getBranch();
2536 if (bo->isSetStandardFlag(f))
2548 QString("%1 (\"%2\")").arg(u).arg(f),
2550 QString("%1 (\"%2\")").arg(r).arg(f),
2551 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2552 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2557 BranchObj* MapEditor::findText (QString s, bool cs)
2559 QTextDocument::FindFlags flags=0;
2560 if (cs) flags=QTextDocument::FindCaseSensitively;
2563 { // Nothing found or new find process
2565 // nothing found, start again
2567 itFind=mapCenter->first();
2569 bool searching=true;
2570 bool foundNote=false;
2571 while (searching && !EOFind)
2575 // Searching in Note
2576 if (itFind->getNote().contains(s,cs))
2578 if (xelection.single()!=itFind)
2580 xelection.select(itFind);
2581 ensureSelectionVisible();
2583 if (textEditor->findText(s,flags))
2589 // Searching in Heading
2590 if (searching && itFind->getHeading().contains (s,cs) )
2592 xelection.select(itFind);
2593 ensureSelectionVisible();
2599 itFind=itFind->next();
2600 if (!itFind) EOFind=true;
2604 return xelection.getBranch();
2609 void MapEditor::findReset()
2610 { // Necessary if text to find changes during a find process
2614 void MapEditor::setURL(const QString &url)
2616 BranchObj *bo=xelection.getBranch();
2619 QString oldurl=bo->getURL();
2623 QString ("setURL (\"%1\")").arg(oldurl),
2625 QString ("setURL (\"%1\")").arg(url),
2626 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2632 void MapEditor::editURL()
2634 BranchObj *bo=xelection.getBranch();
2638 QString text = QInputDialog::getText(
2639 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2640 bo->getURL(), &ok, this );
2642 // user entered something and pressed OK
2647 QString MapEditor::getURL()
2649 BranchObj *bo=xelection.getBranch();
2651 return bo->getURL();
2656 QStringList MapEditor::getURLs()
2659 BranchObj *bo=xelection.getBranch();
2665 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2673 void MapEditor::editHeading2URL()
2675 BranchObj *bo=xelection.getBranch();
2677 setURL (bo->getHeading());
2680 void MapEditor::editBugzilla2URL()
2682 BranchObj *bo=xelection.getBranch();
2685 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2690 void MapEditor::editFATE2URL()
2692 BranchObj *bo=xelection.getBranch();
2695 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2698 "setURL (\""+bo->getURL()+"\")",
2700 "setURL (\""+url+"\")",
2701 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2708 void MapEditor::editVymLink()
2710 BranchObj *bo=xelection.getBranch();
2713 QStringList filters;
2714 filters <<"VYM map (*.vym)";
2715 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2716 fd->setFilters (filters);
2717 fd->setCaption(vymName+" - " +tr("Link to another map"));
2718 if (! bo->getVymLink().isEmpty() )
2719 fd->selectFile( bo->getVymLink() );
2723 if ( fd->exec() == QDialog::Accepted )
2727 "setVymLink (\""+bo->getVymLink()+"\")",
2729 "setVymLink (\""+fd->selectedFile()+"\")",
2730 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2732 bo->setVymLink (fd->selectedFile() );
2734 mapCenter->reposition();
2740 void MapEditor::deleteVymLink()
2742 BranchObj *bo=xelection.getBranch();
2747 "setVymLink (\""+bo->getVymLink()+"\")",
2749 "setVymLink (\"\")",
2750 QString("Unset vymlink of %1").arg(getName(bo))
2752 bo->setVymLink ("" );
2754 mapCenter->reposition();
2759 void MapEditor::setHideExport(bool b)
2761 BranchObj *bo=xelection.getBranch();
2764 bo->setHideInExport (b);
2765 QString u= b ? "false" : "true";
2766 QString r=!b ? "false" : "true";
2770 QString ("setHideExport (%1)").arg(u),
2772 QString ("setHideExport (%1)").arg(r),
2773 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
2776 mapCenter->reposition();
2781 void MapEditor::toggleHideExport()
2783 BranchObj *bo=xelection.getBranch();
2785 setHideExport ( !bo->hideInExport() );
2788 QString MapEditor::getVymLink()
2790 BranchObj *bo=xelection.getBranch();
2792 return bo->getVymLink();
2798 QStringList MapEditor::getVymLinks()
2801 BranchObj *bo=xelection.getBranch();
2807 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2815 void MapEditor::deleteKeepChilds()
2817 BranchObj *bo=xelection.getBranch();
2821 par=(BranchObj*)(bo->getParObj());
2822 QPointF p=bo->getRelPos();
2823 saveStateChangingPart(
2826 "deleteKeepChilds ()",
2827 QString("Remove %1 and keep its childs").arg(getName(bo))
2830 QString sel=bo->getSelectString();
2832 par->removeBranchHere(bo);
2833 mapCenter->reposition();
2835 xelection.getBranch()->move2RelPos (p);
2836 mapCenter->reposition();
2840 void MapEditor::deleteChilds()
2842 BranchObj *bo=xelection.getBranch();
2845 saveStateChangingPart(
2849 QString( "Remove childs of branch %1").arg(getName(bo))
2852 mapCenter->reposition();
2856 void MapEditor::editMapInfo()
2858 ExtraInfoDialog dia;
2859 dia.setMapName (getFileName() );
2860 dia.setAuthor (mapCenter->getAuthor() );
2861 dia.setComment(mapCenter->getComment() );
2865 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
2872 bo=mapCenter->first();
2875 if (!bo->getNote().isEmpty() ) n++;
2876 f+= bo->countFloatImages();
2878 xl+=bo->countXLinks();
2881 stats+=QString ("%1 branches\n").arg (b-1,6);
2882 stats+=QString ("%1 xLinks \n").arg (xl,6);
2883 stats+=QString ("%1 notes\n").arg (n,6);
2884 stats+=QString ("%1 images\n").arg (f,6);
2885 dia.setStats (stats);
2887 // Finally show dialog
2888 if (dia.exec() == QDialog::Accepted)
2890 setMapAuthor (dia.getAuthor() );
2891 setMapComment (dia.getComment() );
2895 void MapEditor::updateActions()
2897 mainWindow->updateActions();
2898 // TODO maybe don't update if blockReposition is set
2901 void MapEditor::updateNoteFlag()
2904 BranchObj *bo=xelection.getBranch();
2907 bo->updateNoteFlag();
2908 mainWindow->updateActions();
2912 void MapEditor::setMapAuthor (const QString &s)
2916 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
2918 QString ("setMapAuthor (\"%1\")").arg(s),
2919 QString ("Set author of map to \"%1\"").arg(s)
2921 mapCenter->setAuthor (s);
2924 void MapEditor::setMapComment (const QString &s)
2928 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
2930 QString ("setMapComment (\"%1\")").arg(s),
2931 QString ("Set comment of map")
2933 mapCenter->setComment (s);
2936 void MapEditor::setMapLinkStyle (const QString & s)
2938 saveStateChangingPart (
2941 QString("setMapLinkStyle (\"%1\")").arg(s),
2942 QString("Set map link style (\"%1\")").arg(s)
2946 linkstyle=StyleLine;
2947 else if (s=="StyleParabel")
2948 linkstyle=StyleParabel;
2949 else if (s=="StylePolyLine")
2950 linkstyle=StylePolyLine;
2952 linkstyle=StylePolyParabel;
2955 bo=mapCenter->first();
2959 bo->setLinkStyle(bo->getDefLinkStyle());
2962 mapCenter->reposition();
2965 LinkStyle MapEditor::getMapLinkStyle ()
2970 void MapEditor::setMapDefLinkColor(QColor c)
2976 void MapEditor::setMapLinkColorHintInt()
2978 // called from setMapLinkColorHint(lch) or at end of parse
2980 bo=mapCenter->first();
2988 void MapEditor::setMapLinkColorHint(LinkColorHint lch)
2991 setMapLinkColorHintInt();
2994 void MapEditor::toggleMapLinkColorHint()
2996 if (linkcolorhint==HeadingColor)
2997 linkcolorhint=DefaultColor;
2999 linkcolorhint=HeadingColor;
3001 bo=mapCenter->first();
3009 LinkColorHint MapEditor::getMapLinkColorHint()
3011 return linkcolorhint;
3014 QColor MapEditor::getMapDefLinkColor()
3016 return defLinkColor;
3019 void MapEditor::setMapDefXLinkColor(QColor col)
3024 QColor MapEditor::getMapDefXLinkColor()
3026 return defXLinkColor;
3029 void MapEditor::setMapDefXLinkWidth (int w)
3034 int MapEditor::getMapDefXLinkWidth()
3036 return defXLinkWidth;
3039 void MapEditor::selectMapLinkColor()
3041 QColor col = QColorDialog::getColor( defLinkColor, this );
3042 if ( !col.isValid() ) return;
3045 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3047 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3048 QString("Set link color to %1").arg(col.name())
3050 setMapDefLinkColor( col );
3054 bool MapEditor::scrollBranch()
3056 BranchObj *bo=xelection.getBranch();
3059 if (bo->isScrolled()) return false;
3060 if (bo->countBranches()==0) return false;
3061 if (bo->getDepth()==0) return false;
3067 QString ("%1 ()").arg(u),
3069 QString ("%1 ()").arg(r),
3070 QString ("%1 %2").arg(r).arg(getName(bo))
3079 bool MapEditor::unscrollBranch()
3081 BranchObj *bo=xelection.getBranch();
3084 if (!bo->isScrolled()) return false;
3085 if (bo->countBranches()==0) return false;
3086 if (bo->getDepth()==0) return false;
3092 QString ("%1 ()").arg(u),
3094 QString ("%1 ()").arg(r),
3095 QString ("%1 %2").arg(r).arg(getName(bo))
3104 void MapEditor::toggleScroll()
3106 BranchObj *bo=xelection.getBranch();
3107 if (xelection.type()==Branch )
3109 if (bo->isScrolled())
3116 void MapEditor::unscrollChilds() // FIXME saveState missing
3118 BranchObj *bo=xelection.getBranch();
3124 if (bo->isScrolled()) bo->toggleScroll();
3130 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3132 BranchObj *bo=xelection.getBranch();
3136 bo->addFloatImage();
3137 fio=bo->getLastFloatImage();
3139 mapCenter->reposition();
3146 void MapEditor::loadFloatImage ()
3148 BranchObj *bo=xelection.getBranch();
3152 Q3FileDialog *fd=new Q3FileDialog( this);
3153 fd->setMode (Q3FileDialog::ExistingFiles);
3154 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3155 ImagePreview *p =new ImagePreview (fd);
3156 fd->setContentsPreviewEnabled( TRUE );
3157 fd->setContentsPreview( p, p );
3158 fd->setPreviewMode( Q3FileDialog::Contents );
3159 fd->setCaption(vymName+" - " +tr("Load image"));
3160 fd->setDir (lastImageDir);
3163 if ( fd->exec() == QDialog::Accepted )
3165 // FIXME loadFIO in QT4 use: lastImageDir=fd->directory();
3166 lastImageDir=QDir (fd->dirPath());
3169 for (int j=0; j<fd->selectedFiles().count(); j++)
3171 s=fd->selectedFiles().at(j);
3172 fio=loadFloatImageInt (s);
3175 (LinkableMapObj*)fio,
3178 QString ("loadImage (%1)").arg(s ),
3179 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3182 // FIXME loadFIO error handling
3183 qWarning ("Failed to load "+s);
3191 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3193 fio->save (fn,type);
3196 void MapEditor::saveFloatImage ()
3198 FloatImageObj *fio=xelection.getFloatImage();
3201 QFileDialog *fd=new QFileDialog( this);
3202 fd->setFilters (imageIO.getFilters());
3203 fd->setCaption(vymName+" - " +tr("Save image"));
3204 fd->setFileMode( QFileDialog::AnyFile );
3205 fd->setDirectory (lastImageDir);
3206 // fd->setSelection (fio->getOriginalFilename());
3210 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3212 fn=fd->selectedFiles().at(0);
3213 if (QFile (fn).exists() )
3215 QMessageBox mb( vymName,
3216 tr("The file %1 exists already.\n"
3217 "Do you want to overwrite it?").arg(fn),
3218 QMessageBox::Warning,
3219 QMessageBox::Yes | QMessageBox::Default,
3220 QMessageBox::Cancel | QMessageBox::Escape,
3221 QMessageBox::QMessageBox::NoButton );
3223 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3224 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3227 case QMessageBox::Yes:
3230 case QMessageBox::Cancel:
3237 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3243 void MapEditor::setFrame(const FrameType &t) // FIXME missing saveState
3245 BranchObj *bo=xelection.getBranch();
3248 bo->setFrameType (t);
3249 mapCenter->reposition();
3254 void MapEditor::setIncludeImagesVer(bool b)
3256 BranchObj *bo=xelection.getBranch();
3259 QString u= b ? "false" : "true";
3260 QString r=!b ? "false" : "true";
3264 QString("setIncludeImagesVertically (%1)").arg(u),
3266 QString("setIncludeImagesVertically (%1)").arg(r),
3267 QString("Include images vertically in %1").arg(getName(bo))
3269 bo->setIncludeImagesVer(b);
3270 mapCenter->reposition();
3274 void MapEditor::setIncludeImagesHor(bool b)
3276 BranchObj *bo=xelection.getBranch();
3279 QString u= b ? "false" : "true";
3280 QString r=!b ? "false" : "true";
3284 QString("setIncludeImagesHorizontally (%1)").arg(u),
3286 QString("setIncludeImagesHorizontally (%1)").arg(r),
3287 QString("Include images horizontally in %1").arg(getName(bo))
3289 bo->setIncludeImagesHor(b);
3290 mapCenter->reposition();
3294 void MapEditor::setHideLinkUnselected (bool b) // FIXME missing saveState
3296 LinkableMapObj *sel=xelection.single();
3298 (xelection.type() == Branch ||
3299 xelection.type() == MapCenter ||
3300 xelection.type() == FloatImage ))
3301 sel->setHideLinkUnselected(b);
3304 void MapEditor::importDirInt(BranchObj *dst, QDir d) // FIXME missing saveState
3306 BranchObj *bo=xelection.getBranch();
3309 // Traverse directories
3310 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3311 QFileInfoList list = d.entryInfoList();
3314 for (int i = 0; i < list.size(); ++i)
3317 if (fi.fileName() != "." && fi.fileName() != ".." )
3320 bo=dst->getLastBranch();
3321 bo->setHeading (fi.fileName() );
3322 bo->setColor (QColor("blue"));
3324 if ( !d.cd(fi.fileName()) )
3325 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3328 // Recursively add subdirs
3329 importDirInt (bo,d);
3335 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3336 list = d.entryInfoList();
3338 for (int i = 0; i < list.size(); ++i)
3342 bo=dst->getLastBranch();
3343 bo->setHeading (fi.fileName() );
3344 bo->setColor (QColor("black"));
3345 if (fi.fileName().right(4) == ".vym" )
3346 bo->setVymLink (fi.filePath());
3351 void MapEditor::importDir()
3353 BranchObj *bo=xelection.getBranch();
3356 QStringList filters;
3357 filters <<"VYM map (*.vym)";
3358 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3359 fd->setMode (QFileDialog::DirectoryOnly);
3360 fd->setFilters (filters);
3361 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3365 if ( fd->exec() == QDialog::Accepted )
3367 importDirInt (bo,QDir(fd->selectedFile()) );
3368 mapCenter->reposition();
3374 void MapEditor::followXLink(int i)
3376 BranchObj *bo=xelection.getBranch();
3379 bo=bo->XLinkTargetAt(i);
3382 xelection.select(bo);
3383 ensureSelectionVisible();
3388 void MapEditor::editXLink(int i) // FIXME missing saveState
3390 BranchObj *bo=xelection.getBranch();
3393 XLinkObj *xlo=bo->XLinkAt(i);
3396 EditXLinkDialog dia;
3398 dia.setSelection(bo);
3399 if (dia.exec() == QDialog::Accepted)
3401 if (dia.useSettingsGlobal() )
3403 setMapDefXLinkColor (xlo->getColor() );
3404 setMapDefXLinkWidth (xlo->getWidth() );
3406 if (dia.deleteXLink())
3407 bo->deleteXLinkAt(i);
3413 void MapEditor::testFunction()
3415 // This is the playground
3420 dia.showCancelButton (true);
3421 dia.setText("This is a longer \nWarning");
3422 dia.setCaption("Warning: Flux problem");
3423 dia.setShowAgainName("mapeditor/testDialog");
3424 if (dia.exec()==QDialog::Accepted)
3425 cout << "accepted!\n";
3427 cout << "canceled!\n";
3431 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
3432 if (hidemode==HideNone)
3434 setHideTmpMode (HideExport);
3435 mapCenter->calcBBoxSizeWithChilds();
3436 QRectF totalBBox=mapCenter->getTotalBBox();
3437 QRectF mapRect=totalBBox;
3438 QCanvasRectangle *frame=NULL;
3440 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3442 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3443 totalBBox.width(), totalBBox.height());
3444 frame=new QCanvasRectangle (mapRect,mapScene);
3445 frame->setBrush (QColor(white));
3446 frame->setPen (QColor(black));
3447 frame->setZValue(0);
3452 setHideTmpMode (HideNone);
3454 cout <<" hidemode="<<hidemode<<endl;
3458 void MapEditor::ensureSelectionVisible()
3460 LinkableMapObj *lmo=xelection.single();
3461 if (lmo) ensureVisible (lmo->getBBox() );
3464 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3466 // Lineedits are already closed by preceding
3467 // mouseEvent, we don't need to close here.
3469 QPointF p = mapToScene(e->pos());
3470 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3473 { // MapObj was found
3474 if (xelection.single() != lmo)
3476 // select the MapObj
3477 xelection.select(lmo);
3480 if (xelection.getBranch() )
3482 // Context Menu on branch or mapcenter
3484 branchContextMenu->popup(e->globalPos() );
3487 if (xelection.getFloatImage() )
3489 // Context Menu on floatimage
3491 floatimageContextMenu->popup(e->globalPos() );
3495 { // No MapObj found, we are on the Canvas itself
3496 // Context Menu on scene
3498 canvasContextMenu->popup(e->globalPos() );
3503 void MapEditor::keyPressEvent(QKeyEvent* e)
3505 if (e->modifiers() & Qt::ControlModifier)
3507 switch (mainWindow->getModMode())
3510 setCursor (PickColorCursor);
3513 setCursor (CopyCursor);
3516 setCursor (XLinkCursor);
3519 setCursor (Qt::ArrowCursor);
3525 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3527 if (!(e->modifiers() & Qt::ControlModifier))
3528 setCursor (Qt::ArrowCursor);
3531 void MapEditor::mousePressEvent(QMouseEvent* e)
3533 // Ignore right clicks, these will go to context menus
3534 if (e->button() == Qt::RightButton )
3540 QPointF p = mapToScene(e->pos());
3541 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3545 //Take care of clickdesystem flags _or_ modifier modes
3547 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3548 typeid(*lmo)==typeid(MapCenterObj) ))
3550 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3551 if (!foname.isEmpty())
3553 // systemFlag clicked
3557 if (e->state() & Qt::ControlModifier)
3558 mainWindow->editOpenURLTab();
3560 mainWindow->editOpenURL();
3562 else if (foname=="vymLink")
3564 mainWindow->editOpenVymLink();
3565 // tabWidget may change, better return now
3566 // before segfaulting...
3567 } else if (foname=="note")
3568 mainWindow->windowToggleNoteEditor();
3569 else if (foname=="hideInExport")
3574 // No system flag clicked, take care of modmodes
3576 // Special case: CTRL is pressed
3577 if (e->state() & Qt::ControlModifier)
3579 if (mainWindow->getModMode()==ModModeColor)
3582 setCursor (PickColorCursor);
3585 if (mainWindow->getModMode()==ModModeXLink)
3587 BranchObj *bo_begin=NULL;
3589 bo_begin=(BranchObj*)(lmo);
3591 if (xelection.getBranch() )
3592 bo_begin=xelection.getBranch();
3596 linkingObj_src=bo_begin;
3597 tmpXLink=new XLinkObj (mapScene);
3598 tmpXLink->setBegin (bo_begin);
3599 tmpXLink->setEnd (p);
3600 tmpXLink->setColor(defXLinkColor);
3601 tmpXLink->setWidth(defXLinkWidth);
3602 tmpXLink->updateXLink();
3603 tmpXLink->setVisibility (true);
3611 // Left Button Move Branches
3612 if (e->button() == Qt::LeftButton )
3614 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
3615 //movingObj_start.setY( p.y() - selection->y() );
3616 movingObj_start.setX( p.x() - lmo->x() );
3617 movingObj_start.setY( p.y() - lmo->y() );
3618 movingObj_orgPos.setX (lmo->x() );
3619 movingObj_orgPos.setY (lmo->y() );
3620 movingObj_orgRelPos=lmo->getRelPos();
3622 // If modMode==copy, then we want to "move" the _new_ object around
3623 // then we need the offset from p to the _old_ selection, because of tmp
3624 if (mainWindow->getModMode()==ModModeCopy &&
3625 e->state() & Qt::ControlModifier)
3627 if (xelection.type()==Branch)
3630 mapCenter->addBranch ((BranchObj*)xelection.single());
3632 xelection.select(mapCenter->getLastBranch());
3633 mapCenter->reposition();
3637 movingObj=xelection.single();
3639 // Middle Button Toggle Scroll
3640 // (On Mac OS X this won't work, but we still have
3641 // a button in the toolbar)
3642 if (e->button() == Qt::MidButton )
3646 { // No MapObj found, we are on the scene itself
3647 // Left Button move Pos of sceneView
3648 if (e->button() == Qt::LeftButton )
3650 movingObj=NULL; // move Content not Obj
3651 movingObj_start=e->globalPos();
3652 movingCont_start=QPointF (
3653 horizontalScrollBar()->value(),
3654 verticalScrollBar()->value());
3655 movingVec=QPointF(0,0);
3656 setCursor(HandOpenCursor);
3661 void MapEditor::mouseMoveEvent(QMouseEvent* e)
3663 QPointF p = mapToScene(e->pos());
3664 LinkableMapObj *lmosel=xelection.single();
3666 // Move the selected MapObj
3667 if ( lmosel && movingObj)
3669 // reset cursor if we are moving and don't copy
3670 if (mainWindow->getModMode()!=ModModeCopy)
3671 setCursor (Qt::ArrowCursor);
3673 // To avoid jumping of the sceneView, only
3674 // ensureSelectionVisible, if not tmp linked
3675 if (!lmosel->hasParObjTmp())
3676 ensureSelectionVisible ();
3678 // Now move the selection, but add relative position
3679 // (movingObj_start) where selection was chosen with
3680 // mousepointer. (This avoids flickering resp. jumping
3681 // of selection back to absPos)
3683 // Check if we could link
3684 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3687 FloatObj *fio=xelection.getFloatImage();
3690 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3692 fio->updateLink(); //no need for reposition, if we update link here
3694 // Relink float to new mapcenter or branch, if shift is pressed
3695 // Only relink, if selection really has a new parent
3696 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3697 ( (typeid(*lmo)==typeid(BranchObj)) ||
3698 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3699 ( lmo != fio->getParObj())
3702 if (typeid(*fio) == typeid(FloatImageObj) &&
3703 ( (typeid(*lmo)==typeid(BranchObj) ||
3704 typeid(*lmo)==typeid(MapCenterObj)) ))
3707 // Also save the move which was done so far
3708 QString pold=qpointfToString(movingObj_orgRelPos);
3709 QString pnow=qpointfToString(fio->getRelPos());
3715 QString("Move %1 to relativ position %2").arg(getName(fio)).arg(pnow));
3716 fio->getParObj()->requestReposition();
3717 mapCenter->reposition();
3719 cout << "current relPos="<<movingObj_orgRelPos<<endl; // FIXME testing
3720 linkTo (lmo->getSelectString());
3721 cout << "setting movingObj\n";
3723 movingObj_orgRelPos=lmosel->getRelPos();
3726 mapCenter->reposition();
3730 { // selection != a FloatObj
3731 if (lmosel->getDepth()==0)
3734 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3735 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3737 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3738 mapCenter->updateRelPositions();
3741 if (lmosel->getDepth()==1)
3744 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3745 lmosel->setRelPos();
3748 // Move ordinary branch
3749 if (lmosel->getOrientation() == OrientLeftOfCenter)
3750 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3751 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3752 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3754 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3757 // Maybe we can relink temporary?
3758 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
3759 (typeid(*lmo)==typeid(BranchObj) ||
3760 typeid(*lmo)==typeid(MapCenterObj)) )
3763 if (e->modifiers()==Qt::ControlModifier)
3765 // Special case: CTRL to link below lmo
3766 lmosel->setParObjTmp (lmo,p,+1);
3768 else if (e->modifiers()==Qt::ShiftModifier)
3769 lmosel->setParObjTmp (lmo,p,-1);
3771 lmosel->setParObjTmp (lmo,p,0);
3774 lmosel->unsetParObjTmp();
3776 // reposition subbranch
3777 lmosel->reposition();
3780 } // no FloatImageObj
3784 } // selection && moving_obj
3786 // Draw a link from one branch to another
3789 tmpXLink->setEnd (p);
3790 tmpXLink->updateXLink();
3794 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
3796 QPointF p=e->globalPos();
3797 movingVec.setX(-p.x() + movingObj_start.x() );
3798 movingVec.setY(-p.y() + movingObj_start.y() );
3799 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
3800 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
3805 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
3807 QPointF p = mapToScene(e->pos());
3808 LinkableMapObj *dst;
3809 LinkableMapObj *lmosel=xelection.single();
3810 // Have we been picking color?
3814 setCursor (Qt::ArrowCursor);
3815 // Check if we are over another branch
3816 dst=mapCenter->findMapObj(p, NULL);
3819 if (e->state() & Qt::ShiftModifier)
3820 colorBranch (((BranchObj*)(dst))->getColor());
3822 colorSubtree (((BranchObj*)(dst))->getColor());
3827 // Have we been drawing a link?
3831 // Check if we are over another branch
3832 dst=mapCenter->findMapObj(p, NULL);
3835 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3836 tmpXLink->updateXLink();
3837 tmpXLink->activate();
3838 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //FIXME undoCommand
3847 // Have we been moving something?
3848 if ( lmosel && movingObj )
3850 FloatImageObj *fo=xelection.getFloatImage();
3853 // Moved FloatObj. Maybe we need to reposition
3854 QString pold=qpointfToString(movingObj_orgRelPos);
3855 QString pnow=qpointfToString(fo->getRelPos());
3861 QString("Move %1 to relativ position %2").arg(getName(fo)).arg(pnow));
3863 fo->getParObj()->requestReposition();
3864 mapCenter->reposition();
3867 // Check if we are over another branch, but ignore
3868 // any found LMOs, which are FloatObjs
3869 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
3871 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3874 if (xelection.type() == MapCenter )
3875 { // FIXME The MapCenter was moved, no savestate yet
3878 if (xelection.type() == Branch )
3879 { // A branch was moved
3881 // save the position in case we link to mapcenter
3882 QPointF savePos=QPointF (lmosel->getAbsPos() );
3884 // Reset the temporary drawn link to the original one
3885 lmosel->unsetParObjTmp();
3887 // For Redo we may need to save original selection
3888 QString preSelStr=lmosel->getSelectString();
3893 BranchObj* bsel=xelection.getBranch();
3894 BranchObj* bdst=(BranchObj*)dst;
3896 QString preParStr=(bsel->getParObj())->getSelectString();
3897 QString preNum=QString::number (bsel->getNum(),10);
3898 QString preDstParStr;
3900 if (e->state() & Qt::ShiftModifier && dst->getParObj())
3902 preDstParStr=dst->getParObj()->getSelectString();
3903 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
3905 if (e->state() & Qt::ControlModifier && dst->getParObj())
3908 preDstParStr=dst->getParObj()->getSelectString();
3909 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
3912 preDstParStr=dst->getSelectString();
3913 bsel->linkTo (bdst,-1);
3914 if (dst->getDepth()==0) bsel->move (savePos);
3916 QString postSelStr=lmosel->getSelectString();
3917 QString postNum=QString::number (bsel->getNum(),10);
3919 QString undoCom="linkTo (\""+
3920 preParStr+ "\"," + preNum +"," +
3921 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
3923 QString redoCom="linkTo (\""+
3924 preDstParStr + "\"," + postNum + "," +
3925 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
3930 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
3932 if (lmosel->getDepth()==1)
3934 // The select string might be different _after_ moving around.
3935 // Therefor reposition and then use string of old selection, too
3936 mapCenter->reposition();
3938 QString ps=qpointfToString ( lmosel->getRelPos() );
3940 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
3941 preSelStr, "moveRel "+ps,
3942 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
3945 // Draw the original link, before selection was moved around
3946 mapCenter->reposition();
3948 // Finally resize scene, if needed
3952 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
3955 // maybe we moved View: set old cursor
3956 setCursor (Qt::ArrowCursor);
3960 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
3962 if (e->button() == Qt::LeftButton )
3964 QPointF p = mapToScene(e->pos());
3965 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3966 if (lmo) { // MapObj was found
3967 // First select the MapObj than edit heading
3968 xelection.select(lmo);
3969 mainWindow->editHeading();
3974 void MapEditor::resizeEvent (QResizeEvent* e)
3976 QGraphicsView::resizeEvent( e );
3979 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
3981 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
3982 // cerr << event->format(i) << endl;
3984 if (event->mimeData()->hasImage())
3985 event->acceptProposedAction();
3987 if (event->mimeData()->hasUrls())
3988 event->acceptProposedAction();
3991 void MapEditor::dragMoveEvent(QDragMoveEvent *event)
3995 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4000 void MapEditor::dropEvent(QDropEvent *event)
4002 BranchObj *sel=xelection.getBranch();
4006 if (event->mimeData()->hasImage())
4008 QVariant imageData = event->mimeData()->imageData();
4009 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4011 if (event->mimeData()->hasUrls())
4012 uris=event->mimeData()->urls();
4020 for (int i=0; i<uris.count();i++)
4022 // Workaround to avoid adding empty branches
4023 if (!uris.at(i).toString().isEmpty())
4025 bo=sel->addBranch();
4028 s=uris.at(i).toLocalFile();
4031 QString file = QDir::convertSeparators(s);
4032 heading = QFileInfo(file).baseName();
4034 if (file.endsWith(".vym", false))
4035 bo->setVymLink(file);
4037 bo->setURL(uris.at(i).toString());
4040 bo->setURL(uris.at(i).toString());
4043 if (!heading.isEmpty())
4044 bo->setHeading(heading);
4046 bo->setHeading(uris.at(i).toString());
4050 mapCenter->reposition();
4053 event->acceptProposedAction();
4057 void MapEditor::contentsDropEvent(QDropEvent *event)
4060 } else if (event->provides("application/x-moz-file-promise-url") &&
4061 event->provides("application/x-moz-nativeimage"))
4063 // Contains url to the img src in unicode16
4064 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4065 QString url = QString((const QChar*)d.data(),d.size()/2);
4069 } else if (event->provides ("text/uri-list"))
4070 { // Uris provided e.g. by konqueror
4071 Q3UriDrag::decode (event,uris);
4072 } else if (event->provides ("_NETSCAPE_URL"))
4073 { // Uris provided by Mozilla
4074 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4077 } else if (event->provides("text/html")) {
4079 // Handels text mime types
4080 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4081 QByteArray d = event->encodedData("text/html");
4084 text = QString((const QChar*)d.data(),d.size()/2);
4088 textEditor->setText(text);
4092 } else if (event->provides("text/plain")) {
4093 QByteArray d = event->encodedData("text/plain");
4096 text = QString((const QChar*)d.data(),d.size()/2);
4100 textEditor->setText(text);
4110 bool isUnicode16(const QByteArray &d)
4112 // TODO: make more precise check for unicode 16.
4113 // Guess unicode16 if any of second bytes are zero
4114 unsigned int length = max(0,d.size()-2)/2;
4115 for (unsigned int i = 0; i<length ; i++)
4116 if (d.at(i*2+1)==0) return true;
4120 void MapEditor::addFloatImageInt (const QPixmap &img)
4122 BranchObj *bo=xelection.getBranch();
4125 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4126 //QString fn=fd->selectedFile();
4127 //lastImageDir=fn.left(fn.findRev ("/"));
4128 FloatImageObj *fio=bo->addFloatImage();
4130 fio->setOriginalFilename("Image added by Drag and Drop");
4131 mapCenter->reposition();
4138 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4140 if (!imageBuffer) imageBuffer = new QBuffer();
4141 if (!imageBuffer->isOpen()) {
4142 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4144 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4148 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4150 if (nop->state()==Q3NetworkProtocol::StDone) {
4151 QPixmap img(imageBuffer->buffer());
4152 addFloatImageInt (img);
4156 imageBuffer->close();
4158 imageBuffer->close();
4165 void MapEditor::fetchImage(const QString &url)
4168 urlOperator->stop();
4169 disconnect(urlOperator);
4173 urlOperator = new Q3UrlOperator(url);
4174 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4175 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4177 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4178 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));