3 #include <q3dragobject.h>
4 #include <q3urloperator.h>
5 #include <q3networkprotocol.h>
6 #include <q3filedialog.h>
15 #include "editxlinkdialog.h"
17 #include "extrainfodialog.h"
19 #include "linkablemapobj.h"
20 #include "mainwindow.h"
22 #include "texteditor.h"
23 #include "warningdialog.h"
27 extern TextEditor *textEditor;
28 extern int statusbarTime;
29 extern Main *mainWindow;
30 extern QString tmpVymDir;
31 extern QString clipboardDir;
32 extern bool clipboardEmpty;
33 extern FlagRowObj *standardFlagsDefault;
35 extern QMenu* branchContextMenu;
36 extern QMenu* branchAddContextMenu;
37 extern QMenu* branchRemoveContextMenu;
38 extern QMenu* branchLinksContextMenu;
39 extern QMenu* branchXLinksContextMenuEdit;
40 extern QMenu* branchXLinksContextMenuFollow;
41 extern QMenu* floatimageContextMenu;
42 extern QMenu* canvasContextMenu;
45 extern Settings settings;
46 extern ImageIO imageIO;
48 extern QString vymName;
49 extern QString vymVersion;
51 extern QString iconPath;
52 extern QDir vymBaseDir;
53 extern QDir lastImageDir;
55 int MapEditor::mapNum=0; // make instance
57 ///////////////////////////////////////////////////////////////////////
58 ///////////////////////////////////////////////////////////////////////
59 MapEditor::MapEditor( QWidget* parent) :
60 QGraphicsView(parent), urlOperator(0), imageBuffer(0)
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=DefaultColor;
85 linkstyle=StylePolyParabel;
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);
104 xelection.setMapCenter (mapCenter);
107 defXLinkColor=QColor (230,230,230);
115 fileName=tr("unnamed");
118 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
119 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
121 // Initialize find routine
128 blockReposition=false;
129 blockSaveState=false;
133 // Create temporary files
136 setAcceptDrops (true);
138 mapCenter->reposition(); // for positioning heading
142 MapEditor::~MapEditor()
144 if (imageBuffer) delete imageBuffer;
150 //cout <<"Destructor MapEditor\n";
153 MapCenterObj* MapEditor::getMapCenter()
158 QGraphicsScene * MapEditor::getScene()
163 bool MapEditor::isRepositionBlocked()
165 return blockReposition;
168 QString MapEditor::getName (const LinkableMapObj *lmo)
171 if (!lmo) return QString("Error: NULL has no name!");
173 if ((typeid(*lmo) == typeid(BranchObj) ||
174 typeid(*lmo) == typeid(MapCenterObj)))
177 s=(((BranchObj*)lmo)->getHeading());
178 if (s=="") s="unnamed";
179 return QString("branch (%1)").arg(s);
180 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
182 if ((typeid(*lmo) == typeid(FloatImageObj) ))
183 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
184 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
185 return QString("Unknown type has no name!");
188 void MapEditor::makeTmpDirs()
190 // Create unique temporary directories
191 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
192 histPath=QDir::convertSeparators (tmpMapDir+"/history");
197 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
199 // tmpdir temporary directory to which data will be written
200 // prefix mapname, which will be appended to images etc.
201 // writeflags Only write flags for "real" save of map, not undo
202 // offset offset of bbox of whole map in scene.
203 // Needed for XML export
219 ls="StylePolyParabel";
223 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
225 if (linkcolorhint==HeadingColor)
226 colhint=attribut("linkColorHint","HeadingColor");
228 QString mapAttr=attribut("version",vymVersion);
229 if (!saveSel || saveSel==mapCenter)
230 mapAttr+= attribut("author",mapCenter->getAuthor()) +
231 attribut("comment",mapCenter->getComment()) +
232 attribut("date",mapCenter->getDate()) +
233 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
234 attribut("linkStyle", ls ) +
235 attribut("linkColor", defLinkColor.name() ) +
236 attribut("defXLinkColor", defXLinkColor.name() ) +
237 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
239 s+=beginElement("vymmap",mapAttr);
242 // Find the used flags while traversing the tree
243 standardFlagsDefault->resetUsedCounter();
245 // Reset the counters before saving
246 // TODO constr. of FIO creates lots of objects, better do this in some other way...
247 FloatImageObj (mapScene).resetSaveCounter();
249 // Build xml recursivly
250 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
251 // Save complete map, if saveSel not set
252 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
255 if ( typeid(*saveSel) == typeid(BranchObj) )
257 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
258 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
260 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
263 // Save local settings
264 s+=settings.getXMLData (destPath);
267 if (selection && !saveSel )
268 s+=valueElement("select",selection->getSelectString());
271 s+=endElement("vymmap");
274 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
278 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
280 // save the selected part of the map, Undo will replace part of map
281 QString undoSelection="";
283 undoSelection=undoSel->getSelectString();
285 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
286 QString redoSelection="";
288 redoSelection=undoSel->getSelectString();
290 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
293 saveState (PartOfMap,
294 undoSelection, "addMapReplace (\"PATH\")",
300 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
304 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
307 QString undoSelection=redoSel->getParObj()->getSelectString();
308 QString redoSelection=redoSel->getSelectString();
309 if (typeid(*redoSel) == typeid(BranchObj) )
311 // save the selected branch of the map, Undo will insert part of map
312 saveState (PartOfMap,
313 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
314 redoSelection, "delete ()",
321 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
323 // "Normal" savestate: save commands, selections and comment
324 // so just save commands for undo and redo
325 // and use current selection
327 QString redoSelection="";
328 if (redoSel) redoSelection=redoSel->getSelectString();
329 QString undoSelection="";
330 if (undoSel) undoSelection=undoSel->getSelectString();
332 saveState (UndoCommand,
339 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
341 // "Normal" savestate: save commands, selections and comment
342 // so just save commands for undo and redo
343 // and use current selection
344 saveState (UndoCommand,
352 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
356 if (blockSaveState) return;
358 /* TODO remove after testing
360 cout << "ME::saveState() "<<endl;
362 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
363 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
364 int curStep=undoSet.readNumEntry ("/history/curStep",0);
365 // Find out current undo directory
366 if (undosAvail<stepsTotal) undosAvail++;
368 if (curStep>stepsTotal) curStep=1;
370 QString backupXML="";
371 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
372 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
373 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
375 // Create bakMapDir if not available
378 makeSubDirs (bakMapDir);
380 // Save depending on how much needs to be saved
382 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPointF (),saveSel);
384 QString undoCommand="";
385 if (savemode==UndoCommand)
389 else if (savemode==PartOfMap )
392 undoCommand.replace ("PATH",bakMapPath);
395 if (!backupXML.isEmpty())
396 // Write XML Data to disk
397 saveStringToDisk (QString(bakMapPath),backupXML);
399 // We would have to save all actions in a tree, to keep track of
400 // possible redos after a action. Possible, but we are too lazy: forget about redos.
403 // Write the current state to disk
404 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
405 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
406 undoSet.setEntry ("/history/curStep",QString::number(curStep));
407 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
408 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
409 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
410 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
411 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
412 undoSet.setEntry (QString("/history/version"),vymVersion);
413 undoSet.writeSettings(histPath);
415 /* TODO remove after testing
417 //cout << " into="<< histPath.toStdString()<<endl;
418 cout << " stepsTotal="<<stepsTotal<<
419 ", undosAvail="<<undosAvail<<
420 ", redosAvail="<<redosAvail<<
421 ", curStep="<<curStep<<endl;
422 cout << " ---------------------------"<<endl;
423 cout << " comment="<<comment.toStdString()<<endl;
424 cout << " undoCom="<<undoCommand.toStdString()<<endl;
425 cout << " undoSel="<<undoSelection.toStdString()<<endl;
426 cout << " redoCom="<<redoCom.toStdString()<<endl;
427 cout << " redoSel="<<redoSelection.toStdString()<<endl;
428 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
429 cout << " ---------------------------"<<endl;
431 mainWindow->updateHistory (undoSet);
436 void MapEditor::parseAtom(const QString &atom)
443 // Split string s into command and parameters
444 api.parseInput (atom);
445 QString com=api.command();
448 if (com=="addBranch")
452 api.setError (Aborted,"Nothing selected");
453 } else if ( (typeid(*selection) != typeid(BranchObj) &&
454 typeid(*selection) != typeid(MapCenterObj)) )
456 api.setError (Aborted,"Type of selection is not a branch");
461 if (api.checkParamCount(pl))
463 if (api.paramCount()==0)
464 addNewBranchInt (-2);
468 if (ok ) addNewBranchInt (y);
472 } else if (com=="addBranchBefore")
476 api.setError (Aborted,"Nothing selected");
477 } else if ( (typeid(*selection) != typeid(BranchObj) &&
478 typeid(*selection) != typeid(MapCenterObj)) )
480 api.setError (Aborted,"Type of selection is not a branch");
483 if (api.paramCount()==0)
485 addNewBranchBefore ();
488 } else if (com==QString("addMapReplace"))
492 api.setError (Aborted,"Nothing selected");
493 } else if ( (typeid(*selection) != typeid(BranchObj) &&
494 typeid(*selection) != typeid(MapCenterObj)) )
496 api.setError (Aborted,"Type of selection is not a branch");
497 } else if (api.checkParamCount(1))
499 //s=api.parString (ok,0); // selection
500 t=api.parString (ok,0); // path to map
501 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
502 addMapReplaceInt(selection->getSelectString(),t);
504 } else if (com==QString("addMapInsert"))
508 api.setError (Aborted,"Nothing selected");
509 } else if ( (typeid(*selection) != typeid(BranchObj) &&
510 typeid(*selection) != typeid(MapCenterObj)) )
512 api.setError (Aborted,"Type of selection is not a branch");
515 if (api.checkParamCount(2))
517 t=api.parString (ok,0); // path to map
518 y=api.parInt(ok,1); // position
519 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
520 addMapInsertInt(t,y);
523 } else if (com=="colorBranch")
527 api.setError (Aborted,"Nothing selected");
528 } else if ( typeid(*selection) != typeid(BranchObj) &&
529 typeid(*selection) != typeid(MapCenterObj))
531 api.setError (Aborted,"Type of selection is not a branch");
532 } else if (api.checkParamCount(1))
534 QColor c=api.parColor (ok,0);
535 if (ok) colorBranch (c);
537 } else if (com=="colorSubtree")
541 api.setError (Aborted,"Nothing selected");
542 } else if ( typeid(*selection) != typeid(BranchObj) &&
543 typeid(*selection) != typeid(MapCenterObj))
545 api.setError (Aborted,"Type of selection is not a branch");
546 } else if (api.checkParamCount(1))
548 QColor c=api.parColor (ok,0);
549 if (ok) colorSubtree (c);
551 } else if (com=="cut")
555 api.setError (Aborted,"Nothing selected");
556 } else if ( typeid(*selection) != typeid(BranchObj) &&
557 typeid(*selection) != typeid(MapCenterObj) &&
558 typeid(*selection) != typeid(FloatImageObj) )
560 api.setError (Aborted,"Type of selection is not a branch or floatimage");
561 } else if (api.checkParamCount(0))
565 } else if (com=="delete")
569 api.setError (Aborted,"Nothing selected");
570 } else if ( (typeid(*selection) != typeid(BranchObj) &&
571 typeid(*selection) != typeid(MapCenterObj)) )
573 api.setError (Aborted,"Type of selection is not a branch");
574 } else if (api.checkParamCount(0))
578 } else if (com=="deleteKeepChilds")
582 api.setError (Aborted,"Nothing selected");
583 } else if ( (typeid(*selection) != typeid(BranchObj) &&
584 typeid(*selection) != typeid(MapCenterObj)) )
586 api.setError (Aborted,"Type of selection is not a branch");
587 } else if (api.checkParamCount(0))
591 } else if (com=="deleteChilds")
595 api.setError (Aborted,"Nothing selected");
596 } else if ( (typeid(*selection) != typeid(BranchObj) &&
597 typeid(*selection) != typeid(MapCenterObj)) )
599 api.setError (Aborted,"Type of selection is not a branch");
600 } else if (api.checkParamCount(0))
604 } else if (com=="linkBranchToPos")
608 api.setError (Aborted,"Nothing selected");
609 } else if ( (typeid(*selection) != typeid(BranchObj) &&
610 typeid(*selection) != typeid(MapCenterObj)) )
612 api.setError (Aborted,"Type of selection is not a branch");
613 } else if (api.checkParamCount(4))
615 // 0 selectstring of parent
616 // 1 num in parent (for branches)
617 // 2,3 x,y of mainbranch or mapcenter
618 s=api.parString(ok,0);
619 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
622 if (typeid(*dst) == typeid(BranchObj) )
624 // Get number in parent
627 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),x);
628 } else if (typeid(*dst) == typeid(MapCenterObj) )
630 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),-1);
631 // Get coordinates of mainbranch
636 if (ok) ((BranchObj*)selection)->move (x,y);
641 } else if (com=="linkTo")
645 api.setError (Aborted,"Nothing selected");
646 } else if ( (typeid(*selection) != typeid(BranchObj) &&
647 typeid(*selection) != typeid(MapCenterObj) &&
648 typeid(*selection) != typeid(FloatImageObj)))
650 api.setError (Aborted,"Type of selection is not a floatimage");
651 } else if (api.checkParamCount(1))
653 // 0 selectstring of parent
654 s=api.parString(ok,0);
655 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
658 if (typeid(*dst) == typeid(BranchObj) ||
659 typeid(*dst) == typeid(MapCenterObj))
660 linkTo (dst->getSelectString());
662 api.setError (Aborted,"Destination is not a branch");
664 } else if (com=="moveBranchUp")
668 api.setError (Aborted,"Nothing selected");
669 } else if ( (typeid(*selection) != typeid(BranchObj) &&
670 typeid(*selection) != typeid(MapCenterObj)) )
672 api.setError (Aborted,"Type of selection is not a branch");
673 } else if (api.checkParamCount(0))
677 } else if (com=="moveBranchDown")
681 api.setError (Aborted,"Nothing selected");
682 } else if ( (typeid(*selection) != typeid(BranchObj) &&
683 typeid(*selection) != typeid(MapCenterObj)) )
685 api.setError (Aborted,"Type of selection is not a branch");
686 } else if (api.checkParamCount(0))
690 } else if (com=="move")
694 api.setError (Aborted,"Nothing selected");
695 } else if ( typeid(*selection) != typeid(BranchObj) &&
696 typeid(*selection) != typeid(MapCenterObj) &&
697 typeid(*selection) != typeid(FloatImageObj) )
699 api.setError (Aborted,"Type of selection is not a branch or floatimage");
700 } else if (api.checkParamCount(2))
709 } else if (com=="moveRel")
713 api.setError (Aborted,"Nothing selected");
714 } else if ( typeid(*selection) != typeid(BranchObj) &&
715 typeid(*selection) != typeid(MapCenterObj) &&
716 typeid(*selection) != typeid(FloatImageObj) )
718 api.setError (Aborted,"Type of selection is not a branch or floatimage");
719 } else if (api.checkParamCount(2))
725 if (ok) moveRel (x,y);
728 } else if (com=="paste")
732 api.setError (Aborted,"Nothing selected");
733 } else if ( typeid(*selection) != typeid(BranchObj) &&
734 typeid(*selection) != typeid(MapCenterObj) )
736 api.setError (Aborted,"Type of selection is not a branch");
737 } else if (api.checkParamCount(0))
741 } else if (com=="select")
743 if (api.checkParamCount(1))
745 s=api.parString(ok,0);
748 } else if (com=="setMapAuthor")
750 if (api.checkParamCount(1))
752 s=api.parString(ok,0);
753 if (ok) setMapAuthor (s);
755 } else if (com=="setMapComment")
757 if (api.checkParamCount(1))
759 s=api.parString(ok,0);
760 if (ok) setMapComment(s);
762 } else if (com=="setMapBackgroundColor")
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) setMapBackgroundColor (c);
776 } else if (com=="setMapDefLinkColor")
780 api.setError (Aborted,"Nothing selected");
781 } else if ( (typeid(*selection) != typeid(BranchObj) &&
782 typeid(*selection) != typeid(MapCenterObj)) )
784 api.setError (Aborted,"Type of selection is not a branch");
785 } else if (api.checkParamCount(1))
787 QColor c=api.parColor (ok,0);
788 if (ok) setMapDefLinkColor (c);
790 } else if (com=="setMapLinkStyle")
792 if (api.checkParamCount(1))
794 s=api.parString (ok,0);
795 if (ok) setMapLinkStyle(s);
797 } else if (com=="setHeading")
801 api.setError (Aborted,"Nothing selected");
802 } else if ( (typeid(*selection) != typeid(BranchObj) &&
803 typeid(*selection) != typeid(MapCenterObj)) )
805 api.setError (Aborted,"Type of selection is not a branch");
806 } else if (api.checkParamCount(1))
808 s=api.parString (ok,0);
812 } else if (com=="setHideExport")
816 api.setError (Aborted,"Nothing selected");
817 } else if ( typeid(*selection) != typeid(BranchObj) &&
818 typeid(*selection) != typeid(FloatImageObj) )
820 api.setError (Aborted,"Type of selection is not a branch or floatimage");
821 } else if (api.checkParamCount(1))
824 if (ok) setHideExport (b);
826 } else if (com=="setURL")
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) setURLInt(s);
840 } else if (com=="setVymLink")
844 api.setError (Aborted,"Nothing selected");
845 } else if ( (typeid(*selection) != typeid(BranchObj) &&
846 typeid(*selection) != typeid(MapCenterObj)) )
848 api.setError (Aborted,"Type of selection is not a branch");
849 } else if (api.checkParamCount(1))
851 s=api.parString (ok,0);
852 if (ok) setVymLinkInt(s);
855 else if (com=="setFlag")
859 api.setError (Aborted,"Nothing selected");
860 } else if ( (typeid(*selection) != typeid(BranchObj) &&
861 typeid(*selection) != typeid(MapCenterObj)) )
863 api.setError (Aborted,"Type of selection is not a branch");
864 } else if (api.checkParamCount(1))
866 s=api.parString(ok,0);
869 BranchObj* bo=(BranchObj*)selection;
870 bo->activateStandardFlag(s);
871 bo->updateFlagsToolbar();
875 else if (com=="unsetFlag")
879 api.setError (Aborted,"Nothing selected");
880 } else if ( (typeid(*selection) != typeid(BranchObj) &&
881 typeid(*selection) != typeid(MapCenterObj)) )
883 api.setError (Aborted,"Type of selection is not a branch");
884 } else if (api.checkParamCount(1))
886 s=api.parString(ok,0);
889 BranchObj* bo=(BranchObj*)selection;
890 bo->deactivateStandardFlag(s);
891 bo->updateFlagsToolbar();
896 api.setError (Aborted,"Unknown command");
900 if (api.errorLevel()==NoError)
904 // TODO Error handling
905 qWarning("MapEditor::parseAtom: Error!");
906 qWarning(api.errorMessage());
911 bool MapEditor::isDefault()
916 bool MapEditor::isUnsaved()
921 bool MapEditor::hasChanged()
926 void MapEditor::setChanged()
934 void MapEditor::closeMap()
936 // Unselect before disabling the toolbar actions
937 if (selection) selection->unselect();
945 void MapEditor::setFilePath(QString fname)
947 setFilePath (fname,fname);
950 void MapEditor::setFilePath(QString fname, QString destname)
952 if (fname.isEmpty() || fname=="")
959 filePath=fname; // becomes absolute path
960 fileName=fname; // gets stripped of path
961 destPath=destname; // needed for vymlinks
963 // If fname is not an absolute path, complete it
964 filePath=QDir(fname).absPath();
965 fileDir=filePath.left (1+filePath.findRev ("/"));
967 // Set short name, too. Search from behind:
968 int i=fileName.findRev("/");
969 if (i>=0) fileName=fileName.remove (0,i+1);
971 // Forget the .vym (or .xml) for name of map
972 mapName=fileName.left(fileName.findRev(".",-1,true) );
976 QString MapEditor::getFilePath()
981 QString MapEditor::getFileName()
986 QString MapEditor::getMapName()
991 QString MapEditor::getDestPath()
996 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
998 ErrorCode err=success;
1002 if (selection) selection->unselect();
1005 mapCenter->setMapEditor(this);
1006 // (map state is set later at end of load...)
1009 if (!selection || (typeid(*selection) != typeid(BranchObj) &&
1010 typeid(*selection) != typeid (MapCenterObj)))
1012 BranchObj *bo=(BranchObj*)selection;
1013 if (lmode==ImportAdd)
1014 saveStateChangingPart(
1017 QString("addMapInsert (%1)").arg(fname),
1018 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1020 saveStateChangingPart(
1023 QString("addMapReplace(%1)").arg(fname),
1024 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1028 mapBuilderHandler handler;
1029 QFile file( fname );
1031 // I am paranoid: file should exist anyway
1032 // according to check in mainwindow.
1033 if (!file.exists() )
1035 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1036 tr("Couldn't open map " +fname)+".");
1040 blockReposition=true;
1041 QXmlInputSource source( file);
1042 QXmlSimpleReader reader;
1043 reader.setContentHandler( &handler );
1044 reader.setErrorHandler( &handler );
1045 handler.setMapEditor( this );
1046 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1047 handler.setInputFile (file.name());
1048 handler.setLoadMode (lmode);
1049 blockSaveState=true;
1050 bool ok = reader.parse( source );
1051 blockReposition=false;
1052 blockSaveState=false;
1056 mapCenter->reposition();
1065 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1066 tr( handler.errorProtocol() ) );
1068 // Still return "success": the map maybe at least
1069 // partially read by the parser
1076 int MapEditor::save (const SaveMode &savemode)
1080 // Create mapName and fileDir
1081 makeSubDirs (fileDir);
1085 fname=mapName+".xml";
1087 // use name given by user, even if he chooses .doc
1092 if (savemode==CompleteMap || selection==NULL)
1093 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1095 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),selection);
1097 if (!saveStringToDisk(fileDir+fname,saveFile))
1110 void MapEditor::setZipped (bool z)
1115 bool MapEditor::saveZipped ()
1120 void MapEditor::print()
1124 printer = new QPrinter;
1125 printer->setColorMode (QPrinter::Color);
1126 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1127 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1128 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1131 QRectF totalBBox=mapCenter->getTotalBBox();
1133 // Try to set orientation automagically
1134 // Note: Interpretation of generated postscript is amibiguous, if
1135 // there are problems with landscape mode, see
1136 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1138 if (totalBBox.width()>totalBBox.height())
1139 // recommend landscape
1140 printer->setOrientation (QPrinter::Landscape);
1142 // recommend portrait
1143 printer->setOrientation (QPrinter::Portrait);
1145 if ( printer->setup(this) )
1146 // returns false, if printing is canceled
1148 QPainter pp(printer);
1150 pp.setRenderHint(QPainter::Antialiasing,true);
1152 // Don't print the visualisation of selection
1153 LinkableMapObj *oldselection=NULL;
1156 oldselection=selection;
1157 selection->unselect();
1160 QRectF mapRect=totalBBox;
1161 QGraphicsRectItem *frame=NULL;
1165 // Print frame around map
1166 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1167 totalBBox.width()+20, totalBBox.height()+20);
1168 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1169 frame->setZValue(0);
1174 double paperAspect = (double)printer->width() / (double)printer->height();
1175 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1177 if (mapAspect>=paperAspect)
1179 // Fit horizontally to paper width
1180 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1181 viewBottom=(int)(printer->width()/mapAspect);
1184 // Fit vertically to paper height
1185 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1186 viewBottom=printer->height();
1191 // Print footer below map
1193 font.setPointSize(10);
1195 QRectF footerBox(0,viewBottom,printer->width(),15);
1196 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1197 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1201 QRectF (0,0,printer->width(),printer->height()-15),
1202 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1205 // Viewport has paper dimension
1206 if (frame) delete (frame);
1208 // Restore selection
1211 selection=oldselection;
1212 selection->select();
1215 // Save settings in vymrc
1216 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1217 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1218 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1222 void MapEditor::setAntiAlias (bool b)
1224 setRenderHint(QPainter::Antialiasing,b);
1227 void MapEditor::setSmoothPixmap(bool b)
1229 setRenderHint(QPainter::SmoothPixmapTransform,b);
1232 QPixmap MapEditor::getPixmap()
1234 QRectF mapRect=mapCenter->getTotalBBox();
1235 QPixmap pix((int)mapRect.width(),(int)mapRect.height());
1236 cout << "w.h="<<(int)mapRect.width()<<","<<(int)mapRect.height()<<endl;
1239 pp.setRenderHints(renderHints());
1241 // Don't print the visualisation of selection
1242 LinkableMapObj *oldselection=NULL;
1245 oldselection=selection;
1246 selection->unselect();
1249 mapScene->render ( &pp,
1250 QRectF(0,0,mapRect.width(),mapRect.height()),
1251 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1253 // mapScene->render(&pp); // draw scene to painter
1257 // Restore selection
1260 selection=oldselection;
1261 selection->select();
1267 void MapEditor::setHideTmpMode (HideTmpMode mode)
1270 mapCenter->setHideTmp (hidemode);
1271 mapCenter->reposition();
1275 HideTmpMode MapEditor::getHideTmpMode()
1280 void MapEditor::exportImage(QString fn)
1282 setExportMode (true);
1283 QPixmap pix (getPixmap());
1284 pix.save(fn, "PNG");
1285 setExportMode (false);
1288 void MapEditor::setExportMode (bool b)
1290 // should be called before and after exports
1291 // depending on the settings
1292 if (b && settings.value("/export/useHideExport","yes")=="yes")
1293 setHideTmpMode (HideExport);
1295 setHideTmpMode (HideNone);
1298 void MapEditor::exportImage(QString fn, QString format)
1300 setExportMode (true);
1301 QPixmap pix (getPixmap());
1302 pix.save(fn, format);
1303 setExportMode (false);
1306 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1310 ex.setMapCenter(mapCenter);
1311 if (ex.setConfigFile(cf))
1313 setExportMode (true);
1314 ex.exportPresentation();
1315 setExportMode (false);
1321 void MapEditor::exportXML(const QString &dir)
1323 // Hide stuff during export, if settings want this
1324 setExportMode (true);
1326 // Create subdirectories
1329 // write to directory
1330 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1333 file.setName ( dir + "/"+mapName+".xml");
1334 if ( !file.open( QIODevice::WriteOnly ) )
1336 // This should neverever happen
1337 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1341 // Write it finally, and write in UTF8, no matter what
1342 QTextStream ts( &file );
1343 ts.setEncoding (QTextStream::UnicodeUTF8);
1347 // Now write image, too
1348 exportImage (dir+"/images/"+mapName+".png");
1350 setExportMode (false);
1353 void MapEditor::clear()
1357 selection->unselect();
1364 void MapEditor::copy()
1368 // write to directory
1369 QString clipfile="part";
1370 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPointF(),selection);
1373 file.setName ( clipboardDir + "/"+clipfile+".xml");
1374 if ( !file.open( QIODevice::WriteOnly ) )
1376 // This should neverever happen
1377 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1381 // Write it finally, and write in UTF8, no matter what
1382 QTextStream ts( &file );
1383 ts.setEncoding (QTextStream::UnicodeUTF8);
1387 clipboardEmpty=false;
1392 void MapEditor::redo()
1394 blockSaveState=true;
1396 // Restore variables
1397 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1398 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1399 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1400 // Can we undo at all?
1401 if (redosAvail<1) return;
1404 if (undosAvail<stepsTotal) undosAvail++;
1406 if (curStep>stepsTotal) curStep=1;
1407 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1408 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1409 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1410 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1411 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1412 QString version=undoSet.readEntry ("/history/version");
1414 if (!checkVersion(version))
1415 QMessageBox::warning(0,tr("Warning"),
1416 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1419 // Find out current undo directory
1420 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1422 /* TODO remove testing
1424 cout << "ME::redo() begin\n";
1425 cout << " undosAvail="<<undosAvail<<endl;
1426 cout << " redosAvail="<<redosAvail<<endl;
1427 cout << " curStep="<<curStep<<endl;
1428 cout << " ---------------------------"<<endl;
1429 cout << " comment="<<comment.toStdString()<<endl;
1430 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1431 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1432 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1433 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1434 cout << " ---------------------------"<<endl<<endl;
1436 // select object before redo
1437 if (!redoSelection.isEmpty())
1438 select (redoSelection);
1441 parseAtom (redoCommand);
1442 mapCenter->reposition();
1444 blockSaveState=false;
1446 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1447 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1448 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1449 undoSet.writeSettings(histPath);
1451 mainWindow->updateHistory (undoSet);
1454 /* TODO remove testing
1455 cout << "ME::redo() end\n";
1456 cout << " undosAvail="<<undosAvail<<endl;
1457 cout << " redosAvail="<<redosAvail<<endl;
1458 cout << " curStep="<<curStep<<endl;
1459 cout << " ---------------------------"<<endl<<endl;
1465 bool MapEditor::isRedoAvailable()
1467 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1473 void MapEditor::undo()
1475 blockSaveState=true;
1477 // Restore variables
1478 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1479 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1480 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1482 // Can we undo at all?
1483 if (undosAvail<1) return;
1485 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1486 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1487 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1488 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1489 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1490 QString version=undoSet.readEntry ("/history/version");
1492 if (!checkVersion(version))
1493 QMessageBox::warning(0,tr("Warning"),
1494 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1496 // Find out current undo directory
1497 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1499 // select object before undo
1500 if (!undoSelection.isEmpty())
1501 select (undoSelection);
1505 cout << "ME::undo() begin\n";
1506 cout << " undosAvail="<<undosAvail<<endl;
1507 cout << " redosAvail="<<redosAvail<<endl;
1508 cout << " curStep="<<curStep<<endl;
1509 cout << " ---------------------------"<<endl;
1510 cout << " comment="<<comment.toStdString()<<endl;
1511 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1512 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1513 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1514 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1515 cout << " ---------------------------"<<endl<<endl;
1516 parseAtom (undoCommand);
1517 mapCenter->reposition();
1521 if (curStep<1) curStep=stepsTotal;
1525 blockSaveState=false;
1526 /* TODO remove testing
1527 cout << "ME::undo() end\n";
1528 cout << " undosAvail="<<undosAvail<<endl;
1529 cout << " redosAvail="<<redosAvail<<endl;
1530 cout << " curStep="<<curStep<<endl;
1531 cout << " ---------------------------"<<endl<<endl;
1534 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1535 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1536 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1537 undoSet.writeSettings(histPath);
1539 mainWindow->updateHistory (undoSet);
1541 ensureSelectionVisible();
1544 bool MapEditor::isUndoAvailable()
1546 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1552 void MapEditor::gotoHistoryStep (int i)
1554 // Restore variables
1555 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1556 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1558 if (i<0) i=undosAvail+redosAvail;
1560 // Clicking above current step makes us undo things
1563 for (int j=0; j<undosAvail-i; j++) undo();
1566 // Clicking below current step makes us redo things
1568 for (int j=undosAvail; j<i; j++) redo();
1570 // And ignore clicking the current row ;-)
1573 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1575 QString pathDir=path.left(path.findRev("/"));
1581 // We need to parse saved XML data
1582 mapBuilderHandler handler;
1583 QXmlInputSource source( file);
1584 QXmlSimpleReader reader;
1585 reader.setContentHandler( &handler );
1586 reader.setErrorHandler( &handler );
1587 handler.setMapEditor( this );
1588 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1589 if (undoSel.isEmpty())
1593 handler.setLoadMode (NewMap);
1597 handler.setLoadMode (ImportReplace);
1599 blockReposition=true;
1600 bool ok = reader.parse( source );
1601 blockReposition=false;
1604 // This should never ever happen
1605 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1606 handler.errorProtocol());
1609 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1612 void MapEditor::addMapInsertInt (const QString &path, int pos)
1614 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1615 typeid(*selection) == typeid(MapCenterObj)))
1617 QString pathDir=path.left(path.findRev("/"));
1623 // We need to parse saved XML data
1624 mapBuilderHandler handler;
1625 QXmlInputSource source( file);
1626 QXmlSimpleReader reader;
1627 reader.setContentHandler( &handler );
1628 reader.setErrorHandler( &handler );
1629 handler.setMapEditor( this );
1630 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1631 handler.setLoadMode (ImportAdd);
1632 blockReposition=true;
1633 bool ok = reader.parse( source );
1634 blockReposition=false;
1637 // This should never ever happen
1638 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1639 handler.errorProtocol());
1641 if (selection!=mapCenter)
1642 ((BranchObj*)selection)->getLastBranch()->moveBranchTo ((BranchObj*)(selection),pos);
1644 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1648 void MapEditor::pasteNoSave()
1650 load (clipboardDir+"/part.xml",ImportAdd);
1653 void MapEditor::cutNoSave()
1659 void MapEditor::paste()
1661 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1662 typeid(*selection) == typeid(MapCenterObj)))
1665 saveStateChangingPart(
1669 QString("Paste to %1").arg( getName(selection))
1671 mapCenter->reposition();
1675 void MapEditor::cut()
1677 saveStateChangingPart(
1678 selection->getParObj(),
1681 QString("Cut %1").arg(getName(selection))
1685 mapCenter->reposition();
1688 void MapEditor::move(const int &x, const int &y)
1692 QString ps=qpointfToString (selection->getAbsPos());
1693 QString s=selection->getSelectString();
1696 s, "move "+qpointfToString (QPointF (x,y)),
1697 QString("Move %1 to %2").arg(getName(selection)).arg(ps));
1698 selection->move(x,y);
1699 mapCenter->reposition();
1704 void MapEditor::moveRel (const int &x, const int &y)
1706 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1707 typeid(*selection) == typeid(MapCenterObj) ||
1708 typeid(*selection) == typeid (FloatImageObj)))
1710 QString ps=qpointfToString (selection->getRelPos());
1711 QString s=selection->getSelectString();
1714 s, "moveRel "+qpointfToString (QPointF (x,y)),
1715 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(ps));
1716 ((OrnamentedObj*)selection)->move2RelPos (x,y);
1717 mapCenter->reposition();
1718 selection->updateLink();
1722 void MapEditor::moveBranchUp()
1726 if (typeid(*selection) == typeid(BranchObj) )
1728 bo=(BranchObj*)selection;
1729 if (!bo->canMoveBranchUp()) return;
1730 par=(BranchObj*)(bo->getParObj());
1731 selection->unselect();
1732 bo=par->moveBranchUp (bo); // bo will be the one below selection
1733 selection->select();
1734 saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1735 mapCenter->reposition();
1737 ensureSelectionVisible();
1741 void MapEditor::moveBranchDown()
1745 if (typeid(*selection) == typeid(BranchObj) )
1747 bo=(BranchObj*)selection;
1748 if (!bo->canMoveBranchDown()) return;
1749 par=(BranchObj*)(bo->getParObj());
1750 selection->unselect();
1751 bo=par->moveBranchDown(bo); // bo will be the one above selection
1752 selection->select();
1753 saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1754 mapCenter->reposition();
1756 ensureSelectionVisible();
1760 void MapEditor::linkTo(const QString &dstString)
1762 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
1763 if (dst && (typeid(*dst)==typeid (BranchObj) ||
1764 typeid(*dst)==typeid (MapCenterObj)))
1766 LinkableMapObj *dstPar=dst->getParObj();
1767 QString parString=dstPar->getSelectString();
1768 if (typeid(*selection)==typeid(FloatImageObj))
1770 FloatImageObj *fio=(FloatImageObj*)selection;
1771 QString fioPreSelectString=fio->getSelectString();
1772 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
1773 ((BranchObj*)(dst))->addFloatImage (fio);
1775 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
1776 fio=((BranchObj*)(dst))->getLastFloatImage();
1779 selection=(LinkableMapObj*)fio;
1780 selection->select();
1782 fio->getSelectString(),
1783 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
1785 QString ("linkTo (\"%1\")").arg(dstString),
1786 QString ("Link floatimage to %1").arg(getName(dst)));
1791 QString MapEditor::getHeading(bool &ok, QPoint &p)
1794 (typeid(*selection) == typeid(BranchObj) ||
1795 typeid(*selection) == typeid(MapCenterObj) ) )
1798 ensureSelectionVisible();
1799 p=mapFromScene(selection->getAbsPos());
1800 return ((BranchObj*)selection)->getHeading();
1806 void MapEditor::setHeading(const QString &s)
1809 (typeid(*selection) == typeid(BranchObj) ||
1810 typeid(*selection) == typeid(MapCenterObj) ) )
1812 editingBO=(BranchObj*)selection;
1815 "setHeading (\""+editingBO->getHeading()+"\")",
1817 "setHeading (\""+s+"\")",
1818 QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(s) );
1819 editingBO->setHeading(s );
1821 mapCenter->reposition();
1822 ensureSelectionVisible();
1826 void MapEditor::setURLInt (const QString &s)
1828 // Internal function, no saveState needed
1830 (typeid(*selection) == typeid(BranchObj) ||
1831 typeid(*selection) == typeid(MapCenterObj) ) )
1833 ((BranchObj*)selection)->setURL(s);
1834 mapCenter->reposition();
1835 ensureSelectionVisible();
1839 void MapEditor::setHeadingInt(const QString &s)
1842 (typeid(*selection) == typeid(BranchObj) ||
1843 typeid(*selection) == typeid(MapCenterObj) ) )
1845 ((BranchObj*)selection)->setHeading(s);
1846 mapCenter->reposition();
1847 ensureSelectionVisible();
1851 void MapEditor::setVymLinkInt (const QString &s)
1853 // Internal function, no saveState needed
1855 (typeid(*selection) == typeid(BranchObj) ||
1856 typeid(*selection) == typeid(MapCenterObj) ) )
1858 ((BranchObj*)selection)->setVymLink(s);
1859 mapCenter->reposition();
1860 ensureSelectionVisible();
1864 BranchObj* MapEditor::addNewBranchInt(int num)
1866 // Depending on pos:
1867 // -3 insert in childs of parent above selection
1868 // -2 add branch to selection
1869 // -1 insert in childs of parent below selection
1870 // 0..n insert in childs of parent at pos
1871 BranchObj *newbo=NULL;
1873 (typeid(*selection) == typeid(BranchObj) ||
1874 typeid(*selection) == typeid(MapCenterObj) ) )
1876 BranchObj* bo = (BranchObj*) selection;
1879 // save scroll state. If scrolled, automatically select
1880 // new branch in order to tmp unscroll parent...
1881 return bo->addBranch();
1886 bo=(BranchObj*)bo->getParObj();
1890 bo=(BranchObj*)bo->getParObj();
1893 newbo=bo->insertBranch(num);
1898 BranchObj* MapEditor::addNewBranch(int pos)
1900 // Different meaning than num in addNewBranchInt!
1904 BranchObj *bo = (BranchObj*) selection;
1905 BranchObj *newbo=NULL;
1908 (typeid(*selection) == typeid(BranchObj) ||
1909 typeid(*selection) == typeid(MapCenterObj) ) )
1911 newbo=addNewBranchInt (pos-2);
1919 QString ("addBranch (%1)").arg(pos-2),
1920 QString ("Add new branch to %1").arg(getName(bo)));
1922 mapCenter->reposition();
1929 BranchObj* MapEditor::addNewBranchBefore()
1931 BranchObj *newbo=NULL;
1933 (typeid(*selection) == typeid(BranchObj) ) )
1934 // We accept no MapCenterObj here, so we _have_ a parent
1936 BranchObj* bo = (BranchObj*) selection;
1937 QPointF p=bo->getRelPos();
1940 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1942 // add below selection
1943 newbo=parbo->insertBranch(bo->getNum()+1);
1946 newbo->move2RelPos (p);
1948 // Move selection to new branch
1949 ((BranchObj*)selection)->moveBranchTo (newbo,-1);
1951 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
1952 QString ("Add branch before %1").arg(getName(bo)));
1954 mapCenter->reposition();
1960 void MapEditor::deleteSelection()
1962 if (selection && typeid(*selection) ==typeid(BranchObj) )
1964 BranchObj* bo=(BranchObj*)selection;
1965 BranchObj* par=(BranchObj*)(bo->getParObj());
1967 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
1969 par->removeBranch(bo);
1971 selection->select();
1972 ensureSelectionVisible();
1973 mapCenter->reposition();
1975 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
1977 FloatImageObj* fio=(FloatImageObj*)selection;
1978 BranchObj* par=(BranchObj*)(fio->getParObj());
1979 saveStateChangingPart(
1983 QString("Delete %1").arg(getName(fio))
1987 par->removeFloatImage(fio);
1989 selection->select();
1990 ensureSelectionVisible();
1991 mapCenter->reposition();
1995 LinkableMapObj* MapEditor::getSelection()
2000 void MapEditor::unselect()
2004 selectionLast=selection;
2005 selection->unselect();
2010 void MapEditor::reselect()
2014 selection=selectionLast;
2015 selection->select();
2020 bool MapEditor::select (const QString &s)
2022 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2024 // Finally select the found object
2027 if (selection) unselect();
2029 selection->select();
2030 ensureSelectionVisible();
2036 QString MapEditor::getSelectString()
2038 if (selection) return selection->getSelectString();
2042 void MapEditor::selectInt (LinkableMapObj *lmo)
2044 if (lmo && selection != lmo)
2046 // select the MapObj
2047 if (selection) selection->unselect();
2049 selection->select();
2053 void MapEditor::selectNextBranchInt()
2055 // Increase number of branch
2058 QString s=selection->getSelectString();
2064 part=s.section(",",-1);
2066 num=part.right(part.length() - 3);
2068 s=s.left (s.length() -num.length());
2071 num=QString ("%1").arg(num.toUInt()+1);
2075 // Try to select this one
2076 if (select (s)) return;
2078 // We have no direct successor,
2079 // try to increase the parental number in order to
2080 // find a successor with same depth
2082 int d=selection->getDepth();
2087 while (!found && d>0)
2089 s=s.section (",",0,d-1);
2090 // replace substring of current depth in s with "1"
2091 part=s.section(",",-1);
2093 num=part.right(part.length() - 3);
2097 // increase number of parent
2098 num=QString ("%1").arg(num.toUInt()+1);
2099 s=s.section (",",0,d-2) + ","+ typ+num;
2102 // Special case, look at orientation
2103 if (selection->getOrientation()==OrientRightOfCenter)
2104 num=QString ("%1").arg(num.toUInt()+1);
2106 num=QString ("%1").arg(num.toUInt()-1);
2111 // pad to oldDepth, select the first branch for each depth
2112 for (i=d;i<oldDepth;i++)
2117 if ( ((BranchObj*)selection)->countBranches()>0)
2125 // try to select the freshly built string
2133 void MapEditor::selectPrevBranchInt()
2135 // Decrease number of branch
2138 QString s=selection->getSelectString();
2144 part=s.section(",",-1);
2146 num=part.right(part.length() - 3);
2148 s=s.left (s.length() -num.length());
2150 int n=num.toInt()-1;
2153 num=QString ("%1").arg(n);
2156 // Try to select this one
2157 if (n>=0 && select (s)) return;
2159 // We have no direct precessor,
2160 // try to decrease the parental number in order to
2161 // find a precessor with same depth
2163 int d=selection->getDepth();
2168 while (!found && d>0)
2170 s=s.section (",",0,d-1);
2171 // replace substring of current depth in s with "1"
2172 part=s.section(",",-1);
2174 num=part.right(part.length() - 3);
2178 // decrease number of parent
2179 num=QString ("%1").arg(num.toInt()-1);
2180 s=s.section (",",0,d-2) + ","+ typ+num;
2183 // Special case, look at orientation
2184 if (selection->getOrientation()==OrientRightOfCenter)
2185 num=QString ("%1").arg(num.toInt()-1);
2187 num=QString ("%1").arg(num.toInt()+1);
2192 // pad to oldDepth, select the last branch for each depth
2193 for (i=d;i<oldDepth;i++)
2197 if ( ((BranchObj*)selection)->countBranches()>0)
2198 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
2205 // try to select the freshly built string
2213 void MapEditor::selectUpperBranch()
2217 if (typeid(*selection) == typeid(BranchObj))
2219 if (selection->getOrientation()==OrientRightOfCenter)
2220 selectPrevBranchInt();
2222 if (selection->getDepth()==1)
2223 selectNextBranchInt();
2225 selectPrevBranchInt();
2230 void MapEditor::selectLowerBranch()
2234 if (typeid(*selection) == typeid(BranchObj))
2236 if (selection->getOrientation()==OrientRightOfCenter)
2237 selectNextBranchInt();
2239 if (selection->getDepth()==1)
2240 selectPrevBranchInt();
2242 selectNextBranchInt();
2248 void MapEditor::selectLeftBranch()
2254 if (typeid(*selection) == typeid(MapCenterObj))
2256 par= (BranchObj*) selection;
2257 bo=par->getLastSelectedBranch();
2260 // Workaround for reselecting on left and right side
2261 if (bo->getOrientation()==OrientRightOfCenter)
2263 bo=par->getLastBranch();
2269 selection->select();
2270 ensureSelectionVisible();
2275 par=(BranchObj*)(selection->getParObj());
2276 if (selection->getOrientation()==OrientRightOfCenter)
2278 if (typeid(*selection) == typeid(BranchObj) ||
2279 typeid(*selection) == typeid(FloatImageObj))
2281 selection->unselect();
2283 selection->select();
2284 ensureSelectionVisible();
2288 if (typeid(*selection) == typeid(BranchObj) )
2290 bo=((BranchObj*)selection)->getLastSelectedBranch();
2293 selection->unselect();
2295 selection->select();
2296 ensureSelectionVisible();
2304 void MapEditor::selectRightBranch()
2311 if (typeid(*selection) == typeid(MapCenterObj))
2313 par= (BranchObj*) selection;
2314 bo=par->getLastSelectedBranch();
2317 // Workaround for reselecting on left and right side
2318 if (bo->getOrientation()==OrientLeftOfCenter)
2319 bo=par->getFirstBranch();
2324 selection->select();
2325 ensureSelectionVisible();
2330 par=(BranchObj*)(selection->getParObj());
2331 if (selection->getOrientation()==OrientLeftOfCenter)
2333 if (typeid(*selection) == typeid(BranchObj) ||
2334 typeid(*selection) == typeid(FloatImageObj))
2336 selection->unselect();
2338 selection->select();
2339 ensureSelectionVisible();
2343 if (typeid(*selection) == typeid(BranchObj) )
2345 bo=((BranchObj*)selection)->getLastSelectedBranch();
2348 selection->unselect();
2350 selection->select();
2351 ensureSelectionVisible();
2359 void MapEditor::selectFirstBranch()
2365 if (typeid(*selection) == typeid(BranchObj))
2367 bo1= (BranchObj*) selection;
2368 par=(BranchObj*)(bo1->getParObj());
2369 bo2=par->getFirstBranch();
2373 selection->select();
2374 ensureSelectionVisible();
2380 void MapEditor::selectLastBranch()
2386 if (typeid(*selection) == typeid(BranchObj))
2388 bo1= (BranchObj*) selection;
2389 par=(BranchObj*)(bo1->getParObj());
2390 bo2=par->getLastBranch();
2394 selection->select();
2395 ensureSelectionVisible();
2401 void MapEditor::selectMapBackgroundImage ()
2403 Q3FileDialog *fd=new Q3FileDialog( this);
2404 fd->setMode (Q3FileDialog::ExistingFile);
2405 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2406 ImagePreview *p =new ImagePreview (fd);
2407 fd->setContentsPreviewEnabled( TRUE );
2408 fd->setContentsPreview( p, p );
2409 fd->setPreviewMode( Q3FileDialog::Contents );
2410 fd->setCaption(vymName+" - " +tr("Load background image"));
2411 fd->setDir (lastImageDir);
2414 if ( fd->exec() == QDialog::Accepted )
2416 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2417 lastImageDir=QDir (fd->dirPath());
2418 setMapBackgroundImage (fd->selectedFile());
2422 void MapEditor::setMapBackgroundImage (const QString &fn)
2424 QColor oldcol=mapScene->backgroundBrush().color();
2428 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2430 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2431 QString("Set background color of map to %1").arg(col.name()));
2433 cout << "Trying to load "<<fn.ascii()<<endl;
2435 brush.setTextureImage (QPixmap (fn));
2436 mapScene->setBackgroundBrush(brush);
2439 void MapEditor::selectMapBackgroundColor()
2441 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2442 if ( !col.isValid() ) return;
2443 setMapBackgroundColor( col );
2447 void MapEditor::setMapBackgroundColor(QColor col)
2449 QColor oldcol=mapScene->backgroundBrush().color();
2452 QString ("setMapBackgroundColor (%1)").arg(oldcol.name()),
2454 QString ("setMapBackgroundColor (%1)").arg(col.name()),
2455 QString("Set background color of map to %1").arg(col.name()));
2456 mapScene->setBackgroundBrush(col);
2459 QColor MapEditor::getMapBackgroundColor()
2461 return mapScene->backgroundBrush().color();
2464 QColor MapEditor::getCurrentHeadingColor()
2468 if (typeid(*selection) == typeid(BranchObj) ||
2469 typeid(*selection) == typeid(MapCenterObj))
2471 BranchObj *bo=(BranchObj*)selection;
2472 return bo->getColor();
2476 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2480 void MapEditor::colorBranch (QColor c)
2484 if (typeid(*selection) == typeid(BranchObj) ||
2485 typeid(*selection) == typeid(MapCenterObj))
2487 BranchObj *bo=(BranchObj*)selection;
2490 QString ("colorBranch (%1)").arg(bo->getColor().name()),
2492 QString ("colorBranch (%1)").arg(c.name()),
2493 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2495 bo->setColor(c); // color branch
2500 void MapEditor::colorSubtree (QColor c)
2504 if (typeid(*selection) == typeid(BranchObj) ||
2505 typeid(*selection) == typeid(MapCenterObj))
2507 BranchObj *bo=(BranchObj*)selection;
2508 saveStateChangingPart(
2511 QString ("colorSubtree (%1)").arg(c.name()),
2512 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2514 bo->setColorSubtree (c); // color links, color childs
2520 void MapEditor::toggleStandardFlag(QString f)
2524 if (typeid(*selection) == typeid(BranchObj) ||
2525 typeid(*selection) == typeid(MapCenterObj))
2527 BranchObj *bo=(BranchObj*)selection;
2529 if (bo->isSetStandardFlag(f))
2541 QString("%1 (\"%2\")").arg(u).arg(f),
2543 QString("%1 (\"%2\")").arg(r).arg(f),
2544 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2545 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2551 BranchObj* MapEditor::findText (QString s, bool cs)
2553 QTextDocument::FindFlags flags=0;
2554 if (cs) flags=QTextDocument::FindCaseSensitively;
2557 { // Nothing found or new find process
2559 // nothing found, start again
2561 itFind=mapCenter->first();
2563 bool searching=true;
2564 bool foundNote=false;
2565 while (searching && !EOFind)
2569 // Searching in Note
2570 if (itFind->getNote().contains(s,cs))
2572 if (selection!=itFind)
2574 if (selection) ((BranchObj*)selection)->unselect();
2576 selection->select();
2577 ensureSelectionVisible();
2579 if (textEditor->findText(s,flags))
2585 // Searching in Heading
2586 if (searching && itFind->getHeading().contains (s,cs) )
2588 if (selection) ((BranchObj*)selection)->unselect();
2590 selection->select();
2591 ensureSelectionVisible();
2597 itFind=itFind->next();
2598 if (!itFind) EOFind=true;
2603 return (BranchObj*)selection;
2608 void MapEditor::findReset()
2609 { // Necessary if text to find changes during a find process
2613 void MapEditor::setURL(const QString &url)
2615 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2616 typeid(*selection) == typeid(MapCenterObj)) )
2618 BranchObj *bo=(BranchObj*)selection;
2619 QString oldurl=bo->getURL();
2623 QString ("setURL (\"%1\")").arg(oldurl),
2625 QString ("setURL (\"%1\")").arg(url),
2626 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2632 void MapEditor::editURL()
2634 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2635 typeid(*selection) == typeid(MapCenterObj)) )
2638 BranchObj *bo=(BranchObj*)selection;
2639 QString text = QInputDialog::getText(
2640 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2641 bo->getURL(), &ok, this );
2643 // user entered something and pressed OK
2648 QString MapEditor::getURL()
2650 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2651 typeid(*selection) == typeid(MapCenterObj)) )
2652 return ((BranchObj*)selection)->getURL();
2657 QStringList MapEditor::getURLs()
2660 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2661 typeid(*selection) == typeid(MapCenterObj)) )
2663 BranchObj *bo=(BranchObj*)selection;
2667 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2675 void MapEditor::editHeading2URL()
2677 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2678 typeid(*selection) == typeid(MapCenterObj)) )
2679 setURL (((BranchObj*)selection)->getHeading());
2682 void MapEditor::editBugzilla2URL()
2684 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2685 typeid(*selection) == typeid(MapCenterObj)) )
2687 BranchObj *bo=(BranchObj*)selection;
2688 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2693 void MapEditor::editFATE2URL()
2695 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2696 typeid(*selection) == typeid(MapCenterObj)) )
2698 BranchObj *bo=(BranchObj*)selection;
2699 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2702 "setURL (\""+bo->getURL()+"\")",
2704 "setURL (\""+url+"\")",
2705 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2712 void MapEditor::editVymLink()
2714 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2715 typeid(*selection) == typeid(MapCenterObj)) )
2717 BranchObj *bo=(BranchObj*)selection;
2718 QStringList filters;
2719 filters <<"VYM map (*.vym)";
2720 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2721 fd->setFilters (filters);
2722 fd->setCaption(vymName+" - " +tr("Link to another map"));
2723 if (! bo->getVymLink().isEmpty() )
2724 fd->selectFile( bo->getVymLink() );
2728 if ( fd->exec() == QDialog::Accepted )
2732 "setVymLink (\""+bo->getVymLink()+"\")",
2734 "setVymLink (\""+fd->selectedFile()+"\")",
2735 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2737 bo->setVymLink (fd->selectedFile() );
2739 mapCenter->reposition();
2745 void MapEditor::deleteVymLink()
2747 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2748 typeid(*selection) == typeid(MapCenterObj)) )
2750 BranchObj *bo=(BranchObj*)selection;
2753 "setVymLink (\""+bo->getVymLink()+"\")",
2755 "setVymLink (\"\")",
2756 QString("Unset vymlink of %1").arg(getName(bo))
2758 bo->setVymLink ("" );
2760 mapCenter->reposition();
2765 void MapEditor::setHideExport(bool b)
2767 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2768 typeid(*selection)==typeid(FloatImageObj)))
2770 OrnamentedObj *oo=(OrnamentedObj*)selection;
2771 oo->setHideInExport (b);
2772 QString u= b ? "false" : "true";
2773 QString r=!b ? "false" : "true";
2777 QString ("setHideExport (%1)").arg(u),
2779 QString ("setHideExport (%1)").arg(r),
2780 QString ("Set HideExport flag of %1 to %2").arg(getName(oo)).arg (r)
2783 mapCenter->reposition();
2788 void MapEditor::toggleHideExport()
2790 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2791 typeid(*selection)==typeid(FloatImageObj)))
2792 setHideExport ( !((OrnamentedObj*)selection)->hideInExport() );
2795 QString MapEditor::getVymLink()
2797 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2798 typeid(*selection) == typeid(MapCenterObj)) )
2800 return ((BranchObj*)selection)->getVymLink();
2806 QStringList MapEditor::getVymLinks()
2809 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2810 typeid(*selection) == typeid(MapCenterObj)) )
2812 BranchObj *bo=(BranchObj*)selection;
2816 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2824 void MapEditor::deleteKeepChilds()
2826 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2828 BranchObj* bo=(BranchObj*)selection;
2829 BranchObj* par=(BranchObj*)(bo->getParObj());
2830 QPointF p=bo->getRelPos();
2831 saveStateChangingPart(
2832 selection->getParObj(),
2834 "deleteKeepChilds ()",
2835 QString("Remove %1 and keep its childs").arg(getName(bo))
2838 QString sel=selection->getSelectString();
2840 par->removeBranchHere(bo);
2841 mapCenter->reposition();
2843 ((BranchObj*)selection)->move2RelPos (p);
2844 mapCenter->reposition();
2848 void MapEditor::deleteChilds()
2850 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2851 typeid(*selection)==typeid(MapCenterObj)))
2853 saveStateChangingPart(
2854 selection->getParObj(),
2857 QString( "Remove childs of branch %1").arg(getName(selection))
2859 ((BranchObj*)selection)->removeChilds();
2860 mapCenter->reposition();
2864 void MapEditor::editMapInfo()
2866 ExtraInfoDialog dia;
2867 dia.setMapName (getFileName() );
2868 dia.setAuthor (mapCenter->getAuthor() );
2869 dia.setComment(mapCenter->getComment() );
2873 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
2880 bo=mapCenter->first();
2883 if (!bo->getNote().isEmpty() ) n++;
2884 f+= bo->countFloatImages();
2886 xl+=bo->countXLinks();
2889 stats+=QString ("%1 branches\n").arg (b-1,6);
2890 stats+=QString ("%1 xLinks \n").arg (xl,6);
2891 stats+=QString ("%1 notes\n").arg (n,6);
2892 stats+=QString ("%1 images\n").arg (f,6);
2893 dia.setStats (stats);
2895 // Finally show dialog
2896 if (dia.exec() == QDialog::Accepted)
2898 setMapAuthor (dia.getAuthor() );
2899 setMapComment (dia.getComment() );
2903 void MapEditor::updateActions()
2905 mainWindow->updateActions();
2906 // TODO maybe don't update if blockReposition is set
2909 void MapEditor::updateNoteFlag()
2912 if ( (typeid(*selection) == typeid(BranchObj)) ||
2913 (typeid(*selection) == typeid(MapCenterObj)) )
2914 ((BranchObj*)selection)->updateNoteFlag();
2917 void MapEditor::setMapAuthor (const QString &s)
2921 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
2923 QString ("setMapAuthor (\"%1\")").arg(s),
2924 QString ("Set author of map to \"%1\"").arg(s)
2926 mapCenter->setAuthor (s);
2929 void MapEditor::setMapComment (const QString &s)
2933 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
2935 QString ("setMapComment (\"%1\")").arg(s),
2936 QString ("Set comment of map")
2938 mapCenter->setComment (s);
2941 void MapEditor::setMapLinkStyle (const QString & s)
2943 saveStateChangingPart (
2946 QString("setMapLinkStyle (\"%1\")").arg(s),
2947 QString("Set map link style (\"%1\")").arg(s)
2951 linkstyle=StyleLine;
2952 else if (s=="StyleParabel")
2953 linkstyle=StyleParabel;
2954 else if (s=="StylePolyLine")
2955 linkstyle=StylePolyLine;
2957 linkstyle=StylePolyParabel;
2960 bo=mapCenter->first();
2964 bo->setLinkStyle(bo->getDefLinkStyle());
2967 mapCenter->reposition();
2970 LinkStyle MapEditor::getMapLinkStyle ()
2975 void MapEditor::setMapDefLinkColor(QColor c)
2981 void MapEditor::setMapLinkColorHintInt()
2983 // called from setMapLinkColorHint(lch) or at end of parse
2985 bo=mapCenter->first();
2993 void MapEditor::setMapLinkColorHint(LinkColorHint lch)
2996 setMapLinkColorHintInt();
2999 void MapEditor::toggleMapLinkColorHint()
3001 if (linkcolorhint==HeadingColor)
3002 linkcolorhint=DefaultColor;
3004 linkcolorhint=HeadingColor;
3006 bo=mapCenter->first();
3014 LinkColorHint MapEditor::getMapLinkColorHint()
3016 return linkcolorhint;
3019 QColor MapEditor::getMapDefLinkColor()
3021 return defLinkColor;
3024 void MapEditor::setMapDefXLinkColor(QColor col)
3029 QColor MapEditor::getMapDefXLinkColor()
3031 return defXLinkColor;
3034 void MapEditor::setMapDefXLinkWidth (int w)
3039 int MapEditor::getMapDefXLinkWidth()
3041 return defXLinkWidth;
3044 void MapEditor::selectMapLinkColor()
3046 QColor col = QColorDialog::getColor( defLinkColor, this );
3047 if ( !col.isValid() ) return;
3050 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3052 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3053 QString("Set link color to %1").arg(col.name())
3055 setMapDefLinkColor( col );
3059 void MapEditor::toggleScroll()
3061 if (selection && (typeid(*selection) == typeid(BranchObj)) )
3063 BranchObj *bo=((BranchObj*)selection);
3064 if (bo->countBranches()==0) return;
3065 if (bo->getDepth()==0) return;
3067 if (bo->isScrolled())
3079 QString ("%1 ()").arg(u),
3081 QString ("%1 ()").arg(r),
3082 QString ("%1 %2").arg(r).arg(getName(bo))
3089 void MapEditor::unScrollAll()
3092 bo=mapCenter->first();
3095 if (bo->isScrolled()) bo->toggleScroll();
3100 void MapEditor::loadFloatImage ()
3103 (typeid(*selection) == typeid(BranchObj)) ||
3104 (typeid(*selection) == typeid(MapCenterObj)) )
3106 BranchObj *bo=((BranchObj*)selection);
3108 Q3FileDialog *fd=new Q3FileDialog( this);
3109 fd->setMode (Q3FileDialog::ExistingFiles);
3110 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3111 ImagePreview *p =new ImagePreview (fd);
3112 fd->setContentsPreviewEnabled( TRUE );
3113 fd->setContentsPreview( p, p );
3114 fd->setPreviewMode( Q3FileDialog::Contents );
3115 fd->setCaption(vymName+" - " +tr("Load image"));
3116 fd->setDir (lastImageDir);
3120 if ( fd->exec() == QDialog::Accepted )
3122 // FIXME loadFIO in QT4 use: lastImageDir=fd->directory();
3123 lastImageDir=QDir (fd->dirPath());
3124 QStringList flist = fd->selectedFiles();
3125 QStringList::Iterator it = flist.begin();
3127 while( it != flist.end() )
3130 bo->addFloatImage();
3131 fio=bo->getLastFloatImage();
3133 // FIXME loadFIO check if load of fio was successful
3135 (LinkableMapObj*)fio,
3138 QString ("loadFloatImage (%1)").arg(*it),
3139 QString("Add floatimage %1 to %2").arg(*it).arg(getName(selection))
3141 bo->getLastFloatImage()->setOriginalFilename(fn);
3145 mapCenter->reposition();
3153 void MapEditor::saveFloatImage ()
3156 (typeid(*selection) == typeid(FloatImageObj)) )
3158 FloatImageObj *fio=((FloatImageObj*)selection);
3159 QFileDialog *fd=new QFileDialog( this);
3160 fd->setFilters (imageIO.getFilters());
3161 fd->setCaption(vymName+" - " +tr("Save image"));
3162 fd->setFileMode( QFileDialog::AnyFile );
3163 fd->setDirectory (lastImageDir);
3164 // fd->setSelection (fio->getOriginalFilename());
3168 if ( fd->exec() == QDialog::Accepted )
3170 if (QFile (fd->selectedFile()).exists() )
3172 QMessageBox mb( vymName,
3173 tr("The file %1 exists already.\n"
3174 "Do you want to overwrite it?").arg(fd->selectedFile()),
3175 QMessageBox::Warning,
3176 QMessageBox::Yes | QMessageBox::Default,
3177 QMessageBox::Cancel | QMessageBox::Escape,
3178 QMessageBox::QMessageBox::NoButton );
3180 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3181 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3184 case QMessageBox::Yes:
3187 case QMessageBox::Cancel:
3194 fio->save (fd->selectedFile(),imageIO.getType (fd->selectedFilter() ) );
3200 void MapEditor::setFrame(const FrameType &t)
3203 (typeid(*selection) == typeid(BranchObj)) ||
3204 (typeid(*selection) == typeid(MapCenterObj)) )
3206 selection->setFrameType (t);
3207 mapCenter->reposition();
3208 selection->updateLink();
3212 void MapEditor::setIncludeImagesVer(bool b)
3215 (typeid(*selection) == typeid(BranchObj)) ||
3216 (typeid(*selection) == typeid(MapCenterObj)) )
3217 ((BranchObj*)selection)->setIncludeImagesVer(b);
3218 mapCenter->reposition();
3221 void MapEditor::setIncludeImagesHor(bool b)
3224 (typeid(*selection) == typeid(BranchObj)) ||
3225 (typeid(*selection) == typeid(MapCenterObj)) )
3226 ((BranchObj*)selection)->setIncludeImagesHor(b);
3227 mapCenter->reposition();
3230 void MapEditor::setHideLinkUnselected (bool b)
3233 (typeid(*selection) == typeid(BranchObj)) ||
3234 (typeid(*selection) == typeid(MapCenterObj)) ||
3235 (typeid(*selection) == typeid(FloatImageObj)) )
3236 selection->setHideLinkUnselected(b);
3239 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3242 (typeid(*selection) == typeid(BranchObj)) ||
3243 (typeid(*selection) == typeid(MapCenterObj)) )
3247 // Traverse directories
3248 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3249 QFileInfoList list = d.entryInfoList();
3252 for (int i = 0; i < list.size(); ++i)
3255 if (fi.fileName() != "." && fi.fileName() != ".." )
3258 bo=dst->getLastBranch();
3259 bo->setHeading (fi.fileName() );
3260 bo->setColor (QColor("blue"));
3262 if ( !d.cd(fi.fileName()) )
3263 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3266 // Recursively add subdirs
3267 importDirInt (bo,d);
3273 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3274 list = d.entryInfoList();
3276 for (int i = 0; i < list.size(); ++i)
3280 bo=dst->getLastBranch();
3281 bo->setHeading (fi.fileName() );
3282 bo->setColor (QColor("black"));
3283 if (fi.fileName().right(4) == ".vym" )
3284 bo->setVymLink (fi.filePath());
3289 void MapEditor::importDir()
3292 (typeid(*selection) == typeid(BranchObj)) ||
3293 (typeid(*selection) == typeid(MapCenterObj)) )
3295 QStringList filters;
3296 filters <<"VYM map (*.vym)";
3297 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3298 fd->setMode (QFileDialog::DirectoryOnly);
3299 fd->setFilters (filters);
3300 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3304 if ( fd->exec() == QDialog::Accepted )
3306 BranchObj *bo=((BranchObj*)selection);
3307 importDirInt (bo,QDir(fd->selectedFile()) );
3308 mapCenter->reposition();
3314 void MapEditor::followXLink(int i)
3317 (typeid(*selection) == typeid(BranchObj)) ||
3318 (typeid(*selection) == typeid(MapCenterObj)) )
3320 BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
3323 selection->unselect();
3325 selection->select();
3326 ensureSelectionVisible();
3331 void MapEditor::editXLink(int i)
3334 (typeid(*selection) == typeid(BranchObj)) ||
3335 (typeid(*selection) == typeid(MapCenterObj)) )
3337 XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
3340 EditXLinkDialog dia;
3342 dia.setSelection(selection);
3343 if (dia.exec() == QDialog::Accepted)
3345 if (dia.useSettingsGlobal() )
3347 setMapDefXLinkColor (xlo->getColor() );
3348 setMapDefXLinkWidth (xlo->getWidth() );
3350 if (dia.deleteXLink())
3351 ((BranchObj*)selection)->deleteXLinkAt(i);
3352 //saveStateComplete("Edit xLink"); //FIXME editXLink undoCommand
3358 void MapEditor::testFunction()
3361 dia.showCancelButton (true);
3362 dia.setText("This is a longer \nWarning");
3364 dia.setCaption("Warning: Flux problem");
3365 dia.setShowAgainName("/warnings/mapeditor");
3367 if (dia.exec()==QDialog::Accepted)
3368 cout << "accepted!\n";
3370 cout << "canceled!\n";
3373 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
3374 if (hidemode==HideNone)
3376 setHideTmpMode (HideExport);
3377 mapCenter->calcBBoxSizeWithChilds();
3378 QRectF totalBBox=mapCenter->getTotalBBox();
3379 QRectF mapRect=totalBBox;
3380 QCanvasRectangle *frame=NULL;
3382 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3384 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3385 totalBBox.width(), totalBBox.height());
3386 frame=new QCanvasRectangle (mapRect,mapScene);
3387 frame->setBrush (QColor(white));
3388 frame->setPen (QColor(black));
3389 frame->setZValue(0);
3394 setHideTmpMode (HideNone);
3396 cout <<" hidemode="<<hidemode<<endl;
3400 void MapEditor::ensureSelectionVisible()
3404 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
3406 if (selection->getOrientation() == OrientLeftOfCenter)
3407 p= matrix().map(QPointF (lmo->x(),lmo->y()));
3409 p= matrix().map(QPointF (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
3410 ensureVisible (QRectF(p.x(), p.y(),0,0 ));
3416 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3418 // Lineedits are already closed by preceding
3419 // mouseEvent, we don't need to close here.
3421 QPointF p = mapToScene(e->pos());
3422 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3425 { // MapObj was found
3426 if (selection != lmo)
3428 // select the MapObj
3429 if (selection) selection->unselect();
3431 selection->select();
3436 if (typeid(*selection)==typeid(BranchObj) ||
3437 typeid(*selection)==typeid(MapCenterObj) )
3439 // Context Menu on branch or mapcenter
3441 branchContextMenu->popup(e->globalPos() );
3443 if (typeid(*selection)==typeid(FloatImageObj))
3445 // Context Menu on floatimage
3447 floatimageContextMenu->popup(e->globalPos() );
3451 { // No MapObj found, we are on the Canvas itself
3452 // Context Menu on scene
3454 canvasContextMenu->popup(e->globalPos() );
3459 void MapEditor::keyPressEvent(QKeyEvent* e)
3461 if (e->modifiers() & Qt::ControlModifier)
3463 switch (mainWindow->getModMode())
3466 setCursor (PickColorCursor);
3469 setCursor (CopyCursor);
3472 setCursor (XLinkCursor);
3475 setCursor (Qt::ArrowCursor);
3481 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3483 if (!(e->modifiers() & Qt::ControlModifier))
3484 setCursor (Qt::ArrowCursor);
3487 void MapEditor::mousePressEvent(QMouseEvent* e)
3489 // Ignore right clicks, these will go to context menus
3490 if (e->button() == Qt::RightButton )
3496 QPointF p = mapToScene(e->pos());
3497 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3501 //Take care of clickdesystem flags _or_ modifier modes
3503 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3504 typeid(*lmo)==typeid(MapCenterObj) ))
3506 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3507 if (!foname.isEmpty())
3509 // systemFlag clicked
3513 if (e->state() & Qt::ControlModifier)
3514 mainWindow->editOpenURLTab();
3516 mainWindow->editOpenURL();
3518 else if (foname=="vymLink")
3520 mainWindow->editOpenVymLink();
3521 // tabWidget may change, better return now
3522 // before segfaulting...
3523 } else if (foname=="note")
3524 mainWindow->windowToggleNoteEditor();
3525 else if (foname=="hideInExport")
3530 // No system flag clicked, take care of modmodes
3532 // Special case: CTRL is pressed
3533 if (e->state() & Qt::ControlModifier)
3535 if (mainWindow->getModMode()==ModModeColor)
3538 setCursor (PickColorCursor);
3541 if (mainWindow->getModMode()==ModModeXLink)
3543 BranchObj *bo_begin=NULL;
3545 bo_begin=(BranchObj*)(lmo);
3548 ((typeid(*selection) == typeid(BranchObj)) ||
3549 (typeid(*selection) == typeid(MapCenterObj))) )
3550 bo_begin=(BranchObj*)selection;
3554 linkingObj_src=bo_begin;
3555 tmpXLink=new XLinkObj (mapScene);
3556 tmpXLink->setBegin (bo_begin);
3557 tmpXLink->setEnd (p);
3558 tmpXLink->setColor(defXLinkColor);
3559 tmpXLink->setWidth(defXLinkWidth);
3560 tmpXLink->updateXLink();
3561 tmpXLink->setVisibility (true);
3569 // Left Button Move Branches
3570 if (e->button() == Qt::LeftButton )
3572 movingObj_start.setX( p.x() - selection->x() );
3573 movingObj_start.setY( p.y() - selection->y() );
3574 movingObj_orgPos.setX (lmo->x() );
3575 movingObj_orgPos.setY (lmo->y() );
3576 movingObj_orgRelPos=lmo->getRelPos();
3578 // If modMode==copy, then we want to "move" the _new_ object around
3579 // then we need the offset from p to the _old_ selection, because of tmp
3580 if (mainWindow->getModMode()==ModModeCopy &&
3581 e->state() & Qt::ControlModifier)
3583 if (typeid(*selection)==typeid(BranchObj) )
3586 mapCenter->addBranch ((BranchObj*)selection);
3588 selection=mapCenter->getLastBranch();
3589 selection->select();
3590 mapCenter->reposition();
3593 movingObj=selection;
3595 // Middle Button Toggle Scroll
3596 // (On Mac OS X this won't work, but we still have
3597 // a button in the toolbar)
3598 if (e->button() == Qt::MidButton )
3602 { // No MapObj found, we are on the scene itself
3603 // Left Button move Pos of sceneView
3604 if (e->button() == Qt::LeftButton )
3606 movingObj=NULL; // move Content not Obj
3607 movingObj_start=e->globalPos();
3608 movingCont_start=QPointF (
3609 horizontalScrollBar()->value(),
3610 verticalScrollBar()->value());
3611 movingVec=QPointF(0,0);
3612 setCursor(HandOpenCursor);
3617 void MapEditor::mouseMoveEvent(QMouseEvent* e)
3619 QPointF p = mapToScene(e->pos());
3621 // Move the selected MapObj
3622 if ( selection && movingObj)
3624 // To avoid jumping of the sceneView, only
3625 // ensureSelectionVisible, if not tmp linked
3626 if (!selection->hasParObjTmp())
3627 ensureSelectionVisible ();
3629 // Now move the selection, but add relative position
3630 // (movingObj_start) where selection was chosen with
3631 // mousepointer. (This avoids flickering resp. jumping
3632 // of selection back to absPos)
3634 LinkableMapObj *lmosel;
3635 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3637 // Check if we could link
3638 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3641 if (typeid(*selection) == typeid(FloatImageObj))
3643 FloatObj *fo=(FloatObj*)selection;
3644 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3646 fo->updateLink(); //no need for reposition, if we update link here
3648 // Relink float to new mapcenter or branch, if shift is pressed
3649 // Only relink, if selection really has a new parent
3650 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3651 ( (typeid(*lmo)==typeid(BranchObj)) ||
3652 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3653 ( lmo != fo->getParObj())
3656 if (typeid(*fo) == typeid(FloatImageObj) &&
3657 ( (typeid(*lmo)==typeid(BranchObj) ||
3658 typeid(*lmo)==typeid(MapCenterObj)) ))
3661 // Also save the move which was done so far
3662 FloatImageObj *fio=(FloatImageObj*)selection;
3663 QString pold=qpointfToString(movingObj_orgRelPos);
3664 QString pnow=qpointfToString(fio->getRelPos());
3670 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(pnow));
3671 fio->getParObj()->requestReposition();
3672 mapCenter->reposition();
3674 cout << "current relPos="<<movingObj_orgRelPos<<endl;
3675 linkTo (lmo->getSelectString());
3676 cout << "setting movingObj\n";
3677 movingObj=(MapObj*)selection;
3678 movingObj_orgRelPos=selection->getRelPos();
3681 mapCenter->reposition();
3685 { // selection != a FloatObj
3686 if (lmosel->getDepth()==0)
3689 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3690 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3692 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3693 mapCenter->updateRelPositions();
3696 if (lmosel->getDepth()==1)
3699 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3700 lmosel->setRelPos();
3703 // Move ordinary branch
3704 if (lmosel->getOrientation() == OrientLeftOfCenter)
3705 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3706 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3707 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3709 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3711 // reposition subbranch
3712 lmosel->reposition();
3714 if (lmo && (lmo!=selection) &&
3715 (typeid(*lmo) == typeid(BranchObj) ||
3716 (typeid(*lmo) == typeid(MapCenterObj) )
3719 if (e->modifiers()==Qt::ControlModifier)
3721 // Special case: CTRL to link below lmo
3722 lmosel->setParObjTmp (lmo,p,+1);
3724 else if (e->modifiers()==Qt::ShiftModifier)
3725 lmosel->setParObjTmp (lmo,p,-1);
3727 lmosel->setParObjTmp (lmo,p,0);
3730 lmosel->unsetParObjTmp();
3734 } // no FloatImageObj
3738 } // selection && moving_obj
3740 // Draw a link from one branch to another
3743 tmpXLink->setEnd (p);
3744 tmpXLink->updateXLink();
3748 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
3750 QPointF p=e->globalPos();
3751 movingVec.setX(-p.x() + movingObj_start.x() );
3752 movingVec.setY(-p.y() + movingObj_start.y() );
3753 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
3754 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
3759 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
3761 QPointF p = mapToScene(e->pos());
3762 LinkableMapObj *dst;
3763 // Have we been picking color?
3767 setCursor (Qt::ArrowCursor);
3768 // Check if we are over another branch
3769 dst=mapCenter->findMapObj(p, NULL);
3770 if (dst && selection)
3772 if (e->state() & Qt::ShiftModifier)
3773 colorBranch (((BranchObj*)(dst))->getColor());
3775 colorSubtree (((BranchObj*)(dst))->getColor());
3780 // Have we been drawing a link?
3784 // Check if we are over another branch
3785 dst=mapCenter->findMapObj(p, NULL);
3786 if (dst && selection)
3788 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3789 tmpXLink->updateXLink();
3790 tmpXLink->activate();
3791 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //FIXME undoCommand
3800 // Have we been moving something?
3801 if ( selection && movingObj )
3803 if(typeid(*selection)==typeid (FloatImageObj))
3805 // Moved FloatObj. Maybe we need to reposition
3806 FloatImageObj *fo=(FloatImageObj*)selection;
3807 QString pold=qpointfToString(movingObj_orgRelPos);
3808 QString pnow=qpointfToString(fo->getRelPos());
3814 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(pnow));
3816 selection->getParObj()->requestReposition();
3817 mapCenter->reposition();
3820 // Check if we are over another branch, but ignore
3821 // any found LMOs, which are FloatObjs
3822 dst=mapCenter->findMapObj(mapToScene(e->pos() ),
3823 ((LinkableMapObj*)selection) );
3825 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3828 if (typeid(*selection) == typeid(MapCenterObj) )
3829 { // FIXME The MapCenter was moved, no savestate yet
3832 if (typeid(*selection) == typeid(BranchObj) )
3833 { // A branch was moved
3835 // save the position in case we link to mapcenter
3836 QPointF savePos=QPointF (selection->x(),selection->y() );
3838 // Reset the temporary drawn link to the original one
3839 ((LinkableMapObj*)selection)->unsetParObjTmp();
3841 // For Redo we may need to save original selection
3842 QString preSelStr=selection->getSelectString();
3847 BranchObj* bsel=(BranchObj*)selection;
3848 BranchObj* bdst=(BranchObj*)dst;
3850 QString preParStr=(bsel->getParObj())->getSelectString();
3851 QString preNum=QString::number (bsel->getNum(),10);
3852 QString preDstParStr;
3854 if (e->state() & Qt::ShiftModifier && dst->getParObj())
3856 preDstParStr=dst->getParObj()->getSelectString();
3857 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
3859 if (e->state() & Qt::ControlModifier && dst->getParObj())
3862 preDstParStr=dst->getParObj()->getSelectString();
3863 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
3866 preDstParStr=dst->getSelectString();
3867 bsel->moveBranchTo (bdst,-1);
3868 if (dst->getDepth()==0) bsel->move (savePos);
3870 QString postSelStr=selection->getSelectString();
3871 QString postNum=QString::number (bsel->getNum(),10);
3873 QString undoCom="linkBranchToPos (\""+
3874 preParStr+ "\"," + preNum +"," +
3875 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
3877 QString redoCom="linkBranchToPos (\""+
3878 preDstParStr + "\"," + postNum + "," +
3879 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
3884 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
3886 if (selection->getDepth()==1)
3888 // The select string might be different _after_ moving around.
3889 // Therefor reposition and then use string of old selection, too
3890 mapCenter->reposition();
3892 QString ps=qpointfToString ( ((BranchObj*)selection)->getRelPos() );
3894 selection->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
3895 preSelStr, "moveRel "+ps,
3896 QString("Move %1 to relative position %2").arg(getName(selection)).arg(ps));
3899 // Draw the original link, before selection was moved around
3900 mapCenter->reposition();
3902 // Finally resize scene, if needed
3906 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
3909 // maybe we moved View: set old cursor
3910 setCursor (Qt::ArrowCursor);
3914 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
3916 if (e->button() == Qt::LeftButton )
3918 QPointF p = mapToScene(e->pos());
3919 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3920 if (lmo) { // MapObj was found
3921 // First select the MapObj than edit heading
3922 if (selection) selection->unselect();
3924 selection->select();
3925 mainWindow->editHeading();
3930 void MapEditor::resizeEvent (QResizeEvent* e)
3932 QGraphicsView::resizeEvent( e );
3935 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
3937 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
3938 // cerr << event->format(i) << endl;
3940 if (event->mimeData()->hasImage())
3941 event->acceptProposedAction();
3943 if (event->mimeData()->hasUrls())
3944 event->acceptProposedAction();
3947 void MapEditor::dragMoveEvent(QDragMoveEvent *event)
3951 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
3956 void MapEditor::dropEvent(QDropEvent *event)
3959 (typeid(*selection) == typeid(BranchObj)) ||
3960 (typeid(*selection) == typeid(MapCenterObj)))
3963 if (event->mimeData()->hasImage())
3965 QVariant imageData = event->mimeData()->imageData();
3966 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
3968 if (event->mimeData()->hasUrls())
3969 uris=event->mimeData()->urls();
3977 for (int i=0; i<uris.count();++i)
3979 bo=((BranchObj*)selection)->addBranch();
3982 s=uris.at(i).toLocalFile();
3985 QString file = QDir::convertSeparators(s);
3986 heading = QFileInfo(file).baseName();
3988 if (file.endsWith(".vym", false))
3989 bo->setVymLink(file);
3991 bo->setURL(uris.at(i).toString());
3994 bo->setURL(uris.at(i).toString());
3997 if (!heading.isEmpty())
3998 bo->setHeading(heading);
4000 bo->setHeading(uris.at(i).toString());
4003 mapCenter->reposition();
4006 event->acceptProposedAction();
4010 void MapEditor::contentsDropEvent(QDropEvent *event)
4013 } else if (event->provides("application/x-moz-file-promise-url") &&
4014 event->provides("application/x-moz-nativeimage"))
4016 // Contains url to the img src in unicode16
4017 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4018 QString url = QString((const QChar*)d.data(),d.size()/2);
4022 } else if (event->provides ("text/uri-list"))
4023 { // Uris provided e.g. by konqueror
4024 Q3UriDrag::decode (event,uris);
4025 } else if (event->provides ("_NETSCAPE_URL"))
4026 { // Uris provided by Mozilla
4027 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4030 } else if (event->provides("text/html")) {
4032 // Handels text mime types
4033 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4034 QByteArray d = event->encodedData("text/html");
4037 text = QString((const QChar*)d.data(),d.size()/2);
4041 textEditor->setText(text);
4045 } else if (event->provides("text/plain")) {
4046 QByteArray d = event->encodedData("text/plain");
4049 text = QString((const QChar*)d.data(),d.size()/2);
4053 textEditor->setText(text);
4063 bool isUnicode16(const QByteArray &d)
4065 // TODO: make more precise check for unicode 16.
4066 // Guess unicode16 if any of second bytes are zero
4067 unsigned int length = max(0,d.size()-2)/2;
4068 for (unsigned int i = 0; i<length ; i++)
4069 if (d.at(i*2+1)==0) return true;
4073 void MapEditor::addFloatImageInt (const QPixmap &img)
4076 (typeid(*selection) == typeid(BranchObj)) ||
4077 (typeid(*selection) == typeid(MapCenterObj)) )
4079 BranchObj *bo=((BranchObj*)selection);
4080 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4081 //QString fn=fd->selectedFile();
4082 //lastImageDir=fn.left(fn.findRev ("/"));
4083 FloatImageObj *fio=bo->addFloatImage();
4085 fio->setOriginalFilename("Image added by Drag and Drop");
4086 mapCenter->reposition();
4093 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4095 if (!imageBuffer) imageBuffer = new QBuffer();
4096 if (!imageBuffer->isOpen()) {
4097 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4099 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4103 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4105 if (nop->state()==Q3NetworkProtocol::StDone) {
4106 QPixmap img(imageBuffer->buffer());
4107 addFloatImageInt (img);
4111 imageBuffer->close();
4113 imageBuffer->close();
4120 void MapEditor::fetchImage(const QString &url)
4123 urlOperator->stop();
4124 disconnect(urlOperator);
4128 urlOperator = new Q3UrlOperator(url);
4129 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4130 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4132 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4133 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));