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 QString clipboardFile;
30 extern bool clipboardEmpty;
32 extern FlagRowObj *standardFlagsDefault;
34 extern QMenu* branchContextMenu;
35 extern QMenu* branchAddContextMenu;
36 extern QMenu* branchRemoveContextMenu;
37 extern QMenu* branchLinksContextMenu;
38 extern QMenu* branchXLinksContextMenuEdit;
39 extern QMenu* branchXLinksContextMenuFollow;
40 extern QMenu* floatimageContextMenu;
41 extern QMenu* canvasContextMenu;
44 extern Settings settings;
45 extern ImageIO imageIO;
47 extern QString vymName;
48 extern QString vymVersion;
50 extern QString iconPath;
51 extern QDir vymBaseDir;
52 extern QDir lastImageDir;
53 extern QDir lastFileDir;
55 int MapEditor::mapNum=0; // make instance
57 ///////////////////////////////////////////////////////////////////////
58 ///////////////////////////////////////////////////////////////////////
59 MapEditor::MapEditor( QWidget* parent) :
62 //cout << "Constructor ME "<<this<<endl;
66 mapScene= new QGraphicsScene(parent);
67 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
68 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
73 mapCenter = new MapCenterObj(mapScene);
74 mapCenter->setVisibility (true);
75 mapCenter->setMapEditor (this);
76 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
77 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
82 defLinkColor=QColor (0,0,255);
83 defXLinkColor=QColor (180,180,180);
84 linkcolorhint=LinkableMapObj::DefaultColor;
85 linkstyle=LinkableMapObj::PolyParabel;
87 // Create bitmap cursors, platform dependant
88 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
89 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
90 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
91 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
93 setFocusPolicy (Qt::StrongFocus);
102 xelection.setMapEditor (this);
103 xelection.unselect();
106 defXLinkColor=QColor (230,230,230);
114 fileName=tr("unnamed");
117 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
118 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
119 mainWindow->updateHistory (undoSet);
121 // Initialize find routine
128 blockReposition=false;
129 blockSaveState=false;
131 hidemode=BranchObj::HideNone;
133 // Create temporary files
136 setAcceptDrops (true);
138 mapCenter->reposition(); // for positioning heading
142 //timerId = startTimer(100);
145 autosaveTimer=new QTimer (this);
146 connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
149 MapEditor::~MapEditor()
151 //cout <<"Destructor MapEditor\n";
152 autosaveTimer->stop();
155 MapCenterObj* MapEditor::getMapCenter()
160 QGraphicsScene * MapEditor::getScene()
165 MapEditor::State MapEditor::getState()
170 void MapEditor::setStateEditHeading(bool s)
174 if (state==Idle) state=EditHeading;
180 bool MapEditor::isRepositionBlocked()
182 return blockReposition;
185 void MapEditor::setSaveStateBlocked(bool b)
190 bool MapEditor::isSelectBlocked()
192 if (state==EditHeading)
198 QString MapEditor::getName (const LinkableMapObj *lmo)
201 if (!lmo) return QString("Error: NULL has no name!");
203 if ((typeid(*lmo) == typeid(BranchObj) ||
204 typeid(*lmo) == typeid(MapCenterObj)))
207 s=(((BranchObj*)lmo)->getHeading());
208 if (s=="") s="unnamed";
209 return QString("branch (%1)").arg(s);
210 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
212 if ((typeid(*lmo) == typeid(FloatImageObj) ))
213 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
214 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
215 return QString("Unknown type has no name!");
218 void MapEditor::makeTmpDirs()
220 // Create unique temporary directories
221 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
222 histPath=QDir::convertSeparators (tmpMapDir+"/history");
227 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
229 // tmpdir temporary directory to which data will be written
230 // prefix mapname, which will be appended to images etc.
231 // writeflags Only write flags for "real" save of map, not undo
232 // offset offset of bbox of whole map in scene.
233 // Needed for XML export
239 case LinkableMapObj::Line:
242 case LinkableMapObj::Parabel:
245 case LinkableMapObj::PolyLine:
249 ls="StylePolyParabel";
253 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
255 if (linkcolorhint==LinkableMapObj::HeadingColor)
256 colhint=attribut("linkColorHint","HeadingColor");
258 QString mapAttr=attribut("version",vymVersion);
259 if (!saveSel || saveSel==mapCenter)
260 mapAttr+= attribut("author",mapCenter->getAuthor()) +
261 attribut("comment",mapCenter->getComment()) +
262 attribut("date",mapCenter->getDate()) +
263 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
264 attribut("selectionColor", xelection.getColor().name() ) +
265 attribut("linkStyle", ls ) +
266 attribut("linkColor", defLinkColor.name() ) +
267 attribut("defXLinkColor", defXLinkColor.name() ) +
268 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
270 s+=beginElement("vymmap",mapAttr);
273 // Find the used flags while traversing the tree
274 standardFlagsDefault->resetUsedCounter();
276 // Reset the counters before saving
277 // TODO constr. of FIO creates lots of objects, better do this in some other way...
278 FloatImageObj (mapScene).resetSaveCounter();
280 // Build xml recursivly
281 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
282 // Save complete map, if saveSel not set
283 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
286 if ( typeid(*saveSel) == typeid(BranchObj) )
288 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
289 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
291 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
294 // Save local settings
295 s+=settings.getXMLData (destPath);
298 if (!xelection.isEmpty() && !saveSel )
299 s+=valueElement("select",xelection.getSelectString());
302 s+=endElement("vymmap");
305 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
309 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
313 if (blockSaveState) return;
315 if (debug) cout << "ME::saveState() for "<<mapName.ascii()<<endl;
317 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
318 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
319 int curStep=undoSet.readNumEntry ("/history/curStep",0);
320 // Find out current undo directory
321 if (undosAvail<stepsTotal) undosAvail++;
323 if (curStep>stepsTotal) curStep=1;
325 QString backupXML="";
326 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
327 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
328 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
330 // Create bakMapDir if not available
333 makeSubDirs (bakMapDir);
335 // Save depending on how much needs to be saved
337 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPointF (),saveSel);
339 QString undoCommand="";
340 if (savemode==UndoCommand)
344 else if (savemode==PartOfMap )
347 undoCommand.replace ("PATH",bakMapPath);
350 if (!backupXML.isEmpty())
351 // Write XML Data to disk
352 saveStringToDisk (QString(bakMapPath),backupXML);
354 // We would have to save all actions in a tree, to keep track of
355 // possible redos after a action. Possible, but we are too lazy: forget about redos.
358 // Write the current state to disk
359 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
360 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
361 undoSet.setEntry ("/history/curStep",QString::number(curStep));
362 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
363 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
364 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
365 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
366 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
367 undoSet.setEntry (QString("/history/version"),vymVersion);
368 undoSet.writeSettings(histPath);
372 // TODO remove after testing
373 //cout << " into="<< histPath.toStdString()<<endl;
374 cout << " stepsTotal="<<stepsTotal<<
375 ", undosAvail="<<undosAvail<<
376 ", redosAvail="<<redosAvail<<
377 ", curStep="<<curStep<<endl;
378 cout << " ---------------------------"<<endl;
379 cout << " comment="<<comment.toStdString()<<endl;
380 cout << " undoCom="<<undoCommand.toStdString()<<endl;
381 cout << " undoSel="<<undoSelection.toStdString()<<endl;
382 cout << " redoCom="<<redoCom.toStdString()<<endl;
383 cout << " redoSel="<<redoSelection.toStdString()<<endl;
384 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
385 cout << " ---------------------------"<<endl;
388 mainWindow->updateHistory (undoSet);
394 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
396 // save the selected part of the map, Undo will replace part of map
397 QString undoSelection="";
399 undoSelection=undoSel->getSelectString();
401 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
402 QString redoSelection="";
404 redoSelection=undoSel->getSelectString();
406 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
409 saveState (PartOfMap,
410 undoSelection, "addMapReplace (\"PATH\")",
416 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
420 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
423 QString undoSelection=redoSel->getParObj()->getSelectString();
424 QString redoSelection=redoSel->getSelectString();
425 if (typeid(*redoSel) == typeid(BranchObj) )
427 // save the selected branch of the map, Undo will insert part of map
428 saveState (PartOfMap,
429 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
430 redoSelection, "delete ()",
437 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
439 // "Normal" savestate: save commands, selections and comment
440 // so just save commands for undo and redo
441 // and use current selection
443 QString redoSelection="";
444 if (redoSel) redoSelection=redoSel->getSelectString();
445 QString undoSelection="";
446 if (undoSel) undoSelection=undoSel->getSelectString();
448 saveState (UndoCommand,
455 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
457 // "Normal" savestate: save commands, selections and comment
458 // so just save commands for undo and redo
459 // and use current selection
460 saveState (UndoCommand,
468 void MapEditor::parseAtom(const QString &atom)
470 BranchObj *selb=xelection.getBranch();
475 // Split string s into command and parameters
476 parser.parseAtom (atom);
477 QString com=parser.getCommand();
480 if (com=="addBranch")
482 if (xelection.isEmpty())
484 parser.setError (Aborted,"Nothing selected");
487 parser.setError (Aborted,"Type of selection is not a branch");
492 if (parser.checkParamCount(pl))
494 if (parser.paramCount()==0)
495 addNewBranchInt (-2);
498 y=parser.parInt (ok,0);
499 if (ok ) addNewBranchInt (y);
503 } else if (com=="addBranchBefore")
505 if (xelection.isEmpty())
507 parser.setError (Aborted,"Nothing selected");
510 parser.setError (Aborted,"Type of selection is not a branch");
513 if (parser.paramCount()==0)
515 addNewBranchBefore ();
518 } else if (com==QString("addMapReplace"))
520 if (xelection.isEmpty())
522 parser.setError (Aborted,"Nothing selected");
525 parser.setError (Aborted,"Type of selection is not a branch");
526 } else if (parser.checkParamCount(1))
528 //s=parser.parString (ok,0); // selection
529 t=parser.parString (ok,0); // path to map
530 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
531 addMapReplaceInt(selb->getSelectString(),t);
533 } else if (com==QString("addMapInsert"))
535 if (xelection.isEmpty())
537 parser.setError (Aborted,"Nothing selected");
540 parser.setError (Aborted,"Type of selection is not a branch");
543 if (parser.checkParamCount(2))
545 t=parser.parString (ok,0); // path to map
546 y=parser.parInt(ok,1); // position
547 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
548 addMapInsertInt(t,y);
551 } else if (com=="clearFlags")
553 if (xelection.isEmpty() )
555 parser.setError (Aborted,"Nothing selected");
558 parser.setError (Aborted,"Type of selection is not a branch");
559 } else if (parser.checkParamCount(0))
561 selb->clearStandardFlags();
562 selb->updateFlagsToolbar();
564 } else if (com=="colorBranch")
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(1))
574 QColor c=parser.parColor (ok,0);
575 if (ok) colorBranch (c);
577 } else if (com=="colorSubtree")
579 if (xelection.isEmpty())
581 parser.setError (Aborted,"Nothing selected");
584 parser.setError (Aborted,"Type of selection is not a branch");
585 } else if (parser.checkParamCount(1))
587 QColor c=parser.parColor (ok,0);
588 if (ok) colorSubtree (c);
590 } else if (com=="cut")
592 if (xelection.isEmpty())
594 parser.setError (Aborted,"Nothing selected");
595 } else if ( xelection.type()!=Selection::Branch &&
596 xelection.type()!=Selection::MapCenter &&
597 xelection.type()!=Selection::FloatImage )
599 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
600 } else if (parser.checkParamCount(0))
604 } else if (com=="delete")
606 if (xelection.isEmpty())
608 parser.setError (Aborted,"Nothing selected");
609 } else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage )
611 parser.setError (Aborted,"Type of selection is wrong.");
612 } else if (parser.checkParamCount(0))
616 } else if (com=="deleteKeepChilds")
618 if (xelection.isEmpty())
620 parser.setError (Aborted,"Nothing selected");
623 parser.setError (Aborted,"Type of selection is not a branch");
624 } else if (parser.checkParamCount(0))
628 } else if (com=="deleteChilds")
630 if (xelection.isEmpty())
632 parser.setError (Aborted,"Nothing selected");
635 parser.setError (Aborted,"Type of selection is not a branch");
636 } else if (parser.checkParamCount(0))
640 } else if (com=="importDir")
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) importDirInt(s);
653 } else if (com=="linkTo")
655 if (xelection.isEmpty())
657 parser.setError (Aborted,"Nothing selected");
660 if (parser.checkParamCount(4))
662 // 0 selectstring of parent
663 // 1 num in parent (for branches)
664 // 2,3 x,y of mainbranch or mapcenter
665 s=parser.parString(ok,0);
666 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
669 if (typeid(*dst) == typeid(BranchObj) )
671 // Get number in parent
672 x=parser.parInt (ok,1);
674 selb->linkTo ((BranchObj*)(dst),x);
675 } else if (typeid(*dst) == typeid(MapCenterObj) )
677 selb->linkTo ((BranchObj*)(dst),-1);
678 // Get coordinates of mainbranch
679 x=parser.parInt (ok,2);
682 y=parser.parInt (ok,3);
683 if (ok) selb->move (x,y);
688 } else if ( xelection.type() == Selection::FloatImage)
690 if (parser.checkParamCount(1))
692 // 0 selectstring of parent
693 s=parser.parString(ok,0);
694 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
697 if (typeid(*dst) == typeid(BranchObj) ||
698 typeid(*dst) == typeid(MapCenterObj))
699 linkTo (dst->getSelectString());
701 parser.setError (Aborted,"Destination is not a branch");
704 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
705 } else if (com=="loadImage")
707 if (xelection.isEmpty())
709 parser.setError (Aborted,"Nothing selected");
712 parser.setError (Aborted,"Type of selection is not a branch");
713 } else if (parser.checkParamCount(1))
715 s=parser.parString(ok,0);
716 if (ok) loadFloatImageInt (s);
718 } else if (com=="moveBranchUp")
720 if (xelection.isEmpty() )
722 parser.setError (Aborted,"Nothing selected");
725 parser.setError (Aborted,"Type of selection is not a branch");
726 } else if (parser.checkParamCount(0))
730 } else if (com=="moveBranchDown")
732 if (xelection.isEmpty() )
734 parser.setError (Aborted,"Nothing selected");
737 parser.setError (Aborted,"Type of selection is not a branch");
738 } else if (parser.checkParamCount(0))
742 } else if (com=="move")
744 if (xelection.isEmpty() )
746 parser.setError (Aborted,"Nothing selected");
747 } else if ( xelection.type()!=Selection::Branch &&
748 xelection.type()!=Selection::MapCenter &&
749 xelection.type()!=Selection::FloatImage )
751 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
752 } else if (parser.checkParamCount(2))
754 x=parser.parInt (ok,0);
757 y=parser.parInt (ok,1);
761 } else if (com=="moveRel")
763 if (xelection.isEmpty() )
765 parser.setError (Aborted,"Nothing selected");
766 } else if ( xelection.type()!=Selection::Selection::Branch &&
767 xelection.type()!=Selection::Selection::MapCenter &&
768 xelection.type()!=Selection::Selection::FloatImage )
770 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
771 } else if (parser.checkParamCount(2))
773 x=parser.parInt (ok,0);
776 y=parser.parInt (ok,1);
777 if (ok) moveRel (x,y);
780 } else if (com=="paste")
782 if (xelection.isEmpty() )
784 parser.setError (Aborted,"Nothing selected");
787 parser.setError (Aborted,"Type of selection is not a branch");
788 } else if (parser.checkParamCount(0))
792 } else if (com=="saveImage")
794 FloatImageObj *fio=xelection.getFloatImage();
797 parser.setError (Aborted,"Type of selection is not an image");
798 } else if (parser.checkParamCount(2))
800 s=parser.parString(ok,0);
803 t=parser.parString(ok,1);
804 if (ok) saveFloatImageInt (fio,t,s);
807 } else if (com=="scroll")
809 if (xelection.isEmpty() )
811 parser.setError (Aborted,"Nothing selected");
814 parser.setError (Aborted,"Type of selection is not a branch");
815 } else if (parser.checkParamCount(0))
817 if (!scrollBranch (selb))
818 parser.setError (Aborted,"Could not scroll branch");
820 } else if (com=="select")
822 if (parser.checkParamCount(1))
824 s=parser.parString(ok,0);
827 } else if (com=="selectLastBranch")
829 if (xelection.isEmpty() )
831 parser.setError (Aborted,"Nothing selected");
834 parser.setError (Aborted,"Type of selection is not a branch");
835 } else if (parser.checkParamCount(0))
837 BranchObj *bo=selb->getLastBranch();
839 parser.setError (Aborted,"Could not select last branch");
843 } else if (com=="selectLastImage")
845 if (xelection.isEmpty() )
847 parser.setError (Aborted,"Nothing selected");
850 parser.setError (Aborted,"Type of selection is not a branch");
851 } else if (parser.checkParamCount(0))
853 FloatImageObj *fio=selb->getLastFloatImage();
855 parser.setError (Aborted,"Could not select last image");
859 } else if (com=="setFrameType")
861 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
863 parser.setError (Aborted,"Type of selection does not allow setting frame type");
865 else if (parser.checkParamCount(1))
867 s=parser.parString(ok,0);
868 if (ok) setFrameType (s);
870 } else if (com=="setFramePenColor")
872 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
874 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
876 else if (parser.checkParamCount(1))
878 QColor c=parser.parColor(ok,0);
879 if (ok) setFramePenColor (c);
881 } else if (com=="setFrameBrushColor")
883 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
885 parser.setError (Aborted,"Type of selection does not allow setting brush color");
887 else if (parser.checkParamCount(1))
889 QColor c=parser.parColor(ok,0);
890 if (ok) setFrameBrushColor (c);
892 } else if (com=="setFramePadding")
894 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
896 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
898 else if (parser.checkParamCount(1))
900 x=parser.parInt(ok,0);
901 if (ok) setFramePadding(x);
903 } else if (com=="setFrameBorderWidth")
905 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
907 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
909 else if (parser.checkParamCount(1))
911 x=parser.parInt(ok,0);
912 if (ok) setFrameBorderWidth (x);
914 } else if (com=="setMapAuthor")
916 if (parser.checkParamCount(1))
918 s=parser.parString(ok,0);
919 if (ok) setMapAuthor (s);
921 } else if (com=="setMapComment")
923 if (parser.checkParamCount(1))
925 s=parser.parString(ok,0);
926 if (ok) setMapComment(s);
928 } else if (com=="setMapBackgroundColor")
930 if (xelection.isEmpty() )
932 parser.setError (Aborted,"Nothing selected");
933 } else if (! xelection.getBranch() )
935 parser.setError (Aborted,"Type of selection is not a branch");
936 } else if (parser.checkParamCount(1))
938 QColor c=parser.parColor (ok,0);
939 if (ok) setMapBackgroundColor (c);
941 } else if (com=="setMapDefLinkColor")
943 if (xelection.isEmpty() )
945 parser.setError (Aborted,"Nothing selected");
948 parser.setError (Aborted,"Type of selection is not a branch");
949 } else if (parser.checkParamCount(1))
951 QColor c=parser.parColor (ok,0);
952 if (ok) setMapDefLinkColor (c);
954 } else if (com=="setMapLinkStyle")
956 if (parser.checkParamCount(1))
958 s=parser.parString (ok,0);
959 if (ok) setMapLinkStyle(s);
961 } else if (com=="setHeading")
963 if (xelection.isEmpty() )
965 parser.setError (Aborted,"Nothing selected");
968 parser.setError (Aborted,"Type of selection is not a branch");
969 } else if (parser.checkParamCount(1))
971 s=parser.parString (ok,0);
975 } else if (com=="setHideExport")
977 if (xelection.isEmpty() )
979 parser.setError (Aborted,"Nothing selected");
980 } else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage)
982 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
983 } else if (parser.checkParamCount(1))
985 b=parser.parBool(ok,0);
986 if (ok) setHideExport (b);
988 } else if (com=="setIncludeImagesHorizontally")
990 if (xelection.isEmpty() )
992 parser.setError (Aborted,"Nothing selected");
995 parser.setError (Aborted,"Type of selection is not a branch");
996 } else if (parser.checkParamCount(1))
998 b=parser.parBool(ok,0);
999 if (ok) setIncludeImagesHor(b);
1001 } else if (com=="setIncludeImagesVertically")
1003 if (xelection.isEmpty() )
1005 parser.setError (Aborted,"Nothing selected");
1008 parser.setError (Aborted,"Type of selection is not a branch");
1009 } else if (parser.checkParamCount(1))
1011 b=parser.parBool(ok,0);
1012 if (ok) setIncludeImagesVer(b);
1014 } else if (com=="setHideLinkUnselected")
1016 if (xelection.isEmpty() )
1018 parser.setError (Aborted,"Nothing selected");
1019 } else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1021 parser.setError (Aborted,"Type of selection does not allow hiding the link");
1022 } else if (parser.checkParamCount(1))
1024 b=parser.parBool(ok,0);
1025 if (ok) setHideLinkUnselected(b);
1027 } else if (com=="setSelectionColor")
1029 if (parser.checkParamCount(1))
1031 QColor c=parser.parColor (ok,0);
1032 if (ok) setSelectionColorInt (c);
1034 } else if (com=="setURL")
1036 if (xelection.isEmpty() )
1038 parser.setError (Aborted,"Nothing selected");
1041 parser.setError (Aborted,"Type of selection is not a branch");
1042 } else if (parser.checkParamCount(1))
1044 s=parser.parString (ok,0);
1047 } else if (com=="setVymLink")
1049 if (xelection.isEmpty() )
1051 parser.setError (Aborted,"Nothing selected");
1054 parser.setError (Aborted,"Type of selection is not a branch");
1055 } else if (parser.checkParamCount(1))
1057 s=parser.parString (ok,0);
1058 if (ok) setVymLinkInt(s);
1061 else if (com=="setFlag")
1063 if (xelection.isEmpty() )
1065 parser.setError (Aborted,"Nothing selected");
1068 parser.setError (Aborted,"Type of selection is not a branch");
1069 } else if (parser.checkParamCount(1))
1071 s=parser.parString(ok,0);
1074 selb->activateStandardFlag(s);
1075 selb->updateFlagsToolbar();
1078 } else if (com=="setFrameType")
1080 if (xelection.isEmpty() )
1082 parser.setError (Aborted,"Nothing selected");
1085 parser.setError (Aborted,"Type of selection is not a branch");
1086 } else if (parser.checkParamCount(1))
1088 s=parser.parString(ok,0);
1092 } else if (com=="toggleFlag")
1094 if (xelection.isEmpty() )
1096 parser.setError (Aborted,"Nothing selected");
1099 parser.setError (Aborted,"Type of selection is not a branch");
1100 } else if (parser.checkParamCount(1))
1102 s=parser.parString(ok,0);
1105 selb->toggleStandardFlag(s);
1106 selb->updateFlagsToolbar();
1109 } else if (com=="unscroll")
1111 if (xelection.isEmpty() )
1113 parser.setError (Aborted,"Nothing selected");
1116 parser.setError (Aborted,"Type of selection is not a branch");
1117 } else if (parser.checkParamCount(0))
1119 if (!unscrollBranch (selb))
1120 parser.setError (Aborted,"Could not unscroll branch");
1122 } else if (com=="unscrollChilds")
1124 if (xelection.isEmpty() )
1126 parser.setError (Aborted,"Nothing selected");
1129 parser.setError (Aborted,"Type of selection is not a branch");
1130 } else if (parser.checkParamCount(0))
1134 } else if (com=="unsetFlag")
1136 if (xelection.isEmpty() )
1138 parser.setError (Aborted,"Nothing selected");
1141 parser.setError (Aborted,"Type of selection is not a branch");
1142 } else if (parser.checkParamCount(1))
1144 s=parser.parString(ok,0);
1147 selb->deactivateStandardFlag(s);
1148 selb->updateFlagsToolbar();
1152 parser.setError (Aborted,"Unknown command");
1155 if (parser.errorLevel()==NoError)
1158 mapCenter->reposition();
1162 // TODO Error handling
1163 qWarning("MapEditor::parseAtom: Error!");
1164 qWarning(parser.errorMessage());
1168 void MapEditor::runScript (QString script)
1170 parser.setScript (script);
1172 while (parser.next() )
1173 parseAtom(parser.getAtom());
1176 bool MapEditor::isDefault()
1181 bool MapEditor::hasChanged()
1186 void MapEditor::setChanged()
1189 autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
1197 void MapEditor::closeMap()
1199 // Unselect before disabling the toolbar actions
1200 if (!xelection.isEmpty() ) xelection.unselect();
1208 void MapEditor::setFilePath(QString fpath, QString destname)
1210 if (fpath.isEmpty() || fpath=="")
1217 filePath=fpath; // becomes absolute path
1218 fileName=fpath; // gets stripped of path
1219 destPath=destname; // needed for vymlinks
1221 // If fpath is not an absolute path, complete it
1222 filePath=QDir(fpath).absPath();
1223 fileDir=filePath.left (1+filePath.findRev ("/"));
1225 // Set short name, too. Search from behind:
1226 int i=fileName.findRev("/");
1227 if (i>=0) fileName=fileName.remove (0,i+1);
1229 // Forget the .vym (or .xml) for name of map
1230 mapName=fileName.left(fileName.findRev(".",-1,true) );
1234 void MapEditor::setFilePath(QString fpath)
1236 setFilePath (fpath,fpath);
1239 QString MapEditor::getFilePath()
1244 QString MapEditor::getFileName()
1249 QString MapEditor::getMapName()
1254 QString MapEditor::getDestPath()
1259 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1261 ErrorCode err=success;
1265 if (xelection.isEmpty() ) xelection.unselect();
1268 mapCenter->setMapEditor(this);
1269 // (map state is set later at end of load...)
1272 BranchObj *bo=xelection.getBranch();
1273 if (!bo) return aborted;
1274 if (lmode==ImportAdd)
1275 saveStateChangingPart(
1278 QString("addMapInsert (%1)").arg(fname),
1279 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1281 saveStateChangingPart(
1284 QString("addMapReplace(%1)").arg(fname),
1285 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1289 mapBuilderHandler handler;
1290 QFile file( fname );
1292 // I am paranoid: file should exist anyway
1293 // according to check in mainwindow.
1294 if (!file.exists() )
1296 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1297 tr("Couldn't open map " +fname)+".");
1301 bool blockSaveStateOrg=blockSaveState;
1302 blockReposition=true;
1303 blockSaveState=true;
1304 QXmlInputSource source( file);
1305 QXmlSimpleReader reader;
1306 reader.setContentHandler( &handler );
1307 reader.setErrorHandler( &handler );
1308 handler.setMapEditor( this );
1311 // We need to set the tmpDir in order to load files with rel. path
1312 QString tmpdir= fname.left(fname.findRev("/",-1));
1313 handler.setTmpDir (tmpdir);
1314 handler.setInputFile (file.name());
1315 handler.setLoadMode (lmode);
1316 bool ok = reader.parse( source );
1317 blockReposition=false;
1318 blockSaveState=blockSaveStateOrg;
1322 mapCenter->reposition();
1329 autosaveTimer->stop();
1333 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1334 tr( handler.errorProtocol() ) );
1336 // Still return "success": the map maybe at least
1337 // partially read by the parser
1344 int MapEditor::save (const SaveMode &savemode)
1348 // Create mapName and fileDir
1349 makeSubDirs (fileDir);
1353 fname=mapName+".xml";
1355 // use name given by user, even if he chooses .doc
1360 if (savemode==CompleteMap || xelection.isEmpty())
1361 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1364 // TODO take care of multiselections
1365 if (xelection.type()==Selection::FloatImage)
1368 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());
1371 if (!saveStringToDisk(fileDir+fname,saveFile))
1378 autosaveTimer->stop();
1385 void MapEditor::setZipped (bool z)
1390 bool MapEditor::saveZipped ()
1395 void MapEditor::print()
1399 printer = new QPrinter;
1400 printer->setColorMode (QPrinter::Color);
1401 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1402 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1403 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1406 QRectF totalBBox=mapCenter->getTotalBBox();
1408 // Try to set orientation automagically
1409 // Note: Interpretation of generated postscript is amibiguous, if
1410 // there are problems with landscape mode, see
1411 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1413 if (totalBBox.width()>totalBBox.height())
1414 // recommend landscape
1415 printer->setOrientation (QPrinter::Landscape);
1417 // recommend portrait
1418 printer->setOrientation (QPrinter::Portrait);
1420 if ( printer->setup(this) )
1421 // returns false, if printing is canceled
1423 QPainter pp(printer);
1425 pp.setRenderHint(QPainter::Antialiasing,true);
1427 // Don't print the visualisation of selection
1428 xelection.unselect();
1430 QRectF mapRect=totalBBox;
1431 QGraphicsRectItem *frame=NULL;
1435 // Print frame around map
1436 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1437 totalBBox.width()+20, totalBBox.height()+20);
1438 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1439 frame->setZValue(0);
1444 double paperAspect = (double)printer->width() / (double)printer->height();
1445 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1447 if (mapAspect>=paperAspect)
1449 // Fit horizontally to paper width
1450 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1451 viewBottom=(int)(printer->width()/mapAspect);
1454 // Fit vertically to paper height
1455 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1456 viewBottom=printer->height();
1461 // Print footer below map
1463 font.setPointSize(10);
1465 QRectF footerBox(0,viewBottom,printer->width(),15);
1466 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1467 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1471 QRectF (0,0,printer->width(),printer->height()-15),
1472 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1475 // Viewport has paper dimension
1476 if (frame) delete (frame);
1478 // Restore selection
1479 xelection.reselect();
1481 // Save settings in vymrc
1482 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1483 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1484 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1488 void MapEditor::setAntiAlias (bool b)
1490 setRenderHint(QPainter::Antialiasing,b);
1493 void MapEditor::setSmoothPixmap(bool b)
1495 setRenderHint(QPainter::SmoothPixmapTransform,b);
1498 QPixmap MapEditor::getPixmap()
1500 QRectF mapRect=mapCenter->getTotalBBox();
1501 QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+2);
1504 pp.setRenderHints(renderHints());
1506 // Don't print the visualisation of selection
1507 xelection.unselect();
1509 mapScene->render ( &pp,
1510 QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1511 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1513 // Restore selection
1514 xelection.reselect();
1519 void MapEditor::setHideTmpMode (BranchObj::HideTmpMode mode)
1522 mapCenter->setHideTmp (hidemode);
1523 mapCenter->reposition();
1527 BranchObj::HideTmpMode MapEditor::getHideTmpMode()
1532 void MapEditor::exportImage(QString fn)
1534 setExportMode (true);
1535 QPixmap pix (getPixmap());
1536 pix.save(fn, "PNG");
1537 setExportMode (false);
1540 void MapEditor::setExportMode (bool b)
1542 // should be called before and after exports
1543 // depending on the settings
1544 if (b && settings.value("/export/useHideExport","yes")=="yes")
1545 setHideTmpMode (BranchObj::HideExport);
1547 setHideTmpMode (BranchObj::HideNone);
1550 void MapEditor::exportImage(QString fn, QString format)
1552 setExportMode (true);
1553 QPixmap pix (getPixmap());
1554 pix.save(fn, format);
1555 setExportMode (false);
1558 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1562 ex.setMapCenter(mapCenter);
1563 if (ex.setConfigFile(cf))
1565 setExportMode (true);
1566 ex.exportPresentation();
1567 setExportMode (false);
1573 void MapEditor::exportXML(const QString &dir)
1575 // Hide stuff during export, if settings want this
1576 setExportMode (true);
1578 // Create subdirectories
1581 // write to directory
1582 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1585 file.setName ( dir + "/"+mapName+".xml");
1586 if ( !file.open( QIODevice::WriteOnly ) )
1588 // This should neverever happen
1589 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1593 // Write it finally, and write in UTF8, no matter what
1594 QTextStream ts( &file );
1595 ts.setEncoding (QTextStream::UnicodeUTF8);
1599 // Now write image, too
1600 exportImage (dir+"/images/"+mapName+".png");
1602 setExportMode (false);
1605 void MapEditor::clear()
1607 xelection.unselect();
1611 void MapEditor::copy()
1613 LinkableMapObj *sel=xelection.single();
1616 // write to directory
1617 QString saveFile=saveToDir (clipboardDir,clipboardFile+"-",true,QPointF(),sel ); // FIXME check FIO
1620 file.setName ( clipboardDir + "/"+clipboardFile);
1621 if ( !file.open( QIODevice::WriteOnly ) )
1623 // This should neverever happen
1624 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1628 // Write it finally, and write in UTF8, no matter what
1629 QTextStream ts( &file );
1630 ts.setEncoding (QTextStream::UnicodeUTF8);
1634 clipboardEmpty=false;
1639 void MapEditor::redo()
1641 // Restore variables
1642 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1643 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1644 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1645 // Can we undo at all?
1646 if (redosAvail<1) return;
1648 bool blockSaveStateOrg=blockSaveState;
1649 blockSaveState=true;
1653 if (undosAvail<stepsTotal) undosAvail++;
1655 if (curStep>stepsTotal) curStep=1;
1656 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1657 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1658 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1659 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1660 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1661 QString version=undoSet.readEntry ("/history/version");
1663 if (!checkVersion(version))
1664 QMessageBox::warning(0,tr("Warning"),
1665 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1668 // Find out current undo directory
1669 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1673 cout << "ME::redo() begin\n";
1674 cout << " undosAvail="<<undosAvail<<endl;
1675 cout << " redosAvail="<<redosAvail<<endl;
1676 cout << " curStep="<<curStep<<endl;
1677 cout << " ---------------------------"<<endl;
1678 cout << " comment="<<comment.toStdString()<<endl;
1679 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1680 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1681 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1682 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1683 cout << " ---------------------------"<<endl<<endl;
1686 // select object before redo
1687 if (!redoSelection.isEmpty())
1688 select (redoSelection);
1691 parseAtom (redoCommand);
1692 mapCenter->reposition();
1694 blockSaveState=blockSaveStateOrg;
1696 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1697 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1698 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1699 undoSet.writeSettings(histPath);
1701 mainWindow->updateHistory (undoSet);
1704 /* TODO remove testing
1705 cout << "ME::redo() end\n";
1706 cout << " undosAvail="<<undosAvail<<endl;
1707 cout << " redosAvail="<<redosAvail<<endl;
1708 cout << " curStep="<<curStep<<endl;
1709 cout << " ---------------------------"<<endl<<endl;
1715 bool MapEditor::isRedoAvailable()
1717 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1723 void MapEditor::undo()
1725 // Restore variables
1726 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1727 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1728 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1730 // Can we undo at all?
1731 if (undosAvail<1) return;
1733 bool blockSaveStateOrg=blockSaveState;
1734 blockSaveState=true;
1736 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1737 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1738 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1739 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1740 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1741 QString version=undoSet.readEntry ("/history/version");
1743 if (!checkVersion(version))
1744 QMessageBox::warning(0,tr("Warning"),
1745 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1747 // Find out current undo directory
1748 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1750 // select object before undo
1751 if (!undoSelection.isEmpty())
1752 select (undoSelection);
1756 cout << "ME::undo() begin\n";
1757 cout << " undosAvail="<<undosAvail<<endl;
1758 cout << " redosAvail="<<redosAvail<<endl;
1759 cout << " curStep="<<curStep<<endl;
1760 cout << " ---------------------------"<<endl;
1761 cout << " comment="<<comment.toStdString()<<endl;
1762 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1763 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1764 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1765 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1766 cout << " ---------------------------"<<endl<<endl;
1768 parseAtom (undoCommand);
1769 mapCenter->reposition();
1773 if (curStep<1) curStep=stepsTotal;
1777 blockSaveState=blockSaveStateOrg;
1778 /* TODO remove testing
1779 cout << "ME::undo() end\n";
1780 cout << " undosAvail="<<undosAvail<<endl;
1781 cout << " redosAvail="<<redosAvail<<endl;
1782 cout << " curStep="<<curStep<<endl;
1783 cout << " ---------------------------"<<endl<<endl;
1786 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1787 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1788 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1789 undoSet.writeSettings(histPath);
1791 mainWindow->updateHistory (undoSet);
1794 ensureSelectionVisible();
1797 bool MapEditor::isUndoAvailable()
1799 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1805 void MapEditor::gotoHistoryStep (int i)
1807 // Restore variables
1808 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1809 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1811 if (i<0) i=undosAvail+redosAvail;
1813 // Clicking above current step makes us undo things
1816 for (int j=0; j<undosAvail-i; j++) undo();
1819 // Clicking below current step makes us redo things
1821 for (int j=undosAvail; j<i; j++)
1823 cout << "redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
1827 // And ignore clicking the current row ;-)
1830 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1832 QString pathDir=path.left(path.findRev("/"));
1838 // We need to parse saved XML data
1839 mapBuilderHandler handler;
1840 QXmlInputSource source( file);
1841 QXmlSimpleReader reader;
1842 reader.setContentHandler( &handler );
1843 reader.setErrorHandler( &handler );
1844 handler.setMapEditor( this );
1845 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1846 if (undoSel.isEmpty())
1850 handler.setLoadMode (NewMap);
1854 handler.setLoadMode (ImportReplace);
1856 blockReposition=true;
1857 bool ok = reader.parse( source );
1858 blockReposition=false;
1861 // This should never ever happen
1862 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1863 handler.errorProtocol());
1866 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1869 void MapEditor::addMapInsertInt (const QString &path, int pos)
1871 BranchObj *sel=xelection.getBranch();
1874 QString pathDir=path.left(path.findRev("/"));
1880 // We need to parse saved XML data
1881 mapBuilderHandler handler;
1882 QXmlInputSource source( file);
1883 QXmlSimpleReader reader;
1884 reader.setContentHandler( &handler );
1885 reader.setErrorHandler( &handler );
1886 handler.setMapEditor( this );
1887 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1888 handler.setLoadMode (ImportAdd);
1889 blockReposition=true;
1890 bool ok = reader.parse( source );
1891 blockReposition=false;
1894 // This should never ever happen
1895 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1896 handler.errorProtocol());
1899 sel->getLastBranch()->linkTo (sel,pos);
1901 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1905 void MapEditor::pasteNoSave()
1907 bool old=blockSaveState;
1908 blockSaveState=true;
1909 load (clipboardDir+"/"+clipboardFile,ImportAdd);
1913 void MapEditor::paste() // FIXME no pasting of FIO ???
1915 BranchObj *sel=xelection.getBranch();
1918 saveStateChangingPart(
1922 QString("Paste to %1").arg( getName(sel))
1925 mapCenter->reposition();
1929 void MapEditor::cut()
1931 LinkableMapObj *sel=xelection.single();
1932 if ( sel && (xelection.type() == Selection::Branch ||
1933 xelection.type()==Selection::MapCenter ||
1934 xelection.type()==Selection::FloatImage))
1936 /* No savestate! savestate is called in cutNoSave
1937 saveStateChangingPart(
1941 QString("Cut %1").arg(getName(sel ))
1946 mapCenter->reposition();
1950 void MapEditor::move(const int &x, const int &y)
1952 LinkableMapObj *sel=xelection.single();
1955 QString ps=qpointfToString (sel->getAbsPos());
1956 QString s=xelection.single()->getSelectString();
1959 s, "move "+qpointfToString (QPointF (x,y)),
1960 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
1962 mapCenter->reposition();
1968 void MapEditor::moveRel (const int &x, const int &y)
1970 LinkableMapObj *sel=xelection.single();
1973 QString ps=qpointfToString (sel->getRelPos());
1974 QString s=sel->getSelectString();
1977 s, "moveRel "+qpointfToString (QPointF (x,y)),
1978 QString("Move %1 to relativ position %2").arg(getName(sel)).arg(ps));
1979 ((OrnamentedObj*)sel)->move2RelPos (x,y);
1980 mapCenter->reposition();
1986 void MapEditor::moveBranchUp()
1988 BranchObj* bo=xelection.getBranch();
1992 if (!bo->canMoveBranchUp()) return;
1993 par=(BranchObj*)(bo->getParObj());
1994 BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
1995 saveState (bo->getSelectString(),"moveBranchDown ()",obo->getSelectString(),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1996 mapCenter->reposition();
1999 ensureSelectionVisible();
2003 void MapEditor::moveBranchDown()
2005 BranchObj* bo=xelection.getBranch();
2009 if (!bo->canMoveBranchDown()) return;
2010 par=(BranchObj*)(bo->getParObj());
2011 BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
2012 saveState(bo->getSelectString(),"moveBranchUp ()",obo->getSelectString(),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
2013 mapCenter->reposition();
2016 ensureSelectionVisible();
2020 void MapEditor::linkTo(const QString &dstString)
2022 FloatImageObj *fio=xelection.getFloatImage();
2025 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
2026 if (dst && (typeid(*dst)==typeid (BranchObj) ||
2027 typeid(*dst)==typeid (MapCenterObj)))
2029 LinkableMapObj *dstPar=dst->getParObj();
2030 QString parString=dstPar->getSelectString();
2031 QString fioPreSelectString=fio->getSelectString();
2032 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
2033 ((BranchObj*)(dst))->addFloatImage (fio);
2034 xelection.unselect();
2035 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
2036 fio=((BranchObj*)(dst))->getLastFloatImage();
2039 xelection.select(fio);
2041 fio->getSelectString(),
2042 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
2044 QString ("linkTo (\"%1\")").arg(dstString),
2045 QString ("Link floatimage to %1").arg(getName(dst)));
2050 QString MapEditor::getHeading(bool &ok, QPoint &p)
2052 BranchObj *bo=xelection.getBranch();
2056 p=mapFromScene(bo->getAbsPos());
2057 return bo->getHeading();
2063 void MapEditor::setHeading(const QString &s)
2065 BranchObj *sel=xelection.getBranch();
2070 "setHeading (\""+sel->getHeading()+"\")",
2072 "setHeading (\""+s+"\")",
2073 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
2074 sel->setHeading(s );
2075 mapCenter->reposition();
2077 ensureSelectionVisible();
2081 void MapEditor::setHeadingInt(const QString &s)
2083 BranchObj *bo=xelection.getBranch();
2087 mapCenter->reposition();
2089 ensureSelectionVisible();
2093 void MapEditor::setVymLinkInt (const QString &s)
2095 // Internal function, no saveState needed
2096 BranchObj *bo=xelection.getBranch();
2100 mapCenter->reposition();
2103 ensureSelectionVisible();
2107 BranchObj* MapEditor::addNewBranchInt(int num)
2109 // Depending on pos:
2110 // -3 insert in childs of parent above selection
2111 // -2 add branch to selection
2112 // -1 insert in childs of parent below selection
2113 // 0..n insert in childs of parent at pos
2114 BranchObj *newbo=NULL;
2115 BranchObj *bo=xelection.getBranch();
2120 // save scroll state. If scrolled, automatically select
2121 // new branch in order to tmp unscroll parent...
2122 return bo->addBranch();
2127 bo=(BranchObj*)bo->getParObj();
2131 bo=(BranchObj*)bo->getParObj();
2134 newbo=bo->insertBranch(num);
2139 BranchObj* MapEditor::addNewBranch(int pos)
2141 // Different meaning than num in addNewBranchInt!
2145 BranchObj *bo = xelection.getBranch();
2146 BranchObj *newbo=NULL;
2150 setCursor (Qt::ArrowCursor);
2152 newbo=addNewBranchInt (pos-2);
2160 QString ("addBranch (%1)").arg(pos-2),
2161 QString ("Add new branch to %1").arg(getName(bo)));
2163 mapCenter->reposition();
2171 BranchObj* MapEditor::addNewBranchBefore()
2173 BranchObj *newbo=NULL;
2174 BranchObj *bo = xelection.getBranch();
2175 if (bo && xelection.type()==Selection::Branch)
2176 // We accept no MapCenterObj here, so we _have_ a parent
2178 QPointF p=bo->getRelPos();
2181 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2183 // add below selection
2184 newbo=parbo->insertBranch(bo->getNum()+1);
2187 newbo->move2RelPos (p);
2189 // Move selection to new branch
2190 bo->linkTo (newbo,-1);
2192 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2193 QString ("Add branch before %1").arg(getName(bo)));
2195 mapCenter->reposition();
2202 void MapEditor::deleteSelection()
2204 BranchObj *bo = xelection.getBranch();
2205 if (bo && xelection.type()==Selection::Branch)
2207 BranchObj* par=(BranchObj*)(bo->getParObj());
2208 xelection.unselect();
2209 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2210 par->removeBranch(bo);
2211 xelection.select (par);
2212 ensureSelectionVisible();
2213 mapCenter->reposition();
2218 FloatImageObj *fio=xelection.getFloatImage();
2221 BranchObj* par=(BranchObj*)(fio->getParObj());
2222 saveStateChangingPart(
2226 QString("Delete %1").arg(getName(fio))
2228 xelection.unselect();
2229 par->removeFloatImage(fio);
2230 xelection.select (par);
2231 mapCenter->reposition();
2233 ensureSelectionVisible();
2238 LinkableMapObj* MapEditor::getSelection()
2240 return xelection.single();
2243 BranchObj* MapEditor::getSelectedBranch()
2245 return xelection.getBranch();
2248 FloatImageObj* MapEditor::getSelectedFloatImage()
2250 return xelection.getFloatImage();
2253 void MapEditor::unselect()
2255 xelection.unselect();
2258 void MapEditor::reselect()
2260 xelection.reselect();
2263 bool MapEditor::select (const QString &s)
2265 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2267 // Finally select the found object
2270 xelection.unselect();
2271 xelection.select(lmo);
2273 ensureSelectionVisible();
2279 QString MapEditor::getSelectString()
2281 return xelection.getSelectString();
2284 void MapEditor::selectInt (LinkableMapObj *lmo)
2286 if (lmo && xelection.single()!= lmo && isSelectBlocked()==false )
2288 xelection.select(lmo);
2293 void MapEditor::selectNextBranchInt()
2295 // Increase number of branch
2296 LinkableMapObj *sel=xelection.single();
2299 QString s=sel->getSelectString();
2305 part=s.section(",",-1);
2307 num=part.right(part.length() - 3);
2309 s=s.left (s.length() -num.length());
2312 num=QString ("%1").arg(num.toUInt()+1);
2316 // Try to select this one
2317 if (select (s)) return;
2319 // We have no direct successor,
2320 // try to increase the parental number in order to
2321 // find a successor with same depth
2323 int d=xelection.single()->getDepth();
2328 while (!found && d>0)
2330 s=s.section (",",0,d-1);
2331 // replace substring of current depth in s with "1"
2332 part=s.section(",",-1);
2334 num=part.right(part.length() - 3);
2338 // increase number of parent
2339 num=QString ("%1").arg(num.toUInt()+1);
2340 s=s.section (",",0,d-2) + ","+ typ+num;
2343 // Special case, look at orientation
2344 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2345 num=QString ("%1").arg(num.toUInt()+1);
2347 num=QString ("%1").arg(num.toUInt()-1);
2352 // pad to oldDepth, select the first branch for each depth
2353 for (i=d;i<oldDepth;i++)
2358 if ( xelection.getBranch()->countBranches()>0)
2366 // try to select the freshly built string
2374 void MapEditor::selectPrevBranchInt()
2376 // Decrease number of branch
2377 BranchObj *bo=xelection.getBranch();
2380 QString s=bo->getSelectString();
2386 part=s.section(",",-1);
2388 num=part.right(part.length() - 3);
2390 s=s.left (s.length() -num.length());
2392 int n=num.toInt()-1;
2395 num=QString ("%1").arg(n);
2398 // Try to select this one
2399 if (n>=0 && select (s)) return;
2401 // We have no direct precessor,
2402 // try to decrease the parental number in order to
2403 // find a precessor with same depth
2405 int d=xelection.single()->getDepth();
2410 while (!found && d>0)
2412 s=s.section (",",0,d-1);
2413 // replace substring of current depth in s with "1"
2414 part=s.section(",",-1);
2416 num=part.right(part.length() - 3);
2420 // decrease number of parent
2421 num=QString ("%1").arg(num.toInt()-1);
2422 s=s.section (",",0,d-2) + ","+ typ+num;
2425 // Special case, look at orientation
2426 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2427 num=QString ("%1").arg(num.toInt()-1);
2429 num=QString ("%1").arg(num.toInt()+1);
2434 // pad to oldDepth, select the last branch for each depth
2435 for (i=d;i<oldDepth;i++)
2439 if ( xelection.getBranch()->countBranches()>0)
2440 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2447 // try to select the freshly built string
2455 void MapEditor::selectUpperBranch()
2457 if (isSelectBlocked() ) return;
2459 BranchObj *bo=xelection.getBranch();
2460 if (bo && xelection.type()==Selection::Branch)
2462 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2463 selectPrevBranchInt();
2465 if (bo->getDepth()==1)
2466 selectNextBranchInt();
2468 selectPrevBranchInt();
2472 void MapEditor::selectLowerBranch()
2474 if (isSelectBlocked() ) return;
2476 BranchObj *bo=xelection.getBranch();
2477 if (bo && xelection.type()==Selection::Branch)
2478 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2479 selectNextBranchInt();
2481 if (bo->getDepth()==1)
2482 selectPrevBranchInt();
2484 selectNextBranchInt();
2488 void MapEditor::selectLeftBranch()
2490 if (isSelectBlocked() ) return;
2494 LinkableMapObj *sel=xelection.single();
2497 if (xelection.type()== Selection::MapCenter)
2499 par=xelection.getBranch();
2500 bo=par->getLastSelectedBranch();
2503 // Workaround for reselecting on left and right side
2504 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2505 bo=par->getLastBranch();
2508 bo=par->getLastBranch();
2509 xelection.select(bo);
2511 ensureSelectionVisible();
2516 par=(BranchObj*)(sel->getParObj());
2517 if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
2519 if (xelection.type() == Selection::Branch ||
2520 xelection.type() == Selection::FloatImage)
2522 xelection.select(par);
2524 ensureSelectionVisible();
2528 if (xelection.type() == Selection::Branch )
2530 bo=xelection.getBranch()->getLastSelectedBranch();
2533 xelection.select(bo);
2535 ensureSelectionVisible();
2543 void MapEditor::selectRightBranch()
2545 if (isSelectBlocked() ) return;
2549 LinkableMapObj *sel=xelection.single();
2552 if (xelection.type()==Selection::MapCenter)
2554 par=xelection.getBranch();
2555 bo=par->getLastSelectedBranch();
2558 // Workaround for reselecting on left and right side
2559 if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
2560 bo=par->getFirstBranch();
2563 xelection.select(bo);
2565 ensureSelectionVisible();
2570 par=(BranchObj*)(xelection.single()->getParObj());
2571 if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
2573 if (xelection.type() == Selection::Branch ||
2574 xelection.type() == Selection::FloatImage)
2576 xelection.select(par);
2578 ensureSelectionVisible();
2582 if (xelection.type() == Selection::Branch)
2584 bo=xelection.getBranch()->getLastSelectedBranch();
2587 xelection.select(bo);
2589 ensureSelectionVisible();
2597 void MapEditor::selectFirstBranch()
2599 BranchObj *bo1=xelection.getBranch();
2604 par=(BranchObj*)(bo1->getParObj());
2605 bo2=par->getFirstBranch();
2607 xelection.select(bo2);
2609 ensureSelectionVisible();
2614 void MapEditor::selectLastBranch()
2616 BranchObj *bo1=xelection.getBranch();
2621 par=(BranchObj*)(bo1->getParObj());
2622 bo2=par->getLastBranch();
2625 xelection.select(bo2);
2627 ensureSelectionVisible();
2632 void MapEditor::selectMapBackgroundImage ()
2634 Q3FileDialog *fd=new Q3FileDialog( this);
2635 fd->setMode (Q3FileDialog::ExistingFile);
2636 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2637 ImagePreview *p =new ImagePreview (fd);
2638 fd->setContentsPreviewEnabled( TRUE );
2639 fd->setContentsPreview( p, p );
2640 fd->setPreviewMode( Q3FileDialog::Contents );
2641 fd->setCaption(vymName+" - " +tr("Load background image"));
2642 fd->setDir (lastImageDir);
2645 if ( fd->exec() == QDialog::Accepted )
2647 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2648 lastImageDir=QDir (fd->dirPath());
2649 setMapBackgroundImage (fd->selectedFile());
2653 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
2655 QColor oldcol=mapScene->backgroundBrush().color();
2659 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2661 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2662 QString("Set background color of map to %1").arg(col.name()));
2665 brush.setTextureImage (QPixmap (fn));
2666 mapScene->setBackgroundBrush(brush);
2669 void MapEditor::selectMapBackgroundColor()
2671 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2672 if ( !col.isValid() ) return;
2673 setMapBackgroundColor( col );
2677 void MapEditor::setMapBackgroundColor(QColor col)
2679 QColor oldcol=mapScene->backgroundBrush().color();
2682 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
2684 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
2685 QString("Set background color of map to %1").arg(col.name()));
2686 mapScene->setBackgroundBrush(col);
2689 QColor MapEditor::getMapBackgroundColor()
2691 return mapScene->backgroundBrush().color();
2694 QColor MapEditor::getCurrentHeadingColor()
2696 BranchObj *bo=xelection.getBranch();
2697 if (bo) return bo->getColor();
2699 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2703 void MapEditor::colorBranch (QColor c)
2705 BranchObj *bo=xelection.getBranch();
2710 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
2712 QString ("colorBranch (\"%1\")").arg(c.name()),
2713 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2715 bo->setColor(c); // color branch
2719 void MapEditor::colorSubtree (QColor c)
2721 BranchObj *bo=xelection.getBranch();
2724 saveStateChangingPart(
2727 QString ("colorSubtree (\"%1\")").arg(c.name()),
2728 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2730 bo->setColorSubtree (c); // color links, color childs
2735 void MapEditor::toggleStandardFlag(QString f)
2737 BranchObj *bo=xelection.getBranch();
2741 if (bo->isSetStandardFlag(f))
2753 QString("%1 (\"%2\")").arg(u).arg(f),
2755 QString("%1 (\"%2\")").arg(r).arg(f),
2756 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2757 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2763 BranchObj* MapEditor::findText (QString s, bool cs)
2765 QTextDocument::FindFlags flags=0;
2766 if (cs) flags=QTextDocument::FindCaseSensitively;
2769 { // Nothing found or new find process
2771 // nothing found, start again
2773 itFind=mapCenter->first();
2775 bool searching=true;
2776 bool foundNote=false;
2777 while (searching && !EOFind)
2781 // Searching in Note
2782 if (itFind->getNote().contains(s,cs))
2784 if (xelection.single()!=itFind)
2786 xelection.select(itFind);
2787 ensureSelectionVisible();
2789 if (textEditor->findText(s,flags))
2795 // Searching in Heading
2796 if (searching && itFind->getHeading().contains (s,cs) )
2798 xelection.select(itFind);
2799 ensureSelectionVisible();
2805 itFind=itFind->next();
2806 if (!itFind) EOFind=true;
2810 return xelection.getBranch();
2815 void MapEditor::findReset()
2816 { // Necessary if text to find changes during a find process
2820 void MapEditor::setURL(const QString &url)
2822 BranchObj *bo=xelection.getBranch();
2825 QString oldurl=bo->getURL();
2829 QString ("setURL (\"%1\")").arg(oldurl),
2831 QString ("setURL (\"%1\")").arg(url),
2832 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2835 mapCenter->reposition();
2837 ensureSelectionVisible();
2841 void MapEditor::editURL()
2843 BranchObj *bo=xelection.getBranch();
2847 QString text = QInputDialog::getText(
2848 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2849 bo->getURL(), &ok, this );
2851 // user entered something and pressed OK
2856 QString MapEditor::getURL()
2858 BranchObj *bo=xelection.getBranch();
2860 return bo->getURL();
2865 QStringList MapEditor::getURLs()
2868 BranchObj *bo=xelection.getBranch();
2874 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2882 void MapEditor::editHeading2URL()
2884 BranchObj *bo=xelection.getBranch();
2886 setURL (bo->getHeading());
2889 void MapEditor::editBugzilla2URL()
2891 BranchObj *bo=xelection.getBranch();
2894 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2899 void MapEditor::editFATE2URL()
2901 BranchObj *bo=xelection.getBranch();
2904 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2907 "setURL (\""+bo->getURL()+"\")",
2909 "setURL (\""+url+"\")",
2910 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2917 void MapEditor::editVymLink()
2919 BranchObj *bo=xelection.getBranch();
2922 QStringList filters;
2923 filters <<"VYM map (*.vym)";
2924 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2925 fd->setFilters (filters);
2926 fd->setCaption(vymName+" - " +tr("Link to another map"));
2927 fd->setDirectory (lastFileDir);
2928 if (! bo->getVymLink().isEmpty() )
2929 fd->selectFile( bo->getVymLink() );
2933 if ( fd->exec() == QDialog::Accepted )
2935 lastFileDir=QDir (fd->directory().path());
2938 "setVymLink (\""+bo->getVymLink()+"\")",
2940 "setVymLink (\""+fd->selectedFile()+"\")",
2941 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2943 setVymLinkInt (fd->selectedFile() );
2948 void MapEditor::deleteVymLink()
2950 BranchObj *bo=xelection.getBranch();
2955 "setVymLink (\""+bo->getVymLink()+"\")",
2957 "setVymLink (\"\")",
2958 QString("Unset vymlink of %1").arg(getName(bo))
2960 bo->setVymLink ("" );
2962 mapCenter->reposition();
2967 void MapEditor::setHideExport(bool b)
2969 BranchObj *bo=xelection.getBranch();
2972 bo->setHideInExport (b);
2973 QString u= b ? "false" : "true";
2974 QString r=!b ? "false" : "true";
2978 QString ("setHideExport (%1)").arg(u),
2980 QString ("setHideExport (%1)").arg(r),
2981 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
2984 mapCenter->reposition();
2990 void MapEditor::toggleHideExport()
2992 BranchObj *bo=xelection.getBranch();
2994 setHideExport ( !bo->hideInExport() );
2997 QString MapEditor::getVymLink()
2999 BranchObj *bo=xelection.getBranch();
3001 return bo->getVymLink();
3007 QStringList MapEditor::getVymLinks()
3010 BranchObj *bo=xelection.getBranch();
3016 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
3024 void MapEditor::deleteKeepChilds()
3026 BranchObj *bo=xelection.getBranch();
3030 par=(BranchObj*)(bo->getParObj());
3031 QPointF p=bo->getRelPos();
3032 saveStateChangingPart(
3035 "deleteKeepChilds ()",
3036 QString("Remove %1 and keep its childs").arg(getName(bo))
3039 QString sel=bo->getSelectString();
3041 par->removeBranchHere(bo);
3042 mapCenter->reposition();
3044 xelection.getBranch()->move2RelPos (p);
3045 mapCenter->reposition();
3049 void MapEditor::deleteChilds()
3051 BranchObj *bo=xelection.getBranch();
3054 saveStateChangingPart(
3058 QString( "Remove childs of branch %1").arg(getName(bo))
3061 mapCenter->reposition();
3065 void MapEditor::editMapInfo()
3067 ExtraInfoDialog dia;
3068 dia.setMapName (getFileName() );
3069 dia.setAuthor (mapCenter->getAuthor() );
3070 dia.setComment(mapCenter->getComment() );
3074 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
3081 bo=mapCenter->first();
3084 if (!bo->getNote().isEmpty() ) n++;
3085 f+= bo->countFloatImages();
3087 xl+=bo->countXLinks();
3090 stats+=QString ("%1 branches\n").arg (b-1,6);
3091 stats+=QString ("%1 xLinks \n").arg (xl,6);
3092 stats+=QString ("%1 notes\n").arg (n,6);
3093 stats+=QString ("%1 images\n").arg (f,6);
3094 dia.setStats (stats);
3096 // Finally show dialog
3097 if (dia.exec() == QDialog::Accepted)
3099 setMapAuthor (dia.getAuthor() );
3100 setMapComment (dia.getComment() );
3104 void MapEditor::ensureSelectionVisible()
3106 LinkableMapObj *lmo=xelection.single();
3107 if (lmo) ensureVisible (lmo->getBBox() );
3111 void MapEditor::updateSelection()
3113 // Tell selection to update geometries
3117 void MapEditor::updateActions()
3119 // Tell mainwindow to update states of actions
3120 mainWindow->updateActions();
3121 // TODO maybe don't update if blockReposition is set
3124 void MapEditor::updateNoteFlag()
3127 BranchObj *bo=xelection.getBranch();
3130 bo->updateNoteFlag();
3131 mainWindow->updateActions();
3135 void MapEditor::setMapAuthor (const QString &s)
3139 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3141 QString ("setMapAuthor (\"%1\")").arg(s),
3142 QString ("Set author of map to \"%1\"").arg(s)
3144 mapCenter->setAuthor (s);
3147 void MapEditor::setMapComment (const QString &s)
3151 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3153 QString ("setMapComment (\"%1\")").arg(s),
3154 QString ("Set comment of map")
3156 mapCenter->setComment (s);
3159 void MapEditor::setMapLinkStyle (const QString & s)
3161 saveStateChangingPart (
3164 QString("setMapLinkStyle (\"%1\")").arg(s),
3165 QString("Set map link style (\"%1\")").arg(s)
3169 linkstyle=LinkableMapObj::Line;
3170 else if (s=="StyleParabel")
3171 linkstyle=LinkableMapObj::Parabel;
3172 else if (s=="StylePolyLine")
3173 linkstyle=LinkableMapObj::PolyLine;
3175 linkstyle=LinkableMapObj::PolyParabel;
3178 bo=mapCenter->first();
3182 bo->setLinkStyle(bo->getDefLinkStyle());
3185 mapCenter->reposition();
3188 LinkableMapObj::Style MapEditor::getMapLinkStyle ()
3193 void MapEditor::setMapDefLinkColor(QColor c)
3199 void MapEditor::setMapLinkColorHintInt()
3201 // called from setMapLinkColorHint(lch) or at end of parse
3203 bo=mapCenter->first();
3211 void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
3214 setMapLinkColorHintInt();
3217 void MapEditor::toggleMapLinkColorHint()
3219 if (linkcolorhint==LinkableMapObj::HeadingColor)
3220 linkcolorhint=LinkableMapObj::DefaultColor;
3222 linkcolorhint=LinkableMapObj::HeadingColor;
3224 bo=mapCenter->first();
3232 LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
3234 return linkcolorhint;
3237 QColor MapEditor::getMapDefLinkColor()
3239 return defLinkColor;
3242 void MapEditor::setMapDefXLinkColor(QColor col)
3247 QColor MapEditor::getMapDefXLinkColor()
3249 return defXLinkColor;
3252 void MapEditor::setMapDefXLinkWidth (int w)
3257 int MapEditor::getMapDefXLinkWidth()
3259 return defXLinkWidth;
3262 void MapEditor::selectMapLinkColor()
3264 QColor col = QColorDialog::getColor( defLinkColor, this );
3265 if ( !col.isValid() ) return;
3268 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3270 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3271 QString("Set link color to %1").arg(col.name())
3273 setMapDefLinkColor( col );
3276 void MapEditor::selectMapSelectionColor()
3278 QColor col = QColorDialog::getColor( defLinkColor, this );
3279 setSelectionColor (col);
3282 void MapEditor::setSelectionColorInt (QColor col)
3284 if ( !col.isValid() ) return;
3285 xelection.setColor (col);
3288 void MapEditor::setSelectionColor(QColor col)
3290 if ( !col.isValid() ) return;
3293 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3295 QString("setSelectionColor (%1)").arg(col.name()),
3296 QString("Set color of selection box to %1").arg(col.name())
3298 setSelectionColorInt (col);
3301 QColor MapEditor::getSelectionColor()
3303 return xelection.getColor();
3306 bool MapEditor::scrollBranch(BranchObj *bo)
3310 if (bo->isScrolled()) return false;
3311 if (bo->countBranches()==0) return false;
3312 if (bo->getDepth()==0) return false;
3318 QString ("%1 ()").arg(u),
3320 QString ("%1 ()").arg(r),
3321 QString ("%1 %2").arg(r).arg(getName(bo))
3331 bool MapEditor::unscrollBranch(BranchObj *bo)
3335 if (!bo->isScrolled()) return false;
3336 if (bo->countBranches()==0) return false;
3337 if (bo->getDepth()==0) return false;
3343 QString ("%1 ()").arg(u),
3345 QString ("%1 ()").arg(r),
3346 QString ("%1 %2").arg(r).arg(getName(bo))
3356 void MapEditor::toggleScroll()
3358 BranchObj *bo=xelection.getBranch();
3359 if (xelection.type()==Selection::Branch )
3361 if (bo->isScrolled())
3362 unscrollBranch (bo);
3368 void MapEditor::unscrollChilds()
3370 BranchObj *bo=xelection.getBranch();
3376 if (bo->isScrolled()) unscrollBranch (bo);
3382 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3384 BranchObj *bo=xelection.getBranch();
3388 bo->addFloatImage();
3389 fio=bo->getLastFloatImage();
3391 mapCenter->reposition();
3398 void MapEditor::loadFloatImage ()
3400 BranchObj *bo=xelection.getBranch();
3404 Q3FileDialog *fd=new Q3FileDialog( this);
3405 fd->setMode (Q3FileDialog::ExistingFiles);
3406 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3407 ImagePreview *p =new ImagePreview (fd);
3408 fd->setContentsPreviewEnabled( TRUE );
3409 fd->setContentsPreview( p, p );
3410 fd->setPreviewMode( Q3FileDialog::Contents );
3411 fd->setCaption(vymName+" - " +tr("Load image"));
3412 fd->setDir (lastImageDir);
3415 if ( fd->exec() == QDialog::Accepted )
3417 // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
3418 lastImageDir=QDir (fd->dirPath());
3421 for (int j=0; j<fd->selectedFiles().count(); j++)
3423 s=fd->selectedFiles().at(j);
3424 fio=loadFloatImageInt (s);
3427 (LinkableMapObj*)fio,
3430 QString ("loadImage (%1)").arg(s ),
3431 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3434 // TODO loadFIO error handling
3435 qWarning ("Failed to load "+s);
3443 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3445 fio->save (fn,type);
3448 void MapEditor::saveFloatImage ()
3450 FloatImageObj *fio=xelection.getFloatImage();
3453 QFileDialog *fd=new QFileDialog( this);
3454 fd->setFilters (imageIO.getFilters());
3455 fd->setCaption(vymName+" - " +tr("Save image"));
3456 fd->setFileMode( QFileDialog::AnyFile );
3457 fd->setDirectory (lastImageDir);
3458 // fd->setSelection (fio->getOriginalFilename());
3462 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3464 fn=fd->selectedFiles().at(0);
3465 if (QFile (fn).exists() )
3467 QMessageBox mb( vymName,
3468 tr("The file %1 exists already.\n"
3469 "Do you want to overwrite it?").arg(fn),
3470 QMessageBox::Warning,
3471 QMessageBox::Yes | QMessageBox::Default,
3472 QMessageBox::Cancel | QMessageBox::Escape,
3473 QMessageBox::QMessageBox::NoButton );
3475 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3476 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3479 case QMessageBox::Yes:
3482 case QMessageBox::Cancel:
3489 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3495 void MapEditor::setFrameType(const FrameObj::FrameType &t)
3497 BranchObj *bo=xelection.getBranch();
3500 QString s=bo->getFrameTypeName();
3501 bo->setFrameType (t);
3502 saveState (bo, QString("setFrameType (\"%1\")").arg(s),
3503 bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
3504 mapCenter->reposition();
3509 void MapEditor::setFrameType(const QString &s)
3511 BranchObj *bo=xelection.getBranch();
3514 saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
3515 bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
3516 bo->setFrameType (s);
3517 mapCenter->reposition();
3522 void MapEditor::setFramePenColor(const QColor &c)
3524 BranchObj *bo=xelection.getBranch();
3527 saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
3528 bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
3529 bo->setFramePenColor (c);
3533 void MapEditor::setFrameBrushColor(const QColor &c)
3535 BranchObj *bo=xelection.getBranch();
3538 saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
3539 bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
3540 bo->setFrameBrushColor (c);
3544 void MapEditor::setFramePadding (const int &i)
3546 BranchObj *bo=xelection.getBranch();
3549 saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
3550 bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
3551 bo->setFramePadding (i);
3552 mapCenter->reposition();
3557 void MapEditor::setFrameBorderWidth(const int &i)
3559 BranchObj *bo=xelection.getBranch();
3562 saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
3563 bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
3564 bo->setFrameBorderWidth (i);
3565 mapCenter->reposition();
3570 void MapEditor::setIncludeImagesVer(bool b)
3572 BranchObj *bo=xelection.getBranch();
3575 QString u= b ? "false" : "true";
3576 QString r=!b ? "false" : "true";
3580 QString("setIncludeImagesVertically (%1)").arg(u),
3582 QString("setIncludeImagesVertically (%1)").arg(r),
3583 QString("Include images vertically in %1").arg(getName(bo))
3585 bo->setIncludeImagesVer(b);
3586 mapCenter->reposition();
3590 void MapEditor::setIncludeImagesHor(bool b)
3592 BranchObj *bo=xelection.getBranch();
3595 QString u= b ? "false" : "true";
3596 QString r=!b ? "false" : "true";
3600 QString("setIncludeImagesHorizontally (%1)").arg(u),
3602 QString("setIncludeImagesHorizontally (%1)").arg(r),
3603 QString("Include images horizontally in %1").arg(getName(bo))
3605 bo->setIncludeImagesHor(b);
3606 mapCenter->reposition();
3610 void MapEditor::setHideLinkUnselected (bool b)
3612 LinkableMapObj *sel=xelection.single();
3614 (xelection.type() == Selection::Branch ||
3615 xelection.type() == Selection::MapCenter ||
3616 xelection.type() == Selection::FloatImage ))
3618 QString u= b ? "false" : "true";
3619 QString r=!b ? "false" : "true";
3623 QString("setHideLinkUnselected (%1)").arg(u),
3625 QString("setHideLinkUnselected (%1)").arg(r),
3626 QString("Hide link of %1 if unselected").arg(getName(sel))
3628 sel->setHideLinkUnselected(b);
3632 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3634 BranchObj *bo=xelection.getBranch();
3637 // Traverse directories
3638 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3639 QFileInfoList list = d.entryInfoList();
3642 for (int i = 0; i < list.size(); ++i)
3645 if (fi.fileName() != "." && fi.fileName() != ".." )
3648 bo=dst->getLastBranch();
3649 bo->setHeading (fi.fileName() );
3650 bo->setColor (QColor("blue"));
3652 if ( !d.cd(fi.fileName()) )
3653 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3656 // Recursively add subdirs
3657 importDirInt (bo,d);
3663 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3664 list = d.entryInfoList();
3666 for (int i = 0; i < list.size(); ++i)
3670 bo=dst->getLastBranch();
3671 bo->setHeading (fi.fileName() );
3672 bo->setColor (QColor("black"));
3673 if (fi.fileName().right(4) == ".vym" )
3674 bo->setVymLink (fi.filePath());
3679 void MapEditor::importDirInt (const QString &s)
3681 BranchObj *bo=xelection.getBranch();
3684 saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
3687 importDirInt (bo,d);
3691 void MapEditor::importDir()
3693 BranchObj *bo=xelection.getBranch();
3696 QStringList filters;
3697 filters <<"VYM map (*.vym)";
3698 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3699 fd->setMode (QFileDialog::DirectoryOnly);
3700 fd->setFilters (filters);
3701 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3705 if ( fd->exec() == QDialog::Accepted )
3707 importDirInt (fd->selectedFile() );
3708 mapCenter->reposition();
3714 void MapEditor::followXLink(int i)
3716 BranchObj *bo=xelection.getBranch();
3719 bo=bo->XLinkTargetAt(i);
3722 xelection.select(bo);
3723 ensureSelectionVisible();
3728 void MapEditor::editXLink(int i) // FIXME missing saveState
3730 BranchObj *bo=xelection.getBranch();
3733 XLinkObj *xlo=bo->XLinkAt(i);
3736 EditXLinkDialog dia;
3738 dia.setSelection(bo);
3739 if (dia.exec() == QDialog::Accepted)
3741 if (dia.useSettingsGlobal() )
3743 setMapDefXLinkColor (xlo->getColor() );
3744 setMapDefXLinkWidth (xlo->getWidth() );
3746 if (dia.deleteXLink())
3747 bo->deleteXLinkAt(i);
3753 void MapEditor::testFunction()
3755 // This is the playground
3757 BranchObj *bo=xelection.getBranch();
3758 if (bo) animObjList.append( bo );
3762 dia.showCancelButton (true);
3763 dia.setText("This is a longer \nWarning");
3764 dia.setCaption("Warning: Flux problem");
3765 dia.setShowAgainName("mapeditor/testDialog");
3766 if (dia.exec()==QDialog::Accepted)
3767 cout << "accepted!\n";
3769 cout << "canceled!\n";
3773 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
3774 if (hidemode==HideNone)
3776 setHideTmpMode (HideExport);
3777 mapCenter->calcBBoxSizeWithChilds();
3778 QRectF totalBBox=mapCenter->getTotalBBox();
3779 QRectF mapRect=totalBBox;
3780 QCanvasRectangle *frame=NULL;
3782 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3784 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3785 totalBBox.width(), totalBBox.height());
3786 frame=new QCanvasRectangle (mapRect,mapScene);
3787 frame->setBrush (QColor(white));
3788 frame->setPen (QColor(black));
3789 frame->setZValue(0);
3794 setHideTmpMode (HideNone);
3796 cout <<" hidemode="<<hidemode<<endl;
3800 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3802 // Lineedits are already closed by preceding
3803 // mouseEvent, we don't need to close here.
3805 QPointF p = mapToScene(e->pos());
3806 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3809 { // MapObj was found
3810 if (xelection.single() != lmo)
3812 // select the MapObj
3813 xelection.select(lmo);
3816 if (xelection.getBranch() )
3818 // Context Menu on branch or mapcenter
3820 branchContextMenu->popup(e->globalPos() );
3823 if (xelection.getFloatImage() )
3825 // Context Menu on floatimage
3827 floatimageContextMenu->popup(e->globalPos() );
3831 { // No MapObj found, we are on the Canvas itself
3832 // Context Menu on scene
3834 canvasContextMenu->popup(e->globalPos() );
3839 void MapEditor::keyPressEvent(QKeyEvent* e)
3841 if (e->modifiers() & Qt::ControlModifier)
3843 switch (mainWindow->getModMode())
3845 case Main::ModModeColor:
3846 setCursor (PickColorCursor);
3848 case Main::ModModeCopy:
3849 setCursor (CopyCursor);
3851 case Main::ModModeXLink:
3852 setCursor (XLinkCursor);
3855 setCursor (Qt::ArrowCursor);
3861 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3863 if (!(e->modifiers() & Qt::ControlModifier))
3864 setCursor (Qt::ArrowCursor);
3867 void MapEditor::mousePressEvent(QMouseEvent* e)
3869 // Ignore right clicks, these will go to context menus
3870 if (e->button() == Qt::RightButton )
3876 //Ignore clicks while editing heading
3877 if (isSelectBlocked() )
3883 QPointF p = mapToScene(e->pos());
3884 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3888 //Take care of system flags _or_ modifier modes
3890 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3891 typeid(*lmo)==typeid(MapCenterObj) ))
3893 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3894 if (!foname.isEmpty())
3896 // systemFlag clicked
3900 if (e->state() & Qt::ControlModifier)
3901 mainWindow->editOpenURLTab();
3903 mainWindow->editOpenURL();
3905 else if (foname=="vymLink")
3907 mainWindow->editOpenVymLink();
3908 // tabWidget may change, better return now
3909 // before segfaulting...
3910 } else if (foname=="note")
3911 mainWindow->windowToggleNoteEditor();
3912 else if (foname=="hideInExport")
3919 // No system flag clicked, take care of modmodes (CTRL-Click)
3920 if (e->state() & Qt::ControlModifier)
3922 if (mainWindow->getModMode()==Main::ModModeColor)
3925 setCursor (PickColorCursor);
3928 if (mainWindow->getModMode()==Main::ModModeXLink)
3930 BranchObj *bo_begin=NULL;
3932 bo_begin=(BranchObj*)(lmo);
3934 if (xelection.getBranch() )
3935 bo_begin=xelection.getBranch();
3939 linkingObj_src=bo_begin;
3940 tmpXLink=new XLinkObj (mapScene);
3941 tmpXLink->setBegin (bo_begin);
3942 tmpXLink->setEnd (p);
3943 tmpXLink->setColor(defXLinkColor);
3944 tmpXLink->setWidth(defXLinkWidth);
3945 tmpXLink->updateXLink();
3946 tmpXLink->setVisibility (true);
3950 } // End of modmodes
3954 // Select the clicked object
3957 // Left Button Move Branches
3958 if (e->button() == Qt::LeftButton )
3960 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
3961 //movingObj_start.setY( p.y() - selection->y() );
3962 movingObj_start.setX( p.x() - lmo->x() );
3963 movingObj_start.setY( p.y() - lmo->y() );
3964 movingObj_orgPos.setX (lmo->x() );
3965 movingObj_orgPos.setY (lmo->y() );
3966 movingObj_orgRelPos=lmo->getRelPos();
3968 // If modMode==copy, then we want to "move" the _new_ object around
3969 // then we need the offset from p to the _old_ selection, because of tmp
3970 if (mainWindow->getModMode()==Main::ModModeCopy &&
3971 e->state() & Qt::ControlModifier)
3973 if (xelection.type()==Selection::Branch)
3976 mapCenter->addBranch ((BranchObj*)xelection.single());
3978 xelection.select(mapCenter->getLastBranch());
3979 mapCenter->reposition();
3983 movingObj=xelection.single();
3985 // Middle Button Toggle Scroll
3986 // (On Mac OS X this won't work, but we still have
3987 // a button in the toolbar)
3988 if (e->button() == Qt::MidButton )
3993 { // No MapObj found, we are on the scene itself
3994 // Left Button move Pos of sceneView
3995 if (e->button() == Qt::LeftButton )
3997 movingObj=NULL; // move Content not Obj
3998 movingObj_start=e->globalPos();
3999 movingCont_start=QPointF (
4000 horizontalScrollBar()->value(),
4001 verticalScrollBar()->value());
4002 movingVec=QPointF(0,0);
4003 setCursor(HandOpenCursor);
4008 void MapEditor::mouseMoveEvent(QMouseEvent* e)
4010 QPointF p = mapToScene(e->pos());
4011 LinkableMapObj *lmosel=xelection.single();
4013 // Move the selected MapObj
4014 if ( lmosel && movingObj)
4016 // reset cursor if we are moving and don't copy
4017 if (mainWindow->getModMode()!=Main::ModModeCopy)
4018 setCursor (Qt::ArrowCursor);
4020 // To avoid jumping of the sceneView, only
4021 // ensureSelectionVisible, if not tmp linked
4022 if (!lmosel->hasParObjTmp())
4023 ensureSelectionVisible ();
4025 // Now move the selection, but add relative position
4026 // (movingObj_start) where selection was chosen with
4027 // mousepointer. (This avoids flickering resp. jumping
4028 // of selection back to absPos)
4030 // Check if we could link
4031 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
4034 FloatObj *fio=xelection.getFloatImage();
4037 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4039 fio->updateLink(); //no need for reposition, if we update link here
4042 // Relink float to new mapcenter or branch, if shift is pressed
4043 // Only relink, if selection really has a new parent
4044 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
4045 ( (typeid(*lmo)==typeid(BranchObj)) ||
4046 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
4047 ( lmo != fio->getParObj())
4050 if (typeid(*fio) == typeid(FloatImageObj) &&
4051 ( (typeid(*lmo)==typeid(BranchObj) ||
4052 typeid(*lmo)==typeid(MapCenterObj)) ))
4055 // Also save the move which was done so far
4056 QString pold=qpointfToString(movingObj_orgRelPos);
4057 QString pnow=qpointfToString(fio->getRelPos());
4063 QString("Move %1 to relativ position %2").arg(getName(fio)).arg(pnow));
4064 fio->getParObj()->requestReposition();
4065 mapCenter->reposition();
4067 linkTo (lmo->getSelectString());
4069 //movingObj_orgRelPos=lmosel->getRelPos();
4071 mapCenter->reposition();
4075 { // selection != a FloatObj
4076 if (lmosel->getDepth()==0)
4079 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
4080 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4082 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4083 mapCenter->updateRelPositions();
4086 if (lmosel->getDepth()==1)
4089 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4090 lmosel->setRelPos();
4093 // Move ordinary branch
4094 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
4095 // Add width of bbox here, otherwise alignRelTo will cause jumping around
4096 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
4097 p.y()-movingObj_start.y() +lmosel->getTopPad() );
4099 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
4102 // Maybe we can relink temporary?
4103 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
4104 (typeid(*lmo)==typeid(BranchObj) ||
4105 typeid(*lmo)==typeid(MapCenterObj)) )
4108 if (e->modifiers()==Qt::ControlModifier)
4110 // Special case: CTRL to link below lmo
4111 lmosel->setParObjTmp (lmo,p,+1);
4113 else if (e->modifiers()==Qt::ShiftModifier)
4114 lmosel->setParObjTmp (lmo,p,-1);
4116 lmosel->setParObjTmp (lmo,p,0);
4119 lmosel->unsetParObjTmp();
4121 // reposition subbranch
4122 lmosel->reposition();
4126 } // no FloatImageObj
4130 } // selection && moving_obj
4132 // Draw a link from one branch to another
4135 tmpXLink->setEnd (p);
4136 tmpXLink->updateXLink();
4140 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
4142 QPointF p=e->globalPos();
4143 movingVec.setX(-p.x() + movingObj_start.x() );
4144 movingVec.setY(-p.y() + movingObj_start.y() );
4145 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
4146 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
4151 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
4153 QPointF p = mapToScene(e->pos());
4154 LinkableMapObj *dst;
4155 LinkableMapObj *lmosel=xelection.single();
4156 // Have we been picking color?
4160 setCursor (Qt::ArrowCursor);
4161 // Check if we are over another branch
4162 dst=mapCenter->findMapObj(p, NULL);
4165 if (e->state() & Qt::ShiftModifier)
4166 colorBranch (((BranchObj*)(dst))->getColor());
4168 colorSubtree (((BranchObj*)(dst))->getColor());
4173 // Have we been drawing a link?
4177 // Check if we are over another branch
4178 dst=mapCenter->findMapObj(p, NULL);
4181 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
4182 tmpXLink->updateXLink();
4183 tmpXLink->activate(); //FIXME savestate missing
4184 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );
4193 // Have we been moving something?
4194 if ( lmosel && movingObj )
4196 FloatImageObj *fo=xelection.getFloatImage();
4199 // Moved FloatObj. Maybe we need to reposition
4200 QString pold=qpointfToString(movingObj_orgRelPos);
4201 QString pnow=qpointfToString(fo->getRelPos());
4207 QString("Move %1 to relativ position %2").arg(getName(fo)).arg(pnow));
4209 fo->getParObj()->requestReposition();
4210 mapCenter->reposition();
4213 // Check if we are over another branch, but ignore
4214 // any found LMOs, which are FloatObjs
4215 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
4217 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4220 if (xelection.type() == Selection::MapCenter )
4221 { // FIXME The MapCenter was moved, no savestate yet
4224 if (xelection.type() == Selection::Branch )
4225 { // A branch was moved
4227 // save the position in case we link to mapcenter
4228 QPointF savePos=QPointF (lmosel->getAbsPos() );
4230 // Reset the temporary drawn link to the original one
4231 lmosel->unsetParObjTmp();
4233 // For Redo we may need to save original selection
4234 QString preSelStr=lmosel->getSelectString();
4239 BranchObj* bsel=xelection.getBranch();
4240 BranchObj* bdst=(BranchObj*)dst;
4242 QString preParStr=(bsel->getParObj())->getSelectString();
4243 QString preNum=QString::number (bsel->getNum(),10);
4244 QString preDstParStr;
4246 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4248 preDstParStr=dst->getParObj()->getSelectString();
4249 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4251 if (e->state() & Qt::ControlModifier && dst->getParObj())
4254 preDstParStr=dst->getParObj()->getSelectString();
4255 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4258 preDstParStr=dst->getSelectString();
4259 bsel->linkTo (bdst,-1);
4260 if (dst->getDepth()==0) bsel->move (savePos);
4262 QString postSelStr=lmosel->getSelectString();
4263 QString postNum=QString::number (bsel->getNum(),10);
4265 QString undoCom="linkTo (\""+
4266 preParStr+ "\"," + preNum +"," +
4267 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4269 QString redoCom="linkTo (\""+
4270 preDstParStr + "\"," + postNum + "," +
4271 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4276 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4278 if (lmosel->getDepth()==1)
4280 // The select string might be different _after_ moving around.
4281 // Therefor reposition and then use string of old selection, too
4282 mapCenter->reposition();
4284 QString ps=qpointfToString ( lmosel->getRelPos() );
4286 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4287 preSelStr, "moveRel "+ps,
4288 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4291 // Draw the original link, before selection was moved around
4292 mapCenter->reposition();
4295 // Finally resize scene, if needed
4299 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4302 // maybe we moved View: set old cursor
4303 setCursor (Qt::ArrowCursor);
4307 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4309 if (isSelectBlocked() )
4315 if (e->button() == Qt::LeftButton )
4317 QPointF p = mapToScene(e->pos());
4318 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4319 if (lmo) { // MapObj was found
4320 // First select the MapObj than edit heading
4321 xelection.select(lmo);
4322 mainWindow->editHeading();
4327 void MapEditor::resizeEvent (QResizeEvent* e)
4329 QGraphicsView::resizeEvent( e );
4332 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4334 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4335 // cerr << event->format(i) << endl;
4337 if (event->mimeData()->hasImage())
4338 event->acceptProposedAction();
4340 if (event->mimeData()->hasUrls())
4341 event->acceptProposedAction();
4344 void MapEditor::dragMoveEvent(QDragMoveEvent *event)
4348 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4353 void MapEditor::dropEvent(QDropEvent *event)
4355 BranchObj *sel=xelection.getBranch();
4359 if (event->mimeData()->hasImage())
4361 QVariant imageData = event->mimeData()->imageData();
4362 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4364 if (event->mimeData()->hasUrls())
4365 uris=event->mimeData()->urls();
4373 for (int i=0; i<uris.count();i++)
4375 // Workaround to avoid adding empty branches
4376 if (!uris.at(i).toString().isEmpty())
4378 bo=sel->addBranch();
4381 s=uris.at(i).toLocalFile();
4384 QString file = QDir::convertSeparators(s);
4385 heading = QFileInfo(file).baseName();
4387 if (file.endsWith(".vym", false))
4388 bo->setVymLink(file);
4390 bo->setURL(uris.at(i).toString());
4393 bo->setURL(uris.at(i).toString());
4396 if (!heading.isEmpty())
4397 bo->setHeading(heading);
4399 bo->setHeading(uris.at(i).toString());
4403 mapCenter->reposition();
4406 event->acceptProposedAction();
4409 void MapEditor::timerEvent(QTimerEvent *event) //TODO animation
4413 cout << "ME::timerEvent\n";
4415 for (int i=0; i<animObjList.size(); ++i)
4417 animObjList.at(i)->animate();
4418 ((BranchObj*)animObjList.at(i))->move2RelPos (((BranchObj*)animObjList.at(i))->getRelPos() );
4420 mapCenter->reposition();
4423 void MapEditor::autosave()
4425 if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() )
4426 mainWindow->fileSave (this);
4430 /*TODO not needed? void MapEditor::contentsDropEvent(QDropEvent *event)
4433 } else if (event->provides("application/x-moz-file-promise-url") &&
4434 event->provides("application/x-moz-nativeimage"))
4436 // Contains url to the img src in unicode16
4437 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4438 QString url = QString((const QChar*)d.data(),d.size()/2);
4442 } else if (event->provides ("text/uri-list"))
4443 { // Uris provided e.g. by konqueror
4444 Q3UriDrag::decode (event,uris);
4445 } else if (event->provides ("_NETSCAPE_URL"))
4446 { // Uris provided by Mozilla
4447 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4450 } else if (event->provides("text/html")) {
4452 // Handels text mime types
4453 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4454 QByteArray d = event->encodedData("text/html");
4457 text = QString((const QChar*)d.data(),d.size()/2);
4461 textEditor->setText(text);
4465 } else if (event->provides("text/plain")) {
4466 QByteArray d = event->encodedData("text/plain");
4469 text = QString((const QChar*)d.data(),d.size()/2);
4473 textEditor->setText(text);
4483 bool isUnicode16(const QByteArray &d)
4485 // TODO: make more precise check for unicode 16.
4486 // Guess unicode16 if any of second bytes are zero
4487 unsigned int length = max(0,d.size()-2)/2;
4488 for (unsigned int i = 0; i<length ; i++)
4489 if (d.at(i*2+1)==0) return true;
4493 void MapEditor::addFloatImageInt (const QPixmap &img)
4495 BranchObj *bo=xelection.getBranch();
4498 FloatImageObj *fio=bo->addFloatImage();
4500 fio->setOriginalFilename("Image added by Drag and Drop"); // FIXME savestate missing
4501 mapCenter->reposition();
4508 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4510 if (!imageBuffer) imageBuffer = new QBuffer();
4511 if (!imageBuffer->isOpen()) {
4512 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4514 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4518 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4520 if (nop->state()==Q3NetworkProtocol::StDone) {
4521 QPixmap img(imageBuffer->buffer());
4522 addFloatImageInt (img);
4526 imageBuffer->close();
4528 imageBuffer->close();
4535 void MapEditor::fetchImage(const QString &url)
4538 urlOperator->stop();
4539 disconnect(urlOperator);
4543 urlOperator = new Q3UrlOperator(url);
4544 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4545 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4547 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4548 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));