Removed some FIXMEs. Added translations
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;
65 viewport()->setAcceptDrops(true);
67 mapScene= new QGraphicsScene(parent);
68 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
69 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
74 mapCenter = new MapCenterObj(mapScene);
75 mapCenter->setVisibility (true);
76 mapCenter->setMapEditor (this);
77 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
78 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
83 defLinkColor=QColor (0,0,255);
84 defXLinkColor=QColor (180,180,180);
85 linkcolorhint=DefaultColor;
86 linkstyle=StylePolyParabel;
88 // Create bitmap cursors, platform dependant
89 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
90 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
91 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
92 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
94 setFocusPolicy (Qt::StrongFocus);
105 xelection.setMapCenter (mapCenter);
108 defXLinkColor=QColor (230,230,230);
116 fileName=tr("unnamed");
119 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
120 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
122 // Initialize find routine
129 blockReposition=false;
130 blockSaveState=false;
134 // Create temporary files
137 // Initially set movingCentre
140 mapCenter->reposition(); // for positioning heading
144 MapEditor::~MapEditor()
146 if (imageBuffer) delete imageBuffer;
152 //cout <<"Destructor MapEditor\n";
155 MapCenterObj* MapEditor::getMapCenter()
160 QGraphicsScene * MapEditor::getScene()
165 bool MapEditor::isRepositionBlocked()
167 return blockReposition;
170 QString MapEditor::getName (LinkableMapObj *lmo)
173 if (!lmo) return QString("Error: NULL has no name!");
175 if ((typeid(*lmo) == typeid(BranchObj) ||
176 typeid(*lmo) == typeid(MapCenterObj)))
179 s=(((BranchObj*)lmo)->getHeading());
180 if (s=="") s="unnamed";
181 return QString("branch (%1)").arg(s);
182 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
184 if ((typeid(*lmo) == typeid(FloatImageObj) ))
185 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
186 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
187 return QString("Unknown type has no name!");
190 void MapEditor::makeTmpDirs()
192 // Create unique temporary directories
193 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
194 histPath=QDir::convertSeparators (tmpMapDir+"/history");
199 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
201 // tmpdir temporary directory to which data will be written
202 // prefix mapname, which will be appended to images etc.
203 // writeflags Only write flags for "real" save of map, not undo
204 // offset offset of bbox of whole map in scene.
205 // Needed for XML export
221 ls="StylePolyParabel";
225 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
227 if (linkcolorhint==HeadingColor)
228 colhint=attribut("linkColorHint","HeadingColor");
230 QString mapAttr=attribut("version",vymVersion);
231 if (!saveSel || saveSel==mapCenter)
232 mapAttr+= attribut("author",mapCenter->getAuthor()) +
233 attribut("comment",mapCenter->getComment()) +
234 attribut("date",mapCenter->getDate()) +
235 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
236 attribut("linkStyle", ls ) +
237 attribut("linkColor", defLinkColor.name() ) +
238 attribut("defXLinkColor", defXLinkColor.name() ) +
239 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
241 s+=beginElement("vymmap",mapAttr);
244 // Find the used flags while traversing the tree
245 standardFlagsDefault->resetUsedCounter();
247 // Reset the counters before saving
248 // TODO constr. of FIO creates lots of objects, better do this in some other way...
249 FloatImageObj (mapScene).resetSaveCounter();
251 // Build xml recursivly
252 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
253 // Save complete map, if saveSel not set
254 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
257 if ( typeid(*saveSel) == typeid(BranchObj) )
259 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
260 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
262 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
265 // Save local settings
266 s+=settings.getXMLData (destPath);
269 if (selection && !saveSel )
270 s+=valueElement("select",selection->getSelectString());
273 s+=endElement("vymmap");
276 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
280 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
282 // save the selected part of the map, Undo will replace part of map
283 QString undoSelection="";
285 undoSelection=undoSel->getSelectString();
287 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
288 QString redoSelection="";
290 redoSelection=undoSel->getSelectString();
292 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
295 saveState (PartOfMap,
296 undoSelection, "addMapReplace (\"PATH\")",
302 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
306 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
309 QString undoSelection=redoSel->getParObj()->getSelectString();
310 QString redoSelection=redoSel->getSelectString();
311 if (typeid(*redoSel) == typeid(BranchObj) )
313 // save the selected branch of the map, Undo will insert part of map
314 saveState (PartOfMap,
315 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
316 redoSelection, "delete ()",
323 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
325 // "Normal" savestate: save commands, selections and comment
326 // so just save commands for undo and redo
327 // and use current selection
329 QString redoSelection="";
330 if (redoSel) redoSelection=redoSel->getSelectString();
331 QString undoSelection="";
332 if (undoSel) undoSelection=undoSel->getSelectString();
334 saveState (UndoCommand,
341 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
343 // "Normal" savestate: save commands, selections and comment
344 // so just save commands for undo and redo
345 // and use current selection
346 saveState (UndoCommand,
354 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
358 if (blockSaveState) return;
360 /* TODO remove after testing
362 cout << "ME::saveState() "<<endl;
364 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
365 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
366 int curStep=undoSet.readNumEntry ("/history/curStep",0);
367 // Find out current undo directory
368 if (undosAvail<stepsTotal) undosAvail++;
370 if (curStep>stepsTotal) curStep=1;
372 QString backupXML="";
373 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
374 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
375 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
377 // Create bakMapDir if not available
380 makeSubDirs (bakMapDir);
382 // Save depending on how much needs to be saved
384 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPointF (),saveSel);
386 QString undoCommand="";
387 if (savemode==UndoCommand)
391 else if (savemode==PartOfMap )
394 undoCommand.replace ("PATH",bakMapPath);
397 if (!backupXML.isEmpty())
398 // Write XML Data to disk
399 saveStringToDisk (QString(bakMapPath),backupXML);
401 // We would have to save all actions in a tree, to keep track of
402 // possible redos after a action. Possible, but we are too lazy: forget about redos.
405 // Write the current state to disk
406 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
407 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
408 undoSet.setEntry ("/history/curStep",QString::number(curStep));
409 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
410 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
411 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
412 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
413 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
414 undoSet.setEntry (QString("/history/version"),vymVersion);
415 undoSet.writeSettings(histPath);
417 /* TODO remove after testing
419 //cout << " into="<< histPath.toStdString()<<endl;
420 cout << " stepsTotal="<<stepsTotal<<
421 ", undosAvail="<<undosAvail<<
422 ", redosAvail="<<redosAvail<<
423 ", curStep="<<curStep<<endl;
424 cout << " ---------------------------"<<endl;
425 cout << " comment="<<comment.toStdString()<<endl;
426 cout << " undoCom="<<undoCommand.toStdString()<<endl;
427 cout << " undoSel="<<undoSelection.toStdString()<<endl;
428 cout << " redoCom="<<redoCom.toStdString()<<endl;
429 cout << " redoSel="<<redoSelection.toStdString()<<endl;
430 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
431 cout << " ---------------------------"<<endl;
433 mainWindow->updateHistory (undoSet);
438 void MapEditor::parseAtom(const QString &atom)
445 // Split string s into command and parameters
446 api.parseInput (atom);
447 QString com=api.command();
450 if (com=="addBranch")
454 api.setError (Aborted,"Nothing selected");
455 } else if ( (typeid(*selection) != typeid(BranchObj) &&
456 typeid(*selection) != typeid(MapCenterObj)) )
458 api.setError (Aborted,"Type of selection is not a branch");
463 if (api.checkParamCount(pl))
465 if (api.paramCount()==0)
466 addNewBranchInt (-2);
470 if (ok ) addNewBranchInt (y);
474 } else if (com=="addBranchBefore")
478 api.setError (Aborted,"Nothing selected");
479 } else if ( (typeid(*selection) != typeid(BranchObj) &&
480 typeid(*selection) != typeid(MapCenterObj)) )
482 api.setError (Aborted,"Type of selection is not a branch");
485 if (api.paramCount()==0)
487 addNewBranchBefore ();
490 } else if (com==QString("addMapReplace"))
494 api.setError (Aborted,"Nothing selected");
495 } else if ( (typeid(*selection) != typeid(BranchObj) &&
496 typeid(*selection) != typeid(MapCenterObj)) )
498 api.setError (Aborted,"Type of selection is not a branch");
499 } else if (api.checkParamCount(1))
501 //s=api.parString (ok,0); // selection
502 t=api.parString (ok,0); // path to map
503 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
504 addMapReplaceInt(selection->getSelectString(),t);
506 } else if (com==QString("addMapInsert"))
510 api.setError (Aborted,"Nothing selected");
511 } else if ( (typeid(*selection) != typeid(BranchObj) &&
512 typeid(*selection) != typeid(MapCenterObj)) )
514 api.setError (Aborted,"Type of selection is not a branch");
517 if (api.checkParamCount(2))
519 t=api.parString (ok,0); // path to map
520 y=api.parInt(ok,1); // position
521 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
522 addMapInsertInt(t,y);
525 } else if (com=="colorItem")
529 api.setError (Aborted,"Nothing selected");
530 } else if ( typeid(*selection) != typeid(BranchObj) &&
531 typeid(*selection) != typeid(MapCenterObj))
533 api.setError (Aborted,"Type of selection is not a branch");
534 } else if (api.checkParamCount(1))
536 QColor c=api.parColor (ok,0);
537 if (ok) colorItem (c);
539 } else if (com=="colorBranch")
543 api.setError (Aborted,"Nothing selected");
544 } else if ( typeid(*selection) != typeid(BranchObj) &&
545 typeid(*selection) != typeid(MapCenterObj))
547 api.setError (Aborted,"Type of selection is not a branch");
548 } else if (api.checkParamCount(1))
550 QColor c=api.parColor (ok,0);
551 if (ok) colorBranch (c);
553 } else if (com=="cut")
557 api.setError (Aborted,"Nothing selected");
558 } else if ( typeid(*selection) != typeid(BranchObj) &&
559 typeid(*selection) != typeid(MapCenterObj) &&
560 typeid(*selection) != typeid(FloatImageObj) )
562 api.setError (Aborted,"Type of selection is not a branch or floatimage");
563 } else if (api.checkParamCount(0))
567 } else if (com=="delete")
571 api.setError (Aborted,"Nothing selected");
572 } else if ( (typeid(*selection) != typeid(BranchObj) &&
573 typeid(*selection) != typeid(MapCenterObj)) )
575 api.setError (Aborted,"Type of selection is not a branch");
576 } else if (api.checkParamCount(0))
580 } else if (com=="deleteKeepChilds")
584 api.setError (Aborted,"Nothing selected");
585 } else if ( (typeid(*selection) != typeid(BranchObj) &&
586 typeid(*selection) != typeid(MapCenterObj)) )
588 api.setError (Aborted,"Type of selection is not a branch");
589 } else if (api.checkParamCount(0))
593 } else if (com=="deleteChilds")
597 api.setError (Aborted,"Nothing selected");
598 } else if ( (typeid(*selection) != typeid(BranchObj) &&
599 typeid(*selection) != typeid(MapCenterObj)) )
601 api.setError (Aborted,"Type of selection is not a branch");
602 } else if (api.checkParamCount(0))
606 } else if (com=="linkBranchToPos")
610 api.setError (Aborted,"Nothing selected");
611 } else if ( (typeid(*selection) != typeid(BranchObj) &&
612 typeid(*selection) != typeid(MapCenterObj)) )
614 api.setError (Aborted,"Type of selection is not a branch");
615 } else if (api.checkParamCount(4))
617 // 0 selectstring of parent
618 // 1 num in parent (for branches)
619 // 2,3 x,y of mainbranch or mapcenter
620 s=api.parString(ok,0);
621 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
624 if (typeid(*dst) == typeid(BranchObj) )
626 // Get number in parent
629 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),x);
630 } else if (typeid(*dst) == typeid(MapCenterObj) )
632 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),-1);
633 // Get coordinates of mainbranch
638 if (ok) ((BranchObj*)selection)->move (x,y);
643 } else if (com=="moveBranchUp")
647 api.setError (Aborted,"Nothing selected");
648 } else if ( (typeid(*selection) != typeid(BranchObj) &&
649 typeid(*selection) != typeid(MapCenterObj)) )
651 api.setError (Aborted,"Type of selection is not a branch");
652 } else if (api.checkParamCount(0))
656 } else if (com=="moveBranchDown")
660 api.setError (Aborted,"Nothing selected");
661 } else if ( (typeid(*selection) != typeid(BranchObj) &&
662 typeid(*selection) != typeid(MapCenterObj)) )
664 api.setError (Aborted,"Type of selection is not a branch");
665 } else if (api.checkParamCount(0))
669 } else if (com=="move")
673 api.setError (Aborted,"Nothing selected");
674 } else if ( typeid(*selection) != typeid(BranchObj) &&
675 typeid(*selection) != typeid(MapCenterObj) &&
676 typeid(*selection) != typeid(FloatImageObj) )
678 api.setError (Aborted,"Type of selection is not a branch or floatimage");
679 } else if (api.checkParamCount(2))
688 } else if (com=="moveRel")
692 api.setError (Aborted,"Nothing selected");
693 } else if ( typeid(*selection) != typeid(BranchObj) &&
694 typeid(*selection) != typeid(MapCenterObj) &&
695 typeid(*selection) != typeid(FloatImageObj) )
697 api.setError (Aborted,"Type of selection is not a branch or floatimage");
698 } else if (api.checkParamCount(2))
704 if (ok) moveRel (x,y);
707 } else if (com=="paste")
711 api.setError (Aborted,"Nothing selected");
712 } else if ( typeid(*selection) != typeid(BranchObj) &&
713 typeid(*selection) != typeid(MapCenterObj) )
715 api.setError (Aborted,"Type of selection is not a branch");
716 } else if (api.checkParamCount(0))
720 } else if (com=="select")
722 if (api.checkParamCount(1))
724 s=api.parString(ok,0);
727 } else if (com=="setMapAuthor")
729 if (api.checkParamCount(1))
731 s=api.parString(ok,0);
732 if (ok) setMapAuthor (s);
734 } else if (com=="setMapComment")
736 if (api.checkParamCount(1))
738 s=api.parString(ok,0);
739 if (ok) setMapComment(s);
741 } else if (com=="setMapBackgroundColor")
745 api.setError (Aborted,"Nothing selected");
746 } else if ( (typeid(*selection) != typeid(BranchObj) &&
747 typeid(*selection) != typeid(MapCenterObj)) )
749 api.setError (Aborted,"Type of selection is not a branch");
750 } else if (api.checkParamCount(1))
752 QColor c=api.parColor (ok,0);
753 if (ok) setMapBackgroundColor (c);
755 } else if (com=="setMapDefLinkColor")
759 api.setError (Aborted,"Nothing selected");
760 } else if ( (typeid(*selection) != typeid(BranchObj) &&
761 typeid(*selection) != typeid(MapCenterObj)) )
763 api.setError (Aborted,"Type of selection is not a branch");
764 } else if (api.checkParamCount(1))
766 QColor c=api.parColor (ok,0);
767 if (ok) setMapDefLinkColor (c);
769 } else if (com=="setMapLinkStyle")
771 if (api.checkParamCount(1))
773 s=api.parString (ok,0);
774 if (ok) setMapLinkStyle(s);
776 } else if (com=="setHeading")
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 s=api.parString (ok,0);
791 } else if (com=="setHideExport")
795 api.setError (Aborted,"Nothing selected");
796 } else if ( typeid(*selection) != typeid(BranchObj) &&
797 typeid(*selection) != typeid(FloatImageObj) )
799 api.setError (Aborted,"Type of selection is not a branch or floatimage");
800 } else if (api.checkParamCount(1))
803 if (ok) setHideExport (b);
805 } else if (com=="setURL")
809 api.setError (Aborted,"Nothing selected");
810 } else if ( (typeid(*selection) != typeid(BranchObj) &&
811 typeid(*selection) != typeid(MapCenterObj)) )
813 api.setError (Aborted,"Type of selection is not a branch");
814 } else if (api.checkParamCount(1))
816 s=api.parString (ok,0);
817 if (ok) setURLInt(s);
819 } else if (com=="setVymLink")
823 api.setError (Aborted,"Nothing selected");
824 } else if ( (typeid(*selection) != typeid(BranchObj) &&
825 typeid(*selection) != typeid(MapCenterObj)) )
827 api.setError (Aborted,"Type of selection is not a branch");
828 } else if (api.checkParamCount(1))
830 s=api.parString (ok,0);
831 if (ok) setVymLinkInt(s);
834 else if (com=="setFlag")
838 api.setError (Aborted,"Nothing selected");
839 } else if ( (typeid(*selection) != typeid(BranchObj) &&
840 typeid(*selection) != typeid(MapCenterObj)) )
842 api.setError (Aborted,"Type of selection is not a branch");
843 } else if (api.checkParamCount(1))
845 s=api.parString(ok,0);
848 BranchObj* bo=(BranchObj*)selection;
849 bo->activateStandardFlag(s);
850 bo->updateFlagsToolbar();
854 else if (com=="unsetFlag")
858 api.setError (Aborted,"Nothing selected");
859 } else if ( (typeid(*selection) != typeid(BranchObj) &&
860 typeid(*selection) != typeid(MapCenterObj)) )
862 api.setError (Aborted,"Type of selection is not a branch");
863 } else if (api.checkParamCount(1))
865 s=api.parString(ok,0);
868 BranchObj* bo=(BranchObj*)selection;
869 bo->deactivateStandardFlag(s);
870 bo->updateFlagsToolbar();
875 api.setError (Aborted,"Unknown command");
879 if (api.errorLevel()==NoError)
883 // TODO Error handling
884 qWarning("MapEditor::parseAtom: Error!");
885 qWarning(api.errorMessage());
890 bool MapEditor::isDefault()
895 bool MapEditor::isUnsaved()
900 bool MapEditor::hasChanged()
905 void MapEditor::setChanged()
913 void MapEditor::closeMap()
915 // Unselect before disabling the toolbar actions
916 if (selection) selection->unselect();
924 void MapEditor::setFilePath(QString fname)
926 setFilePath (fname,fname);
929 void MapEditor::setFilePath(QString fname, QString destname)
931 if (fname.isEmpty() || fname=="")
938 filePath=fname; // becomes absolute path
939 fileName=fname; // gets stripped of path
940 destPath=destname; // needed for vymlinks
942 // If fname is not an absolute path, complete it
943 filePath=QDir(fname).absPath();
944 fileDir=filePath.left (1+filePath.findRev ("/"));
946 // Set short name, too. Search from behind:
947 int i=fileName.findRev("/");
948 if (i>=0) fileName=fileName.remove (0,i+1);
950 // Forget the .vym (or .xml) for name of map
951 mapName=fileName.left(fileName.findRev(".",-1,true) );
955 QString MapEditor::getFilePath()
960 QString MapEditor::getFileName()
965 QString MapEditor::getMapName()
970 QString MapEditor::getDestPath()
975 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
977 ErrorCode err=success;
981 if (selection) selection->unselect();
984 mapCenter->setMapEditor(this);
985 // (map state is set later at end of load...)
988 if (!selection || (typeid(*selection) != typeid(BranchObj) &&
989 typeid(*selection) != typeid (MapCenterObj)))
991 BranchObj *bo=(BranchObj*)selection;
992 if (lmode==ImportAdd)
993 saveStateChangingPart(
996 QString("addMapInsert (%1)").arg(fname),
997 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
999 saveStateChangingPart(
1002 QString("addMapReplace(%1)").arg(fname),
1003 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1007 mapBuilderHandler handler;
1008 QFile file( fname );
1010 // I am paranoid: file should exist anyway
1011 // according to check in mainwindow.
1012 if (!file.exists() )
1014 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1015 tr("Couldn't open map " +fname)+".");
1019 blockReposition=true;
1020 QXmlInputSource source( file);
1021 QXmlSimpleReader reader;
1022 reader.setContentHandler( &handler );
1023 reader.setErrorHandler( &handler );
1024 handler.setMapEditor( this );
1025 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1026 handler.setInputFile (file.name());
1027 handler.setLoadMode (lmode);
1028 blockSaveState=true;
1029 bool ok = reader.parse( source );
1030 blockReposition=false;
1031 blockSaveState=false;
1035 mapCenter->reposition();
1044 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1045 tr( handler.errorProtocol() ) );
1047 // Still return "success": the map maybe at least
1048 // partially read by the parser
1055 int MapEditor::save (const SaveMode &savemode)
1059 // Create mapName and fileDir
1060 makeSubDirs (fileDir);
1064 fname=mapName+".xml";
1066 // use name given by user, even if he chooses .doc
1071 if (savemode==CompleteMap || selection==NULL)
1072 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1074 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),selection);
1076 if (!saveStringToDisk(fileDir+fname,saveFile))
1089 void MapEditor::setZipped (bool z)
1094 bool MapEditor::saveZipped ()
1099 void MapEditor::print()
1103 printer = new QPrinter;
1104 printer->setColorMode (QPrinter::Color);
1105 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1106 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1107 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1110 QRectF totalBBox=mapCenter->getTotalBBox();
1112 // Try to set orientation automagically
1113 // Note: Interpretation of generated postscript is amibiguous, if
1114 // there are problems with landscape mode, see
1115 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1117 if (totalBBox.width()>totalBBox.height())
1118 // recommend landscape
1119 printer->setOrientation (QPrinter::Landscape);
1121 // recommend portrait
1122 printer->setOrientation (QPrinter::Portrait);
1124 if ( printer->setup(this) )
1125 // returns false, if printing is canceled
1127 QPainter pp(printer);
1129 //pp.setRenderHints(renderHints());
1130 pp.setRenderHint(QPainter::Antialiasing,true);
1132 // Don't print the visualisation of selection
1133 LinkableMapObj *oldselection=NULL;
1136 oldselection=selection;
1137 selection->unselect();
1140 QRectF mapRect=totalBBox;
1141 QGraphicsRectItem *frame=NULL;
1143 if (printFrame || printFooter)
1148 // Print frame around map
1149 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1150 totalBBox.width()+20, totalBBox.height()+20);
1151 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1152 frame->setZValue(0);
1158 // Print footer below map
1160 font.setPointSize(10);
1162 QRectF footerBox(0,printer->height()-15,printer->width(),15);
1163 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1164 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1169 double paperAspect = (double)printer->width() / (double)printer->height();
1170 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1171 cout <<"mapAspect="<<mapAspect<<" paperAspect"<<paperAspect<<endl;
1172 if (mapAspect>=paperAspect)
1174 // Fit horizontally to paper width
1175 pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1176 qWarning ("Fit hor");
1179 // Fit vertically to paper height
1180 pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1181 qWarning ("Fit ver");
1187 QRectF (0,0,printer->width(),printer->height()-15),
1188 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1191 //render (&pp,printer->pageRect(), QRect ((int)mapRect.x(),(int)mapRect.y(),400,400));
1193 //pp.setWindow (QRect (mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height()));
1194 //mapScene->render(&pp); // draw scene to printer
1196 // Viewport has paper dimension
1197 pp.drawLine (QLine (0,0,printer->width(),printer->height()));
1198 cout << "sceneRect: "
1199 <<mapScene->sceneRect().x()<<","
1200 <<mapScene->sceneRect().y()<<","
1201 <<mapScene->sceneRect().width()<<","
1202 <<mapScene->sceneRect().height()<<","<<endl;
1206 <<mapRect.width()<<","
1207 <<mapRect.height()<<","<<endl;
1208 cout << "pp.viewport: "
1209 <<pp.viewport().x()<<","
1210 <<pp.viewport().y()<<","
1211 <<pp.viewport().width()<<","
1212 <<pp.viewport().height()<<","<<endl;
1213 cout << "painter: w,h="<<pp.viewport().width()<<","<<pp.viewport().height()<<endl;
1214 cout << "printer: w,h="<<printer->width()<<","<<printer->height()<<endl;
1216 if (frame) delete (frame);
1218 // Restore selection
1221 selection=oldselection;
1222 selection->select();
1225 // Save settings in vymrc
1226 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1227 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1228 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1232 void MapEditor::setAntiAlias (bool b)
1234 setRenderHint(QPainter::Antialiasing,b);
1237 void MapEditor::setSmoothPixmap(bool b)
1239 setRenderHint(QPainter::SmoothPixmapTransform,b);
1242 QPixmap MapEditor::getPixmap()
1244 /* FIXME getPixmap not ported yet to QT4
1245 QRectF mapRect=mapCenter->getTotalBBox();
1246 QPixmap pix (mapRect.size());
1249 // Don't print the visualisation of selection
1250 LinkableMapObj *oldselection=NULL;
1253 oldselection=selection;
1254 selection->unselect();
1257 pp.setWindow (mapRect);
1259 mapScene->drawArea(mapRect, &pp); // draw scene to painter
1262 // Restore selection
1265 selection=oldselection;
1266 selection->select();
1274 void MapEditor::setHideTmpMode (HideTmpMode mode)
1277 mapCenter->setHideTmp (hidemode);
1278 mapCenter->reposition();
1282 HideTmpMode MapEditor::getHideTmpMode()
1287 void MapEditor::exportImage(QString fn)
1289 setExportMode (true);
1290 QPixmap pix (getPixmap());
1291 pix.save(fn, "PNG");
1292 setExportMode (false);
1295 void MapEditor::setExportMode (bool b)
1297 // should be called before and after exports
1298 // depending on the settings
1299 if (b && settings.value("/export/useHideExport","yes")=="yes")
1300 setHideTmpMode (HideExport);
1302 setHideTmpMode (HideNone);
1305 void MapEditor::exportImage(QString fn, QString format)
1307 setExportMode (true);
1308 QPixmap pix (getPixmap());
1309 pix.save(fn, format);
1310 setExportMode (false);
1313 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1317 ex.setMapCenter(mapCenter);
1318 if (ex.setConfigFile(cf))
1320 setExportMode (true);
1321 ex.exportPresentation();
1322 setExportMode (false);
1328 void MapEditor::exportXML(const QString &dir)
1330 // Hide stuff during export, if settings want this
1331 setExportMode (true);
1333 // Create subdirectories
1336 // write to directory
1337 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1340 file.setName ( dir + "/"+mapName+".xml");
1341 if ( !file.open( QIODevice::WriteOnly ) )
1343 // This should neverever happen
1344 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1348 // Write it finally, and write in UTF8, no matter what
1349 QTextStream ts( &file );
1350 ts.setEncoding (QTextStream::UnicodeUTF8);
1354 // Now write image, too
1355 exportImage (dir+"/images/"+mapName+".png");
1357 setExportMode (false);
1360 void MapEditor::clear()
1364 selection->unselect();
1371 void MapEditor::copy()
1375 // write to directory
1376 QString clipfile="part";
1377 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPointF(),selection);
1380 file.setName ( clipboardDir + "/"+clipfile+".xml");
1381 if ( !file.open( QIODevice::WriteOnly ) )
1383 // This should neverever happen
1384 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1388 // Write it finally, and write in UTF8, no matter what
1389 QTextStream ts( &file );
1390 ts.setEncoding (QTextStream::UnicodeUTF8);
1394 clipboardEmpty=false;
1399 void MapEditor::redo()
1401 blockSaveState=true;
1403 // Restore variables
1404 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1405 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1406 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1407 // Can we undo at all?
1408 if (redosAvail<1) return;
1411 if (undosAvail<stepsTotal) undosAvail++;
1413 if (curStep>stepsTotal) curStep=1;
1414 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1415 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1416 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1417 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1418 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1419 QString version=undoSet.readEntry ("/history/version");
1421 if (!checkVersion(version))
1422 QMessageBox::warning(0,tr("Warning"),
1423 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1426 // Find out current undo directory
1427 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1429 /* TODO remove testing
1431 cout << "ME::redo() begin\n";
1432 cout << " undosAvail="<<undosAvail<<endl;
1433 cout << " redosAvail="<<redosAvail<<endl;
1434 cout << " curStep="<<curStep<<endl;
1435 cout << " ---------------------------"<<endl;
1436 cout << " comment="<<comment.toStdString()<<endl;
1437 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1438 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1439 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1440 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1441 cout << " ---------------------------"<<endl<<endl;
1443 // select object before redo
1444 if (!redoSelection.isEmpty())
1445 select (redoSelection);
1448 parseAtom (redoCommand);
1449 mapCenter->reposition();
1451 blockSaveState=false;
1453 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1454 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1455 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1456 undoSet.writeSettings(histPath);
1458 mainWindow->updateHistory (undoSet);
1461 /* TODO remove testing
1462 cout << "ME::redo() end\n";
1463 cout << " undosAvail="<<undosAvail<<endl;
1464 cout << " redosAvail="<<redosAvail<<endl;
1465 cout << " curStep="<<curStep<<endl;
1466 cout << " ---------------------------"<<endl<<endl;
1472 bool MapEditor::isRedoAvailable()
1474 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1480 void MapEditor::undo()
1482 blockSaveState=true;
1484 // Restore variables
1485 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1486 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1487 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1489 // Can we undo at all?
1490 if (undosAvail<1) return;
1492 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1493 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1494 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1495 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1496 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1497 QString version=undoSet.readEntry ("/history/version");
1499 if (!checkVersion(version))
1500 QMessageBox::warning(0,tr("Warning"),
1501 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1503 // Find out current undo directory
1504 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1506 // select object before undo
1507 if (!undoSelection.isEmpty())
1508 select (undoSelection);
1512 cout << "ME::undo() begin\n";
1513 cout << " undosAvail="<<undosAvail<<endl;
1514 cout << " redosAvail="<<redosAvail<<endl;
1515 cout << " curStep="<<curStep<<endl;
1516 cout << " ---------------------------"<<endl;
1517 cout << " comment="<<comment.toStdString()<<endl;
1518 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1519 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1520 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1521 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1522 cout << " ---------------------------"<<endl<<endl;
1523 parseAtom (undoCommand);
1524 mapCenter->reposition();
1528 if (curStep<1) curStep=stepsTotal;
1532 blockSaveState=false;
1533 /* TODO remove testing
1534 cout << "ME::undo() end\n";
1535 cout << " undosAvail="<<undosAvail<<endl;
1536 cout << " redosAvail="<<redosAvail<<endl;
1537 cout << " curStep="<<curStep<<endl;
1538 cout << " ---------------------------"<<endl<<endl;
1541 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1542 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1543 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1544 undoSet.writeSettings(histPath);
1546 mainWindow->updateHistory (undoSet);
1550 bool MapEditor::isUndoAvailable()
1552 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1558 void MapEditor::gotoHistoryStep (int i)
1560 // Restore variables
1561 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1562 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1564 if (i<0) i=undosAvail+redosAvail;
1566 // Clicking above current step makes us undo things
1569 for (int j=0; j<undosAvail-i; j++) undo();
1572 // Clicking below current step makes us redo things
1574 for (int j=undosAvail; j<i; j++) redo();
1576 // And ignore clicking the current row ;-)
1579 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1581 QString pathDir=path.left(path.findRev("/"));
1587 // We need to parse saved XML data
1588 mapBuilderHandler handler;
1589 QXmlInputSource source( file);
1590 QXmlSimpleReader reader;
1591 reader.setContentHandler( &handler );
1592 reader.setErrorHandler( &handler );
1593 handler.setMapEditor( this );
1594 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1595 if (undoSel.isEmpty())
1599 handler.setLoadMode (NewMap);
1603 handler.setLoadMode (ImportReplace);
1605 blockReposition=true;
1606 bool ok = reader.parse( source );
1607 blockReposition=false;
1610 // This should never ever happen
1611 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1612 handler.errorProtocol());
1615 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1618 void MapEditor::addMapInsertInt (const QString &path, int pos)
1620 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1621 typeid(*selection) == typeid(MapCenterObj)))
1623 QString pathDir=path.left(path.findRev("/"));
1629 // We need to parse saved XML data
1630 mapBuilderHandler handler;
1631 QXmlInputSource source( file);
1632 QXmlSimpleReader reader;
1633 reader.setContentHandler( &handler );
1634 reader.setErrorHandler( &handler );
1635 handler.setMapEditor( this );
1636 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1637 handler.setLoadMode (ImportAdd);
1638 blockReposition=true;
1639 bool ok = reader.parse( source );
1640 blockReposition=false;
1643 // This should never ever happen
1644 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1645 handler.errorProtocol());
1647 if (selection!=mapCenter)
1648 ((BranchObj*)selection)->getLastBranch()->moveBranchTo ((BranchObj*)(selection),pos);
1650 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1654 void MapEditor::pasteNoSave()
1656 load (clipboardDir+"/part.xml",ImportAdd);
1659 void MapEditor::cutNoSave()
1665 void MapEditor::paste()
1667 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1668 typeid(*selection) == typeid(MapCenterObj)))
1671 saveStateChangingPart(
1675 QString("Paste to %1").arg( getName(selection))
1677 mapCenter->reposition();
1681 void MapEditor::cut()
1683 saveStateChangingPart(
1684 selection->getParObj(),
1687 QString("Cut %1").arg(getName(selection))
1691 mapCenter->reposition();
1694 void MapEditor::move(const int &x, const int &y)
1698 QString ps=qpointfToString (selection->getAbsPos());
1699 QString s=selection->getSelectString();
1702 s, "move "+qpointfToString (QPointF (x,y)),
1703 QString("Move %1 to %2").arg(getName(selection)).arg(ps));
1704 selection->move(x,y);
1705 mapCenter->reposition();
1710 void MapEditor::moveRel (const int &x, const int &y)
1712 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1713 typeid(*selection) == typeid(MapCenterObj) ||
1714 typeid(*selection) == typeid (FloatImageObj)))
1716 QString ps=qpointfToString (selection->getRelPos());
1717 QString s=selection->getSelectString();
1720 s, "moveRel "+qpointfToString (QPointF (x,y)),
1721 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(ps));
1722 ((OrnamentedObj*)selection)->move2RelPos (x,y);
1723 mapCenter->reposition();
1727 void MapEditor::moveBranchUp()
1731 if (typeid(*selection) == typeid(BranchObj) )
1733 bo=(BranchObj*)selection;
1734 if (!bo->canMoveBranchUp()) return;
1735 par=(BranchObj*)(bo->getParObj());
1736 selection->unselect();
1737 bo=par->moveBranchUp (bo); // bo will be the one below selection
1738 selection->select();
1739 saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1740 mapCenter->reposition();
1741 ensureSelectionVisible();
1745 void MapEditor::moveBranchDown()
1749 if (typeid(*selection) == typeid(BranchObj) )
1751 bo=(BranchObj*)selection;
1752 if (!bo->canMoveBranchDown()) return;
1753 par=(BranchObj*)(bo->getParObj());
1754 selection->unselect();
1755 bo=par->moveBranchDown(bo); // bo will be the one above selection
1756 selection->select();
1757 saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1758 mapCenter->reposition();
1759 ensureSelectionVisible();
1763 QString MapEditor::getHeading(bool &ok, QPoint &p)
1766 (typeid(*selection) == typeid(BranchObj) ||
1767 typeid(*selection) == typeid(MapCenterObj) ) )
1770 ensureSelectionVisible();
1771 p=mapFromScene(selection->getAbsPos());
1772 return ((BranchObj*)selection)->getHeading();
1778 void MapEditor::setHeading(const QString &s)
1781 (typeid(*selection) == typeid(BranchObj) ||
1782 typeid(*selection) == typeid(MapCenterObj) ) )
1784 editingBO=(BranchObj*)selection;
1787 "setHeading (\""+editingBO->getHeading()+"\")",
1789 "setHeading (\""+s+"\")",
1790 QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(s) );
1791 editingBO->setHeading(s );
1793 mapCenter->reposition();
1794 ensureSelectionVisible();
1798 void MapEditor::setURLInt (const QString &s)
1800 // Internal function, no saveState needed
1802 (typeid(*selection) == typeid(BranchObj) ||
1803 typeid(*selection) == typeid(MapCenterObj) ) )
1805 ((BranchObj*)selection)->setURL(s);
1806 mapCenter->reposition();
1807 ensureSelectionVisible();
1811 void MapEditor::setHeadingInt(const QString &s)
1814 (typeid(*selection) == typeid(BranchObj) ||
1815 typeid(*selection) == typeid(MapCenterObj) ) )
1817 ((BranchObj*)selection)->setHeading(s);
1818 mapCenter->reposition();
1819 ensureSelectionVisible();
1823 void MapEditor::setVymLinkInt (const QString &s)
1825 // Internal function, no saveState needed
1827 (typeid(*selection) == typeid(BranchObj) ||
1828 typeid(*selection) == typeid(MapCenterObj) ) )
1830 ((BranchObj*)selection)->setVymLink(s);
1831 mapCenter->reposition();
1832 ensureSelectionVisible();
1836 BranchObj* MapEditor::addNewBranchInt(int num)
1838 // Depending on pos:
1839 // -3 insert in childs of parent above selection
1840 // -2 add branch to selection
1841 // -1 insert in childs of parent below selection
1842 // 0..n insert in childs of parent at pos
1843 BranchObj *newbo=NULL;
1845 (typeid(*selection) == typeid(BranchObj) ||
1846 typeid(*selection) == typeid(MapCenterObj) ) )
1848 BranchObj* bo = (BranchObj*) selection;
1851 // save scroll state. If scrolled, automatically select
1852 // new branch in order to tmp unscroll parent...
1853 return bo->addBranch();
1858 bo=(BranchObj*)bo->getParObj();
1862 bo=(BranchObj*)bo->getParObj();
1865 newbo=bo->insertBranch(num);
1870 BranchObj* MapEditor::addNewBranch(int pos)
1872 // Different meaning than num in addNewBranchInt!
1876 BranchObj *bo = (BranchObj*) selection;
1877 BranchObj *newbo=NULL;
1880 (typeid(*selection) == typeid(BranchObj) ||
1881 typeid(*selection) == typeid(MapCenterObj) ) )
1883 newbo=addNewBranchInt (pos-2);
1888 selection, // FIXME addNewBranch (int pos) sholdnt newbo be deleted here???
1891 QString ("addBranch (%1)").arg(pos-2),
1892 QString ("Add new branch to %1").arg(getName(bo)));
1894 mapCenter->reposition();
1901 BranchObj* MapEditor::addNewBranchBefore()
1903 BranchObj *newbo=NULL;
1905 (typeid(*selection) == typeid(BranchObj) ) )
1906 // We accept no MapCenterObj here, so we _have_ a parent
1908 BranchObj* bo = (BranchObj*) selection;
1909 QPointF p=bo->getRelPos();
1912 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1914 // add below selection
1915 newbo=parbo->insertBranch(bo->getNum()+1);
1918 newbo->move2RelPos (p);
1920 // Move selection to new branch
1921 ((BranchObj*)selection)->moveBranchTo (newbo,-1);
1923 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
1924 QString ("Add branch before %1").arg(getName(bo)));
1926 mapCenter->reposition();
1932 void MapEditor::deleteSelection()
1934 if (selection && typeid(*selection) ==typeid(BranchObj) )
1936 BranchObj* bo=(BranchObj*)selection;
1937 BranchObj* par=(BranchObj*)(bo->getParObj());
1939 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
1941 par->removeBranch(bo);
1943 selection->select();
1944 ensureSelectionVisible();
1945 mapCenter->reposition();
1947 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
1949 FloatImageObj* fio=(FloatImageObj*)selection;
1950 BranchObj* par=(BranchObj*)(fio->getParObj());
1951 saveStateChangingPart(
1955 QString("Delete %1").arg(getName(fio))
1959 par->removeFloatImage(fio);
1961 selection->select();
1962 ensureSelectionVisible();
1963 mapCenter->reposition();
1967 LinkableMapObj* MapEditor::getSelection()
1972 void MapEditor::unselect()
1976 selectionLast=selection;
1977 selection->unselect();
1982 void MapEditor::reselect()
1986 selection=selectionLast;
1987 selection->select();
1992 bool MapEditor::select (const QString &s)
1994 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
1996 // Finally select the found object
1999 if (selection) unselect();
2001 selection->select();
2002 ensureSelectionVisible();
2008 QString MapEditor::getSelectString()
2010 if (selection) return selection->getSelectString();
2014 void MapEditor::selectInt (LinkableMapObj *lmo)
2016 if (lmo && selection != lmo)
2018 // select the MapObj
2019 if (selection) selection->unselect();
2021 selection->select();
2025 void MapEditor::selectNextBranchInt()
2027 // Increase number of branch
2030 QString s=selection->getSelectString();
2036 part=s.section(",",-1);
2038 num=part.right(part.length() - 3);
2040 s=s.left (s.length() -num.length());
2043 num=QString ("%1").arg(num.toUInt()+1);
2047 // Try to select this one
2048 if (select (s)) return;
2050 // We have no direct successor,
2051 // try to increase the parental number in order to
2052 // find a successor with same depth
2054 int d=selection->getDepth();
2059 while (!found && d>0)
2061 s=s.section (",",0,d-1);
2062 // replace substring of current depth in s with "1"
2063 part=s.section(",",-1);
2065 num=part.right(part.length() - 3);
2069 // increase number of parent
2070 num=QString ("%1").arg(num.toUInt()+1);
2071 s=s.section (",",0,d-2) + ","+ typ+num;
2074 // Special case, look at orientation
2075 if (selection->getOrientation()==OrientRightOfCenter)
2076 num=QString ("%1").arg(num.toUInt()+1);
2078 num=QString ("%1").arg(num.toUInt()-1);
2083 // pad to oldDepth, select the first branch for each depth
2084 for (i=d;i<oldDepth;i++)
2089 if ( ((BranchObj*)selection)->countBranches()>0)
2097 // try to select the freshly built string
2105 void MapEditor::selectPrevBranchInt()
2107 // Decrease number of branch
2110 QString s=selection->getSelectString();
2116 part=s.section(",",-1);
2118 num=part.right(part.length() - 3);
2120 s=s.left (s.length() -num.length());
2122 int n=num.toInt()-1;
2125 num=QString ("%1").arg(n);
2128 // Try to select this one
2129 if (n>=0 && select (s)) return;
2131 // We have no direct precessor,
2132 // try to decrease the parental number in order to
2133 // find a precessor with same depth
2135 int d=selection->getDepth();
2140 while (!found && d>0)
2142 s=s.section (",",0,d-1);
2143 // replace substring of current depth in s with "1"
2144 part=s.section(",",-1);
2146 num=part.right(part.length() - 3);
2150 // decrease number of parent
2151 num=QString ("%1").arg(num.toInt()-1);
2152 s=s.section (",",0,d-2) + ","+ typ+num;
2155 // Special case, look at orientation
2156 if (selection->getOrientation()==OrientRightOfCenter)
2157 num=QString ("%1").arg(num.toInt()-1);
2159 num=QString ("%1").arg(num.toInt()+1);
2164 // pad to oldDepth, select the last branch for each depth
2165 for (i=d;i<oldDepth;i++)
2169 if ( ((BranchObj*)selection)->countBranches()>0)
2170 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
2177 // try to select the freshly built string
2185 void MapEditor::selectUpperBranch()
2189 if (typeid(*selection) == typeid(BranchObj))
2191 if (selection->getOrientation()==OrientRightOfCenter)
2192 selectPrevBranchInt();
2194 if (selection->getDepth()==1)
2195 selectNextBranchInt();
2197 selectPrevBranchInt();
2202 void MapEditor::selectLowerBranch()
2206 if (typeid(*selection) == typeid(BranchObj))
2208 if (selection->getOrientation()==OrientRightOfCenter)
2209 selectNextBranchInt();
2211 if (selection->getDepth()==1)
2212 selectPrevBranchInt();
2214 selectNextBranchInt();
2220 void MapEditor::selectLeftBranch()
2226 if (typeid(*selection) == typeid(MapCenterObj))
2228 par= (BranchObj*) selection;
2229 bo=par->getLastSelectedBranch();
2232 // Workaround for reselecting on left and right side
2233 if (bo->getOrientation()==OrientRightOfCenter)
2235 bo=par->getLastBranch();
2241 selection->select();
2242 ensureSelectionVisible();
2247 par=(BranchObj*)(selection->getParObj());
2248 if (selection->getOrientation()==OrientRightOfCenter)
2250 if (typeid(*selection) == typeid(BranchObj) ||
2251 typeid(*selection) == typeid(FloatImageObj))
2253 selection->unselect();
2255 selection->select();
2256 ensureSelectionVisible();
2260 if (typeid(*selection) == typeid(BranchObj) )
2262 bo=((BranchObj*)selection)->getLastSelectedBranch();
2265 selection->unselect();
2267 selection->select();
2268 ensureSelectionVisible();
2276 void MapEditor::selectRightBranch()
2283 if (typeid(*selection) == typeid(MapCenterObj))
2285 par= (BranchObj*) selection;
2286 bo=par->getLastSelectedBranch();
2289 // Workaround for reselecting on left and right side
2290 if (bo->getOrientation()==OrientLeftOfCenter)
2291 bo=par->getFirstBranch();
2296 selection->select();
2297 ensureSelectionVisible();
2302 par=(BranchObj*)(selection->getParObj());
2303 if (selection->getOrientation()==OrientLeftOfCenter)
2305 if (typeid(*selection) == typeid(BranchObj) ||
2306 typeid(*selection) == typeid(FloatImageObj))
2308 selection->unselect();
2310 selection->select();
2311 ensureSelectionVisible();
2315 if (typeid(*selection) == typeid(BranchObj) )
2317 bo=((BranchObj*)selection)->getLastSelectedBranch();
2320 selection->unselect();
2322 selection->select();
2323 ensureSelectionVisible();
2331 void MapEditor::selectFirstBranch()
2337 if (typeid(*selection) == typeid(BranchObj))
2339 bo1= (BranchObj*) selection;
2340 par=(BranchObj*)(bo1->getParObj());
2341 bo2=par->getFirstBranch();
2345 selection->select();
2346 ensureSelectionVisible();
2352 void MapEditor::selectLastBranch()
2358 if (typeid(*selection) == typeid(BranchObj))
2360 bo1= (BranchObj*) selection;
2361 par=(BranchObj*)(bo1->getParObj());
2362 bo2=par->getLastBranch();
2366 selection->select();
2367 ensureSelectionVisible();
2373 void MapEditor::selectMapBackgroundImage ()
2375 Q3FileDialog *fd=new Q3FileDialog( this);
2376 fd->setMode (Q3FileDialog::ExistingFile);
2377 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2378 ImagePreview *p =new ImagePreview (fd);
2379 fd->setContentsPreviewEnabled( TRUE );
2380 fd->setContentsPreview( p, p );
2381 fd->setPreviewMode( Q3FileDialog::Contents );
2382 fd->setCaption(vymName+" - " +tr("Load background image"));
2383 fd->setDir (lastImageDir);
2386 if ( fd->exec() == QDialog::Accepted )
2388 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2389 lastImageDir=QDir (fd->dirPath());
2390 setMapBackgroundImage (fd->selectedFile());
2394 void MapEditor::setMapBackgroundImage (const QString &fn)
2396 QColor oldcol=mapScene->backgroundBrush().color();
2400 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2402 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2403 QString("Set background color of map to %1").arg(col.name()));
2405 cout << "Trying to load "<<fn.ascii()<<endl;
2407 brush.setTextureImage (QPixmap (fn));
2408 mapScene->setBackgroundBrush(brush);
2411 void MapEditor::selectMapBackgroundColor()
2413 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2414 if ( !col.isValid() ) return;
2415 setMapBackgroundColor( col );
2419 void MapEditor::setMapBackgroundColor(QColor col)
2421 QColor oldcol=mapScene->backgroundBrush().color();
2424 QString ("setMapBackgroundColor (%1)").arg(oldcol.name()),
2426 QString ("setMapBackgroundColor (%1)").arg(col.name()),
2427 QString("Set background color of map to %1").arg(col.name()));
2428 mapScene->setBackgroundBrush(col);
2431 QColor MapEditor::getMapBackgroundColor()
2433 return mapScene->backgroundBrush().color();
2436 QColor MapEditor::getCurrentHeadingColor()
2440 if (typeid(*selection) == typeid(BranchObj) ||
2441 typeid(*selection) == typeid(MapCenterObj))
2443 BranchObj *bo=(BranchObj*)selection;
2444 return bo->getColor();
2448 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2452 void MapEditor::colorItem(QColor c)
2456 if (typeid(*selection) == typeid(BranchObj) ||
2457 typeid(*selection) == typeid(MapCenterObj))
2459 BranchObj *bo=(BranchObj*)selection;
2462 QString ("colorItem (%1)").arg(bo->getColor().name()),
2464 QString ("colorItem (%1)").arg(c.name()),
2465 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2467 bo->setColor(c); // color branch
2472 void MapEditor::colorBranch(QColor c)
2476 if (typeid(*selection) == typeid(BranchObj) ||
2477 typeid(*selection) == typeid(MapCenterObj))
2479 BranchObj *bo=(BranchObj*)selection;
2480 saveStateChangingPart(
2483 QString ("colorBranch (%1)").arg(c.name()),
2484 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2486 bo->setColorChilds(c); // color links, color childs
2492 void MapEditor::toggleStandardFlag(QString f)
2496 if (typeid(*selection) == typeid(BranchObj) ||
2497 typeid(*selection) == typeid(MapCenterObj))
2499 BranchObj *bo=(BranchObj*)selection;
2501 if (bo->isSetStandardFlag(f))
2513 QString("%1 (\"%2\")").arg(u).arg(f),
2515 QString("%1 (\"%2\")").arg(r).arg(f),
2516 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2517 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2522 void MapEditor::setViewCenter()
2524 // transform to sceneView Coord:
2525 QPointF p=matrix().map(movingCenter);
2526 //FIXME setViewCenter not ported yet to QT4 (center ist TextStream there)
2527 //center ( p.x(), p.y());
2531 BranchObj* MapEditor::findText (QString s, bool cs)
2533 QTextDocument::FindFlags flags=0;
2534 if (cs) flags=QTextDocument::FindCaseSensitively;
2537 { // Nothing found or new find process
2539 // nothing found, start again
2541 itFind=mapCenter->first();
2543 bool searching=true;
2544 bool foundNote=false;
2545 while (searching && !EOFind)
2549 // Searching in Note
2550 if (itFind->getNote().contains(s,cs))
2552 if (selection!=itFind)
2554 if (selection) ((BranchObj*)selection)->unselect();
2556 selection->select();
2557 ensureSelectionVisible();
2559 if (textEditor->findText(s,flags))
2565 // Searching in Heading
2566 if (searching && itFind->getHeading().contains (s,cs) )
2568 if (selection) ((BranchObj*)selection)->unselect();
2570 selection->select();
2571 ensureSelectionVisible();
2577 itFind=itFind->next();
2578 if (!itFind) EOFind=true;
2583 return (BranchObj*)selection;
2588 void MapEditor::findReset()
2589 { // Necessary if text to find changes during a find process
2593 void MapEditor::setURL(const QString &url)
2595 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2596 typeid(*selection) == typeid(MapCenterObj)) )
2598 BranchObj *bo=(BranchObj*)selection;
2599 QString oldurl=bo->getURL();
2603 QString ("setURL (\"%1\")").arg(oldurl),
2605 QString ("setURL (\"%1\")").arg(url),
2606 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2612 void MapEditor::editURL()
2614 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2615 typeid(*selection) == typeid(MapCenterObj)) )
2618 BranchObj *bo=(BranchObj*)selection;
2619 QString text = QInputDialog::getText(
2620 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2621 bo->getURL(), &ok, this );
2623 // user entered something and pressed OK
2628 QString MapEditor::getURL()
2630 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2631 typeid(*selection) == typeid(MapCenterObj)) )
2632 return ((BranchObj*)selection)->getURL();
2637 QStringList MapEditor::getURLs()
2640 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2641 typeid(*selection) == typeid(MapCenterObj)) )
2643 BranchObj *bo=(BranchObj*)selection;
2647 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2655 void MapEditor::editHeading2URL()
2657 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2658 typeid(*selection) == typeid(MapCenterObj)) )
2659 setURL (((BranchObj*)selection)->getHeading());
2662 void MapEditor::editBugzilla2URL()
2664 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2665 typeid(*selection) == typeid(MapCenterObj)) )
2667 BranchObj *bo=(BranchObj*)selection;
2668 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2673 void MapEditor::editFATE2URL()
2675 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2676 typeid(*selection) == typeid(MapCenterObj)) )
2678 BranchObj *bo=(BranchObj*)selection;
2679 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2682 "setURL (\""+bo->getURL()+"\")",
2684 "setURL (\""+url+"\")",
2685 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2692 void MapEditor::editVymLink()
2694 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2695 typeid(*selection) == typeid(MapCenterObj)) )
2697 BranchObj *bo=(BranchObj*)selection;
2698 QStringList filters;
2699 filters <<"VYM map (*.vym)";
2700 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2701 fd->setFilters (filters);
2702 fd->setCaption(vymName+" - " +tr("Link to another map"));
2703 if (! bo->getVymLink().isEmpty() )
2704 fd->selectFile( bo->getVymLink() );
2708 if ( fd->exec() == QDialog::Accepted )
2712 "setVymLink (\""+bo->getVymLink()+"\")",
2714 "setVymLink (\""+fd->selectedFile()+"\")",
2715 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2717 bo->setVymLink (fd->selectedFile() );
2719 mapCenter->reposition();
2725 void MapEditor::deleteVymLink()
2727 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2728 typeid(*selection) == typeid(MapCenterObj)) )
2730 BranchObj *bo=(BranchObj*)selection;
2733 "setVymLink (\""+bo->getVymLink()+"\")",
2735 "setVymLink (\"\")",
2736 QString("Unset vymlink of %1").arg(getName(bo))
2738 bo->setVymLink ("" );
2740 mapCenter->reposition();
2745 void MapEditor::setHideExport(bool b)
2747 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2748 typeid(*selection)==typeid(FloatImageObj)))
2750 OrnamentedObj *oo=(OrnamentedObj*)selection;
2751 oo->setHideInExport (b);
2752 QString u= b ? "false" : "true";
2753 QString r=!b ? "false" : "true";
2757 QString ("setHideExport (%1)").arg(u),
2759 QString ("setHideExport (%1)").arg(r),
2760 QString ("Set HideExport flag of %1 to %2").arg(getName(oo)).arg (r)
2763 mapCenter->reposition();
2768 void MapEditor::toggleHideExport()
2770 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2771 typeid(*selection)==typeid(FloatImageObj)))
2772 setHideExport ( !((OrnamentedObj*)selection)->hideInExport() );
2775 QString MapEditor::getVymLink()
2777 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2778 typeid(*selection) == typeid(MapCenterObj)) )
2780 return ((BranchObj*)selection)->getVymLink();
2786 QStringList MapEditor::getVymLinks()
2789 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2790 typeid(*selection) == typeid(MapCenterObj)) )
2792 BranchObj *bo=(BranchObj*)selection;
2796 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2804 void MapEditor::deleteKeepChilds()
2806 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2808 BranchObj* bo=(BranchObj*)selection;
2809 BranchObj* par=(BranchObj*)(bo->getParObj());
2810 QPointF p=bo->getRelPos();
2811 saveStateChangingPart(
2812 selection->getParObj(),
2814 "deleteKeepChilds ()",
2815 QString("Remove %1 and keep its childs").arg(getName(bo))
2818 QString sel=selection->getSelectString();
2820 par->removeBranchHere(bo);
2821 mapCenter->reposition();
2823 ((BranchObj*)selection)->move2RelPos (p);
2824 mapCenter->reposition();
2828 void MapEditor::deleteChilds()
2830 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2831 typeid(*selection)==typeid(MapCenterObj)))
2833 saveStateChangingPart(
2834 selection->getParObj(),
2837 QString( "Remove childs of branch %1").arg(getName(selection))
2839 ((BranchObj*)selection)->removeChilds();
2840 mapCenter->reposition();
2844 void MapEditor::editMapInfo()
2846 ExtraInfoDialog dia;
2847 dia.setMapName (getFileName() );
2848 dia.setAuthor (mapCenter->getAuthor() );
2849 dia.setComment(mapCenter->getComment() );
2853 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
2860 bo=mapCenter->first();
2863 if (!bo->getNote().isEmpty() ) n++;
2864 f+= bo->countFloatImages();
2866 xl+=bo->countXLinks();
2869 stats+=QString ("%1 branches\n").arg (b-1,6);
2870 stats+=QString ("%1 xLinks \n").arg (xl,6);
2871 stats+=QString ("%1 notes\n").arg (n,6);
2872 stats+=QString ("%1 images\n").arg (f,6);
2873 dia.setStats (stats);
2875 // Finally show dialog
2876 if (dia.exec() == QDialog::Accepted)
2878 setMapAuthor (dia.getAuthor() );
2879 setMapComment (dia.getComment() );
2883 void MapEditor::updateActions()
2885 mainWindow->updateActions();
2886 // TODO maybe don't update if blockReposition is set
2889 void MapEditor::updateNoteFlag()
2892 if ( (typeid(*selection) == typeid(BranchObj)) ||
2893 (typeid(*selection) == typeid(MapCenterObj)) )
2894 ((BranchObj*)selection)->updateNoteFlag();
2897 void MapEditor::setMapAuthor (const QString &s)
2901 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
2903 QString ("setMapAuthor (\"%1\")").arg(s),
2904 QString ("Set author of map to \"%1\"").arg(s)
2906 mapCenter->setAuthor (s);
2909 void MapEditor::setMapComment (const QString &s)
2913 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
2915 QString ("setMapComment (\"%1\")").arg(s),
2916 QString ("Set comment of map")
2918 mapCenter->setComment (s);
2921 void MapEditor::setMapLinkStyle (const QString & s)
2923 saveStateChangingPart (
2926 QString("setMapLinkStyle (\"%1\")").arg(s),
2927 QString("Set map link style (\"%1\")").arg(s)
2931 linkstyle=StyleLine;
2932 else if (s=="StyleParabel")
2933 linkstyle=StyleParabel;
2934 else if (s=="StylePolyLine")
2935 linkstyle=StylePolyLine;
2937 linkstyle=StylePolyParabel;
2940 bo=mapCenter->first();
2944 bo->setLinkStyle(bo->getDefLinkStyle());
2947 mapCenter->reposition();
2950 LinkStyle MapEditor::getMapLinkStyle ()
2955 void MapEditor::setMapDefLinkColor(QColor c)
2961 void MapEditor::setMapLinkColorHintInt()
2963 // called from setMapLinkColorHint(lch) or at end of parse
2965 bo=mapCenter->first();
2973 void MapEditor::setMapLinkColorHint(LinkColorHint lch)
2976 setMapLinkColorHintInt();
2979 void MapEditor::toggleMapLinkColorHint()
2981 if (linkcolorhint==HeadingColor)
2982 linkcolorhint=DefaultColor;
2984 linkcolorhint=HeadingColor;
2986 bo=mapCenter->first();
2994 LinkColorHint MapEditor::getMapLinkColorHint()
2996 return linkcolorhint;
2999 QColor MapEditor::getMapDefLinkColor()
3001 return defLinkColor;
3004 void MapEditor::setMapDefXLinkColor(QColor col)
3009 QColor MapEditor::getMapDefXLinkColor()
3011 return defXLinkColor;
3014 void MapEditor::setMapDefXLinkWidth (int w)
3019 int MapEditor::getMapDefXLinkWidth()
3021 return defXLinkWidth;
3024 void MapEditor::selectMapLinkColor()
3026 QColor col = QColorDialog::getColor( defLinkColor, this );
3027 if ( !col.isValid() ) return;
3030 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3032 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3033 QString("Set link color to %1").arg(col.name())
3035 setMapDefLinkColor( col );
3039 void MapEditor::toggleScroll()
3041 if (selection && (typeid(*selection) == typeid(BranchObj)) )
3043 BranchObj *bo=((BranchObj*)selection);
3044 if (bo->countBranches()==0) return;
3045 if (bo->getDepth()==0) return;
3047 if (bo->isScrolled())
3059 QString ("%1 ()").arg(u),
3061 QString ("%1 ()").arg(r),
3062 QString ("%1 %2").arg(r).arg(getName(bo))
3069 void MapEditor::unScrollAll()
3072 bo=mapCenter->first();
3075 if (bo->isScrolled()) bo->toggleScroll();
3080 void MapEditor::loadFloatImage ()
3083 (typeid(*selection) == typeid(BranchObj)) ||
3084 (typeid(*selection) == typeid(MapCenterObj)) )
3086 BranchObj *bo=((BranchObj*)selection);
3088 Q3FileDialog *fd=new Q3FileDialog( this);
3089 fd->setMode (Q3FileDialog::ExistingFiles);
3090 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3091 ImagePreview *p =new ImagePreview (fd);
3092 fd->setContentsPreviewEnabled( TRUE );
3093 fd->setContentsPreview( p, p );
3094 fd->setPreviewMode( Q3FileDialog::Contents );
3095 fd->setCaption(vymName+" - " +tr("Load image"));
3096 fd->setDir (lastImageDir);
3100 if ( fd->exec() == QDialog::Accepted )
3102 // FIXME loadFIO in QT4 use: lastImageDir=fd->directory();
3103 lastImageDir=QDir (fd->dirPath());
3104 QStringList flist = fd->selectedFiles();
3105 QStringList::Iterator it = flist.begin();
3107 while( it != flist.end() )
3110 bo->addFloatImage();
3111 fio=bo->getLastFloatImage();
3113 // FIXME loadFIO check if load of fio was successful
3115 (LinkableMapObj*)fio,
3118 QString ("loadFloatImage (%1)").arg(*it),
3119 QString("Add floatimage %1 to %2").arg(*it).arg(getName(selection))
3121 bo->getLastFloatImage()->setOriginalFilename(fn);
3125 mapCenter->reposition();
3133 void MapEditor::saveFloatImage ()
3136 (typeid(*selection) == typeid(FloatImageObj)) )
3138 FloatImageObj *fio=((FloatImageObj*)selection);
3139 QFileDialog *fd=new QFileDialog( this);
3140 fd->setFilters (imageIO.getFilters());
3141 fd->setCaption(vymName+" - " +tr("Save image"));
3142 fd->setFileMode( QFileDialog::AnyFile );
3143 fd->setDirectory (lastImageDir);
3144 // fd->setSelection (fio->getOriginalFilename());
3148 if ( fd->exec() == QDialog::Accepted )
3150 if (QFile (fd->selectedFile()).exists() )
3152 QMessageBox mb( vymName,
3153 tr("The file %1 exists already.\n"
3154 "Do you want to overwrite it?").arg(fd->selectedFile()),
3155 QMessageBox::Warning,
3156 QMessageBox::Yes | QMessageBox::Default,
3157 QMessageBox::Cancel | QMessageBox::Escape,
3158 QMessageBox::QMessageBox::NoButton );
3160 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3161 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3164 case QMessageBox::Yes:
3167 case QMessageBox::Cancel:
3174 fio->save (fd->selectedFile(),imageIO.getType (fd->selectedFilter() ) );
3180 void MapEditor::setFrame(const FrameType &t)
3183 (typeid(*selection) == typeid(BranchObj)) ||
3184 (typeid(*selection) == typeid(MapCenterObj)) )
3186 selection->setFrameType (t);
3187 mapCenter->reposition();
3188 selection->updateLink();
3192 void MapEditor::setIncludeImagesVer(bool b)
3195 (typeid(*selection) == typeid(BranchObj)) ||
3196 (typeid(*selection) == typeid(MapCenterObj)) )
3197 ((BranchObj*)selection)->setIncludeImagesVer(b);
3198 mapCenter->reposition();
3201 void MapEditor::setIncludeImagesHor(bool b)
3204 (typeid(*selection) == typeid(BranchObj)) ||
3205 (typeid(*selection) == typeid(MapCenterObj)) )
3206 ((BranchObj*)selection)->setIncludeImagesHor(b);
3207 mapCenter->reposition();
3210 void MapEditor::setHideLinkUnselected (bool b)
3213 (typeid(*selection) == typeid(BranchObj)) ||
3214 (typeid(*selection) == typeid(MapCenterObj)) ||
3215 (typeid(*selection) == typeid(FloatImageObj)) )
3216 selection->setHideLinkUnselected(b);
3219 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3222 (typeid(*selection) == typeid(BranchObj)) ||
3223 (typeid(*selection) == typeid(MapCenterObj)) )
3227 // Traverse directories
3228 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3229 QFileInfoList list = d.entryInfoList();
3232 for (int i = 0; i < list.size(); ++i)
3235 if (fi.fileName() != "." && fi.fileName() != ".." )
3238 bo=dst->getLastBranch();
3239 bo->setHeading (fi.fileName() );
3240 bo->setColor (QColor("blue"));
3242 if ( !d.cd(fi.fileName()) )
3243 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3246 // Recursively add subdirs
3247 importDirInt (bo,d);
3253 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3254 list = d.entryInfoList();
3256 for (int i = 0; i < list.size(); ++i)
3260 bo=dst->getLastBranch();
3261 bo->setHeading (fi.fileName() );
3262 bo->setColor (QColor("black"));
3263 if (fi.fileName().right(4) == ".vym" )
3264 bo->setVymLink (fi.filePath());
3269 void MapEditor::importDir()
3272 (typeid(*selection) == typeid(BranchObj)) ||
3273 (typeid(*selection) == typeid(MapCenterObj)) )
3275 QStringList filters;
3276 filters <<"VYM map (*.vym)";
3277 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3278 fd->setMode (QFileDialog::DirectoryOnly);
3279 fd->setFilters (filters);
3280 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3284 if ( fd->exec() == QDialog::Accepted )
3286 BranchObj *bo=((BranchObj*)selection);
3287 importDirInt (bo,QDir(fd->selectedFile()) );
3288 mapCenter->reposition();
3294 void MapEditor::followXLink(int i)
3297 (typeid(*selection) == typeid(BranchObj)) ||
3298 (typeid(*selection) == typeid(MapCenterObj)) )
3300 BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
3303 selection->unselect();
3305 selection->select();
3306 ensureSelectionVisible();
3311 void MapEditor::editXLink(int i)
3314 (typeid(*selection) == typeid(BranchObj)) ||
3315 (typeid(*selection) == typeid(MapCenterObj)) )
3317 XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
3320 EditXLinkDialog dia;
3322 dia.setSelection(selection);
3323 if (dia.exec() == QDialog::Accepted)
3325 if (dia.useSettingsGlobal() )
3327 setMapDefXLinkColor (xlo->getColor() );
3328 setMapDefXLinkWidth (xlo->getWidth() );
3330 if (dia.deleteXLink())
3331 ((BranchObj*)selection)->deleteXLinkAt(i);
3332 //saveStateComplete("Edit xLink"); //FIXME editXLink undoCommand
3338 void MapEditor::testFunction()
3341 dia.showCancelButton (true);
3342 dia.setText("This is a longer \nWarning");
3344 dia.setCaption("Warning: Flux problem");
3345 dia.setShowAgainName("/warnings/mapeditor");
3347 if (dia.exec()==QDialog::Accepted)
3348 cout << "accepted!\n";
3350 cout << "canceled!\n";
3353 /* Hide hidden stuff temporary, maybe add this as regular function somewhere
3354 if (hidemode==HideNone)
3356 setHideTmpMode (HideExport);
3357 mapCenter->calcBBoxSizeWithChilds();
3358 QRectF totalBBox=mapCenter->getTotalBBox();
3359 QRectF mapRect=totalBBox;
3360 QCanvasRectangle *frame=NULL;
3362 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3364 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3365 totalBBox.width(), totalBBox.height());
3366 frame=new QCanvasRectangle (mapRect,mapScene);
3367 frame->setBrush (QColor(white));
3368 frame->setPen (QColor(black));
3369 frame->setZValue(0);
3374 setHideTmpMode (HideNone);
3376 cout <<" hidemode="<<hidemode<<endl;
3380 void MapEditor::ensureSelectionVisible()
3384 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
3386 if (selection->getOrientation() == OrientLeftOfCenter)
3387 p= matrix().map(QPointF (lmo->x(),lmo->y()));
3389 p= matrix().map(QPointF (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
3390 ensureVisible (QRectF(p.x(), p.y(),0,0 ));
3396 void MapEditor::updateViewCenter()
3398 /* FIXME updateViewCenter still to port to QT4 inverseworldmatrix
3399 // Update movingCenter, so that we can zoom comfortably later
3400 QRectF rc = QRectF( contentsX(), contentsY(),
3401 visibleWidth(), visibleHeight() );
3402 QRectF canvasRect = inverseWorldMatrix().mapRect(rc);
3403 movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
3404 movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
3408 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3410 // Lineedits are already closed by preceding
3411 // mouseEvent, we don't need to close here.
3413 QPointF p = mapToScene(e->pos());
3414 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3417 { // MapObj was found
3418 if (selection != lmo)
3420 // select the MapObj
3421 if (selection) selection->unselect();
3423 selection->select();
3428 if (typeid(*selection)==typeid(BranchObj) ||
3429 typeid(*selection)==typeid(MapCenterObj) )
3431 // Context Menu on branch or mapcenter
3433 branchContextMenu->popup(e->globalPos() );
3435 if (typeid(*selection)==typeid(FloatImageObj))
3437 // Context Menu on floatimage
3439 floatimageContextMenu->popup(e->globalPos() );
3443 { // No MapObj found, we are on the Canvas itself
3444 // Context Menu on scene
3446 canvasContextMenu->popup(e->globalPos() );
3451 void MapEditor::keyPressEvent(QKeyEvent* e)
3453 if (e->modifiers() & Qt::ControlModifier)
3455 switch (mainWindow->getModMode())
3458 setCursor (PickColorCursor);
3461 setCursor (CopyCursor);
3464 setCursor (XLinkCursor);
3467 setCursor (Qt::ArrowCursor);
3473 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3475 if (!(e->modifiers() & Qt::ControlModifier))
3476 setCursor (Qt::ArrowCursor);
3479 void MapEditor::mousePressEvent(QMouseEvent* e)
3481 // Ignore right clicks, these will go to context menus
3482 if (e->button() == Qt::RightButton )
3488 QPointF p = mapToScene(e->pos());
3489 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3493 //Take care of clickdesystem flags _or_ modifier modes
3495 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3496 typeid(*lmo)==typeid(MapCenterObj) ))
3498 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3499 if (!foname.isEmpty())
3501 // systemFlag clicked
3505 if (e->state() & Qt::ControlModifier)
3506 mainWindow->editOpenURLTab();
3508 mainWindow->editOpenURL();
3510 else if (foname=="vymLink")
3512 mainWindow->editOpenVymLink();
3513 // tabWidget may change, better return now
3514 // before segfaulting...
3515 } else if (foname=="note")
3516 mainWindow->windowToggleNoteEditor();
3517 else if (foname=="hideInExport")
3522 // No system flag clicked, take care of modmodes
3524 // Special case: CTRL is pressed
3525 if (e->state() & Qt::ControlModifier)
3527 if (mainWindow->getModMode()==ModModeColor)
3530 setCursor (PickColorCursor);
3533 if (mainWindow->getModMode()==ModModeXLink)
3535 BranchObj *bo_begin=NULL;
3537 bo_begin=(BranchObj*)(lmo);
3540 ((typeid(*selection) == typeid(BranchObj)) ||
3541 (typeid(*selection) == typeid(MapCenterObj))) )
3542 bo_begin=(BranchObj*)selection;
3546 linkingObj_src=bo_begin;
3547 tmpXLink=new XLinkObj (mapScene);
3548 tmpXLink->setBegin (bo_begin);
3549 tmpXLink->setEnd (p);
3550 tmpXLink->setColor(defXLinkColor);
3551 tmpXLink->setWidth(defXLinkWidth);
3552 tmpXLink->updateXLink();
3553 tmpXLink->setVisibility (true);
3561 // Left Button Move Branches
3562 if (e->button() == Qt::LeftButton )
3564 movingObj_start.setX( p.x() - selection->x() );
3565 movingObj_start.setY( p.y() - selection->y() );
3566 movingObj_orgPos.setX (lmo->x() );
3567 movingObj_orgPos.setY (lmo->y() );
3568 movingObj_orgRelPos=lmo->getRelPos();
3570 // If modMode==copy, then we want to "move" the _new_ object around
3571 // then we need the offset from p to the _old_ selection, because of tmp
3572 if (mainWindow->getModMode()==ModModeCopy &&
3573 e->state() & Qt::ControlModifier)
3575 if (typeid(*selection)==typeid(BranchObj) )
3578 mapCenter->addBranch ((BranchObj*)selection);
3580 selection=mapCenter->getLastBranch();
3581 selection->select();
3582 mapCenter->reposition();
3585 movingObj=selection;
3587 // Middle Button Toggle Scroll
3588 // (On Mac OS X this won't work, but we still have
3589 // a button in the toolbar)
3590 if (e->button() == Qt::MidButton )
3594 { // No MapObj found, we are on the scene itself
3595 // Left Button move Pos of sceneView
3596 if (e->button() == Qt::LeftButton )
3598 movingObj=NULL; // move Content not Obj
3599 movingObj_start=e->globalPos();
3600 movingCont_start=QPointF (
3601 horizontalScrollBar()->value(),
3602 verticalScrollBar()->value());
3603 movingVec=QPointF(0,0);
3604 setCursor(HandOpenCursor);
3609 void MapEditor::mouseMoveEvent(QMouseEvent* e)
3611 QPointF p = mapToScene(e->pos());
3613 // Move the selected MapObj
3614 if ( selection && movingObj)
3616 // To avoid jumping of the sceneView, only
3617 // ensureSelectionVisible, if not tmp linked
3618 if (!selection->hasParObjTmp())
3619 ensureSelectionVisible ();
3621 // Now move the selection, but add relative position
3622 // (movingObj_start) where selection was chosen with
3623 // mousepointer. (This avoids flickering resp. jumping
3624 // of selection back to absPos)
3626 LinkableMapObj *lmosel;
3627 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3629 // Check if we could link
3630 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3633 if (typeid(*selection) == typeid(FloatImageObj))
3635 FloatObj *fo=(FloatObj*)selection;
3636 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3638 fo->updateLink(); //no need for reposition, if we update link here
3640 // Relink float to new mapcenter or branch, if shift is pressed
3641 // Only relink, if selection really has a new parent
3642 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3643 ( (typeid(*lmo)==typeid(BranchObj)) ||
3644 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3645 ( lmo != fo->getParObj())
3648 if (typeid(*fo) == typeid(FloatImageObj))
3650 //FIXME undocom for relinking of floats
3652 //saveStateComplete(QString("Relink %1 to %2").arg(getName(fo)).arg(getName(lmo) ) );
3653 FloatImageObj *fio=(FloatImageObj*)(fo);
3654 ((BranchObj*)(lmo))->addFloatImage (fio);
3656 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
3657 fio=((BranchObj*)(lmo))->getLastFloatImage();
3660 selection=(LinkableMapObj*)(fio);
3661 selection->select();
3662 movingObj=(MapObj*)(fio);
3666 { // selection != a FloatObj
3667 if (lmosel->getDepth()==0)
3670 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3671 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3673 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3674 mapCenter->updateRelPositions();
3677 if (lmosel->getDepth()==1)
3680 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3681 lmosel->setRelPos();
3684 // Move ordinary branch
3685 if (lmosel->getOrientation() == OrientLeftOfCenter)
3686 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3687 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3688 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3690 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3692 // reposition subbranch
3693 lmosel->reposition();
3695 if (lmo && (lmo!=selection) &&
3696 (typeid(*lmo) == typeid(BranchObj) ||
3697 (typeid(*lmo) == typeid(MapCenterObj) )
3700 if (e->modifiers()==Qt::ControlModifier)
3702 // Special case: CTRL to link below lmo
3703 lmosel->setParObjTmp (lmo,p,+1);
3705 else if (e->modifiers()==Qt::ShiftModifier)
3706 lmosel->setParObjTmp (lmo,p,-1);
3708 lmosel->setParObjTmp (lmo,p,0);
3711 lmosel->unsetParObjTmp();
3715 } // no FloatImageObj
3719 } // selection && moving_obj
3721 // Draw a link from one branch to another
3724 tmpXLink->setEnd (p);
3725 tmpXLink->updateXLink();
3729 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
3731 QPointF p=e->globalPos();
3732 movingVec.setX(-p.x() + movingObj_start.x() );
3733 movingVec.setY(-p.y() + movingObj_start.y() );
3734 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
3735 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
3740 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
3742 QPointF p = mapToScene(e->pos());
3743 LinkableMapObj *dst;
3744 // Have we been picking color?
3748 setCursor (Qt::ArrowCursor);
3749 // Check if we are over another branch
3750 dst=mapCenter->findMapObj(p, NULL);
3751 if (dst && selection)
3753 if (e->state() & Qt::ShiftModifier)
3755 ((BranchObj*)selection)->setColor (((BranchObj*)(dst))->getColor());
3756 ((BranchObj*)selection)->setLinkColor ();
3760 ((BranchObj*)selection)->setColorChilds (((BranchObj*)(dst))->getColor());
3761 ((BranchObj*)selection)->setLinkColor ();
3767 // Have we been drawing a link?
3771 // Check if we are over another branch
3772 dst=mapCenter->findMapObj(p, NULL);
3773 if (dst && selection)
3775 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3776 tmpXLink->updateXLink();
3777 tmpXLink->activate();
3778 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //FIXME undoCommand
3787 // Have we been moving something?
3788 if ( selection && movingObj )
3790 if(typeid(*selection)==typeid (FloatImageObj))
3792 // Moved FloatObj. Maybe we need to reposition
3793 FloatImageObj *fo=(FloatImageObj*)selection;
3794 QString pold=qpointfToString(movingObj_orgRelPos);
3795 QString pnow=qpointfToString(fo->getRelPos());
3801 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(pnow));
3803 selection->getParObj()->requestReposition();
3804 mapCenter->reposition();
3807 // Check if we are over another branch, but ignore
3808 // any found LMOs, which are FloatObjs
3809 dst=mapCenter->findMapObj(mapToScene(e->pos() ),
3810 ((LinkableMapObj*)selection) );
3812 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3815 if (typeid(*selection) == typeid(MapCenterObj) )
3816 { // FIXME The MapCenter was moved, no savestate yet
3819 if (typeid(*selection) == typeid(BranchObj) )
3820 { // A branch was moved
3822 // save the position in case we link to mapcenter
3823 QPointF savePos=QPointF (selection->x(),selection->y() );
3825 // Reset the temporary drawn link to the original one
3826 ((LinkableMapObj*)selection)->unsetParObjTmp();
3828 // For Redo we may need to save original selection
3829 QString preSelStr=selection->getSelectString();
3834 BranchObj* bsel=(BranchObj*)selection;
3835 BranchObj* bdst=(BranchObj*)dst;
3837 QString preParStr=(bsel->getParObj())->getSelectString();
3838 QString preNum=QString::number (bsel->getNum(),10);
3839 QString preDstParStr;
3841 if (e->state() & Qt::ShiftModifier && dst->getParObj())
3843 preDstParStr=dst->getParObj()->getSelectString();
3844 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
3846 if (e->state() & Qt::ControlModifier && dst->getParObj())
3849 preDstParStr=dst->getParObj()->getSelectString();
3850 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
3853 preDstParStr=dst->getSelectString();
3854 bsel->moveBranchTo (bdst,-1);
3855 if (dst->getDepth()==0) bsel->move (savePos);
3857 QString postSelStr=selection->getSelectString();
3858 QString postNum=QString::number (bsel->getNum(),10);
3860 QString undoCom="linkBranchToPos (\""+
3861 preParStr+ "\"," + preNum +"," +
3862 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
3864 QString redoCom="linkBranchToPos (\""+
3865 preDstParStr + "\"," + postNum + "," +
3866 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
3871 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
3873 if (selection->getDepth()==1)
3875 // The select string might be different _after_ moving around.
3876 // Therefor reposition and then use string of old selection, too
3877 mapCenter->reposition();
3879 QString ps=qpointfToString ( ((BranchObj*)selection)->getRelPos() );
3881 selection->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
3882 preSelStr, "moveRel "+ps,
3883 QString("Move %1 to relative position %2").arg(getName(selection)).arg(ps));
3886 // Draw the original link, before selection was moved around
3887 mapCenter->reposition();
3889 // Finally resize scene, if needed
3893 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
3896 // maybe we moved View: set old cursor
3897 setCursor (Qt::ArrowCursor);
3901 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
3903 if (e->button() == Qt::LeftButton )
3905 QPointF p = mapToScene(e->pos());
3906 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3907 if (lmo) { // MapObj was found
3908 // First select the MapObj than edit heading
3909 if (selection) selection->unselect();
3911 selection->select();
3912 mainWindow->editHeading();
3917 void MapEditor::resizeEvent (QResizeEvent* e)
3919 QGraphicsView::resizeEvent( e );
3922 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
3924 for (unsigned int i=0;event->format(i);i++) // Debug mime type
3925 cerr << event->format(i) << endl;
3927 if (event->mimeData()->hasFormat("image/png"))
3928 event->acceptProposedAction();
3931 void MapEditor::dropEvent(QDropEvent *event)
3933 if (event->mimeData()->hasFormat("image/png"))
3936 void MapEditor::contentsDropEvent(QDropEvent *event)
3938 //FIXME dropEvent not ported to QT4 yet
3940 (typeid(*selection) == typeid(BranchObj)) ||
3941 (typeid(*selection) == typeid(MapCenterObj)))
3948 if (event->mimeData()->hasFormat("image/png"))
3950 event->acceptProposedAction();
3951 addFloatImageInt(event->mimeData()->imageData().value<QPixmap>());
3952 cout << "accepted drop\n";
3956 if (event->provides("image/png"))
3959 if (Q3ImageDrag::decode(event, pix))
3961 addFloatImageInt(pix);
3967 } else if (event->provides("application/x-moz-file-promise-url") &&
3968 event->provides("application/x-moz-nativeimage"))
3970 // Contains url to the img src in unicode16
3971 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
3972 QString url = QString((const QChar*)d.data(),d.size()/2);
3976 } else if (event->provides ("text/uri-list"))
3977 { // Uris provided e.g. by konqueror
3978 Q3UriDrag::decode (event,uris);
3979 } else if (event->provides ("_NETSCAPE_URL"))
3980 { // Uris provided by Mozilla
3981 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
3984 } else if (event->provides("text/html")) {
3986 // Handels text mime types
3987 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
3988 QByteArray d = event->encodedData("text/html");
3991 text = QString((const QChar*)d.data(),d.size()/2);
3995 textEditor->setText(text);
3999 } else if (event->provides("text/plain")) {
4000 QByteArray d = event->encodedData("text/plain");
4003 text = QString((const QChar*)d.data(),d.size()/2);
4007 textEditor->setText(text);
4014 /* not ported yet QSTRINGLIST has no next...
4021 for (const char* u=uris.first(); u; u=uris.next())
4023 bo=((BranchObj*)selection)->addBranch();
4026 s=Q3UriDrag::uriToLocalFile(u);
4029 QString file = QDir::convertSeparators(s);
4030 heading = QFileInfo(file).baseName();
4032 if (file.endsWith(".vym", false))
4033 bo->setVymLink(file);
4042 if (!heading.isEmpty())
4043 bo->setHeading(heading);
4053 //FIXME dropEvent: saveState has to be called earlier for each of the drops...
4054 //saveStateComplete("Drop Event"); //TODO undo Command
4055 mapCenter->reposition();
4062 void MapEditor::contentsDragEnterEvent(QDragEnterEvent *event)
4064 //FIXME contentsDragEnterEvent not ported to QT4 yet
4066 // for (unsigned int i=0;event->format(i);i++) // Debug mime type
4067 // cerr << event->format(i) << endl;
4070 (typeid(*selection) == typeid(BranchObj)) ||
4071 (typeid(*selection) == typeid(MapCenterObj))) {
4073 // If QImageDrag can decode mime type
4074 if (Q3ImageDrag::canDecode(event)) {
4079 // If image are dragged from firefox
4080 if (event->provides("application/x-moz-file-promise-url") &&
4081 event->provides("application/x-moz-nativeimage")) {
4082 event->accept(true);
4086 // If QUriDrag can decode mime type
4087 if (Q3UriDrag::canDecode(event)) {
4092 // If Uri are dragged from firefox
4093 if (event->provides("_NETSCAPE_URL")){
4098 // If QTextDrag can decode mime type
4099 if (Q3TextDrag::canDecode(event)) {
4108 bool isUnicode16(const QByteArray &d)
4110 // TODO: make more precise check for unicode 16.
4111 // Guess unicode16 if any of second bytes are zero
4112 unsigned int length = max(0,d.size()-2)/2;
4113 for (unsigned int i = 0; i<length ; i++)
4114 if (d.at(i*2+1)==0) return true;
4118 void MapEditor::addFloatImageInt (const QPixmap &img)
4121 (typeid(*selection) == typeid(BranchObj)) ||
4122 (typeid(*selection) == typeid(MapCenterObj)) )
4124 BranchObj *bo=((BranchObj*)selection);
4125 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4126 //QString fn=fd->selectedFile();
4127 //lastImageDir=fn.left(fn.findRev ("/"));
4128 FloatImageObj *fio=bo->addFloatImage();
4130 fio->setOriginalFilename("Image added by Drag and Drop");
4131 mapCenter->reposition();
4138 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4140 if (!imageBuffer) imageBuffer = new QBuffer();
4141 if (!imageBuffer->isOpen()) {
4142 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4144 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4148 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4150 if (nop->state()==Q3NetworkProtocol::StDone) {
4151 QPixmap img(imageBuffer->buffer());
4152 addFloatImageInt (img);
4156 imageBuffer->close();
4158 imageBuffer->close();
4165 void MapEditor::fetchImage(const QString &url)
4168 urlOperator->stop();
4169 disconnect(urlOperator);
4173 urlOperator = new Q3UrlOperator(url);
4174 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4175 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4177 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4178 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));