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 (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=="moveBranchUp")
645 api.setError (Aborted,"Nothing selected");
646 } else if ( (typeid(*selection) != typeid(BranchObj) &&
647 typeid(*selection) != typeid(MapCenterObj)) )
649 api.setError (Aborted,"Type of selection is not a branch");
650 } else if (api.checkParamCount(0))
654 } else if (com=="moveBranchDown")
658 api.setError (Aborted,"Nothing selected");
659 } else if ( (typeid(*selection) != typeid(BranchObj) &&
660 typeid(*selection) != typeid(MapCenterObj)) )
662 api.setError (Aborted,"Type of selection is not a branch");
663 } else if (api.checkParamCount(0))
667 } else if (com=="move")
671 api.setError (Aborted,"Nothing selected");
672 } else if ( typeid(*selection) != typeid(BranchObj) &&
673 typeid(*selection) != typeid(MapCenterObj) &&
674 typeid(*selection) != typeid(FloatImageObj) )
676 api.setError (Aborted,"Type of selection is not a branch or floatimage");
677 } else if (api.checkParamCount(2))
686 } else if (com=="moveRel")
690 api.setError (Aborted,"Nothing selected");
691 } else if ( typeid(*selection) != typeid(BranchObj) &&
692 typeid(*selection) != typeid(MapCenterObj) &&
693 typeid(*selection) != typeid(FloatImageObj) )
695 api.setError (Aborted,"Type of selection is not a branch or floatimage");
696 } else if (api.checkParamCount(2))
702 if (ok) moveRel (x,y);
705 } else if (com=="paste")
709 api.setError (Aborted,"Nothing selected");
710 } else if ( typeid(*selection) != typeid(BranchObj) &&
711 typeid(*selection) != typeid(MapCenterObj) )
713 api.setError (Aborted,"Type of selection is not a branch");
714 } else if (api.checkParamCount(0))
718 } else if (com=="select")
720 if (api.checkParamCount(1))
722 s=api.parString(ok,0);
725 } else if (com=="setMapAuthor")
727 if (api.checkParamCount(1))
729 s=api.parString(ok,0);
730 if (ok) setMapAuthor (s);
732 } else if (com=="setMapComment")
734 if (api.checkParamCount(1))
736 s=api.parString(ok,0);
737 if (ok) setMapComment(s);
739 } else if (com=="setMapBackgroundColor")
743 api.setError (Aborted,"Nothing selected");
744 } else if ( (typeid(*selection) != typeid(BranchObj) &&
745 typeid(*selection) != typeid(MapCenterObj)) )
747 api.setError (Aborted,"Type of selection is not a branch");
748 } else if (api.checkParamCount(1))
750 QColor c=api.parColor (ok,0);
751 if (ok) setMapBackgroundColor (c);
753 } else if (com=="setMapDefLinkColor")
757 api.setError (Aborted,"Nothing selected");
758 } else if ( (typeid(*selection) != typeid(BranchObj) &&
759 typeid(*selection) != typeid(MapCenterObj)) )
761 api.setError (Aborted,"Type of selection is not a branch");
762 } else if (api.checkParamCount(1))
764 QColor c=api.parColor (ok,0);
765 if (ok) setMapDefLinkColor (c);
767 } else if (com=="setMapLinkStyle")
769 if (api.checkParamCount(1))
771 s=api.parString (ok,0);
772 if (ok) setMapLinkStyle(s);
774 } else if (com=="setHeading")
778 api.setError (Aborted,"Nothing selected");
779 } else if ( (typeid(*selection) != typeid(BranchObj) &&
780 typeid(*selection) != typeid(MapCenterObj)) )
782 api.setError (Aborted,"Type of selection is not a branch");
783 } else if (api.checkParamCount(1))
785 s=api.parString (ok,0);
789 } else if (com=="setHideExport")
793 api.setError (Aborted,"Nothing selected");
794 } else if ( typeid(*selection) != typeid(BranchObj) &&
795 typeid(*selection) != typeid(FloatImageObj) )
797 api.setError (Aborted,"Type of selection is not a branch or floatimage");
798 } else if (api.checkParamCount(1))
801 if (ok) setHideExport (b);
803 } else if (com=="setURL")
807 api.setError (Aborted,"Nothing selected");
808 } else if ( (typeid(*selection) != typeid(BranchObj) &&
809 typeid(*selection) != typeid(MapCenterObj)) )
811 api.setError (Aborted,"Type of selection is not a branch");
812 } else if (api.checkParamCount(1))
814 s=api.parString (ok,0);
815 if (ok) setURLInt(s);
817 } else if (com=="setVymLink")
821 api.setError (Aborted,"Nothing selected");
822 } else if ( (typeid(*selection) != typeid(BranchObj) &&
823 typeid(*selection) != typeid(MapCenterObj)) )
825 api.setError (Aborted,"Type of selection is not a branch");
826 } else if (api.checkParamCount(1))
828 s=api.parString (ok,0);
829 if (ok) setVymLinkInt(s);
832 else if (com=="setFlag")
836 api.setError (Aborted,"Nothing selected");
837 } else if ( (typeid(*selection) != typeid(BranchObj) &&
838 typeid(*selection) != typeid(MapCenterObj)) )
840 api.setError (Aborted,"Type of selection is not a branch");
841 } else if (api.checkParamCount(1))
843 s=api.parString(ok,0);
846 BranchObj* bo=(BranchObj*)selection;
847 bo->activateStandardFlag(s);
848 bo->updateFlagsToolbar();
852 else if (com=="unsetFlag")
856 api.setError (Aborted,"Nothing selected");
857 } else if ( (typeid(*selection) != typeid(BranchObj) &&
858 typeid(*selection) != typeid(MapCenterObj)) )
860 api.setError (Aborted,"Type of selection is not a branch");
861 } else if (api.checkParamCount(1))
863 s=api.parString(ok,0);
866 BranchObj* bo=(BranchObj*)selection;
867 bo->deactivateStandardFlag(s);
868 bo->updateFlagsToolbar();
873 api.setError (Aborted,"Unknown command");
877 if (api.errorLevel()==NoError)
881 // TODO Error handling
882 qWarning("MapEditor::parseAtom: Error!");
883 qWarning(api.errorMessage());
888 bool MapEditor::isDefault()
893 bool MapEditor::isUnsaved()
898 bool MapEditor::hasChanged()
903 void MapEditor::setChanged()
911 void MapEditor::closeMap()
913 // Unselect before disabling the toolbar actions
914 if (selection) selection->unselect();
922 void MapEditor::setFilePath(QString fname)
924 setFilePath (fname,fname);
927 void MapEditor::setFilePath(QString fname, QString destname)
929 if (fname.isEmpty() || fname=="")
936 filePath=fname; // becomes absolute path
937 fileName=fname; // gets stripped of path
938 destPath=destname; // needed for vymlinks
940 // If fname is not an absolute path, complete it
941 filePath=QDir(fname).absPath();
942 fileDir=filePath.left (1+filePath.findRev ("/"));
944 // Set short name, too. Search from behind:
945 int i=fileName.findRev("/");
946 if (i>=0) fileName=fileName.remove (0,i+1);
948 // Forget the .vym (or .xml) for name of map
949 mapName=fileName.left(fileName.findRev(".",-1,true) );
953 QString MapEditor::getFilePath()
958 QString MapEditor::getFileName()
963 QString MapEditor::getMapName()
968 QString MapEditor::getDestPath()
973 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
975 ErrorCode err=success;
979 if (selection) selection->unselect();
982 mapCenter->setMapEditor(this);
983 // (map state is set later at end of load...)
986 if (!selection || (typeid(*selection) != typeid(BranchObj) &&
987 typeid(*selection) != typeid (MapCenterObj)))
989 BranchObj *bo=(BranchObj*)selection;
990 if (lmode==ImportAdd)
991 saveStateChangingPart(
994 QString("addMapInsert (%1)").arg(fname),
995 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
997 saveStateChangingPart(
1000 QString("addMapReplace(%1)").arg(fname),
1001 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1005 mapBuilderHandler handler;
1006 QFile file( fname );
1008 // I am paranoid: file should exist anyway
1009 // according to check in mainwindow.
1010 if (!file.exists() )
1012 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1013 tr("Couldn't open map " +fname)+".");
1017 blockReposition=true;
1018 QXmlInputSource source( file);
1019 QXmlSimpleReader reader;
1020 reader.setContentHandler( &handler );
1021 reader.setErrorHandler( &handler );
1022 handler.setMapEditor( this );
1023 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1024 handler.setInputFile (file.name());
1025 handler.setLoadMode (lmode);
1026 blockSaveState=true;
1027 bool ok = reader.parse( source );
1028 blockReposition=false;
1029 blockSaveState=false;
1033 mapCenter->reposition();
1042 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1043 tr( handler.errorProtocol() ) );
1045 // Still return "success": the map maybe at least
1046 // partially read by the parser
1053 int MapEditor::save (const SaveMode &savemode)
1057 // Create mapName and fileDir
1058 makeSubDirs (fileDir);
1062 fname=mapName+".xml";
1064 // use name given by user, even if he chooses .doc
1069 if (savemode==CompleteMap || selection==NULL)
1070 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1072 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),selection);
1074 if (!saveStringToDisk(fileDir+fname,saveFile))
1087 void MapEditor::setZipped (bool z)
1092 bool MapEditor::saveZipped ()
1097 void MapEditor::print()
1101 printer = new QPrinter;
1102 printer->setColorMode (QPrinter::Color);
1103 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1104 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1105 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1108 QRectF totalBBox=mapCenter->getTotalBBox();
1110 // Try to set orientation automagically
1111 // Note: Interpretation of generated postscript is amibiguous, if
1112 // there are problems with landscape mode, see
1113 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1115 if (totalBBox.width()>totalBBox.height())
1116 // recommend landscape
1117 printer->setOrientation (QPrinter::Landscape);
1119 // recommend portrait
1120 printer->setOrientation (QPrinter::Portrait);
1122 if ( printer->setup(this) )
1123 // returns false, if printing is canceled
1125 QPainter pp(printer);
1127 pp.setRenderHint(QPainter::Antialiasing,true);
1129 // Don't print the visualisation of selection
1130 LinkableMapObj *oldselection=NULL;
1133 oldselection=selection;
1134 selection->unselect();
1137 QRectF mapRect=totalBBox;
1138 QGraphicsRectItem *frame=NULL;
1142 // Print frame around map
1143 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1144 totalBBox.width()+20, totalBBox.height()+20);
1145 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1146 frame->setZValue(0);
1151 double paperAspect = (double)printer->width() / (double)printer->height();
1152 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1154 if (mapAspect>=paperAspect)
1156 // Fit horizontally to paper width
1157 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1158 viewBottom=(int)(printer->width()/mapAspect);
1161 // Fit vertically to paper height
1162 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1163 viewBottom=printer->height();
1168 // Print footer below map
1170 font.setPointSize(10);
1172 QRectF footerBox(0,viewBottom,printer->width(),15);
1173 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1174 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1178 QRectF (0,0,printer->width(),printer->height()-15),
1179 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1182 // Viewport has paper dimension
1183 if (frame) delete (frame);
1185 // Restore selection
1188 selection=oldselection;
1189 selection->select();
1192 // Save settings in vymrc
1193 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1194 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1195 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1199 void MapEditor::setAntiAlias (bool b)
1201 setRenderHint(QPainter::Antialiasing,b);
1204 void MapEditor::setSmoothPixmap(bool b)
1206 setRenderHint(QPainter::SmoothPixmapTransform,b);
1209 QPixmap MapEditor::getPixmap()
1211 /* FIXME getPixmap not ported yet to QT4
1212 QRectF mapRect=mapCenter->getTotalBBox();
1216 // Don't print the visualisation of selection
1217 LinkableMapObj *oldselection=NULL;
1220 oldselection=selection;
1221 selection->unselect();
1224 pp.setWindow (mapRect);
1226 //mapScene->drawArea(mapRect, &pp); // draw scene to painter
1227 mapScene->render(&pp); // draw scene to painter
1231 // Restore selection
1234 selection=oldselection;
1235 selection->select();
1242 void MapEditor::setHideTmpMode (HideTmpMode mode)
1245 mapCenter->setHideTmp (hidemode);
1246 mapCenter->reposition();
1250 HideTmpMode MapEditor::getHideTmpMode()
1255 void MapEditor::exportImage(QString fn)
1257 setExportMode (true);
1258 QPixmap pix (getPixmap());
1259 pix.save(fn, "PNG");
1260 setExportMode (false);
1263 void MapEditor::setExportMode (bool b)
1265 // should be called before and after exports
1266 // depending on the settings
1267 if (b && settings.value("/export/useHideExport","yes")=="yes")
1268 setHideTmpMode (HideExport);
1270 setHideTmpMode (HideNone);
1273 void MapEditor::exportImage(QString fn, QString format)
1275 setExportMode (true);
1276 QPixmap pix (getPixmap());
1277 pix.save(fn, format);
1278 setExportMode (false);
1281 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1285 ex.setMapCenter(mapCenter);
1286 if (ex.setConfigFile(cf))
1288 setExportMode (true);
1289 ex.exportPresentation();
1290 setExportMode (false);
1296 void MapEditor::exportXML(const QString &dir)
1298 // Hide stuff during export, if settings want this
1299 setExportMode (true);
1301 // Create subdirectories
1304 // write to directory
1305 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1308 file.setName ( dir + "/"+mapName+".xml");
1309 if ( !file.open( QIODevice::WriteOnly ) )
1311 // This should neverever happen
1312 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1316 // Write it finally, and write in UTF8, no matter what
1317 QTextStream ts( &file );
1318 ts.setEncoding (QTextStream::UnicodeUTF8);
1322 // Now write image, too
1323 exportImage (dir+"/images/"+mapName+".png");
1325 setExportMode (false);
1328 void MapEditor::clear()
1332 selection->unselect();
1339 void MapEditor::copy()
1343 // write to directory
1344 QString clipfile="part";
1345 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPointF(),selection);
1348 file.setName ( clipboardDir + "/"+clipfile+".xml");
1349 if ( !file.open( QIODevice::WriteOnly ) )
1351 // This should neverever happen
1352 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1356 // Write it finally, and write in UTF8, no matter what
1357 QTextStream ts( &file );
1358 ts.setEncoding (QTextStream::UnicodeUTF8);
1362 clipboardEmpty=false;
1367 void MapEditor::redo()
1369 blockSaveState=true;
1371 // Restore variables
1372 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1373 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1374 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1375 // Can we undo at all?
1376 if (redosAvail<1) return;
1379 if (undosAvail<stepsTotal) undosAvail++;
1381 if (curStep>stepsTotal) curStep=1;
1382 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1383 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1384 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1385 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1386 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1387 QString version=undoSet.readEntry ("/history/version");
1389 if (!checkVersion(version))
1390 QMessageBox::warning(0,tr("Warning"),
1391 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1394 // Find out current undo directory
1395 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1397 /* TODO remove testing
1399 cout << "ME::redo() begin\n";
1400 cout << " undosAvail="<<undosAvail<<endl;
1401 cout << " redosAvail="<<redosAvail<<endl;
1402 cout << " curStep="<<curStep<<endl;
1403 cout << " ---------------------------"<<endl;
1404 cout << " comment="<<comment.toStdString()<<endl;
1405 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1406 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1407 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1408 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1409 cout << " ---------------------------"<<endl<<endl;
1411 // select object before redo
1412 if (!redoSelection.isEmpty())
1413 select (redoSelection);
1416 parseAtom (redoCommand);
1417 mapCenter->reposition();
1419 blockSaveState=false;
1421 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1422 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1423 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1424 undoSet.writeSettings(histPath);
1426 mainWindow->updateHistory (undoSet);
1429 /* TODO remove testing
1430 cout << "ME::redo() end\n";
1431 cout << " undosAvail="<<undosAvail<<endl;
1432 cout << " redosAvail="<<redosAvail<<endl;
1433 cout << " curStep="<<curStep<<endl;
1434 cout << " ---------------------------"<<endl<<endl;
1440 bool MapEditor::isRedoAvailable()
1442 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1448 void MapEditor::undo()
1450 blockSaveState=true;
1452 // Restore variables
1453 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1454 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1455 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1457 // Can we undo at all?
1458 if (undosAvail<1) return;
1460 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1461 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1462 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1463 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1464 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1465 QString version=undoSet.readEntry ("/history/version");
1467 if (!checkVersion(version))
1468 QMessageBox::warning(0,tr("Warning"),
1469 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1471 // Find out current undo directory
1472 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1474 // select object before undo
1475 if (!undoSelection.isEmpty())
1476 select (undoSelection);
1480 cout << "ME::undo() begin\n";
1481 cout << " undosAvail="<<undosAvail<<endl;
1482 cout << " redosAvail="<<redosAvail<<endl;
1483 cout << " curStep="<<curStep<<endl;
1484 cout << " ---------------------------"<<endl;
1485 cout << " comment="<<comment.toStdString()<<endl;
1486 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1487 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1488 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1489 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1490 cout << " ---------------------------"<<endl<<endl;
1491 parseAtom (undoCommand);
1492 mapCenter->reposition();
1496 if (curStep<1) curStep=stepsTotal;
1500 blockSaveState=false;
1501 /* TODO remove testing
1502 cout << "ME::undo() end\n";
1503 cout << " undosAvail="<<undosAvail<<endl;
1504 cout << " redosAvail="<<redosAvail<<endl;
1505 cout << " curStep="<<curStep<<endl;
1506 cout << " ---------------------------"<<endl<<endl;
1509 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1510 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1511 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1512 undoSet.writeSettings(histPath);
1514 mainWindow->updateHistory (undoSet);
1518 bool MapEditor::isUndoAvailable()
1520 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1526 void MapEditor::gotoHistoryStep (int i)
1528 // Restore variables
1529 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1530 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1532 if (i<0) i=undosAvail+redosAvail;
1534 // Clicking above current step makes us undo things
1537 for (int j=0; j<undosAvail-i; j++) undo();
1540 // Clicking below current step makes us redo things
1542 for (int j=undosAvail; j<i; j++) redo();
1544 // And ignore clicking the current row ;-)
1547 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1549 QString pathDir=path.left(path.findRev("/"));
1555 // We need to parse saved XML data
1556 mapBuilderHandler handler;
1557 QXmlInputSource source( file);
1558 QXmlSimpleReader reader;
1559 reader.setContentHandler( &handler );
1560 reader.setErrorHandler( &handler );
1561 handler.setMapEditor( this );
1562 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1563 if (undoSel.isEmpty())
1567 handler.setLoadMode (NewMap);
1571 handler.setLoadMode (ImportReplace);
1573 blockReposition=true;
1574 bool ok = reader.parse( source );
1575 blockReposition=false;
1578 // This should never ever happen
1579 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1580 handler.errorProtocol());
1583 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1586 void MapEditor::addMapInsertInt (const QString &path, int pos)
1588 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1589 typeid(*selection) == typeid(MapCenterObj)))
1591 QString pathDir=path.left(path.findRev("/"));
1597 // We need to parse saved XML data
1598 mapBuilderHandler handler;
1599 QXmlInputSource source( file);
1600 QXmlSimpleReader reader;
1601 reader.setContentHandler( &handler );
1602 reader.setErrorHandler( &handler );
1603 handler.setMapEditor( this );
1604 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1605 handler.setLoadMode (ImportAdd);
1606 blockReposition=true;
1607 bool ok = reader.parse( source );
1608 blockReposition=false;
1611 // This should never ever happen
1612 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1613 handler.errorProtocol());
1615 if (selection!=mapCenter)
1616 ((BranchObj*)selection)->getLastBranch()->moveBranchTo ((BranchObj*)(selection),pos);
1618 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1622 void MapEditor::pasteNoSave()
1624 load (clipboardDir+"/part.xml",ImportAdd);
1627 void MapEditor::cutNoSave()
1633 void MapEditor::paste()
1635 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1636 typeid(*selection) == typeid(MapCenterObj)))
1639 saveStateChangingPart(
1643 QString("Paste to %1").arg( getName(selection))
1645 mapCenter->reposition();
1649 void MapEditor::cut()
1651 saveStateChangingPart(
1652 selection->getParObj(),
1655 QString("Cut %1").arg(getName(selection))
1659 mapCenter->reposition();
1662 void MapEditor::move(const int &x, const int &y)
1666 QString ps=qpointfToString (selection->getAbsPos());
1667 QString s=selection->getSelectString();
1670 s, "move "+qpointfToString (QPointF (x,y)),
1671 QString("Move %1 to %2").arg(getName(selection)).arg(ps));
1672 selection->move(x,y);
1673 mapCenter->reposition();
1678 void MapEditor::moveRel (const int &x, const int &y)
1680 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1681 typeid(*selection) == typeid(MapCenterObj) ||
1682 typeid(*selection) == typeid (FloatImageObj)))
1684 QString ps=qpointfToString (selection->getRelPos());
1685 QString s=selection->getSelectString();
1688 s, "moveRel "+qpointfToString (QPointF (x,y)),
1689 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(ps));
1690 ((OrnamentedObj*)selection)->move2RelPos (x,y);
1691 mapCenter->reposition();
1695 void MapEditor::moveBranchUp()
1699 if (typeid(*selection) == typeid(BranchObj) )
1701 bo=(BranchObj*)selection;
1702 if (!bo->canMoveBranchUp()) return;
1703 par=(BranchObj*)(bo->getParObj());
1704 selection->unselect();
1705 bo=par->moveBranchUp (bo); // bo will be the one below selection
1706 selection->select();
1707 saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1708 mapCenter->reposition();
1709 ensureSelectionVisible();
1713 void MapEditor::moveBranchDown()
1717 if (typeid(*selection) == typeid(BranchObj) )
1719 bo=(BranchObj*)selection;
1720 if (!bo->canMoveBranchDown()) return;
1721 par=(BranchObj*)(bo->getParObj());
1722 selection->unselect();
1723 bo=par->moveBranchDown(bo); // bo will be the one above selection
1724 selection->select();
1725 saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1726 mapCenter->reposition();
1727 ensureSelectionVisible();
1731 QString MapEditor::getHeading(bool &ok, QPoint &p)
1734 (typeid(*selection) == typeid(BranchObj) ||
1735 typeid(*selection) == typeid(MapCenterObj) ) )
1738 ensureSelectionVisible();
1739 p=mapFromScene(selection->getAbsPos());
1740 return ((BranchObj*)selection)->getHeading();
1746 void MapEditor::setHeading(const QString &s)
1749 (typeid(*selection) == typeid(BranchObj) ||
1750 typeid(*selection) == typeid(MapCenterObj) ) )
1752 editingBO=(BranchObj*)selection;
1755 "setHeading (\""+editingBO->getHeading()+"\")",
1757 "setHeading (\""+s+"\")",
1758 QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(s) );
1759 editingBO->setHeading(s );
1761 mapCenter->reposition();
1762 ensureSelectionVisible();
1766 void MapEditor::setURLInt (const QString &s)
1768 // Internal function, no saveState needed
1770 (typeid(*selection) == typeid(BranchObj) ||
1771 typeid(*selection) == typeid(MapCenterObj) ) )
1773 ((BranchObj*)selection)->setURL(s);
1774 mapCenter->reposition();
1775 ensureSelectionVisible();
1779 void MapEditor::setHeadingInt(const QString &s)
1782 (typeid(*selection) == typeid(BranchObj) ||
1783 typeid(*selection) == typeid(MapCenterObj) ) )
1785 ((BranchObj*)selection)->setHeading(s);
1786 mapCenter->reposition();
1787 ensureSelectionVisible();
1791 void MapEditor::setVymLinkInt (const QString &s)
1793 // Internal function, no saveState needed
1795 (typeid(*selection) == typeid(BranchObj) ||
1796 typeid(*selection) == typeid(MapCenterObj) ) )
1798 ((BranchObj*)selection)->setVymLink(s);
1799 mapCenter->reposition();
1800 ensureSelectionVisible();
1804 BranchObj* MapEditor::addNewBranchInt(int num)
1806 // Depending on pos:
1807 // -3 insert in childs of parent above selection
1808 // -2 add branch to selection
1809 // -1 insert in childs of parent below selection
1810 // 0..n insert in childs of parent at pos
1811 BranchObj *newbo=NULL;
1813 (typeid(*selection) == typeid(BranchObj) ||
1814 typeid(*selection) == typeid(MapCenterObj) ) )
1816 BranchObj* bo = (BranchObj*) selection;
1819 // save scroll state. If scrolled, automatically select
1820 // new branch in order to tmp unscroll parent...
1821 return bo->addBranch();
1826 bo=(BranchObj*)bo->getParObj();
1830 bo=(BranchObj*)bo->getParObj();
1833 newbo=bo->insertBranch(num);
1838 BranchObj* MapEditor::addNewBranch(int pos)
1840 // Different meaning than num in addNewBranchInt!
1844 BranchObj *bo = (BranchObj*) selection;
1845 BranchObj *newbo=NULL;
1848 (typeid(*selection) == typeid(BranchObj) ||
1849 typeid(*selection) == typeid(MapCenterObj) ) )
1851 newbo=addNewBranchInt (pos-2);
1859 QString ("addBranch (%1)").arg(pos-2),
1860 QString ("Add new branch to %1").arg(getName(bo)));
1862 mapCenter->reposition();
1869 BranchObj* MapEditor::addNewBranchBefore()
1871 BranchObj *newbo=NULL;
1873 (typeid(*selection) == typeid(BranchObj) ) )
1874 // We accept no MapCenterObj here, so we _have_ a parent
1876 BranchObj* bo = (BranchObj*) selection;
1877 QPointF p=bo->getRelPos();
1880 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1882 // add below selection
1883 newbo=parbo->insertBranch(bo->getNum()+1);
1886 newbo->move2RelPos (p);
1888 // Move selection to new branch
1889 ((BranchObj*)selection)->moveBranchTo (newbo,-1);
1891 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
1892 QString ("Add branch before %1").arg(getName(bo)));
1894 mapCenter->reposition();
1900 void MapEditor::deleteSelection()
1902 if (selection && typeid(*selection) ==typeid(BranchObj) )
1904 BranchObj* bo=(BranchObj*)selection;
1905 BranchObj* par=(BranchObj*)(bo->getParObj());
1907 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
1909 par->removeBranch(bo);
1911 selection->select();
1912 ensureSelectionVisible();
1913 mapCenter->reposition();
1915 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
1917 FloatImageObj* fio=(FloatImageObj*)selection;
1918 BranchObj* par=(BranchObj*)(fio->getParObj());
1919 saveStateChangingPart(
1923 QString("Delete %1").arg(getName(fio))
1927 par->removeFloatImage(fio);
1929 selection->select();
1930 ensureSelectionVisible();
1931 mapCenter->reposition();
1935 LinkableMapObj* MapEditor::getSelection()
1940 void MapEditor::unselect()
1944 selectionLast=selection;
1945 selection->unselect();
1950 void MapEditor::reselect()
1954 selection=selectionLast;
1955 selection->select();
1960 bool MapEditor::select (const QString &s)
1962 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
1964 // Finally select the found object
1967 if (selection) unselect();
1969 selection->select();
1970 ensureSelectionVisible();
1976 QString MapEditor::getSelectString()
1978 if (selection) return selection->getSelectString();
1982 void MapEditor::selectInt (LinkableMapObj *lmo)
1984 if (lmo && selection != lmo)
1986 // select the MapObj
1987 if (selection) selection->unselect();
1989 selection->select();
1993 void MapEditor::selectNextBranchInt()
1995 // Increase number of branch
1998 QString s=selection->getSelectString();
2004 part=s.section(",",-1);
2006 num=part.right(part.length() - 3);
2008 s=s.left (s.length() -num.length());
2011 num=QString ("%1").arg(num.toUInt()+1);
2015 // Try to select this one
2016 if (select (s)) return;
2018 // We have no direct successor,
2019 // try to increase the parental number in order to
2020 // find a successor with same depth
2022 int d=selection->getDepth();
2027 while (!found && d>0)
2029 s=s.section (",",0,d-1);
2030 // replace substring of current depth in s with "1"
2031 part=s.section(",",-1);
2033 num=part.right(part.length() - 3);
2037 // increase number of parent
2038 num=QString ("%1").arg(num.toUInt()+1);
2039 s=s.section (",",0,d-2) + ","+ typ+num;
2042 // Special case, look at orientation
2043 if (selection->getOrientation()==OrientRightOfCenter)
2044 num=QString ("%1").arg(num.toUInt()+1);
2046 num=QString ("%1").arg(num.toUInt()-1);
2051 // pad to oldDepth, select the first branch for each depth
2052 for (i=d;i<oldDepth;i++)
2057 if ( ((BranchObj*)selection)->countBranches()>0)
2065 // try to select the freshly built string
2073 void MapEditor::selectPrevBranchInt()
2075 // Decrease number of branch
2078 QString s=selection->getSelectString();
2084 part=s.section(",",-1);
2086 num=part.right(part.length() - 3);
2088 s=s.left (s.length() -num.length());
2090 int n=num.toInt()-1;
2093 num=QString ("%1").arg(n);
2096 // Try to select this one
2097 if (n>=0 && select (s)) return;
2099 // We have no direct precessor,
2100 // try to decrease the parental number in order to
2101 // find a precessor with same depth
2103 int d=selection->getDepth();
2108 while (!found && d>0)
2110 s=s.section (",",0,d-1);
2111 // replace substring of current depth in s with "1"
2112 part=s.section(",",-1);
2114 num=part.right(part.length() - 3);
2118 // decrease number of parent
2119 num=QString ("%1").arg(num.toInt()-1);
2120 s=s.section (",",0,d-2) + ","+ typ+num;
2123 // Special case, look at orientation
2124 if (selection->getOrientation()==OrientRightOfCenter)
2125 num=QString ("%1").arg(num.toInt()-1);
2127 num=QString ("%1").arg(num.toInt()+1);
2132 // pad to oldDepth, select the last branch for each depth
2133 for (i=d;i<oldDepth;i++)
2137 if ( ((BranchObj*)selection)->countBranches()>0)
2138 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
2145 // try to select the freshly built string
2153 void MapEditor::selectUpperBranch()
2157 if (typeid(*selection) == typeid(BranchObj))
2159 if (selection->getOrientation()==OrientRightOfCenter)
2160 selectPrevBranchInt();
2162 if (selection->getDepth()==1)
2163 selectNextBranchInt();
2165 selectPrevBranchInt();
2170 void MapEditor::selectLowerBranch()
2174 if (typeid(*selection) == typeid(BranchObj))
2176 if (selection->getOrientation()==OrientRightOfCenter)
2177 selectNextBranchInt();
2179 if (selection->getDepth()==1)
2180 selectPrevBranchInt();
2182 selectNextBranchInt();
2188 void MapEditor::selectLeftBranch()
2194 if (typeid(*selection) == typeid(MapCenterObj))
2196 par= (BranchObj*) selection;
2197 bo=par->getLastSelectedBranch();
2200 // Workaround for reselecting on left and right side
2201 if (bo->getOrientation()==OrientRightOfCenter)
2203 bo=par->getLastBranch();
2209 selection->select();
2210 ensureSelectionVisible();
2215 par=(BranchObj*)(selection->getParObj());
2216 if (selection->getOrientation()==OrientRightOfCenter)
2218 if (typeid(*selection) == typeid(BranchObj) ||
2219 typeid(*selection) == typeid(FloatImageObj))
2221 selection->unselect();
2223 selection->select();
2224 ensureSelectionVisible();
2228 if (typeid(*selection) == typeid(BranchObj) )
2230 bo=((BranchObj*)selection)->getLastSelectedBranch();
2233 selection->unselect();
2235 selection->select();
2236 ensureSelectionVisible();
2244 void MapEditor::selectRightBranch()
2251 if (typeid(*selection) == typeid(MapCenterObj))
2253 par= (BranchObj*) selection;
2254 bo=par->getLastSelectedBranch();
2257 // Workaround for reselecting on left and right side
2258 if (bo->getOrientation()==OrientLeftOfCenter)
2259 bo=par->getFirstBranch();
2264 selection->select();
2265 ensureSelectionVisible();
2270 par=(BranchObj*)(selection->getParObj());
2271 if (selection->getOrientation()==OrientLeftOfCenter)
2273 if (typeid(*selection) == typeid(BranchObj) ||
2274 typeid(*selection) == typeid(FloatImageObj))
2276 selection->unselect();
2278 selection->select();
2279 ensureSelectionVisible();
2283 if (typeid(*selection) == typeid(BranchObj) )
2285 bo=((BranchObj*)selection)->getLastSelectedBranch();
2288 selection->unselect();
2290 selection->select();
2291 ensureSelectionVisible();
2299 void MapEditor::selectFirstBranch()
2305 if (typeid(*selection) == typeid(BranchObj))
2307 bo1= (BranchObj*) selection;
2308 par=(BranchObj*)(bo1->getParObj());
2309 bo2=par->getFirstBranch();
2313 selection->select();
2314 ensureSelectionVisible();
2320 void MapEditor::selectLastBranch()
2326 if (typeid(*selection) == typeid(BranchObj))
2328 bo1= (BranchObj*) selection;
2329 par=(BranchObj*)(bo1->getParObj());
2330 bo2=par->getLastBranch();
2334 selection->select();
2335 ensureSelectionVisible();
2341 void MapEditor::selectMapBackgroundImage ()
2343 Q3FileDialog *fd=new Q3FileDialog( this);
2344 fd->setMode (Q3FileDialog::ExistingFile);
2345 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2346 ImagePreview *p =new ImagePreview (fd);
2347 fd->setContentsPreviewEnabled( TRUE );
2348 fd->setContentsPreview( p, p );
2349 fd->setPreviewMode( Q3FileDialog::Contents );
2350 fd->setCaption(vymName+" - " +tr("Load background image"));
2351 fd->setDir (lastImageDir);
2354 if ( fd->exec() == QDialog::Accepted )
2356 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2357 lastImageDir=QDir (fd->dirPath());
2358 setMapBackgroundImage (fd->selectedFile());
2362 void MapEditor::setMapBackgroundImage (const QString &fn)
2364 QColor oldcol=mapScene->backgroundBrush().color();
2368 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2370 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2371 QString("Set background color of map to %1").arg(col.name()));
2373 cout << "Trying to load "<<fn.ascii()<<endl;
2375 brush.setTextureImage (QPixmap (fn));
2376 mapScene->setBackgroundBrush(brush);
2379 void MapEditor::selectMapBackgroundColor()
2381 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2382 if ( !col.isValid() ) return;
2383 setMapBackgroundColor( col );
2387 void MapEditor::setMapBackgroundColor(QColor col)
2389 QColor oldcol=mapScene->backgroundBrush().color();
2392 QString ("setMapBackgroundColor (%1)").arg(oldcol.name()),
2394 QString ("setMapBackgroundColor (%1)").arg(col.name()),
2395 QString("Set background color of map to %1").arg(col.name()));
2396 mapScene->setBackgroundBrush(col);
2399 QColor MapEditor::getMapBackgroundColor()
2401 return mapScene->backgroundBrush().color();
2404 QColor MapEditor::getCurrentHeadingColor()
2408 if (typeid(*selection) == typeid(BranchObj) ||
2409 typeid(*selection) == typeid(MapCenterObj))
2411 BranchObj *bo=(BranchObj*)selection;
2412 return bo->getColor();
2416 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2420 void MapEditor::colorBranch (QColor c)
2424 if (typeid(*selection) == typeid(BranchObj) ||
2425 typeid(*selection) == typeid(MapCenterObj))
2427 BranchObj *bo=(BranchObj*)selection;
2430 QString ("colorBranch (%1)").arg(bo->getColor().name()),
2432 QString ("colorBranch (%1)").arg(c.name()),
2433 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2435 bo->setColor(c); // color branch
2440 void MapEditor::colorSubtree (QColor c)
2444 if (typeid(*selection) == typeid(BranchObj) ||
2445 typeid(*selection) == typeid(MapCenterObj))
2447 BranchObj *bo=(BranchObj*)selection;
2448 saveStateChangingPart(
2451 QString ("colorSubtree (%1)").arg(c.name()),
2452 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2454 bo->setColorSubtree (c); // color links, color childs
2460 void MapEditor::toggleStandardFlag(QString f)
2464 if (typeid(*selection) == typeid(BranchObj) ||
2465 typeid(*selection) == typeid(MapCenterObj))
2467 BranchObj *bo=(BranchObj*)selection;
2469 if (bo->isSetStandardFlag(f))
2481 QString("%1 (\"%2\")").arg(u).arg(f),
2483 QString("%1 (\"%2\")").arg(r).arg(f),
2484 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2485 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2491 BranchObj* MapEditor::findText (QString s, bool cs)
2493 QTextDocument::FindFlags flags=0;
2494 if (cs) flags=QTextDocument::FindCaseSensitively;
2497 { // Nothing found or new find process
2499 // nothing found, start again
2501 itFind=mapCenter->first();
2503 bool searching=true;
2504 bool foundNote=false;
2505 while (searching && !EOFind)
2509 // Searching in Note
2510 if (itFind->getNote().contains(s,cs))
2512 if (selection!=itFind)
2514 if (selection) ((BranchObj*)selection)->unselect();
2516 selection->select();
2517 ensureSelectionVisible();
2519 if (textEditor->findText(s,flags))
2525 // Searching in Heading
2526 if (searching && itFind->getHeading().contains (s,cs) )
2528 if (selection) ((BranchObj*)selection)->unselect();
2530 selection->select();
2531 ensureSelectionVisible();
2537 itFind=itFind->next();
2538 if (!itFind) EOFind=true;
2543 return (BranchObj*)selection;
2548 void MapEditor::findReset()
2549 { // Necessary if text to find changes during a find process
2553 void MapEditor::setURL(const QString &url)
2555 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2556 typeid(*selection) == typeid(MapCenterObj)) )
2558 BranchObj *bo=(BranchObj*)selection;
2559 QString oldurl=bo->getURL();
2563 QString ("setURL (\"%1\")").arg(oldurl),
2565 QString ("setURL (\"%1\")").arg(url),
2566 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2572 void MapEditor::editURL()
2574 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2575 typeid(*selection) == typeid(MapCenterObj)) )
2578 BranchObj *bo=(BranchObj*)selection;
2579 QString text = QInputDialog::getText(
2580 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2581 bo->getURL(), &ok, this );
2583 // user entered something and pressed OK
2588 QString MapEditor::getURL()
2590 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2591 typeid(*selection) == typeid(MapCenterObj)) )
2592 return ((BranchObj*)selection)->getURL();
2597 QStringList MapEditor::getURLs()
2600 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2601 typeid(*selection) == typeid(MapCenterObj)) )
2603 BranchObj *bo=(BranchObj*)selection;
2607 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2615 void MapEditor::editHeading2URL()
2617 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2618 typeid(*selection) == typeid(MapCenterObj)) )
2619 setURL (((BranchObj*)selection)->getHeading());
2622 void MapEditor::editBugzilla2URL()
2624 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2625 typeid(*selection) == typeid(MapCenterObj)) )
2627 BranchObj *bo=(BranchObj*)selection;
2628 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2633 void MapEditor::editFATE2URL()
2635 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2636 typeid(*selection) == typeid(MapCenterObj)) )
2638 BranchObj *bo=(BranchObj*)selection;
2639 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2642 "setURL (\""+bo->getURL()+"\")",
2644 "setURL (\""+url+"\")",
2645 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2652 void MapEditor::editVymLink()
2654 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2655 typeid(*selection) == typeid(MapCenterObj)) )
2657 BranchObj *bo=(BranchObj*)selection;
2658 QStringList filters;
2659 filters <<"VYM map (*.vym)";
2660 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2661 fd->setFilters (filters);
2662 fd->setCaption(vymName+" - " +tr("Link to another map"));
2663 if (! bo->getVymLink().isEmpty() )
2664 fd->selectFile( bo->getVymLink() );
2668 if ( fd->exec() == QDialog::Accepted )
2672 "setVymLink (\""+bo->getVymLink()+"\")",
2674 "setVymLink (\""+fd->selectedFile()+"\")",
2675 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2677 bo->setVymLink (fd->selectedFile() );
2679 mapCenter->reposition();
2685 void MapEditor::deleteVymLink()
2687 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2688 typeid(*selection) == typeid(MapCenterObj)) )
2690 BranchObj *bo=(BranchObj*)selection;
2693 "setVymLink (\""+bo->getVymLink()+"\")",
2695 "setVymLink (\"\")",
2696 QString("Unset vymlink of %1").arg(getName(bo))
2698 bo->setVymLink ("" );
2700 mapCenter->reposition();
2705 void MapEditor::setHideExport(bool b)
2707 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2708 typeid(*selection)==typeid(FloatImageObj)))
2710 OrnamentedObj *oo=(OrnamentedObj*)selection;
2711 oo->setHideInExport (b);
2712 QString u= b ? "false" : "true";
2713 QString r=!b ? "false" : "true";
2717 QString ("setHideExport (%1)").arg(u),
2719 QString ("setHideExport (%1)").arg(r),
2720 QString ("Set HideExport flag of %1 to %2").arg(getName(oo)).arg (r)
2723 mapCenter->reposition();
2728 void MapEditor::toggleHideExport()
2730 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2731 typeid(*selection)==typeid(FloatImageObj)))
2732 setHideExport ( !((OrnamentedObj*)selection)->hideInExport() );
2735 QString MapEditor::getVymLink()
2737 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2738 typeid(*selection) == typeid(MapCenterObj)) )
2740 return ((BranchObj*)selection)->getVymLink();
2746 QStringList MapEditor::getVymLinks()
2749 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2750 typeid(*selection) == typeid(MapCenterObj)) )
2752 BranchObj *bo=(BranchObj*)selection;
2756 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2764 void MapEditor::deleteKeepChilds()
2766 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2768 BranchObj* bo=(BranchObj*)selection;
2769 BranchObj* par=(BranchObj*)(bo->getParObj());
2770 QPointF p=bo->getRelPos();
2771 saveStateChangingPart(
2772 selection->getParObj(),
2774 "deleteKeepChilds ()",
2775 QString("Remove %1 and keep its childs").arg(getName(bo))
2778 QString sel=selection->getSelectString();
2780 par->removeBranchHere(bo);
2781 mapCenter->reposition();
2783 ((BranchObj*)selection)->move2RelPos (p);
2784 mapCenter->reposition();
2788 void MapEditor::deleteChilds()
2790 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2791 typeid(*selection)==typeid(MapCenterObj)))
2793 saveStateChangingPart(
2794 selection->getParObj(),
2797 QString( "Remove childs of branch %1").arg(getName(selection))
2799 ((BranchObj*)selection)->removeChilds();
2800 mapCenter->reposition();
2804 void MapEditor::editMapInfo()
2806 ExtraInfoDialog dia;
2807 dia.setMapName (getFileName() );
2808 dia.setAuthor (mapCenter->getAuthor() );
2809 dia.setComment(mapCenter->getComment() );
2813 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
2820 bo=mapCenter->first();
2823 if (!bo->getNote().isEmpty() ) n++;
2824 f+= bo->countFloatImages();
2826 xl+=bo->countXLinks();
2829 stats+=QString ("%1 branches\n").arg (b-1,6);
2830 stats+=QString ("%1 xLinks \n").arg (xl,6);
2831 stats+=QString ("%1 notes\n").arg (n,6);
2832 stats+=QString ("%1 images\n").arg (f,6);
2833 dia.setStats (stats);
2835 // Finally show dialog
2836 if (dia.exec() == QDialog::Accepted)
2838 setMapAuthor (dia.getAuthor() );
2839 setMapComment (dia.getComment() );
2843 void MapEditor::updateActions()
2845 mainWindow->updateActions();
2846 // TODO maybe don't update if blockReposition is set
2849 void MapEditor::updateNoteFlag()
2852 if ( (typeid(*selection) == typeid(BranchObj)) ||
2853 (typeid(*selection) == typeid(MapCenterObj)) )
2854 ((BranchObj*)selection)->updateNoteFlag();
2857 void MapEditor::setMapAuthor (const QString &s)
2861 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
2863 QString ("setMapAuthor (\"%1\")").arg(s),
2864 QString ("Set author of map to \"%1\"").arg(s)
2866 mapCenter->setAuthor (s);
2869 void MapEditor::setMapComment (const QString &s)
2873 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
2875 QString ("setMapComment (\"%1\")").arg(s),
2876 QString ("Set comment of map")
2878 mapCenter->setComment (s);
2881 void MapEditor::setMapLinkStyle (const QString & s)
2883 saveStateChangingPart (
2886 QString("setMapLinkStyle (\"%1\")").arg(s),
2887 QString("Set map link style (\"%1\")").arg(s)
2891 linkstyle=StyleLine;
2892 else if (s=="StyleParabel")
2893 linkstyle=StyleParabel;
2894 else if (s=="StylePolyLine")
2895 linkstyle=StylePolyLine;
2897 linkstyle=StylePolyParabel;
2900 bo=mapCenter->first();
2904 bo->setLinkStyle(bo->getDefLinkStyle());
2907 mapCenter->reposition();
2910 LinkStyle MapEditor::getMapLinkStyle ()
2915 void MapEditor::setMapDefLinkColor(QColor c)
2921 void MapEditor::setMapLinkColorHintInt()
2923 // called from setMapLinkColorHint(lch) or at end of parse
2925 bo=mapCenter->first();
2933 void MapEditor::setMapLinkColorHint(LinkColorHint lch)
2936 setMapLinkColorHintInt();
2939 void MapEditor::toggleMapLinkColorHint()
2941 if (linkcolorhint==HeadingColor)
2942 linkcolorhint=DefaultColor;
2944 linkcolorhint=HeadingColor;
2946 bo=mapCenter->first();
2954 LinkColorHint MapEditor::getMapLinkColorHint()
2956 return linkcolorhint;
2959 QColor MapEditor::getMapDefLinkColor()
2961 return defLinkColor;
2964 void MapEditor::setMapDefXLinkColor(QColor col)
2969 QColor MapEditor::getMapDefXLinkColor()
2971 return defXLinkColor;
2974 void MapEditor::setMapDefXLinkWidth (int w)
2979 int MapEditor::getMapDefXLinkWidth()
2981 return defXLinkWidth;
2984 void MapEditor::selectMapLinkColor()
2986 QColor col = QColorDialog::getColor( defLinkColor, this );
2987 if ( !col.isValid() ) return;
2990 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
2992 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
2993 QString("Set link color to %1").arg(col.name())
2995 setMapDefLinkColor( col );
2999 void MapEditor::toggleScroll()
3001 if (selection && (typeid(*selection) == typeid(BranchObj)) )
3003 BranchObj *bo=((BranchObj*)selection);
3004 if (bo->countBranches()==0) return;
3005 if (bo->getDepth()==0) return;
3007 if (bo->isScrolled())
3019 QString ("%1 ()").arg(u),
3021 QString ("%1 ()").arg(r),
3022 QString ("%1 %2").arg(r).arg(getName(bo))
3029 void MapEditor::unScrollAll()
3032 bo=mapCenter->first();
3035 if (bo->isScrolled()) bo->toggleScroll();
3040 void MapEditor::loadFloatImage ()
3043 (typeid(*selection) == typeid(BranchObj)) ||
3044 (typeid(*selection) == typeid(MapCenterObj)) )
3046 BranchObj *bo=((BranchObj*)selection);
3048 Q3FileDialog *fd=new Q3FileDialog( this);
3049 fd->setMode (Q3FileDialog::ExistingFiles);
3050 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3051 ImagePreview *p =new ImagePreview (fd);
3052 fd->setContentsPreviewEnabled( TRUE );
3053 fd->setContentsPreview( p, p );
3054 fd->setPreviewMode( Q3FileDialog::Contents );
3055 fd->setCaption(vymName+" - " +tr("Load image"));
3056 fd->setDir (lastImageDir);
3060 if ( fd->exec() == QDialog::Accepted )
3062 // FIXME loadFIO in QT4 use: lastImageDir=fd->directory();
3063 lastImageDir=QDir (fd->dirPath());
3064 QStringList flist = fd->selectedFiles();
3065 QStringList::Iterator it = flist.begin();
3067 while( it != flist.end() )
3070 bo->addFloatImage();
3071 fio=bo->getLastFloatImage();
3073 // FIXME loadFIO check if load of fio was successful
3075 (LinkableMapObj*)fio,
3078 QString ("loadFloatImage (%1)").arg(*it),
3079 QString("Add floatimage %1 to %2").arg(*it).arg(getName(selection))
3081 bo->getLastFloatImage()->setOriginalFilename(fn);
3085 mapCenter->reposition();
3093 void MapEditor::saveFloatImage ()
3096 (typeid(*selection) == typeid(FloatImageObj)) )
3098 FloatImageObj *fio=((FloatImageObj*)selection);
3099 QFileDialog *fd=new QFileDialog( this);
3100 fd->setFilters (imageIO.getFilters());
3101 fd->setCaption(vymName+" - " +tr("Save image"));
3102 fd->setFileMode( QFileDialog::AnyFile );
3103 fd->setDirectory (lastImageDir);
3104 // fd->setSelection (fio->getOriginalFilename());
3108 if ( fd->exec() == QDialog::Accepted )
3110 if (QFile (fd->selectedFile()).exists() )
3112 QMessageBox mb( vymName,
3113 tr("The file %1 exists already.\n"
3114 "Do you want to overwrite it?").arg(fd->selectedFile()),
3115 QMessageBox::Warning,
3116 QMessageBox::Yes | QMessageBox::Default,
3117 QMessageBox::Cancel | QMessageBox::Escape,
3118 QMessageBox::QMessageBox::NoButton );
3120 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3121 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3124 case QMessageBox::Yes:
3127 case QMessageBox::Cancel:
3134 fio->save (fd->selectedFile(),imageIO.getType (fd->selectedFilter() ) );
3140 void MapEditor::setFrame(const FrameType &t)
3143 (typeid(*selection) == typeid(BranchObj)) ||
3144 (typeid(*selection) == typeid(MapCenterObj)) )
3146 selection->setFrameType (t);
3147 mapCenter->reposition();
3148 selection->updateLink();
3152 void MapEditor::setIncludeImagesVer(bool b)
3155 (typeid(*selection) == typeid(BranchObj)) ||
3156 (typeid(*selection) == typeid(MapCenterObj)) )
3157 ((BranchObj*)selection)->setIncludeImagesVer(b);
3158 mapCenter->reposition();
3161 void MapEditor::setIncludeImagesHor(bool b)
3164 (typeid(*selection) == typeid(BranchObj)) ||
3165 (typeid(*selection) == typeid(MapCenterObj)) )
3166 ((BranchObj*)selection)->setIncludeImagesHor(b);
3167 mapCenter->reposition();
3170 void MapEditor::setHideLinkUnselected (bool b)
3173 (typeid(*selection) == typeid(BranchObj)) ||
3174 (typeid(*selection) == typeid(MapCenterObj)) ||
3175 (typeid(*selection) == typeid(FloatImageObj)) )
3176 selection->setHideLinkUnselected(b);
3179 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3182 (typeid(*selection) == typeid(BranchObj)) ||
3183 (typeid(*selection) == typeid(MapCenterObj)) )
3187 // Traverse directories
3188 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3189 QFileInfoList list = d.entryInfoList();
3192 for (int i = 0; i < list.size(); ++i)
3195 if (fi.fileName() != "." && fi.fileName() != ".." )
3198 bo=dst->getLastBranch();
3199 bo->setHeading (fi.fileName() );
3200 bo->setColor (QColor("blue"));
3202 if ( !d.cd(fi.fileName()) )
3203 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3206 // Recursively add subdirs
3207 importDirInt (bo,d);
3213 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3214 list = d.entryInfoList();
3216 for (int i = 0; i < list.size(); ++i)
3220 bo=dst->getLastBranch();
3221 bo->setHeading (fi.fileName() );
3222 bo->setColor (QColor("black"));
3223 if (fi.fileName().right(4) == ".vym" )
3224 bo->setVymLink (fi.filePath());
3229 void MapEditor::importDir()
3232 (typeid(*selection) == typeid(BranchObj)) ||
3233 (typeid(*selection) == typeid(MapCenterObj)) )
3235 QStringList filters;
3236 filters <<"VYM map (*.vym)";
3237 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3238 fd->setMode (QFileDialog::DirectoryOnly);
3239 fd->setFilters (filters);
3240 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3244 if ( fd->exec() == QDialog::Accepted )
3246 BranchObj *bo=((BranchObj*)selection);
3247 importDirInt (bo,QDir(fd->selectedFile()) );
3248 mapCenter->reposition();
3254 void MapEditor::followXLink(int i)
3257 (typeid(*selection) == typeid(BranchObj)) ||
3258 (typeid(*selection) == typeid(MapCenterObj)) )
3260 BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
3263 selection->unselect();
3265 selection->select();
3266 ensureSelectionVisible();
3271 void MapEditor::editXLink(int i)
3274 (typeid(*selection) == typeid(BranchObj)) ||
3275 (typeid(*selection) == typeid(MapCenterObj)) )
3277 XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
3280 EditXLinkDialog dia;
3282 dia.setSelection(selection);
3283 if (dia.exec() == QDialog::Accepted)
3285 if (dia.useSettingsGlobal() )
3287 setMapDefXLinkColor (xlo->getColor() );
3288 setMapDefXLinkWidth (xlo->getWidth() );
3290 if (dia.deleteXLink())
3291 ((BranchObj*)selection)->deleteXLinkAt(i);
3292 //saveStateComplete("Edit xLink"); //FIXME editXLink undoCommand
3298 void MapEditor::testFunction()
3301 dia.showCancelButton (true);
3302 dia.setText("This is a longer \nWarning");
3304 dia.setCaption("Warning: Flux problem");
3305 dia.setShowAgainName("/warnings/mapeditor");
3307 if (dia.exec()==QDialog::Accepted)
3308 cout << "accepted!\n";
3310 cout << "canceled!\n";
3313 /* Hide hidden stuff temporary, maybe add this as regular function somewhere
3314 if (hidemode==HideNone)
3316 setHideTmpMode (HideExport);
3317 mapCenter->calcBBoxSizeWithChilds();
3318 QRectF totalBBox=mapCenter->getTotalBBox();
3319 QRectF mapRect=totalBBox;
3320 QCanvasRectangle *frame=NULL;
3322 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3324 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3325 totalBBox.width(), totalBBox.height());
3326 frame=new QCanvasRectangle (mapRect,mapScene);
3327 frame->setBrush (QColor(white));
3328 frame->setPen (QColor(black));
3329 frame->setZValue(0);
3334 setHideTmpMode (HideNone);
3336 cout <<" hidemode="<<hidemode<<endl;
3340 void MapEditor::ensureSelectionVisible()
3344 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
3346 if (selection->getOrientation() == OrientLeftOfCenter)
3347 p= matrix().map(QPointF (lmo->x(),lmo->y()));
3349 p= matrix().map(QPointF (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
3350 ensureVisible (QRectF(p.x(), p.y(),0,0 ));
3356 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3358 // Lineedits are already closed by preceding
3359 // mouseEvent, we don't need to close here.
3361 QPointF p = mapToScene(e->pos());
3362 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3365 { // MapObj was found
3366 if (selection != lmo)
3368 // select the MapObj
3369 if (selection) selection->unselect();
3371 selection->select();
3376 if (typeid(*selection)==typeid(BranchObj) ||
3377 typeid(*selection)==typeid(MapCenterObj) )
3379 // Context Menu on branch or mapcenter
3381 branchContextMenu->popup(e->globalPos() );
3383 if (typeid(*selection)==typeid(FloatImageObj))
3385 // Context Menu on floatimage
3387 floatimageContextMenu->popup(e->globalPos() );
3391 { // No MapObj found, we are on the Canvas itself
3392 // Context Menu on scene
3394 canvasContextMenu->popup(e->globalPos() );
3399 void MapEditor::keyPressEvent(QKeyEvent* e)
3401 if (e->modifiers() & Qt::ControlModifier)
3403 switch (mainWindow->getModMode())
3406 setCursor (PickColorCursor);
3409 setCursor (CopyCursor);
3412 setCursor (XLinkCursor);
3415 setCursor (Qt::ArrowCursor);
3421 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3423 if (!(e->modifiers() & Qt::ControlModifier))
3424 setCursor (Qt::ArrowCursor);
3427 void MapEditor::mousePressEvent(QMouseEvent* e)
3429 // Ignore right clicks, these will go to context menus
3430 if (e->button() == Qt::RightButton )
3436 QPointF p = mapToScene(e->pos());
3437 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3441 //Take care of clickdesystem flags _or_ modifier modes
3443 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3444 typeid(*lmo)==typeid(MapCenterObj) ))
3446 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3447 if (!foname.isEmpty())
3449 // systemFlag clicked
3453 if (e->state() & Qt::ControlModifier)
3454 mainWindow->editOpenURLTab();
3456 mainWindow->editOpenURL();
3458 else if (foname=="vymLink")
3460 mainWindow->editOpenVymLink();
3461 // tabWidget may change, better return now
3462 // before segfaulting...
3463 } else if (foname=="note")
3464 mainWindow->windowToggleNoteEditor();
3465 else if (foname=="hideInExport")
3470 // No system flag clicked, take care of modmodes
3472 // Special case: CTRL is pressed
3473 if (e->state() & Qt::ControlModifier)
3475 if (mainWindow->getModMode()==ModModeColor)
3478 setCursor (PickColorCursor);
3481 if (mainWindow->getModMode()==ModModeXLink)
3483 BranchObj *bo_begin=NULL;
3485 bo_begin=(BranchObj*)(lmo);
3488 ((typeid(*selection) == typeid(BranchObj)) ||
3489 (typeid(*selection) == typeid(MapCenterObj))) )
3490 bo_begin=(BranchObj*)selection;
3494 linkingObj_src=bo_begin;
3495 tmpXLink=new XLinkObj (mapScene);
3496 tmpXLink->setBegin (bo_begin);
3497 tmpXLink->setEnd (p);
3498 tmpXLink->setColor(defXLinkColor);
3499 tmpXLink->setWidth(defXLinkWidth);
3500 tmpXLink->updateXLink();
3501 tmpXLink->setVisibility (true);
3509 // Left Button Move Branches
3510 if (e->button() == Qt::LeftButton )
3512 movingObj_start.setX( p.x() - selection->x() );
3513 movingObj_start.setY( p.y() - selection->y() );
3514 movingObj_orgPos.setX (lmo->x() );
3515 movingObj_orgPos.setY (lmo->y() );
3516 movingObj_orgRelPos=lmo->getRelPos();
3518 // If modMode==copy, then we want to "move" the _new_ object around
3519 // then we need the offset from p to the _old_ selection, because of tmp
3520 if (mainWindow->getModMode()==ModModeCopy &&
3521 e->state() & Qt::ControlModifier)
3523 if (typeid(*selection)==typeid(BranchObj) )
3526 mapCenter->addBranch ((BranchObj*)selection);
3528 selection=mapCenter->getLastBranch();
3529 selection->select();
3530 mapCenter->reposition();
3533 movingObj=selection;
3535 // Middle Button Toggle Scroll
3536 // (On Mac OS X this won't work, but we still have
3537 // a button in the toolbar)
3538 if (e->button() == Qt::MidButton )
3542 { // No MapObj found, we are on the scene itself
3543 // Left Button move Pos of sceneView
3544 if (e->button() == Qt::LeftButton )
3546 movingObj=NULL; // move Content not Obj
3547 movingObj_start=e->globalPos();
3548 movingCont_start=QPointF (
3549 horizontalScrollBar()->value(),
3550 verticalScrollBar()->value());
3551 movingVec=QPointF(0,0);
3552 setCursor(HandOpenCursor);
3557 void MapEditor::mouseMoveEvent(QMouseEvent* e)
3559 QPointF p = mapToScene(e->pos());
3561 // Move the selected MapObj
3562 if ( selection && movingObj)
3564 // To avoid jumping of the sceneView, only
3565 // ensureSelectionVisible, if not tmp linked
3566 if (!selection->hasParObjTmp())
3567 ensureSelectionVisible ();
3569 // Now move the selection, but add relative position
3570 // (movingObj_start) where selection was chosen with
3571 // mousepointer. (This avoids flickering resp. jumping
3572 // of selection back to absPos)
3574 LinkableMapObj *lmosel;
3575 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3577 // Check if we could link
3578 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3581 if (typeid(*selection) == typeid(FloatImageObj))
3583 FloatObj *fo=(FloatObj*)selection;
3584 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3586 fo->updateLink(); //no need for reposition, if we update link here
3588 // Relink float to new mapcenter or branch, if shift is pressed
3589 // Only relink, if selection really has a new parent
3590 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3591 ( (typeid(*lmo)==typeid(BranchObj)) ||
3592 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3593 ( lmo != fo->getParObj())
3596 if (typeid(*fo) == typeid(FloatImageObj))
3598 //FIXME undocom for relinking of floats
3600 //saveStateComplete(QString("Relink %1 to %2").arg(getName(fo)).arg(getName(lmo) ) );
3601 FloatImageObj *fio=(FloatImageObj*)(fo);
3602 ((BranchObj*)(lmo))->addFloatImage (fio);
3604 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
3605 fio=((BranchObj*)(lmo))->getLastFloatImage();
3608 selection=(LinkableMapObj*)(fio);
3609 selection->select();
3610 movingObj=(MapObj*)(fio);
3614 { // selection != a FloatObj
3615 if (lmosel->getDepth()==0)
3618 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3619 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3621 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3622 mapCenter->updateRelPositions();
3625 if (lmosel->getDepth()==1)
3628 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3629 lmosel->setRelPos();
3632 // Move ordinary branch
3633 if (lmosel->getOrientation() == OrientLeftOfCenter)
3634 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3635 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3636 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3638 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3640 // reposition subbranch
3641 lmosel->reposition();
3643 if (lmo && (lmo!=selection) &&
3644 (typeid(*lmo) == typeid(BranchObj) ||
3645 (typeid(*lmo) == typeid(MapCenterObj) )
3648 if (e->modifiers()==Qt::ControlModifier)
3650 // Special case: CTRL to link below lmo
3651 lmosel->setParObjTmp (lmo,p,+1);
3653 else if (e->modifiers()==Qt::ShiftModifier)
3654 lmosel->setParObjTmp (lmo,p,-1);
3656 lmosel->setParObjTmp (lmo,p,0);
3659 lmosel->unsetParObjTmp();
3663 } // no FloatImageObj
3667 } // selection && moving_obj
3669 // Draw a link from one branch to another
3672 tmpXLink->setEnd (p);
3673 tmpXLink->updateXLink();
3677 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
3679 QPointF p=e->globalPos();
3680 movingVec.setX(-p.x() + movingObj_start.x() );
3681 movingVec.setY(-p.y() + movingObj_start.y() );
3682 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
3683 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
3688 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
3690 QPointF p = mapToScene(e->pos());
3691 LinkableMapObj *dst;
3692 // Have we been picking color?
3696 setCursor (Qt::ArrowCursor);
3697 // Check if we are over another branch
3698 dst=mapCenter->findMapObj(p, NULL);
3699 if (dst && selection)
3701 if (e->state() & Qt::ShiftModifier)
3702 colorBranch (((BranchObj*)(dst))->getColor());
3704 colorSubtree (((BranchObj*)(dst))->getColor());
3709 // Have we been drawing a link?
3713 // Check if we are over another branch
3714 dst=mapCenter->findMapObj(p, NULL);
3715 if (dst && selection)
3717 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3718 tmpXLink->updateXLink();
3719 tmpXLink->activate();
3720 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //FIXME undoCommand
3729 // Have we been moving something?
3730 if ( selection && movingObj )
3732 if(typeid(*selection)==typeid (FloatImageObj))
3734 // Moved FloatObj. Maybe we need to reposition
3735 FloatImageObj *fo=(FloatImageObj*)selection;
3736 QString pold=qpointfToString(movingObj_orgRelPos);
3737 QString pnow=qpointfToString(fo->getRelPos());
3743 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(pnow));
3745 selection->getParObj()->requestReposition();
3746 mapCenter->reposition();
3749 // Check if we are over another branch, but ignore
3750 // any found LMOs, which are FloatObjs
3751 dst=mapCenter->findMapObj(mapToScene(e->pos() ),
3752 ((LinkableMapObj*)selection) );
3754 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3757 if (typeid(*selection) == typeid(MapCenterObj) )
3758 { // FIXME The MapCenter was moved, no savestate yet
3761 if (typeid(*selection) == typeid(BranchObj) )
3762 { // A branch was moved
3764 // save the position in case we link to mapcenter
3765 QPointF savePos=QPointF (selection->x(),selection->y() );
3767 // Reset the temporary drawn link to the original one
3768 ((LinkableMapObj*)selection)->unsetParObjTmp();
3770 // For Redo we may need to save original selection
3771 QString preSelStr=selection->getSelectString();
3776 BranchObj* bsel=(BranchObj*)selection;
3777 BranchObj* bdst=(BranchObj*)dst;
3779 QString preParStr=(bsel->getParObj())->getSelectString();
3780 QString preNum=QString::number (bsel->getNum(),10);
3781 QString preDstParStr;
3783 if (e->state() & Qt::ShiftModifier && dst->getParObj())
3785 preDstParStr=dst->getParObj()->getSelectString();
3786 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
3788 if (e->state() & Qt::ControlModifier && dst->getParObj())
3791 preDstParStr=dst->getParObj()->getSelectString();
3792 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
3795 preDstParStr=dst->getSelectString();
3796 bsel->moveBranchTo (bdst,-1);
3797 if (dst->getDepth()==0) bsel->move (savePos);
3799 QString postSelStr=selection->getSelectString();
3800 QString postNum=QString::number (bsel->getNum(),10);
3802 QString undoCom="linkBranchToPos (\""+
3803 preParStr+ "\"," + preNum +"," +
3804 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
3806 QString redoCom="linkBranchToPos (\""+
3807 preDstParStr + "\"," + postNum + "," +
3808 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
3813 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
3815 if (selection->getDepth()==1)
3817 // The select string might be different _after_ moving around.
3818 // Therefor reposition and then use string of old selection, too
3819 mapCenter->reposition();
3821 QString ps=qpointfToString ( ((BranchObj*)selection)->getRelPos() );
3823 selection->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
3824 preSelStr, "moveRel "+ps,
3825 QString("Move %1 to relative position %2").arg(getName(selection)).arg(ps));
3828 // Draw the original link, before selection was moved around
3829 mapCenter->reposition();
3831 // Finally resize scene, if needed
3835 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
3838 // maybe we moved View: set old cursor
3839 setCursor (Qt::ArrowCursor);
3843 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
3845 if (e->button() == Qt::LeftButton )
3847 QPointF p = mapToScene(e->pos());
3848 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3849 if (lmo) { // MapObj was found
3850 // First select the MapObj than edit heading
3851 if (selection) selection->unselect();
3853 selection->select();
3854 mainWindow->editHeading();
3859 void MapEditor::resizeEvent (QResizeEvent* e)
3861 QGraphicsView::resizeEvent( e );
3864 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
3866 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
3867 // cerr << event->format(i) << endl;
3869 if (event->mimeData()->hasImage())
3870 event->acceptProposedAction();
3872 if (event->mimeData()->hasUrls())
3873 event->acceptProposedAction();
3876 void MapEditor::dragMoveEvent(QDragMoveEvent *event)
3880 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
3885 void MapEditor::dropEvent(QDropEvent *event)
3888 (typeid(*selection) == typeid(BranchObj)) ||
3889 (typeid(*selection) == typeid(MapCenterObj)))
3892 if (event->mimeData()->hasImage())
3894 QVariant imageData = event->mimeData()->imageData();
3895 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
3897 if (event->mimeData()->hasUrls())
3898 uris=event->mimeData()->urls();
3906 for (int i=0; i<uris.count();++i)
3908 bo=((BranchObj*)selection)->addBranch();
3911 s=uris.at(i).toLocalFile();
3914 QString file = QDir::convertSeparators(s);
3915 heading = QFileInfo(file).baseName();
3917 if (file.endsWith(".vym", false))
3918 bo->setVymLink(file);
3920 bo->setURL(uris.at(i).toString());
3923 bo->setURL(uris.at(i).toString());
3926 if (!heading.isEmpty())
3927 bo->setHeading(heading);
3929 bo->setHeading(uris.at(i).toString());
3932 mapCenter->reposition();
3935 event->acceptProposedAction();
3939 void MapEditor::contentsDropEvent(QDropEvent *event)
3942 } else if (event->provides("application/x-moz-file-promise-url") &&
3943 event->provides("application/x-moz-nativeimage"))
3945 // Contains url to the img src in unicode16
3946 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
3947 QString url = QString((const QChar*)d.data(),d.size()/2);
3951 } else if (event->provides ("text/uri-list"))
3952 { // Uris provided e.g. by konqueror
3953 Q3UriDrag::decode (event,uris);
3954 } else if (event->provides ("_NETSCAPE_URL"))
3955 { // Uris provided by Mozilla
3956 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
3959 } else if (event->provides("text/html")) {
3961 // Handels text mime types
3962 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
3963 QByteArray d = event->encodedData("text/html");
3966 text = QString((const QChar*)d.data(),d.size()/2);
3970 textEditor->setText(text);
3974 } else if (event->provides("text/plain")) {
3975 QByteArray d = event->encodedData("text/plain");
3978 text = QString((const QChar*)d.data(),d.size()/2);
3982 textEditor->setText(text);
3992 bool isUnicode16(const QByteArray &d)
3994 // TODO: make more precise check for unicode 16.
3995 // Guess unicode16 if any of second bytes are zero
3996 unsigned int length = max(0,d.size()-2)/2;
3997 for (unsigned int i = 0; i<length ; i++)
3998 if (d.at(i*2+1)==0) return true;
4002 void MapEditor::addFloatImageInt (const QPixmap &img)
4005 (typeid(*selection) == typeid(BranchObj)) ||
4006 (typeid(*selection) == typeid(MapCenterObj)) )
4008 BranchObj *bo=((BranchObj*)selection);
4009 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4010 //QString fn=fd->selectedFile();
4011 //lastImageDir=fn.left(fn.findRev ("/"));
4012 FloatImageObj *fio=bo->addFloatImage();
4014 fio->setOriginalFilename("Image added by Drag and Drop");
4015 mapCenter->reposition();
4022 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4024 if (!imageBuffer) imageBuffer = new QBuffer();
4025 if (!imageBuffer->isOpen()) {
4026 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4028 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4032 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4034 if (nop->state()==Q3NetworkProtocol::StDone) {
4035 QPixmap img(imageBuffer->buffer());
4036 addFloatImageInt (img);
4040 imageBuffer->close();
4042 imageBuffer->close();
4049 void MapEditor::fetchImage(const QString &url)
4052 urlOperator->stop();
4053 disconnect(urlOperator);
4057 urlOperator = new Q3UrlOperator(url);
4058 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4059 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4061 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4062 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));