3 #include <q3filedialog.h>
12 #include "editxlinkdialog.h"
14 #include "extrainfodialog.h"
16 #include "linkablemapobj.h"
17 #include "mainwindow.h"
19 #include "texteditor.h"
20 #include "warningdialog.h"
24 extern TextEditor *textEditor;
25 extern int statusbarTime;
26 extern Main *mainWindow;
27 extern QString tmpVymDir;
28 extern QString clipboardDir;
29 extern bool clipboardEmpty;
30 extern FlagRowObj *standardFlagsDefault;
32 extern QMenu* branchContextMenu;
33 extern QMenu* branchAddContextMenu;
34 extern QMenu* branchRemoveContextMenu;
35 extern QMenu* branchLinksContextMenu;
36 extern QMenu* branchXLinksContextMenuEdit;
37 extern QMenu* branchXLinksContextMenuFollow;
38 extern QMenu* floatimageContextMenu;
39 extern QMenu* canvasContextMenu;
42 extern Settings settings;
43 extern ImageIO imageIO;
45 extern QString vymName;
46 extern QString vymVersion;
48 extern QString iconPath;
49 extern QDir vymBaseDir;
50 extern QDir lastImageDir;
51 extern QDir lastFileDir;
53 int MapEditor::mapNum=0; // make instance
55 ///////////////////////////////////////////////////////////////////////
56 ///////////////////////////////////////////////////////////////////////
57 MapEditor::MapEditor( QWidget* parent) :
60 //cout << "Constructor ME "<<this<<endl;
64 mapScene= new QGraphicsScene(parent);
65 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
66 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
71 mapCenter = new MapCenterObj(mapScene);
72 mapCenter->setVisibility (true);
73 mapCenter->setMapEditor (this);
74 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
75 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
80 defLinkColor=QColor (0,0,255);
81 defXLinkColor=QColor (180,180,180);
82 linkcolorhint=DefaultColor;
83 linkstyle=StylePolyParabel;
85 // Create bitmap cursors, platform dependant
86 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
87 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
88 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
89 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
91 setFocusPolicy (Qt::StrongFocus);
102 xelection.setMapCenter (mapCenter);
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));
120 // Initialize find routine
127 blockReposition=false;
128 blockSaveState=false;
132 // Create temporary files
135 setAcceptDrops (true);
137 mapCenter->reposition(); // for positioning heading
141 MapEditor::~MapEditor()
143 //cout <<"Destructor MapEditor\n";
146 MapCenterObj* MapEditor::getMapCenter()
151 QGraphicsScene * MapEditor::getScene()
156 bool MapEditor::isRepositionBlocked()
158 return blockReposition;
161 QString MapEditor::getName (const LinkableMapObj *lmo)
164 if (!lmo) return QString("Error: NULL has no name!");
166 if ((typeid(*lmo) == typeid(BranchObj) ||
167 typeid(*lmo) == typeid(MapCenterObj)))
170 s=(((BranchObj*)lmo)->getHeading());
171 if (s=="") s="unnamed";
172 return QString("branch (%1)").arg(s);
173 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
175 if ((typeid(*lmo) == typeid(FloatImageObj) ))
176 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
177 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
178 return QString("Unknown type has no name!");
181 void MapEditor::makeTmpDirs()
183 // Create unique temporary directories
184 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
185 histPath=QDir::convertSeparators (tmpMapDir+"/history");
190 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
192 // tmpdir temporary directory to which data will be written
193 // prefix mapname, which will be appended to images etc.
194 // writeflags Only write flags for "real" save of map, not undo
195 // offset offset of bbox of whole map in scene.
196 // Needed for XML export
212 ls="StylePolyParabel";
216 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
218 if (linkcolorhint==HeadingColor)
219 colhint=attribut("linkColorHint","HeadingColor");
221 QString mapAttr=attribut("version",vymVersion);
222 if (!saveSel || saveSel==mapCenter)
223 mapAttr+= attribut("author",mapCenter->getAuthor()) +
224 attribut("comment",mapCenter->getComment()) +
225 attribut("date",mapCenter->getDate()) +
226 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
227 attribut("linkStyle", ls ) +
228 attribut("linkColor", defLinkColor.name() ) +
229 attribut("defXLinkColor", defXLinkColor.name() ) +
230 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
232 s+=beginElement("vymmap",mapAttr);
235 // Find the used flags while traversing the tree
236 standardFlagsDefault->resetUsedCounter();
238 // Reset the counters before saving
239 // TODO constr. of FIO creates lots of objects, better do this in some other way...
240 FloatImageObj (mapScene).resetSaveCounter();
242 // Build xml recursivly
243 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
244 // Save complete map, if saveSel not set
245 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
248 if ( typeid(*saveSel) == typeid(BranchObj) )
250 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
251 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
253 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
256 // Save local settings
257 s+=settings.getXMLData (destPath);
260 if (selection && !saveSel )
261 s+=valueElement("select",selection->getSelectString());
264 s+=endElement("vymmap");
267 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
271 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
273 // save the selected part of the map, Undo will replace part of map
274 QString undoSelection="";
276 undoSelection=undoSel->getSelectString();
278 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
279 QString redoSelection="";
281 redoSelection=undoSel->getSelectString();
283 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
286 saveState (PartOfMap,
287 undoSelection, "addMapReplace (\"PATH\")",
293 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
297 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
300 QString undoSelection=redoSel->getParObj()->getSelectString();
301 QString redoSelection=redoSel->getSelectString();
302 if (typeid(*redoSel) == typeid(BranchObj) )
304 // save the selected branch of the map, Undo will insert part of map
305 saveState (PartOfMap,
306 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
307 redoSelection, "delete ()",
314 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
316 // "Normal" savestate: save commands, selections and comment
317 // so just save commands for undo and redo
318 // and use current selection
320 QString redoSelection="";
321 if (redoSel) redoSelection=redoSel->getSelectString();
322 QString undoSelection="";
323 if (undoSel) undoSelection=undoSel->getSelectString();
325 saveState (UndoCommand,
332 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
334 // "Normal" savestate: save commands, selections and comment
335 // so just save commands for undo and redo
336 // and use current selection
337 saveState (UndoCommand,
345 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
349 if (blockSaveState) return;
351 /* TODO remove after testing
353 cout << "ME::saveState() "<<endl;
355 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
356 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
357 int curStep=undoSet.readNumEntry ("/history/curStep",0);
358 // Find out current undo directory
359 if (undosAvail<stepsTotal) undosAvail++;
361 if (curStep>stepsTotal) curStep=1;
363 QString backupXML="";
364 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
365 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
366 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
368 // Create bakMapDir if not available
371 makeSubDirs (bakMapDir);
373 // Save depending on how much needs to be saved
375 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPointF (),saveSel);
377 QString undoCommand="";
378 if (savemode==UndoCommand)
382 else if (savemode==PartOfMap )
385 undoCommand.replace ("PATH",bakMapPath);
388 if (!backupXML.isEmpty())
389 // Write XML Data to disk
390 saveStringToDisk (QString(bakMapPath),backupXML);
392 // We would have to save all actions in a tree, to keep track of
393 // possible redos after a action. Possible, but we are too lazy: forget about redos.
396 // Write the current state to disk
397 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
398 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
399 undoSet.setEntry ("/history/curStep",QString::number(curStep));
400 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
401 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
402 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
403 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
404 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
405 undoSet.setEntry (QString("/history/version"),vymVersion);
406 undoSet.writeSettings(histPath);
408 /* TODO remove after testing
410 //cout << " into="<< histPath.toStdString()<<endl;
411 cout << " stepsTotal="<<stepsTotal<<
412 ", undosAvail="<<undosAvail<<
413 ", redosAvail="<<redosAvail<<
414 ", curStep="<<curStep<<endl;
415 cout << " ---------------------------"<<endl;
416 cout << " comment="<<comment.toStdString()<<endl;
417 cout << " undoCom="<<undoCommand.toStdString()<<endl;
418 cout << " undoSel="<<undoSelection.toStdString()<<endl;
419 cout << " redoCom="<<redoCom.toStdString()<<endl;
420 cout << " redoSel="<<redoSelection.toStdString()<<endl;
421 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
422 cout << " ---------------------------"<<endl;
424 mainWindow->updateHistory (undoSet);
429 void MapEditor::parseAtom(const QString &atom)
436 // Split string s into command and parameters
437 api.parseInput (atom);
438 QString com=api.command();
441 if (com=="addBranch")
445 api.setError (Aborted,"Nothing selected");
446 } else if ( (typeid(*selection) != typeid(BranchObj) &&
447 typeid(*selection) != typeid(MapCenterObj)) )
449 api.setError (Aborted,"Type of selection is not a branch");
454 if (api.checkParamCount(pl))
456 if (api.paramCount()==0)
457 addNewBranchInt (-2);
461 if (ok ) addNewBranchInt (y);
465 } else if (com=="addBranchBefore")
469 api.setError (Aborted,"Nothing selected");
470 } else if ( (typeid(*selection) != typeid(BranchObj) &&
471 typeid(*selection) != typeid(MapCenterObj)) )
473 api.setError (Aborted,"Type of selection is not a branch");
476 if (api.paramCount()==0)
478 addNewBranchBefore ();
481 } else if (com==QString("addMapReplace"))
485 api.setError (Aborted,"Nothing selected");
486 } else if ( (typeid(*selection) != typeid(BranchObj) &&
487 typeid(*selection) != typeid(MapCenterObj)) )
489 api.setError (Aborted,"Type of selection is not a branch");
490 } else if (api.checkParamCount(1))
492 //s=api.parString (ok,0); // selection
493 t=api.parString (ok,0); // path to map
494 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
495 addMapReplaceInt(selection->getSelectString(),t);
497 } else if (com==QString("addMapInsert"))
501 api.setError (Aborted,"Nothing selected");
502 } else if ( (typeid(*selection) != typeid(BranchObj) &&
503 typeid(*selection) != typeid(MapCenterObj)) )
505 api.setError (Aborted,"Type of selection is not a branch");
508 if (api.checkParamCount(2))
510 t=api.parString (ok,0); // path to map
511 y=api.parInt(ok,1); // position
512 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
513 addMapInsertInt(t,y);
516 } else if (com=="colorBranch")
520 api.setError (Aborted,"Nothing selected");
521 } else if ( typeid(*selection) != typeid(BranchObj) &&
522 typeid(*selection) != typeid(MapCenterObj))
524 api.setError (Aborted,"Type of selection is not a branch");
525 } else if (api.checkParamCount(1))
527 QColor c=api.parColor (ok,0);
528 if (ok) colorBranch (c);
530 } else if (com=="colorSubtree")
534 api.setError (Aborted,"Nothing selected");
535 } else if ( typeid(*selection) != typeid(BranchObj) &&
536 typeid(*selection) != typeid(MapCenterObj))
538 api.setError (Aborted,"Type of selection is not a branch");
539 } else if (api.checkParamCount(1))
541 QColor c=api.parColor (ok,0);
542 if (ok) colorSubtree (c);
544 } else if (com=="cut")
548 api.setError (Aborted,"Nothing selected");
549 } else if ( typeid(*selection) != typeid(BranchObj) &&
550 typeid(*selection) != typeid(MapCenterObj) &&
551 typeid(*selection) != typeid(FloatImageObj) )
553 api.setError (Aborted,"Type of selection is not a branch or floatimage");
554 } else if (api.checkParamCount(0))
558 } else if (com=="delete")
562 api.setError (Aborted,"Nothing selected");
563 } else if ( (typeid(*selection) != typeid(BranchObj) &&
564 typeid(*selection) != typeid(MapCenterObj)) )
566 api.setError (Aborted,"Type of selection is not a branch");
567 } else if (api.checkParamCount(0))
571 } else if (com=="deleteKeepChilds")
575 api.setError (Aborted,"Nothing selected");
576 } else if ( (typeid(*selection) != typeid(BranchObj) &&
577 typeid(*selection) != typeid(MapCenterObj)) )
579 api.setError (Aborted,"Type of selection is not a branch");
580 } else if (api.checkParamCount(0))
584 } else if (com=="deleteChilds")
588 api.setError (Aborted,"Nothing selected");
589 } else if ( (typeid(*selection) != typeid(BranchObj) &&
590 typeid(*selection) != typeid(MapCenterObj)) )
592 api.setError (Aborted,"Type of selection is not a branch");
593 } else if (api.checkParamCount(0))
597 } else if (com=="linkTo")
601 api.setError (Aborted,"Nothing selected");
602 } else if ( (typeid(*selection) == typeid(BranchObj) ||
603 typeid(*selection) == typeid(MapCenterObj)) )
605 if (api.checkParamCount(4))
607 // 0 selectstring of parent
608 // 1 num in parent (for branches)
609 // 2,3 x,y of mainbranch or mapcenter
610 s=api.parString(ok,0);
611 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
614 if (typeid(*dst) == typeid(BranchObj) )
616 // Get number in parent
619 ((BranchObj*)selection)->linkTo ((BranchObj*)(dst),x);
620 } else if (typeid(*dst) == typeid(MapCenterObj) )
622 ((BranchObj*)selection)->linkTo ((BranchObj*)(dst),-1);
623 // Get coordinates of mainbranch
628 if (ok) ((BranchObj*)selection)->move (x,y);
633 } else if ( typeid(*selection) != typeid(FloatImageObj))
635 if (api.checkParamCount(1))
637 // 0 selectstring of parent
638 s=api.parString(ok,0);
639 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
642 if (typeid(*dst) == typeid(BranchObj) ||
643 typeid(*dst) == typeid(MapCenterObj))
644 linkTo (dst->getSelectString());
646 api.setError (Aborted,"Destination is not a branch");
649 api.setError (Aborted,"Type of selection is not a floatimage or branch");
650 } else if (com=="moveBranchUp")
654 api.setError (Aborted,"Nothing selected");
655 } else if ( (typeid(*selection) != typeid(BranchObj) &&
656 typeid(*selection) != typeid(MapCenterObj)) )
658 api.setError (Aborted,"Type of selection is not a branch");
659 } else if (api.checkParamCount(0))
663 } else if (com=="moveBranchDown")
667 api.setError (Aborted,"Nothing selected");
668 } else if ( (typeid(*selection) != typeid(BranchObj) &&
669 typeid(*selection) != typeid(MapCenterObj)) )
671 api.setError (Aborted,"Type of selection is not a branch");
672 } else if (api.checkParamCount(0))
676 } else if (com=="move")
680 api.setError (Aborted,"Nothing selected");
681 } else if ( typeid(*selection) != typeid(BranchObj) &&
682 typeid(*selection) != typeid(MapCenterObj) &&
683 typeid(*selection) != typeid(FloatImageObj) )
685 api.setError (Aborted,"Type of selection is not a branch or floatimage");
686 } else if (api.checkParamCount(2))
695 } else if (com=="moveRel")
699 api.setError (Aborted,"Nothing selected");
700 } else if ( typeid(*selection) != typeid(BranchObj) &&
701 typeid(*selection) != typeid(MapCenterObj) &&
702 typeid(*selection) != typeid(FloatImageObj) )
704 api.setError (Aborted,"Type of selection is not a branch or floatimage");
705 } else if (api.checkParamCount(2))
711 if (ok) moveRel (x,y);
714 } else if (com=="paste")
718 api.setError (Aborted,"Nothing selected");
719 } else if ( typeid(*selection) != typeid(BranchObj) &&
720 typeid(*selection) != typeid(MapCenterObj) )
722 api.setError (Aborted,"Type of selection is not a branch");
723 } else if (api.checkParamCount(0))
727 } else if (com=="select")
729 if (api.checkParamCount(1))
731 s=api.parString(ok,0);
734 } else if (com=="setMapAuthor")
736 if (api.checkParamCount(1))
738 s=api.parString(ok,0);
739 if (ok) setMapAuthor (s);
741 } else if (com=="setMapComment")
743 if (api.checkParamCount(1))
745 s=api.parString(ok,0);
746 if (ok) setMapComment(s);
748 } else if (com=="setMapBackgroundColor")
752 api.setError (Aborted,"Nothing selected");
753 } else if ( (typeid(*selection) != typeid(BranchObj) &&
754 typeid(*selection) != typeid(MapCenterObj)) )
756 api.setError (Aborted,"Type of selection is not a branch");
757 } else if (api.checkParamCount(1))
759 QColor c=api.parColor (ok,0);
760 if (ok) setMapBackgroundColor (c);
762 } else if (com=="setMapDefLinkColor")
766 api.setError (Aborted,"Nothing selected");
767 } else if ( (typeid(*selection) != typeid(BranchObj) &&
768 typeid(*selection) != typeid(MapCenterObj)) )
770 api.setError (Aborted,"Type of selection is not a branch");
771 } else if (api.checkParamCount(1))
773 QColor c=api.parColor (ok,0);
774 if (ok) setMapDefLinkColor (c);
776 } else if (com=="setMapLinkStyle")
778 if (api.checkParamCount(1))
780 s=api.parString (ok,0);
781 if (ok) setMapLinkStyle(s);
783 } else if (com=="setHeading")
787 api.setError (Aborted,"Nothing selected");
788 } else if ( (typeid(*selection) != typeid(BranchObj) &&
789 typeid(*selection) != typeid(MapCenterObj)) )
791 api.setError (Aborted,"Type of selection is not a branch");
792 } else if (api.checkParamCount(1))
794 s=api.parString (ok,0);
798 } else if (com=="setHideExport")
802 api.setError (Aborted,"Nothing selected");
803 } else if ( typeid(*selection) != typeid(BranchObj) &&
804 typeid(*selection) != typeid(FloatImageObj) )
806 api.setError (Aborted,"Type of selection is not a branch or floatimage");
807 } else if (api.checkParamCount(1))
810 if (ok) setHideExport (b);
812 } else if (com=="setURL")
816 api.setError (Aborted,"Nothing selected");
817 } else if ( (typeid(*selection) != typeid(BranchObj) &&
818 typeid(*selection) != typeid(MapCenterObj)) )
820 api.setError (Aborted,"Type of selection is not a branch");
821 } else if (api.checkParamCount(1))
823 s=api.parString (ok,0);
824 if (ok) setURLInt(s);
826 } else if (com=="setVymLink")
830 api.setError (Aborted,"Nothing selected");
831 } else if ( (typeid(*selection) != typeid(BranchObj) &&
832 typeid(*selection) != typeid(MapCenterObj)) )
834 api.setError (Aborted,"Type of selection is not a branch");
835 } else if (api.checkParamCount(1))
837 s=api.parString (ok,0);
838 if (ok) setVymLinkInt(s);
841 else if (com=="setFlag")
845 api.setError (Aborted,"Nothing selected");
846 } else if ( (typeid(*selection) != typeid(BranchObj) &&
847 typeid(*selection) != typeid(MapCenterObj)) )
849 api.setError (Aborted,"Type of selection is not a branch");
850 } else if (api.checkParamCount(1))
852 s=api.parString(ok,0);
855 BranchObj* bo=(BranchObj*)selection;
856 bo->activateStandardFlag(s);
857 bo->updateFlagsToolbar();
861 else if (com=="unsetFlag")
865 api.setError (Aborted,"Nothing selected");
866 } else if ( (typeid(*selection) != typeid(BranchObj) &&
867 typeid(*selection) != typeid(MapCenterObj)) )
869 api.setError (Aborted,"Type of selection is not a branch");
870 } else if (api.checkParamCount(1))
872 s=api.parString(ok,0);
875 BranchObj* bo=(BranchObj*)selection;
876 bo->deactivateStandardFlag(s);
877 bo->updateFlagsToolbar();
881 api.setError (Aborted,"Unknown command");
884 if (api.errorLevel()==NoError)
888 // TODO Error handling
889 qWarning("MapEditor::parseAtom: Error!");
890 qWarning(api.errorMessage());
895 bool MapEditor::isDefault()
900 bool MapEditor::isUnsaved()
905 bool MapEditor::hasChanged()
910 void MapEditor::setChanged()
918 void MapEditor::closeMap()
920 // Unselect before disabling the toolbar actions
921 if (selection) selection->unselect();
929 void MapEditor::setFilePath(QString fname)
931 setFilePath (fname,fname);
934 void MapEditor::setFilePath(QString fname, QString destname)
936 if (fname.isEmpty() || fname=="")
943 filePath=fname; // becomes absolute path
944 fileName=fname; // gets stripped of path
945 destPath=destname; // needed for vymlinks
947 // If fname is not an absolute path, complete it
948 filePath=QDir(fname).absPath();
949 fileDir=filePath.left (1+filePath.findRev ("/"));
951 // Set short name, too. Search from behind:
952 int i=fileName.findRev("/");
953 if (i>=0) fileName=fileName.remove (0,i+1);
955 // Forget the .vym (or .xml) for name of map
956 mapName=fileName.left(fileName.findRev(".",-1,true) );
960 QString MapEditor::getFilePath()
965 QString MapEditor::getFileName()
970 QString MapEditor::getMapName()
975 QString MapEditor::getDestPath()
980 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
982 ErrorCode err=success;
986 if (selection) selection->unselect();
989 mapCenter->setMapEditor(this);
990 // (map state is set later at end of load...)
993 if (!selection || (typeid(*selection) != typeid(BranchObj) &&
994 typeid(*selection) != typeid (MapCenterObj)))
996 BranchObj *bo=(BranchObj*)selection;
997 if (lmode==ImportAdd)
998 saveStateChangingPart(
1001 QString("addMapInsert (%1)").arg(fname),
1002 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1004 saveStateChangingPart(
1007 QString("addMapReplace(%1)").arg(fname),
1008 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1012 mapBuilderHandler handler;
1013 QFile file( fname );
1015 // I am paranoid: file should exist anyway
1016 // according to check in mainwindow.
1017 if (!file.exists() )
1019 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1020 tr("Couldn't open map " +fname)+".");
1024 blockReposition=true;
1025 QXmlInputSource source( file);
1026 QXmlSimpleReader reader;
1027 reader.setContentHandler( &handler );
1028 reader.setErrorHandler( &handler );
1029 handler.setMapEditor( this );
1030 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1031 handler.setInputFile (file.name());
1032 handler.setLoadMode (lmode);
1033 blockSaveState=true;
1034 bool ok = reader.parse( source );
1035 blockReposition=false;
1036 blockSaveState=false;
1040 mapCenter->reposition();
1049 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1050 tr( handler.errorProtocol() ) );
1052 // Still return "success": the map maybe at least
1053 // partially read by the parser
1060 int MapEditor::save (const SaveMode &savemode)
1064 // Create mapName and fileDir
1065 makeSubDirs (fileDir);
1069 fname=mapName+".xml";
1071 // use name given by user, even if he chooses .doc
1076 if (savemode==CompleteMap || selection==NULL)
1077 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1079 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),selection);
1081 if (!saveStringToDisk(fileDir+fname,saveFile))
1094 void MapEditor::setZipped (bool z)
1099 bool MapEditor::saveZipped ()
1104 void MapEditor::print()
1108 printer = new QPrinter;
1109 printer->setColorMode (QPrinter::Color);
1110 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1111 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1112 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1115 // FIXME testing cout << "ME::print printProgram="<<printer->printProgram().ascii()<<endl;
1117 QRectF totalBBox=mapCenter->getTotalBBox();
1119 // Try to set orientation automagically
1120 // Note: Interpretation of generated postscript is amibiguous, if
1121 // there are problems with landscape mode, see
1122 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1124 if (totalBBox.width()>totalBBox.height())
1125 // recommend landscape
1126 printer->setOrientation (QPrinter::Landscape);
1128 // recommend portrait
1129 printer->setOrientation (QPrinter::Portrait);
1131 if ( printer->setup(this) )
1132 // returns false, if printing is canceled
1134 QPainter pp(printer);
1136 pp.setRenderHint(QPainter::Antialiasing,true);
1138 // Don't print the visualisation of selection
1139 LinkableMapObj *oldselection=NULL;
1142 oldselection=selection;
1143 selection->unselect();
1146 QRectF mapRect=totalBBox;
1147 QGraphicsRectItem *frame=NULL;
1151 // Print frame around map
1152 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1153 totalBBox.width()+20, totalBBox.height()+20);
1154 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1155 frame->setZValue(0);
1160 double paperAspect = (double)printer->width() / (double)printer->height();
1161 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1163 if (mapAspect>=paperAspect)
1165 // Fit horizontally to paper width
1166 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1167 viewBottom=(int)(printer->width()/mapAspect);
1170 // Fit vertically to paper height
1171 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1172 viewBottom=printer->height();
1177 // Print footer below map
1179 font.setPointSize(10);
1181 QRectF footerBox(0,viewBottom,printer->width(),15);
1182 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1183 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1187 QRectF (0,0,printer->width(),printer->height()-15),
1188 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1191 // Viewport has paper dimension
1192 if (frame) delete (frame);
1194 // Restore selection
1197 selection=oldselection;
1198 selection->select();
1201 // Save settings in vymrc
1202 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1203 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1204 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1208 void MapEditor::setAntiAlias (bool b)
1210 setRenderHint(QPainter::Antialiasing,b);
1213 void MapEditor::setSmoothPixmap(bool b)
1215 setRenderHint(QPainter::SmoothPixmapTransform,b);
1218 QPixmap MapEditor::getPixmap()
1220 QRectF mapRect=mapCenter->getTotalBBox();
1221 QPixmap pix((int)mapRect.width(),(int)mapRect.height());
1222 cout << "w.h="<<(int)mapRect.width()<<","<<(int)mapRect.height()<<endl;
1225 pp.setRenderHints(renderHints());
1227 // Don't print the visualisation of selection
1228 LinkableMapObj *oldselection=NULL;
1231 oldselection=selection;
1232 selection->unselect();
1235 mapScene->render ( &pp,
1236 QRectF(0,0,mapRect.width(),mapRect.height()),
1237 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1239 // mapScene->render(&pp); // draw scene to painter
1243 // Restore selection
1246 selection=oldselection;
1247 selection->select();
1253 void MapEditor::setHideTmpMode (HideTmpMode mode)
1256 mapCenter->setHideTmp (hidemode);
1257 mapCenter->reposition();
1261 HideTmpMode MapEditor::getHideTmpMode()
1266 void MapEditor::exportImage(QString fn)
1268 setExportMode (true);
1269 QPixmap pix (getPixmap());
1270 pix.save(fn, "PNG");
1271 setExportMode (false);
1274 void MapEditor::setExportMode (bool b)
1276 // should be called before and after exports
1277 // depending on the settings
1278 if (b && settings.value("/export/useHideExport","yes")=="yes")
1279 setHideTmpMode (HideExport);
1281 setHideTmpMode (HideNone);
1284 void MapEditor::exportImage(QString fn, QString format)
1286 setExportMode (true);
1287 QPixmap pix (getPixmap());
1288 pix.save(fn, format);
1289 setExportMode (false);
1292 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1296 ex.setMapCenter(mapCenter);
1297 if (ex.setConfigFile(cf))
1299 setExportMode (true);
1300 ex.exportPresentation();
1301 setExportMode (false);
1307 void MapEditor::exportXML(const QString &dir)
1309 // Hide stuff during export, if settings want this
1310 setExportMode (true);
1312 // Create subdirectories
1315 // write to directory
1316 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1319 file.setName ( dir + "/"+mapName+".xml");
1320 if ( !file.open( QIODevice::WriteOnly ) )
1322 // This should neverever happen
1323 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1327 // Write it finally, and write in UTF8, no matter what
1328 QTextStream ts( &file );
1329 ts.setEncoding (QTextStream::UnicodeUTF8);
1333 // Now write image, too
1334 exportImage (dir+"/images/"+mapName+".png");
1336 setExportMode (false);
1339 void MapEditor::clear()
1343 selection->unselect();
1350 void MapEditor::copy()
1354 // write to directory
1355 QString clipfile="part";
1356 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPointF(),selection);
1359 file.setName ( clipboardDir + "/"+clipfile+".xml");
1360 if ( !file.open( QIODevice::WriteOnly ) )
1362 // This should neverever happen
1363 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1367 // Write it finally, and write in UTF8, no matter what
1368 QTextStream ts( &file );
1369 ts.setEncoding (QTextStream::UnicodeUTF8);
1373 clipboardEmpty=false;
1378 void MapEditor::redo()
1380 blockSaveState=true;
1382 // Restore variables
1383 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1384 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1385 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1386 // Can we undo at all?
1387 if (redosAvail<1) return;
1390 if (undosAvail<stepsTotal) undosAvail++;
1392 if (curStep>stepsTotal) curStep=1;
1393 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1394 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1395 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1396 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1397 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1398 QString version=undoSet.readEntry ("/history/version");
1400 if (!checkVersion(version))
1401 QMessageBox::warning(0,tr("Warning"),
1402 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1405 // Find out current undo directory
1406 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1408 /* TODO remove testing
1410 cout << "ME::redo() begin\n";
1411 cout << " undosAvail="<<undosAvail<<endl;
1412 cout << " redosAvail="<<redosAvail<<endl;
1413 cout << " curStep="<<curStep<<endl;
1414 cout << " ---------------------------"<<endl;
1415 cout << " comment="<<comment.toStdString()<<endl;
1416 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1417 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1418 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1419 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1420 cout << " ---------------------------"<<endl<<endl;
1422 // select object before redo
1423 if (!redoSelection.isEmpty())
1424 select (redoSelection);
1427 parseAtom (redoCommand);
1428 mapCenter->reposition();
1430 blockSaveState=false;
1432 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1433 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1434 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1435 undoSet.writeSettings(histPath);
1437 mainWindow->updateHistory (undoSet);
1440 /* TODO remove testing
1441 cout << "ME::redo() end\n";
1442 cout << " undosAvail="<<undosAvail<<endl;
1443 cout << " redosAvail="<<redosAvail<<endl;
1444 cout << " curStep="<<curStep<<endl;
1445 cout << " ---------------------------"<<endl<<endl;
1451 bool MapEditor::isRedoAvailable()
1453 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1459 void MapEditor::undo()
1461 blockSaveState=true;
1463 // Restore variables
1464 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1465 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1466 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1468 // Can we undo at all?
1469 if (undosAvail<1) return;
1471 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1472 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1473 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1474 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1475 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1476 QString version=undoSet.readEntry ("/history/version");
1478 if (!checkVersion(version))
1479 QMessageBox::warning(0,tr("Warning"),
1480 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1482 // Find out current undo directory
1483 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1485 // select object before undo
1486 if (!undoSelection.isEmpty())
1487 select (undoSelection);
1491 cout << "ME::undo() begin\n";
1492 cout << " undosAvail="<<undosAvail<<endl;
1493 cout << " redosAvail="<<redosAvail<<endl;
1494 cout << " curStep="<<curStep<<endl;
1495 cout << " ---------------------------"<<endl;
1496 cout << " comment="<<comment.toStdString()<<endl;
1497 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1498 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1499 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1500 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1501 cout << " ---------------------------"<<endl<<endl;
1502 parseAtom (undoCommand);
1503 mapCenter->reposition();
1507 if (curStep<1) curStep=stepsTotal;
1511 blockSaveState=false;
1512 /* TODO remove testing
1513 cout << "ME::undo() end\n";
1514 cout << " undosAvail="<<undosAvail<<endl;
1515 cout << " redosAvail="<<redosAvail<<endl;
1516 cout << " curStep="<<curStep<<endl;
1517 cout << " ---------------------------"<<endl<<endl;
1520 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1521 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1522 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1523 undoSet.writeSettings(histPath);
1525 mainWindow->updateHistory (undoSet);
1527 ensureSelectionVisible();
1530 bool MapEditor::isUndoAvailable()
1532 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1538 void MapEditor::gotoHistoryStep (int i)
1540 // Restore variables
1541 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1542 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1544 if (i<0) i=undosAvail+redosAvail;
1546 // Clicking above current step makes us undo things
1549 for (int j=0; j<undosAvail-i; j++) undo();
1552 // Clicking below current step makes us redo things
1554 for (int j=undosAvail; j<i; j++) redo();
1556 // And ignore clicking the current row ;-)
1559 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1561 QString pathDir=path.left(path.findRev("/"));
1567 // We need to parse saved XML data
1568 mapBuilderHandler handler;
1569 QXmlInputSource source( file);
1570 QXmlSimpleReader reader;
1571 reader.setContentHandler( &handler );
1572 reader.setErrorHandler( &handler );
1573 handler.setMapEditor( this );
1574 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1575 if (undoSel.isEmpty())
1579 handler.setLoadMode (NewMap);
1583 handler.setLoadMode (ImportReplace);
1585 blockReposition=true;
1586 bool ok = reader.parse( source );
1587 blockReposition=false;
1590 // This should never ever happen
1591 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1592 handler.errorProtocol());
1595 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1598 void MapEditor::addMapInsertInt (const QString &path, int pos)
1600 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1601 typeid(*selection) == typeid(MapCenterObj)))
1603 QString pathDir=path.left(path.findRev("/"));
1609 // We need to parse saved XML data
1610 mapBuilderHandler handler;
1611 QXmlInputSource source( file);
1612 QXmlSimpleReader reader;
1613 reader.setContentHandler( &handler );
1614 reader.setErrorHandler( &handler );
1615 handler.setMapEditor( this );
1616 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1617 handler.setLoadMode (ImportAdd);
1618 blockReposition=true;
1619 bool ok = reader.parse( source );
1620 blockReposition=false;
1623 // This should never ever happen
1624 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1625 handler.errorProtocol());
1627 if (selection!=mapCenter)
1628 ((BranchObj*)selection)->getLastBranch()->linkTo ((BranchObj*)(selection),pos);
1630 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1634 void MapEditor::pasteNoSave()
1636 load (clipboardDir+"/part.xml",ImportAdd);
1639 void MapEditor::cutNoSave()
1645 void MapEditor::paste()
1647 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1648 typeid(*selection) == typeid(MapCenterObj)))
1651 saveStateChangingPart(
1655 QString("Paste to %1").arg( getName(selection))
1657 mapCenter->reposition();
1661 void MapEditor::cut()
1663 saveStateChangingPart(
1664 selection->getParObj(),
1667 QString("Cut %1").arg(getName(selection))
1671 mapCenter->reposition();
1674 void MapEditor::move(const int &x, const int &y)
1678 QString ps=qpointfToString (selection->getAbsPos());
1679 QString s=selection->getSelectString();
1682 s, "move "+qpointfToString (QPointF (x,y)),
1683 QString("Move %1 to %2").arg(getName(selection)).arg(ps));
1684 selection->move(x,y);
1685 mapCenter->reposition();
1690 void MapEditor::moveRel (const int &x, const int &y)
1692 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1693 typeid(*selection) == typeid(MapCenterObj) ||
1694 typeid(*selection) == typeid (FloatImageObj)))
1696 QString ps=qpointfToString (selection->getRelPos());
1697 QString s=selection->getSelectString();
1700 s, "moveRel "+qpointfToString (QPointF (x,y)),
1701 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(ps));
1702 ((OrnamentedObj*)selection)->move2RelPos (x,y);
1703 mapCenter->reposition();
1704 selection->updateLink();
1708 void MapEditor::moveBranchUp()
1712 if (typeid(*selection) == typeid(BranchObj) )
1714 bo=(BranchObj*)selection;
1715 if (!bo->canMoveBranchUp()) return;
1716 par=(BranchObj*)(bo->getParObj());
1717 selection->unselect();
1718 bo=par->moveBranchUp (bo); // bo will be the one below selection
1719 selection->select();
1720 saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1721 mapCenter->reposition();
1723 ensureSelectionVisible();
1727 void MapEditor::moveBranchDown()
1731 if (typeid(*selection) == typeid(BranchObj) )
1733 bo=(BranchObj*)selection;
1734 if (!bo->canMoveBranchDown()) return;
1735 par=(BranchObj*)(bo->getParObj());
1736 selection->unselect();
1737 bo=par->moveBranchDown(bo); // bo will be the one above selection
1738 selection->select();
1739 saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1740 mapCenter->reposition();
1742 ensureSelectionVisible();
1746 void MapEditor::linkTo(const QString &dstString)
1748 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
1749 if (dst && (typeid(*dst)==typeid (BranchObj) ||
1750 typeid(*dst)==typeid (MapCenterObj)))
1752 LinkableMapObj *dstPar=dst->getParObj();
1753 QString parString=dstPar->getSelectString();
1754 if (typeid(*selection)==typeid(FloatImageObj))
1756 FloatImageObj *fio=(FloatImageObj*)selection;
1757 QString fioPreSelectString=fio->getSelectString();
1758 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
1759 ((BranchObj*)(dst))->addFloatImage (fio);
1761 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
1762 fio=((BranchObj*)(dst))->getLastFloatImage();
1765 selection=(LinkableMapObj*)fio;
1766 selection->select();
1768 fio->getSelectString(),
1769 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
1771 QString ("linkTo (\"%1\")").arg(dstString),
1772 QString ("Link floatimage to %1").arg(getName(dst)));
1777 QString MapEditor::getHeading(bool &ok, QPoint &p)
1780 (typeid(*selection) == typeid(BranchObj) ||
1781 typeid(*selection) == typeid(MapCenterObj) ) )
1784 p=mapFromScene(selection->getAbsPos());
1785 return ((BranchObj*)selection)->getHeading();
1791 void MapEditor::setHeading(const QString &s)
1794 (typeid(*selection) == typeid(BranchObj) ||
1795 typeid(*selection) == typeid(MapCenterObj) ) )
1797 editingBO=(BranchObj*)selection;
1800 "setHeading (\""+editingBO->getHeading()+"\")",
1802 "setHeading (\""+s+"\")",
1803 QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(s) );
1804 editingBO->setHeading(s );
1806 mapCenter->reposition();
1807 ensureSelectionVisible();
1811 void MapEditor::setURLInt (const QString &s)
1813 // Internal function, no saveState needed
1815 (typeid(*selection) == typeid(BranchObj) ||
1816 typeid(*selection) == typeid(MapCenterObj) ) )
1818 ((BranchObj*)selection)->setURL(s);
1819 mapCenter->reposition();
1820 ensureSelectionVisible();
1824 void MapEditor::setHeadingInt(const QString &s)
1827 (typeid(*selection) == typeid(BranchObj) ||
1828 typeid(*selection) == typeid(MapCenterObj) ) )
1830 ((BranchObj*)selection)->setHeading(s);
1831 mapCenter->reposition();
1832 ensureSelectionVisible();
1836 void MapEditor::setVymLinkInt (const QString &s)
1838 // Internal function, no saveState needed
1840 (typeid(*selection) == typeid(BranchObj) ||
1841 typeid(*selection) == typeid(MapCenterObj) ) )
1843 ((BranchObj*)selection)->setVymLink(s);
1844 mapCenter->reposition();
1845 ensureSelectionVisible();
1849 BranchObj* MapEditor::addNewBranchInt(int num)
1851 // Depending on pos:
1852 // -3 insert in childs of parent above selection
1853 // -2 add branch to selection
1854 // -1 insert in childs of parent below selection
1855 // 0..n insert in childs of parent at pos
1856 BranchObj *newbo=NULL;
1858 (typeid(*selection) == typeid(BranchObj) ||
1859 typeid(*selection) == typeid(MapCenterObj) ) )
1861 BranchObj* bo = (BranchObj*) selection;
1864 // save scroll state. If scrolled, automatically select
1865 // new branch in order to tmp unscroll parent...
1866 return bo->addBranch();
1871 bo=(BranchObj*)bo->getParObj();
1875 bo=(BranchObj*)bo->getParObj();
1878 newbo=bo->insertBranch(num);
1883 BranchObj* MapEditor::addNewBranch(int pos)
1885 // Different meaning than num in addNewBranchInt!
1889 BranchObj *bo = (BranchObj*) selection;
1890 BranchObj *newbo=NULL;
1893 (typeid(*selection) == typeid(BranchObj) ||
1894 typeid(*selection) == typeid(MapCenterObj) ) )
1896 setCursor (Qt::ArrowCursor);
1898 newbo=addNewBranchInt (pos-2);
1906 QString ("addBranch (%1)").arg(pos-2),
1907 QString ("Add new branch to %1").arg(getName(bo)));
1909 mapCenter->reposition();
1916 BranchObj* MapEditor::addNewBranchBefore()
1918 BranchObj *newbo=NULL;
1920 (typeid(*selection) == typeid(BranchObj) ) )
1921 // We accept no MapCenterObj here, so we _have_ a parent
1923 BranchObj* bo = (BranchObj*) selection;
1924 QPointF p=bo->getRelPos();
1927 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1929 // add below selection
1930 newbo=parbo->insertBranch(bo->getNum()+1);
1933 newbo->move2RelPos (p);
1935 // Move selection to new branch
1936 ((BranchObj*)selection)->linkTo (newbo,-1);
1938 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
1939 QString ("Add branch before %1").arg(getName(bo)));
1941 mapCenter->reposition();
1947 void MapEditor::deleteSelection()
1949 if (selection && typeid(*selection) ==typeid(BranchObj) )
1951 BranchObj* bo=(BranchObj*)selection;
1952 BranchObj* par=(BranchObj*)(bo->getParObj());
1954 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
1956 par->removeBranch(bo);
1958 selection->select();
1959 ensureSelectionVisible();
1960 mapCenter->reposition();
1962 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
1964 FloatImageObj* fio=(FloatImageObj*)selection;
1965 BranchObj* par=(BranchObj*)(fio->getParObj());
1966 saveStateChangingPart(
1970 QString("Delete %1").arg(getName(fio))
1974 par->removeFloatImage(fio);
1976 selection->select();
1977 ensureSelectionVisible();
1978 mapCenter->reposition();
1983 LinkableMapObj* MapEditor::getSelection()
1988 void MapEditor::unselect()
1992 selectionLast=selection;
1993 selection->unselect();
1998 void MapEditor::reselect()
2002 selection=selectionLast;
2003 selection->select();
2008 bool MapEditor::select (const QString &s)
2010 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2012 // Finally select the found object
2015 if (selection) unselect();
2017 selection->select();
2018 ensureSelectionVisible();
2024 QString MapEditor::getSelectString()
2026 if (selection) return selection->getSelectString();
2030 void MapEditor::selectInt (LinkableMapObj *lmo)
2032 if (lmo && selection != lmo)
2034 // select the MapObj
2035 if (selection) selection->unselect();
2037 selection->select();
2041 void MapEditor::selectNextBranchInt()
2043 // Increase number of branch
2046 QString s=selection->getSelectString();
2052 part=s.section(",",-1);
2054 num=part.right(part.length() - 3);
2056 s=s.left (s.length() -num.length());
2059 num=QString ("%1").arg(num.toUInt()+1);
2063 // Try to select this one
2064 if (select (s)) return;
2066 // We have no direct successor,
2067 // try to increase the parental number in order to
2068 // find a successor with same depth
2070 int d=selection->getDepth();
2075 while (!found && d>0)
2077 s=s.section (",",0,d-1);
2078 // replace substring of current depth in s with "1"
2079 part=s.section(",",-1);
2081 num=part.right(part.length() - 3);
2085 // increase number of parent
2086 num=QString ("%1").arg(num.toUInt()+1);
2087 s=s.section (",",0,d-2) + ","+ typ+num;
2090 // Special case, look at orientation
2091 if (selection->getOrientation()==OrientRightOfCenter)
2092 num=QString ("%1").arg(num.toUInt()+1);
2094 num=QString ("%1").arg(num.toUInt()-1);
2099 // pad to oldDepth, select the first branch for each depth
2100 for (i=d;i<oldDepth;i++)
2105 if ( ((BranchObj*)selection)->countBranches()>0)
2113 // try to select the freshly built string
2121 void MapEditor::selectPrevBranchInt()
2123 // Decrease number of branch
2126 QString s=selection->getSelectString();
2132 part=s.section(",",-1);
2134 num=part.right(part.length() - 3);
2136 s=s.left (s.length() -num.length());
2138 int n=num.toInt()-1;
2141 num=QString ("%1").arg(n);
2144 // Try to select this one
2145 if (n>=0 && select (s)) return;
2147 // We have no direct precessor,
2148 // try to decrease the parental number in order to
2149 // find a precessor with same depth
2151 int d=selection->getDepth();
2156 while (!found && d>0)
2158 s=s.section (",",0,d-1);
2159 // replace substring of current depth in s with "1"
2160 part=s.section(",",-1);
2162 num=part.right(part.length() - 3);
2166 // decrease number of parent
2167 num=QString ("%1").arg(num.toInt()-1);
2168 s=s.section (",",0,d-2) + ","+ typ+num;
2171 // Special case, look at orientation
2172 if (selection->getOrientation()==OrientRightOfCenter)
2173 num=QString ("%1").arg(num.toInt()-1);
2175 num=QString ("%1").arg(num.toInt()+1);
2180 // pad to oldDepth, select the last branch for each depth
2181 for (i=d;i<oldDepth;i++)
2185 if ( ((BranchObj*)selection)->countBranches()>0)
2186 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
2193 // try to select the freshly built string
2201 void MapEditor::selectUpperBranch()
2205 if (typeid(*selection) == typeid(BranchObj))
2207 if (selection->getOrientation()==OrientRightOfCenter)
2208 selectPrevBranchInt();
2210 if (selection->getDepth()==1)
2211 selectNextBranchInt();
2213 selectPrevBranchInt();
2218 void MapEditor::selectLowerBranch()
2222 if (typeid(*selection) == typeid(BranchObj))
2224 if (selection->getOrientation()==OrientRightOfCenter)
2225 selectNextBranchInt();
2227 if (selection->getDepth()==1)
2228 selectPrevBranchInt();
2230 selectNextBranchInt();
2236 void MapEditor::selectLeftBranch()
2242 if (typeid(*selection) == typeid(MapCenterObj))
2244 par= (BranchObj*) selection;
2245 bo=par->getLastSelectedBranch();
2248 // Workaround for reselecting on left and right side
2249 if (bo->getOrientation()==OrientRightOfCenter)
2251 bo=par->getLastBranch();
2257 selection->select();
2258 ensureSelectionVisible();
2263 par=(BranchObj*)(selection->getParObj());
2264 if (selection->getOrientation()==OrientRightOfCenter)
2266 if (typeid(*selection) == typeid(BranchObj) ||
2267 typeid(*selection) == typeid(FloatImageObj))
2269 selection->unselect();
2271 selection->select();
2272 ensureSelectionVisible();
2276 if (typeid(*selection) == typeid(BranchObj) )
2278 bo=((BranchObj*)selection)->getLastSelectedBranch();
2281 selection->unselect();
2283 selection->select();
2284 ensureSelectionVisible();
2292 void MapEditor::selectRightBranch()
2299 if (typeid(*selection) == typeid(MapCenterObj))
2301 par= (BranchObj*) selection;
2302 bo=par->getLastSelectedBranch();
2305 // Workaround for reselecting on left and right side
2306 if (bo->getOrientation()==OrientLeftOfCenter)
2307 bo=par->getFirstBranch();
2312 selection->select();
2313 ensureSelectionVisible();
2318 par=(BranchObj*)(selection->getParObj());
2319 if (selection->getOrientation()==OrientLeftOfCenter)
2321 if (typeid(*selection) == typeid(BranchObj) ||
2322 typeid(*selection) == typeid(FloatImageObj))
2324 selection->unselect();
2326 selection->select();
2327 ensureSelectionVisible();
2331 if (typeid(*selection) == typeid(BranchObj) )
2333 bo=((BranchObj*)selection)->getLastSelectedBranch();
2336 selection->unselect();
2338 selection->select();
2339 ensureSelectionVisible();
2347 void MapEditor::selectFirstBranch()
2353 if (typeid(*selection) == typeid(BranchObj))
2355 bo1= (BranchObj*) selection;
2356 par=(BranchObj*)(bo1->getParObj());
2357 bo2=par->getFirstBranch();
2361 selection->select();
2362 ensureSelectionVisible();
2368 void MapEditor::selectLastBranch()
2374 if (typeid(*selection) == typeid(BranchObj))
2376 bo1= (BranchObj*) selection;
2377 par=(BranchObj*)(bo1->getParObj());
2378 bo2=par->getLastBranch();
2382 selection->select();
2383 ensureSelectionVisible();
2389 void MapEditor::selectMapBackgroundImage ()
2391 Q3FileDialog *fd=new Q3FileDialog( this);
2392 fd->setMode (Q3FileDialog::ExistingFile);
2393 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2394 ImagePreview *p =new ImagePreview (fd);
2395 fd->setContentsPreviewEnabled( TRUE );
2396 fd->setContentsPreview( p, p );
2397 fd->setPreviewMode( Q3FileDialog::Contents );
2398 fd->setCaption(vymName+" - " +tr("Load background image"));
2399 fd->setDir (lastImageDir);
2402 if ( fd->exec() == QDialog::Accepted )
2404 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2405 lastImageDir=QDir (fd->dirPath());
2406 setMapBackgroundImage (fd->selectedFile());
2410 void MapEditor::setMapBackgroundImage (const QString &fn)
2412 QColor oldcol=mapScene->backgroundBrush().color();
2416 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2418 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2419 QString("Set background color of map to %1").arg(col.name()));
2421 cout << "Trying to load "<<fn.ascii()<<endl;
2423 brush.setTextureImage (QPixmap (fn));
2424 mapScene->setBackgroundBrush(brush);
2427 void MapEditor::selectMapBackgroundColor()
2429 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2430 if ( !col.isValid() ) return;
2431 setMapBackgroundColor( col );
2435 void MapEditor::setMapBackgroundColor(QColor col)
2437 QColor oldcol=mapScene->backgroundBrush().color();
2440 QString ("setMapBackgroundColor (%1)").arg(oldcol.name()),
2442 QString ("setMapBackgroundColor (%1)").arg(col.name()),
2443 QString("Set background color of map to %1").arg(col.name()));
2444 mapScene->setBackgroundBrush(col);
2447 QColor MapEditor::getMapBackgroundColor()
2449 return mapScene->backgroundBrush().color();
2452 QColor MapEditor::getCurrentHeadingColor()
2456 if (typeid(*selection) == typeid(BranchObj) ||
2457 typeid(*selection) == typeid(MapCenterObj))
2459 BranchObj *bo=(BranchObj*)selection;
2460 return bo->getColor();
2464 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2468 void MapEditor::colorBranch (QColor c)
2472 if (typeid(*selection) == typeid(BranchObj) ||
2473 typeid(*selection) == typeid(MapCenterObj))
2475 BranchObj *bo=(BranchObj*)selection;
2478 QString ("colorBranch (%1)").arg(bo->getColor().name()),
2480 QString ("colorBranch (%1)").arg(c.name()),
2481 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2483 bo->setColor(c); // color branch
2488 void MapEditor::colorSubtree (QColor c)
2492 if (typeid(*selection) == typeid(BranchObj) ||
2493 typeid(*selection) == typeid(MapCenterObj))
2495 BranchObj *bo=(BranchObj*)selection;
2496 saveStateChangingPart(
2499 QString ("colorSubtree (%1)").arg(c.name()),
2500 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2502 bo->setColorSubtree (c); // color links, color childs
2508 void MapEditor::toggleStandardFlag(QString f)
2512 if (typeid(*selection) == typeid(BranchObj) ||
2513 typeid(*selection) == typeid(MapCenterObj))
2515 BranchObj *bo=(BranchObj*)selection;
2517 if (bo->isSetStandardFlag(f))
2529 QString("%1 (\"%2\")").arg(u).arg(f),
2531 QString("%1 (\"%2\")").arg(r).arg(f),
2532 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2533 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2539 BranchObj* MapEditor::findText (QString s, bool cs)
2541 QTextDocument::FindFlags flags=0;
2542 if (cs) flags=QTextDocument::FindCaseSensitively;
2545 { // Nothing found or new find process
2547 // nothing found, start again
2549 itFind=mapCenter->first();
2551 bool searching=true;
2552 bool foundNote=false;
2553 while (searching && !EOFind)
2557 // Searching in Note
2558 if (itFind->getNote().contains(s,cs))
2560 if (selection!=itFind)
2562 if (selection) ((BranchObj*)selection)->unselect();
2564 selection->select();
2565 ensureSelectionVisible();
2567 if (textEditor->findText(s,flags))
2573 // Searching in Heading
2574 if (searching && itFind->getHeading().contains (s,cs) )
2576 if (selection) ((BranchObj*)selection)->unselect();
2578 selection->select();
2579 ensureSelectionVisible();
2585 itFind=itFind->next();
2586 if (!itFind) EOFind=true;
2591 return (BranchObj*)selection;
2596 void MapEditor::findReset()
2597 { // Necessary if text to find changes during a find process
2601 void MapEditor::setURL(const QString &url)
2603 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2604 typeid(*selection) == typeid(MapCenterObj)) )
2606 BranchObj *bo=(BranchObj*)selection;
2607 QString oldurl=bo->getURL();
2611 QString ("setURL (\"%1\")").arg(oldurl),
2613 QString ("setURL (\"%1\")").arg(url),
2614 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2620 void MapEditor::editURL()
2622 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2623 typeid(*selection) == typeid(MapCenterObj)) )
2626 BranchObj *bo=(BranchObj*)selection;
2627 QString text = QInputDialog::getText(
2628 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2629 bo->getURL(), &ok, this );
2631 // user entered something and pressed OK
2636 QString MapEditor::getURL()
2638 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2639 typeid(*selection) == typeid(MapCenterObj)) )
2640 return ((BranchObj*)selection)->getURL();
2645 QStringList MapEditor::getURLs()
2648 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2649 typeid(*selection) == typeid(MapCenterObj)) )
2651 BranchObj *bo=(BranchObj*)selection;
2655 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2663 void MapEditor::editHeading2URL()
2665 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2666 typeid(*selection) == typeid(MapCenterObj)) )
2667 setURL (((BranchObj*)selection)->getHeading());
2670 void MapEditor::editBugzilla2URL()
2672 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2673 typeid(*selection) == typeid(MapCenterObj)) )
2675 BranchObj *bo=(BranchObj*)selection;
2676 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2681 void MapEditor::editFATE2URL()
2683 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2684 typeid(*selection) == typeid(MapCenterObj)) )
2686 BranchObj *bo=(BranchObj*)selection;
2687 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2690 "setURL (\""+bo->getURL()+"\")",
2692 "setURL (\""+url+"\")",
2693 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2700 void MapEditor::editVymLink()
2702 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2703 typeid(*selection) == typeid(MapCenterObj)) )
2705 BranchObj *bo=(BranchObj*)selection;
2706 QStringList filters;
2707 filters <<"VYM map (*.vym)";
2708 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2709 fd->setFilters (filters);
2710 fd->setCaption(vymName+" - " +tr("Link to another map"));
2711 if (! bo->getVymLink().isEmpty() )
2712 fd->selectFile( bo->getVymLink() );
2716 if ( fd->exec() == QDialog::Accepted )
2720 "setVymLink (\""+bo->getVymLink()+"\")",
2722 "setVymLink (\""+fd->selectedFile()+"\")",
2723 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2725 bo->setVymLink (fd->selectedFile() );
2727 mapCenter->reposition();
2733 void MapEditor::deleteVymLink()
2735 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2736 typeid(*selection) == typeid(MapCenterObj)) )
2738 BranchObj *bo=(BranchObj*)selection;
2741 "setVymLink (\""+bo->getVymLink()+"\")",
2743 "setVymLink (\"\")",
2744 QString("Unset vymlink of %1").arg(getName(bo))
2746 bo->setVymLink ("" );
2748 mapCenter->reposition();
2753 void MapEditor::setHideExport(bool b)
2755 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2756 typeid(*selection)==typeid(FloatImageObj)))
2758 OrnamentedObj *oo=(OrnamentedObj*)selection;
2759 oo->setHideInExport (b);
2760 QString u= b ? "false" : "true";
2761 QString r=!b ? "false" : "true";
2765 QString ("setHideExport (%1)").arg(u),
2767 QString ("setHideExport (%1)").arg(r),
2768 QString ("Set HideExport flag of %1 to %2").arg(getName(oo)).arg (r)
2771 mapCenter->reposition();
2776 void MapEditor::toggleHideExport()
2778 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2779 typeid(*selection)==typeid(FloatImageObj)))
2780 setHideExport ( !((OrnamentedObj*)selection)->hideInExport() );
2783 QString MapEditor::getVymLink()
2785 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2786 typeid(*selection) == typeid(MapCenterObj)) )
2788 return ((BranchObj*)selection)->getVymLink();
2794 QStringList MapEditor::getVymLinks()
2797 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2798 typeid(*selection) == typeid(MapCenterObj)) )
2800 BranchObj *bo=(BranchObj*)selection;
2804 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2812 void MapEditor::deleteKeepChilds()
2814 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2816 BranchObj* bo=(BranchObj*)selection;
2817 BranchObj* par=(BranchObj*)(bo->getParObj());
2818 QPointF p=bo->getRelPos();
2819 saveStateChangingPart(
2820 selection->getParObj(),
2822 "deleteKeepChilds ()",
2823 QString("Remove %1 and keep its childs").arg(getName(bo))
2826 QString sel=selection->getSelectString();
2828 par->removeBranchHere(bo);
2829 mapCenter->reposition();
2831 ((BranchObj*)selection)->move2RelPos (p);
2832 mapCenter->reposition();
2836 void MapEditor::deleteChilds()
2838 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2839 typeid(*selection)==typeid(MapCenterObj)))
2841 saveStateChangingPart(
2842 selection->getParObj(),
2845 QString( "Remove childs of branch %1").arg(getName(selection))
2847 ((BranchObj*)selection)->removeChilds();
2848 mapCenter->reposition();
2852 void MapEditor::editMapInfo()
2854 ExtraInfoDialog dia;
2855 dia.setMapName (getFileName() );
2856 dia.setAuthor (mapCenter->getAuthor() );
2857 dia.setComment(mapCenter->getComment() );
2861 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
2868 bo=mapCenter->first();
2871 if (!bo->getNote().isEmpty() ) n++;
2872 f+= bo->countFloatImages();
2874 xl+=bo->countXLinks();
2877 stats+=QString ("%1 branches\n").arg (b-1,6);
2878 stats+=QString ("%1 xLinks \n").arg (xl,6);
2879 stats+=QString ("%1 notes\n").arg (n,6);
2880 stats+=QString ("%1 images\n").arg (f,6);
2881 dia.setStats (stats);
2883 // Finally show dialog
2884 if (dia.exec() == QDialog::Accepted)
2886 setMapAuthor (dia.getAuthor() );
2887 setMapComment (dia.getComment() );
2891 void MapEditor::updateActions()
2893 mainWindow->updateActions();
2894 // TODO maybe don't update if blockReposition is set
2897 void MapEditor::updateNoteFlag()
2900 if ( (typeid(*selection) == typeid(BranchObj)) ||
2901 (typeid(*selection) == typeid(MapCenterObj)) )
2902 ((BranchObj*)selection)->updateNoteFlag();
2905 void MapEditor::setMapAuthor (const QString &s)
2909 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
2911 QString ("setMapAuthor (\"%1\")").arg(s),
2912 QString ("Set author of map to \"%1\"").arg(s)
2914 mapCenter->setAuthor (s);
2917 void MapEditor::setMapComment (const QString &s)
2921 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
2923 QString ("setMapComment (\"%1\")").arg(s),
2924 QString ("Set comment of map")
2926 mapCenter->setComment (s);
2929 void MapEditor::setMapLinkStyle (const QString & s)
2931 saveStateChangingPart (
2934 QString("setMapLinkStyle (\"%1\")").arg(s),
2935 QString("Set map link style (\"%1\")").arg(s)
2939 linkstyle=StyleLine;
2940 else if (s=="StyleParabel")
2941 linkstyle=StyleParabel;
2942 else if (s=="StylePolyLine")
2943 linkstyle=StylePolyLine;
2945 linkstyle=StylePolyParabel;
2948 bo=mapCenter->first();
2952 bo->setLinkStyle(bo->getDefLinkStyle());
2955 mapCenter->reposition();
2958 LinkStyle MapEditor::getMapLinkStyle ()
2963 void MapEditor::setMapDefLinkColor(QColor c)
2969 void MapEditor::setMapLinkColorHintInt()
2971 // called from setMapLinkColorHint(lch) or at end of parse
2973 bo=mapCenter->first();
2981 void MapEditor::setMapLinkColorHint(LinkColorHint lch)
2984 setMapLinkColorHintInt();
2987 void MapEditor::toggleMapLinkColorHint()
2989 if (linkcolorhint==HeadingColor)
2990 linkcolorhint=DefaultColor;
2992 linkcolorhint=HeadingColor;
2994 bo=mapCenter->first();
3002 LinkColorHint MapEditor::getMapLinkColorHint()
3004 return linkcolorhint;
3007 QColor MapEditor::getMapDefLinkColor()
3009 return defLinkColor;
3012 void MapEditor::setMapDefXLinkColor(QColor col)
3017 QColor MapEditor::getMapDefXLinkColor()
3019 return defXLinkColor;
3022 void MapEditor::setMapDefXLinkWidth (int w)
3027 int MapEditor::getMapDefXLinkWidth()
3029 return defXLinkWidth;
3032 void MapEditor::selectMapLinkColor()
3034 QColor col = QColorDialog::getColor( defLinkColor, this );
3035 if ( !col.isValid() ) return;
3038 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3040 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3041 QString("Set link color to %1").arg(col.name())
3043 setMapDefLinkColor( col );
3047 void MapEditor::toggleScroll()
3049 if (selection && (typeid(*selection) == typeid(BranchObj)) )
3051 BranchObj *bo=((BranchObj*)selection);
3052 if (bo->countBranches()==0) return;
3053 if (bo->getDepth()==0) return;
3055 if (bo->isScrolled())
3067 QString ("%1 ()").arg(u),
3069 QString ("%1 ()").arg(r),
3070 QString ("%1 %2").arg(r).arg(getName(bo))
3077 void MapEditor::unScrollAll()
3080 bo=mapCenter->first();
3083 if (bo->isScrolled()) bo->toggleScroll();
3088 void MapEditor::loadFloatImage ()
3091 (typeid(*selection) == typeid(BranchObj)) ||
3092 (typeid(*selection) == typeid(MapCenterObj)) )
3094 BranchObj *bo=((BranchObj*)selection);
3096 Q3FileDialog *fd=new Q3FileDialog( this);
3097 fd->setMode (Q3FileDialog::ExistingFiles);
3098 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3099 ImagePreview *p =new ImagePreview (fd);
3100 fd->setContentsPreviewEnabled( TRUE );
3101 fd->setContentsPreview( p, p );
3102 fd->setPreviewMode( Q3FileDialog::Contents );
3103 fd->setCaption(vymName+" - " +tr("Load image"));
3104 fd->setDir (lastImageDir);
3108 if ( fd->exec() == QDialog::Accepted )
3110 // FIXME loadFIO in QT4 use: lastImageDir=fd->directory();
3111 lastImageDir=QDir (fd->dirPath());
3112 QStringList flist = fd->selectedFiles();
3113 QStringList::Iterator it = flist.begin();
3115 while( it != flist.end() )
3118 bo->addFloatImage();
3119 fio=bo->getLastFloatImage();
3121 // FIXME loadFIO check if load of fio was successful
3123 (LinkableMapObj*)fio,
3126 QString ("loadFloatImage (%1)").arg(*it),
3127 QString("Add floatimage %1 to %2").arg(*it).arg(getName(selection))
3129 bo->getLastFloatImage()->setOriginalFilename(fn);
3133 mapCenter->reposition();
3141 void MapEditor::saveFloatImage ()
3144 (typeid(*selection) == typeid(FloatImageObj)) )
3146 FloatImageObj *fio=((FloatImageObj*)selection);
3147 QFileDialog *fd=new QFileDialog( this);
3148 fd->setFilters (imageIO.getFilters());
3149 fd->setCaption(vymName+" - " +tr("Save image"));
3150 fd->setFileMode( QFileDialog::AnyFile );
3151 fd->setDirectory (lastImageDir);
3152 // fd->setSelection (fio->getOriginalFilename());
3156 if ( fd->exec() == QDialog::Accepted )
3158 if (QFile (fd->selectedFile()).exists() )
3160 QMessageBox mb( vymName,
3161 tr("The file %1 exists already.\n"
3162 "Do you want to overwrite it?").arg(fd->selectedFile()),
3163 QMessageBox::Warning,
3164 QMessageBox::Yes | QMessageBox::Default,
3165 QMessageBox::Cancel | QMessageBox::Escape,
3166 QMessageBox::QMessageBox::NoButton );
3168 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3169 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3172 case QMessageBox::Yes:
3175 case QMessageBox::Cancel:
3182 fio->save (fd->selectedFile(),imageIO.getType (fd->selectedFilter() ) );
3188 void MapEditor::setFrame(const FrameType &t) // FIXME missing saveState
3191 (typeid(*selection) == typeid(BranchObj)) ||
3192 (typeid(*selection) == typeid(MapCenterObj)) )
3194 selection->setFrameType (t);
3195 mapCenter->reposition();
3196 selection->updateLink();
3200 void MapEditor::setIncludeImagesVer(bool b) // FIXME missing saveState
3203 (typeid(*selection) == typeid(BranchObj)) ||
3204 (typeid(*selection) == typeid(MapCenterObj)) )
3205 ((BranchObj*)selection)->setIncludeImagesVer(b);
3206 mapCenter->reposition();
3209 void MapEditor::setIncludeImagesHor(bool b) // FIXME missing saveState
3212 (typeid(*selection) == typeid(BranchObj)) ||
3213 (typeid(*selection) == typeid(MapCenterObj)) )
3214 ((BranchObj*)selection)->setIncludeImagesHor(b);
3215 mapCenter->reposition();
3218 void MapEditor::setHideLinkUnselected (bool b) // FIXME missing saveState
3221 (typeid(*selection) == typeid(BranchObj)) ||
3222 (typeid(*selection) == typeid(MapCenterObj)) ||
3223 (typeid(*selection) == typeid(FloatImageObj)) )
3224 selection->setHideLinkUnselected(b);
3227 void MapEditor::importDirInt(BranchObj *dst, QDir d) // FIXME missing saveState
3230 (typeid(*selection) == typeid(BranchObj)) ||
3231 (typeid(*selection) == typeid(MapCenterObj)) )
3235 // Traverse directories
3236 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3237 QFileInfoList list = d.entryInfoList();
3240 for (int i = 0; i < list.size(); ++i)
3243 if (fi.fileName() != "." && fi.fileName() != ".." )
3246 bo=dst->getLastBranch();
3247 bo->setHeading (fi.fileName() );
3248 bo->setColor (QColor("blue"));
3250 if ( !d.cd(fi.fileName()) )
3251 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3254 // Recursively add subdirs
3255 importDirInt (bo,d);
3261 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3262 list = d.entryInfoList();
3264 for (int i = 0; i < list.size(); ++i)
3268 bo=dst->getLastBranch();
3269 bo->setHeading (fi.fileName() );
3270 bo->setColor (QColor("black"));
3271 if (fi.fileName().right(4) == ".vym" )
3272 bo->setVymLink (fi.filePath());
3277 void MapEditor::importDir()
3280 (typeid(*selection) == typeid(BranchObj)) ||
3281 (typeid(*selection) == typeid(MapCenterObj)) )
3283 QStringList filters;
3284 filters <<"VYM map (*.vym)";
3285 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3286 fd->setMode (QFileDialog::DirectoryOnly);
3287 fd->setFilters (filters);
3288 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3292 if ( fd->exec() == QDialog::Accepted )
3294 BranchObj *bo=((BranchObj*)selection);
3295 importDirInt (bo,QDir(fd->selectedFile()) );
3296 mapCenter->reposition();
3302 void MapEditor::followXLink(int i)
3305 (typeid(*selection) == typeid(BranchObj)) ||
3306 (typeid(*selection) == typeid(MapCenterObj)) )
3308 BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
3311 selection->unselect();
3313 selection->select();
3314 ensureSelectionVisible();
3319 void MapEditor::editXLink(int i) // FIXME missing saveState
3322 (typeid(*selection) == typeid(BranchObj)) ||
3323 (typeid(*selection) == typeid(MapCenterObj)) )
3325 XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
3328 EditXLinkDialog dia;
3330 dia.setSelection(selection);
3331 if (dia.exec() == QDialog::Accepted)
3333 if (dia.useSettingsGlobal() )
3335 setMapDefXLinkColor (xlo->getColor() );
3336 setMapDefXLinkWidth (xlo->getWidth() );
3338 if (dia.deleteXLink())
3339 ((BranchObj*)selection)->deleteXLinkAt(i);
3345 void MapEditor::testFunction()
3347 // This is the playground
3350 dia.showCancelButton (true);
3351 dia.setText("This is a longer \nWarning");
3353 dia.setCaption("Warning: Flux problem");
3354 dia.setShowAgainName("/warnings/mapeditor");
3356 if (dia.exec()==QDialog::Accepted)
3357 cout << "accepted!\n";
3359 cout << "canceled!\n";
3362 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
3363 if (hidemode==HideNone)
3365 setHideTmpMode (HideExport);
3366 mapCenter->calcBBoxSizeWithChilds();
3367 QRectF totalBBox=mapCenter->getTotalBBox();
3368 QRectF mapRect=totalBBox;
3369 QCanvasRectangle *frame=NULL;
3371 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3373 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3374 totalBBox.width(), totalBBox.height());
3375 frame=new QCanvasRectangle (mapRect,mapScene);
3376 frame->setBrush (QColor(white));
3377 frame->setPen (QColor(black));
3378 frame->setZValue(0);
3383 setHideTmpMode (HideNone);
3385 cout <<" hidemode="<<hidemode<<endl;
3389 void MapEditor::ensureSelectionVisible()
3393 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
3394 ensureVisible (lmo->getBBox());
3399 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3401 // Lineedits are already closed by preceding
3402 // mouseEvent, we don't need to close here.
3404 QPointF p = mapToScene(e->pos());
3405 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3408 { // MapObj was found
3409 if (selection != lmo)
3411 // select the MapObj
3412 if (selection) selection->unselect();
3414 selection->select();
3419 if (typeid(*selection)==typeid(BranchObj) ||
3420 typeid(*selection)==typeid(MapCenterObj) )
3422 // Context Menu on branch or mapcenter
3424 branchContextMenu->popup(e->globalPos() );
3426 if (typeid(*selection)==typeid(FloatImageObj))
3428 // Context Menu on floatimage
3430 floatimageContextMenu->popup(e->globalPos() );
3434 { // No MapObj found, we are on the Canvas itself
3435 // Context Menu on scene
3437 canvasContextMenu->popup(e->globalPos() );
3442 void MapEditor::keyPressEvent(QKeyEvent* e)
3444 if (e->modifiers() & Qt::ControlModifier)
3446 switch (mainWindow->getModMode())
3449 setCursor (PickColorCursor);
3452 setCursor (CopyCursor);
3455 setCursor (XLinkCursor);
3458 setCursor (Qt::ArrowCursor);
3464 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3466 if (!(e->modifiers() & Qt::ControlModifier))
3467 setCursor (Qt::ArrowCursor);
3470 void MapEditor::mousePressEvent(QMouseEvent* e)
3472 // Ignore right clicks, these will go to context menus
3473 if (e->button() == Qt::RightButton )
3479 QPointF p = mapToScene(e->pos());
3480 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3484 //Take care of clickdesystem flags _or_ modifier modes
3486 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3487 typeid(*lmo)==typeid(MapCenterObj) ))
3489 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3490 if (!foname.isEmpty())
3492 // systemFlag clicked
3496 if (e->state() & Qt::ControlModifier)
3497 mainWindow->editOpenURLTab();
3499 mainWindow->editOpenURL();
3501 else if (foname=="vymLink")
3503 mainWindow->editOpenVymLink();
3504 // tabWidget may change, better return now
3505 // before segfaulting...
3506 } else if (foname=="note")
3507 mainWindow->windowToggleNoteEditor();
3508 else if (foname=="hideInExport")
3513 // No system flag clicked, take care of modmodes
3515 // Special case: CTRL is pressed
3516 if (e->state() & Qt::ControlModifier)
3518 if (mainWindow->getModMode()==ModModeColor)
3521 setCursor (PickColorCursor);
3524 if (mainWindow->getModMode()==ModModeXLink)
3526 BranchObj *bo_begin=NULL;
3528 bo_begin=(BranchObj*)(lmo);
3531 ((typeid(*selection) == typeid(BranchObj)) ||
3532 (typeid(*selection) == typeid(MapCenterObj))) )
3533 bo_begin=(BranchObj*)selection;
3537 linkingObj_src=bo_begin;
3538 tmpXLink=new XLinkObj (mapScene);
3539 tmpXLink->setBegin (bo_begin);
3540 tmpXLink->setEnd (p);
3541 tmpXLink->setColor(defXLinkColor);
3542 tmpXLink->setWidth(defXLinkWidth);
3543 tmpXLink->updateXLink();
3544 tmpXLink->setVisibility (true);
3552 // Left Button Move Branches
3553 if (e->button() == Qt::LeftButton )
3555 movingObj_start.setX( p.x() - selection->x() );
3556 movingObj_start.setY( p.y() - selection->y() );
3557 movingObj_orgPos.setX (lmo->x() );
3558 movingObj_orgPos.setY (lmo->y() );
3559 movingObj_orgRelPos=lmo->getRelPos();
3561 // If modMode==copy, then we want to "move" the _new_ object around
3562 // then we need the offset from p to the _old_ selection, because of tmp
3563 if (mainWindow->getModMode()==ModModeCopy &&
3564 e->state() & Qt::ControlModifier)
3566 if (typeid(*selection)==typeid(BranchObj) )
3569 mapCenter->addBranch ((BranchObj*)selection);
3571 selection=mapCenter->getLastBranch();
3572 selection->select();
3573 mapCenter->reposition();
3577 movingObj=selection;
3579 // Middle Button Toggle Scroll
3580 // (On Mac OS X this won't work, but we still have
3581 // a button in the toolbar)
3582 if (e->button() == Qt::MidButton )
3586 { // No MapObj found, we are on the scene itself
3587 // Left Button move Pos of sceneView
3588 if (e->button() == Qt::LeftButton )
3590 movingObj=NULL; // move Content not Obj
3591 movingObj_start=e->globalPos();
3592 movingCont_start=QPointF (
3593 horizontalScrollBar()->value(),
3594 verticalScrollBar()->value());
3595 movingVec=QPointF(0,0);
3596 setCursor(HandOpenCursor);
3601 void MapEditor::mouseMoveEvent(QMouseEvent* e)
3603 QPointF p = mapToScene(e->pos());
3605 // Move the selected MapObj
3606 if ( selection && movingObj)
3608 // reset cursor if we are moving and don't copy
3609 if (mainWindow->getModMode()!=ModModeCopy)
3610 setCursor (Qt::ArrowCursor);
3612 // To avoid jumping of the sceneView, only
3613 // ensureSelectionVisible, if not tmp linked
3614 if (!selection->hasParObjTmp())
3615 ensureSelectionVisible ();
3617 // Now move the selection, but add relative position
3618 // (movingObj_start) where selection was chosen with
3619 // mousepointer. (This avoids flickering resp. jumping
3620 // of selection back to absPos)
3622 LinkableMapObj *lmosel;
3623 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3625 // Check if we could link
3626 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3629 if (typeid(*selection) == typeid(FloatImageObj))
3631 FloatObj *fo=(FloatObj*)selection;
3632 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3634 fo->updateLink(); //no need for reposition, if we update link here
3636 // Relink float to new mapcenter or branch, if shift is pressed
3637 // Only relink, if selection really has a new parent
3638 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3639 ( (typeid(*lmo)==typeid(BranchObj)) ||
3640 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3641 ( lmo != fo->getParObj())
3644 if (typeid(*fo) == typeid(FloatImageObj) &&
3645 ( (typeid(*lmo)==typeid(BranchObj) ||
3646 typeid(*lmo)==typeid(MapCenterObj)) ))
3649 // Also save the move which was done so far
3650 FloatImageObj *fio=(FloatImageObj*)selection;
3651 QString pold=qpointfToString(movingObj_orgRelPos);
3652 QString pnow=qpointfToString(fio->getRelPos());
3658 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(pnow));
3659 fio->getParObj()->requestReposition();
3660 mapCenter->reposition();
3662 cout << "current relPos="<<movingObj_orgRelPos<<endl;
3663 linkTo (lmo->getSelectString());
3664 cout << "setting movingObj\n";
3665 movingObj=(MapObj*)selection;
3666 movingObj_orgRelPos=selection->getRelPos();
3669 mapCenter->reposition();
3673 { // selection != a FloatObj
3674 if (lmosel->getDepth()==0)
3677 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3678 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3680 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3681 mapCenter->updateRelPositions();
3684 if (lmosel->getDepth()==1)
3687 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3688 lmosel->setRelPos();
3691 // Move ordinary branch
3692 if (lmosel->getOrientation() == OrientLeftOfCenter)
3693 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3694 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3695 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3697 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3699 // reposition subbranch
3700 lmosel->reposition();
3702 if (lmo && (lmo!=selection) &&
3703 (typeid(*lmo) == typeid(BranchObj) ||
3704 (typeid(*lmo) == typeid(MapCenterObj) )
3707 if (e->modifiers()==Qt::ControlModifier)
3709 // Special case: CTRL to link below lmo
3710 lmosel->setParObjTmp (lmo,p,+1);
3712 else if (e->modifiers()==Qt::ShiftModifier)
3713 lmosel->setParObjTmp (lmo,p,-1);
3715 lmosel->setParObjTmp (lmo,p,0);
3718 lmosel->unsetParObjTmp();
3722 } // no FloatImageObj
3726 } // selection && moving_obj
3728 // Draw a link from one branch to another
3731 tmpXLink->setEnd (p);
3732 tmpXLink->updateXLink();
3736 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
3738 QPointF p=e->globalPos();
3739 movingVec.setX(-p.x() + movingObj_start.x() );
3740 movingVec.setY(-p.y() + movingObj_start.y() );
3741 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
3742 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
3747 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
3749 QPointF p = mapToScene(e->pos());
3750 LinkableMapObj *dst;
3751 // Have we been picking color?
3755 setCursor (Qt::ArrowCursor);
3756 // Check if we are over another branch
3757 dst=mapCenter->findMapObj(p, NULL);
3758 if (dst && selection)
3760 if (e->state() & Qt::ShiftModifier)
3761 colorBranch (((BranchObj*)(dst))->getColor());
3763 colorSubtree (((BranchObj*)(dst))->getColor());
3768 // Have we been drawing a link?
3772 // Check if we are over another branch
3773 dst=mapCenter->findMapObj(p, NULL);
3774 if (dst && selection)
3776 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3777 tmpXLink->updateXLink();
3778 tmpXLink->activate();
3779 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //FIXME undoCommand
3788 // Have we been moving something?
3789 if ( selection && movingObj )
3791 if(typeid(*selection)==typeid (FloatImageObj))
3793 // Moved FloatObj. Maybe we need to reposition
3794 FloatImageObj *fo=(FloatImageObj*)selection;
3795 QString pold=qpointfToString(movingObj_orgRelPos);
3796 QString pnow=qpointfToString(fo->getRelPos());
3802 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(pnow));
3804 selection->getParObj()->requestReposition();
3805 mapCenter->reposition();
3808 // Check if we are over another branch, but ignore
3809 // any found LMOs, which are FloatObjs
3810 dst=mapCenter->findMapObj(mapToScene(e->pos() ),
3811 ((LinkableMapObj*)selection) );
3813 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3816 if (typeid(*selection) == typeid(MapCenterObj) )
3817 { // FIXME The MapCenter was moved, no savestate yet
3820 if (typeid(*selection) == typeid(BranchObj) )
3821 { // A branch was moved
3823 // save the position in case we link to mapcenter
3824 QPointF savePos=QPointF (selection->x(),selection->y() );
3826 // Reset the temporary drawn link to the original one
3827 ((LinkableMapObj*)selection)->unsetParObjTmp();
3829 // For Redo we may need to save original selection
3830 QString preSelStr=selection->getSelectString();
3835 BranchObj* bsel=(BranchObj*)selection;
3836 BranchObj* bdst=(BranchObj*)dst;
3838 QString preParStr=(bsel->getParObj())->getSelectString();
3839 QString preNum=QString::number (bsel->getNum(),10);
3840 QString preDstParStr;
3842 if (e->state() & Qt::ShiftModifier && dst->getParObj())
3844 preDstParStr=dst->getParObj()->getSelectString();
3845 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
3847 if (e->state() & Qt::ControlModifier && dst->getParObj())
3850 preDstParStr=dst->getParObj()->getSelectString();
3851 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
3854 preDstParStr=dst->getSelectString();
3855 bsel->linkTo (bdst,-1);
3856 if (dst->getDepth()==0) bsel->move (savePos);
3858 QString postSelStr=selection->getSelectString();
3859 QString postNum=QString::number (bsel->getNum(),10);
3861 QString undoCom="linkTo (\""+
3862 preParStr+ "\"," + preNum +"," +
3863 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
3865 QString redoCom="linkTo (\""+
3866 preDstParStr + "\"," + postNum + "," +
3867 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
3872 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
3874 if (selection->getDepth()==1)
3876 // The select string might be different _after_ moving around.
3877 // Therefor reposition and then use string of old selection, too
3878 mapCenter->reposition();
3880 QString ps=qpointfToString ( ((BranchObj*)selection)->getRelPos() );
3882 selection->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
3883 preSelStr, "moveRel "+ps,
3884 QString("Move %1 to relative position %2").arg(getName(selection)).arg(ps));
3887 // Draw the original link, before selection was moved around
3888 mapCenter->reposition();
3890 // Finally resize scene, if needed
3894 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
3897 // maybe we moved View: set old cursor
3898 setCursor (Qt::ArrowCursor);
3902 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
3904 if (e->button() == Qt::LeftButton )
3906 QPointF p = mapToScene(e->pos());
3907 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3908 if (lmo) { // MapObj was found
3909 // First select the MapObj than edit heading
3910 if (selection) selection->unselect();
3912 selection->select();
3913 mainWindow->editHeading();
3918 void MapEditor::resizeEvent (QResizeEvent* e)
3920 QGraphicsView::resizeEvent( e );
3923 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
3925 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
3926 // cerr << event->format(i) << endl;
3928 if (event->mimeData()->hasImage())
3929 event->acceptProposedAction();
3931 if (event->mimeData()->hasUrls())
3932 event->acceptProposedAction();
3935 void MapEditor::dragMoveEvent(QDragMoveEvent *event)
3939 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
3944 void MapEditor::dropEvent(QDropEvent *event)
3947 (typeid(*selection) == typeid(BranchObj)) ||
3948 (typeid(*selection) == typeid(MapCenterObj)))
3951 if (event->mimeData()->hasImage())
3953 QVariant imageData = event->mimeData()->imageData();
3954 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
3956 if (event->mimeData()->hasUrls())
3957 uris=event->mimeData()->urls();
3965 for (int i=0; i<uris.count();++i)
3967 bo=((BranchObj*)selection)->addBranch();
3970 s=uris.at(i).toLocalFile();
3973 QString file = QDir::convertSeparators(s);
3974 heading = QFileInfo(file).baseName();
3976 if (file.endsWith(".vym", false))
3977 bo->setVymLink(file);
3979 bo->setURL(uris.at(i).toString());
3982 bo->setURL(uris.at(i).toString());
3985 if (!heading.isEmpty())
3986 bo->setHeading(heading);
3988 bo->setHeading(uris.at(i).toString());
3991 mapCenter->reposition();
3994 event->acceptProposedAction();
3998 void MapEditor::contentsDropEvent(QDropEvent *event)
4001 } else if (event->provides("application/x-moz-file-promise-url") &&
4002 event->provides("application/x-moz-nativeimage"))
4004 // Contains url to the img src in unicode16
4005 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4006 QString url = QString((const QChar*)d.data(),d.size()/2);
4010 } else if (event->provides ("text/uri-list"))
4011 { // Uris provided e.g. by konqueror
4012 Q3UriDrag::decode (event,uris);
4013 } else if (event->provides ("_NETSCAPE_URL"))
4014 { // Uris provided by Mozilla
4015 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4018 } else if (event->provides("text/html")) {
4020 // Handels text mime types
4021 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4022 QByteArray d = event->encodedData("text/html");
4025 text = QString((const QChar*)d.data(),d.size()/2);
4029 textEditor->setText(text);
4033 } else if (event->provides("text/plain")) {
4034 QByteArray d = event->encodedData("text/plain");
4037 text = QString((const QChar*)d.data(),d.size()/2);
4041 textEditor->setText(text);
4051 bool isUnicode16(const QByteArray &d)
4053 // TODO: make more precise check for unicode 16.
4054 // Guess unicode16 if any of second bytes are zero
4055 unsigned int length = max(0,d.size()-2)/2;
4056 for (unsigned int i = 0; i<length ; i++)
4057 if (d.at(i*2+1)==0) return true;
4061 void MapEditor::addFloatImageInt (const QPixmap &img)
4064 (typeid(*selection) == typeid(BranchObj)) ||
4065 (typeid(*selection) == typeid(MapCenterObj)) )
4067 BranchObj *bo=((BranchObj*)selection);
4068 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4069 //QString fn=fd->selectedFile();
4070 //lastImageDir=fn.left(fn.findRev ("/"));
4071 FloatImageObj *fio=bo->addFloatImage();
4073 fio->setOriginalFilename("Image added by Drag and Drop");
4074 mapCenter->reposition();
4081 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4083 if (!imageBuffer) imageBuffer = new QBuffer();
4084 if (!imageBuffer->isOpen()) {
4085 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4087 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4091 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4093 if (nop->state()==Q3NetworkProtocol::StDone) {
4094 QPixmap img(imageBuffer->buffer());
4095 addFloatImageInt (img);
4099 imageBuffer->close();
4101 imageBuffer->close();
4108 void MapEditor::fetchImage(const QString &url)
4111 urlOperator->stop();
4112 disconnect(urlOperator);
4116 urlOperator = new Q3UrlOperator(url);
4117 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4118 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4120 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4121 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));