3 #include <q3dragobject.h>
4 #include <q3urloperator.h>
5 #include <q3networkprotocol.h>
6 #include <q3paintdevicemetrics.h>
7 #include <q3filedialog.h>
16 #include "editxlinkdialog.h"
18 #include "extrainfodialog.h"
20 #include "linkablemapobj.h"
21 #include "mainwindow.h"
23 #include "texteditor.h"
24 #include "warningdialog.h"
28 extern TextEditor *textEditor;
29 extern int statusbarTime;
30 extern Main *mainWindow;
31 extern QString tmpVymDir;
32 extern QString clipboardDir;
33 extern bool clipboardEmpty;
34 extern FlagRowObj *standardFlagsDefault;
36 extern QMenu* branchContextMenu;
37 extern QMenu* branchAddContextMenu;
38 extern QMenu* branchRemoveContextMenu;
39 extern QMenu* branchLinksContextMenu;
40 extern QMenu* branchXLinksContextMenuEdit;
41 extern QMenu* branchXLinksContextMenuFollow;
42 extern QMenu* floatimageContextMenu;
43 extern QMenu* canvasContextMenu;
46 extern Settings settings;
47 extern ImageIO imageIO;
49 extern QString vymName;
50 extern QString vymVersion;
52 extern QString iconPath;
53 extern QDir vymBaseDir;
54 extern QDir lastImageDir;
56 int MapEditor::mapNum=0; // make instance
58 ///////////////////////////////////////////////////////////////////////
59 ///////////////////////////////////////////////////////////////////////
60 MapEditor::MapEditor( QWidget* parent) :
61 QGraphicsView(parent), urlOperator(0), imageBuffer(0)
63 //cout << "Constructor ME "<<this<<endl;
66 viewport()->setAcceptDrops(true);
68 mapScene= new QGraphicsScene(parent);
69 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
70 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
75 /* FIXME not needed in QT4?
76 // Maybe check QAbstractScrollArea...
77 // Always show scroll bars (automatic would flicker sometimes)
78 setVScrollBarMode ( QScrollView::AlwaysOn );
79 setHScrollBarMode ( QScrollView::AlwaysOn );
82 mapCenter = new MapCenterObj(mapScene);
83 mapCenter->setVisibility (true);
84 mapCenter->setMapEditor (this);
85 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
86 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
91 defLinkColor=QColor (0,0,255);
92 defXLinkColor=QColor (180,180,180);
93 linkcolorhint=DefaultColor;
94 linkstyle=StylePolyParabel;
96 // Create bitmap cursors, platform dependant
97 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
98 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
99 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
100 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
102 setFocusPolicy (Qt::StrongFocus);
113 xelection.setMapCenter (mapCenter);
116 defXLinkColor=QColor (230,230,230);
124 fileName=tr("unnamed");
127 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
128 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
130 // Initialize find routine
137 blockReposition=false;
138 blockSaveState=false;
142 // Create temporary files
145 // Initially set movingCentre
148 mapCenter->reposition(); // for positioning heading
152 MapEditor::~MapEditor()
154 if (imageBuffer) delete imageBuffer;
160 //cout <<"Destructor MapEditor\n";
163 MapCenterObj* MapEditor::getMapCenter()
168 QGraphicsScene * MapEditor::getScene()
173 void MapEditor::adjustCanvasSize()
176 /* FIXME QT4 probably not needed any longer!
178 // To adjust the scene to map, viewport size and position, we have to
179 // do some coordinate magic...
181 // Get rectangle of (scroll-)view.
182 // We want to be in scene coords, so
183 // we map. Important if view is zoomed...
184 QRectF view = inverseWorldMatrix().mapRect( QRectF( contentsX(), contentsY(),
185 visibleWidth(), visibleHeight()) );
187 // Now we need the bounding box of view AND map to calc the correct scene size.
188 // Why? Because if the map itself is moved out of view, the view has to be enlarged
189 // to avoid jumping aroung...
190 QRectF map=mapCenter->getTotalBBox();
192 // right edge - left edge
193 int cw= max(map.x() + map.width(), view.x() + view.width()) - min(map.x(), view.x());
194 int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
197 if ( (cw!=mapScene->width()) || (ch!=mapScene->height()) ||
198 !mapScene->onCanvas (map.topLeft()) || !mapScene->onCanvas (map.bottomRight())
201 // move the map on scene (in order to not move it on screen) this is neccessary
202 // a) if topleft corner of scene is left or above topleft corner of view and also left of
203 // above topleft corner of map. E.g. if map is completly inside view, but it would be possible
204 // to scroll to an empty area of scene to the left.
205 // b) if topleft corner of map left of or above topleft of scene
209 if (cw > mapScene->width() )
211 if (map.x()<0) dx=-map.x();
213 if (cw < mapScene->width() )
214 dx=-min (view.x(),map.x());
215 if (ch > mapScene->height() )
217 if (map.y()<0) dy=-map.y();
219 if (ch < mapScene->height() )
221 dy=-min (view.y(),map.y());
223 // We really have to resize now. Let's go...
224 // FIXME old code mapScene->resize (cw,ch);
225 mapScene->setSceneRect (QRectFF(0,0,cw,ch));
226 if ( (dx!=0) || (dy!=0) )
228 mapCenter->moveAllBy(dx,dy);
229 mapCenter->reposition();
230 // mapCenter->positionBBox(); // To move float
232 // scroll the view (in order to not move map on screen)
240 bool MapEditor::isRepositionBlocked()
242 return blockReposition;
245 QString MapEditor::getName (LinkableMapObj *lmo)
248 if (!lmo) return QString("Error: NULL has no name!");
250 if ((typeid(*lmo) == typeid(BranchObj) ||
251 typeid(*lmo) == typeid(MapCenterObj)))
254 s=(((BranchObj*)lmo)->getHeading());
255 if (s=="") s="unnamed";
256 return QString("branch (%1)").arg(s);
257 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
259 if ((typeid(*lmo) == typeid(FloatImageObj) ))
260 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
261 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
262 return QString("Unknown type has no name!");
265 void MapEditor::makeTmpDirs()
267 // Create unique temporary directories
268 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
269 histPath=QDir::convertSeparators (tmpMapDir+"/history");
274 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
276 // tmpdir temporary directory to which data will be written
277 // prefix mapname, which will be appended to images etc.
278 // writeflags Only write flags for "real" save of map, not undo
279 // offset offset of bbox of whole map in scene.
280 // Needed for XML export
296 ls="StylePolyParabel";
300 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
302 if (linkcolorhint==HeadingColor)
303 colhint=attribut("linkColorHint","HeadingColor");
305 QString mapAttr=attribut("version",vymVersion);
306 if (!saveSel || saveSel==mapCenter)
307 mapAttr+= attribut("author",mapCenter->getAuthor()) +
308 attribut("comment",mapCenter->getComment()) +
309 attribut("date",mapCenter->getDate()) +
310 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
311 attribut("linkStyle", ls ) +
312 attribut("linkColor", defLinkColor.name() ) +
313 attribut("defXLinkColor", defXLinkColor.name() ) +
314 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
316 s+=beginElement("vymmap",mapAttr);
319 // Find the used flags while traversing the tree
320 standardFlagsDefault->resetUsedCounter();
322 // Reset the counters before saving
323 // TODO constr. of FIO creates lots of objects, better do this in some other way...
324 FloatImageObj (mapScene).resetSaveCounter();
326 // Build xml recursivly
327 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
328 // Save complete map, if saveSel not set
329 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
332 if ( typeid(*saveSel) == typeid(BranchObj) )
334 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
335 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
337 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
339 else if (selection && typeid(*selection)==typeid(BranchObj))
340 // Save selected branch is saved from mainwindow //FIXME maybe use "subtree" above?
341 // FIXME is this possible at all? BO is already above...
342 s+=((BranchObj*)selection)->saveToDir(tmpdir,prefix,offset);
345 // Save local settings
346 s+=settings.getXMLData (destPath);
349 if (selection && !saveSel )
350 s+=valueElement("select",selection->getSelectString());
353 s+=endElement("vymmap");
356 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
360 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
362 // save the selected part of the map, Undo will replace part of map
363 QString undoSelection="";
365 undoSelection=undoSel->getSelectString();
367 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
368 QString redoSelection="";
370 redoSelection=undoSel->getSelectString();
372 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
375 saveState (PartOfMap,
376 undoSelection, "addMapReplace (\"PATH\")",
382 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
386 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
389 QString undoSelection=redoSel->getParObj()->getSelectString();
390 QString redoSelection=redoSel->getSelectString();
391 if (typeid(*redoSel) == typeid(BranchObj) )
393 // save the selected branch of the map, Undo will insert part of map
394 saveState (PartOfMap,
395 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
396 redoSelection, "delete ()",
403 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
405 // "Normal" savestate: save commands, selections and comment
406 // so just save commands for undo and redo
407 // and use current selection
409 QString redoSelection="";
410 if (redoSel) redoSelection=redoSel->getSelectString();
411 QString undoSelection="";
412 if (undoSel) undoSelection=undoSel->getSelectString();
414 saveState (UndoCommand,
421 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
423 // "Normal" savestate: save commands, selections and comment
424 // so just save commands for undo and redo
425 // and use current selection
426 saveState (UndoCommand,
434 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
438 if (blockSaveState) return;
440 /* TODO remove after testing
442 cout << "ME::saveState() "<<endl;
444 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
445 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
446 int curStep=undoSet.readNumEntry ("/history/curStep",0);
447 // Find out current undo directory
448 if (undosAvail<stepsTotal) undosAvail++;
450 if (curStep>stepsTotal) curStep=1;
452 QString backupXML="";
453 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
454 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
455 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
457 // Create bakMapDir if not available
460 makeSubDirs (bakMapDir);
462 // Save depending on how much needs to be saved
464 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPointF (),saveSel);
466 QString undoCommand="";
467 if (savemode==UndoCommand)
471 else if (savemode==PartOfMap )
474 undoCommand.replace ("PATH",bakMapPath);
477 if (!backupXML.isEmpty())
478 // Write XML Data to disk
479 saveStringToDisk (QString(bakMapPath),backupXML);
481 // We would have to save all actions in a tree, to keep track of
482 // possible redos after a action. Possible, but we are too lazy: forget about redos.
485 // Write the current state to disk
486 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
487 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
488 undoSet.setEntry ("/history/curStep",QString::number(curStep));
489 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
490 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
491 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
492 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
493 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
494 undoSet.setEntry (QString("/history/version"),vymVersion);
495 undoSet.writeSettings(histPath);
497 /* TODO remove after testing
499 //cout << " into="<< histPath.toStdString()<<endl;
500 cout << " stepsTotal="<<stepsTotal<<
501 ", undosAvail="<<undosAvail<<
502 ", redosAvail="<<redosAvail<<
503 ", curStep="<<curStep<<endl;
504 cout << " ---------------------------"<<endl;
505 cout << " comment="<<comment.toStdString()<<endl;
506 cout << " undoCom="<<undoCommand.toStdString()<<endl;
507 cout << " undoSel="<<undoSelection.toStdString()<<endl;
508 cout << " redoCom="<<redoCom.toStdString()<<endl;
509 cout << " redoSel="<<redoSelection.toStdString()<<endl;
510 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
511 cout << " ---------------------------"<<endl;
513 mainWindow->updateHistory (undoSet);
518 void MapEditor::parseAtom(const QString &atom)
525 // Split string s into command and parameters
526 api.parseInput (atom);
527 QString com=api.command();
530 if (com=="addBranch")
534 api.setError (Aborted,"Nothing selected");
535 } else if ( (typeid(*selection) != typeid(BranchObj) &&
536 typeid(*selection) != typeid(MapCenterObj)) )
538 api.setError (Aborted,"Type of selection is not a branch");
543 if (api.checkParamCount(pl))
545 if (api.paramCount()==0)
546 addNewBranchInt (-2);
550 if (ok ) addNewBranchInt (y);
554 } else if (com=="addBranchBefore")
558 api.setError (Aborted,"Nothing selected");
559 } else if ( (typeid(*selection) != typeid(BranchObj) &&
560 typeid(*selection) != typeid(MapCenterObj)) )
562 api.setError (Aborted,"Type of selection is not a branch");
565 if (api.paramCount()==0)
567 addNewBranchBefore ();
570 } else if (com==QString("addMapReplace"))
574 api.setError (Aborted,"Nothing selected");
575 } else if ( (typeid(*selection) != typeid(BranchObj) &&
576 typeid(*selection) != typeid(MapCenterObj)) )
578 api.setError (Aborted,"Type of selection is not a branch");
579 } else if (api.checkParamCount(1))
581 //s=api.parString (ok,0); // selection
582 t=api.parString (ok,0); // path to map
583 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
584 addMapReplaceInt(selection->getSelectString(),t);
586 } else if (com==QString("addMapInsert"))
590 api.setError (Aborted,"Nothing selected");
591 } else if ( (typeid(*selection) != typeid(BranchObj) &&
592 typeid(*selection) != typeid(MapCenterObj)) )
594 api.setError (Aborted,"Type of selection is not a branch");
597 if (api.checkParamCount(2))
599 t=api.parString (ok,0); // path to map
600 y=api.parInt(ok,1); // position
601 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
602 addMapInsertInt(t,y);
605 } else if (com=="colorItem")
609 api.setError (Aborted,"Nothing selected");
610 } else if ( typeid(*selection) != typeid(BranchObj) &&
611 typeid(*selection) != typeid(MapCenterObj))
613 api.setError (Aborted,"Type of selection is not a branch");
614 } else if (api.checkParamCount(1))
616 QColor c=api.parColor (ok,0);
617 if (ok) colorItem (c);
619 } else if (com=="colorBranch")
623 api.setError (Aborted,"Nothing selected");
624 } else if ( typeid(*selection) != typeid(BranchObj) &&
625 typeid(*selection) != typeid(MapCenterObj))
627 api.setError (Aborted,"Type of selection is not a branch");
628 } else if (api.checkParamCount(1))
630 QColor c=api.parColor (ok,0);
631 if (ok) colorBranch (c);
633 } else if (com=="cut")
637 api.setError (Aborted,"Nothing selected");
638 } else if ( typeid(*selection) != typeid(BranchObj) &&
639 typeid(*selection) != typeid(MapCenterObj) &&
640 typeid(*selection) != typeid(FloatImageObj) )
642 api.setError (Aborted,"Type of selection is not a branch or floatimage");
643 } else if (api.checkParamCount(0))
647 } else if (com=="delete")
651 api.setError (Aborted,"Nothing selected");
652 } else if ( (typeid(*selection) != typeid(BranchObj) &&
653 typeid(*selection) != typeid(MapCenterObj)) )
655 api.setError (Aborted,"Type of selection is not a branch");
656 } else if (api.checkParamCount(0))
660 } else if (com=="deleteKeepChilds")
664 api.setError (Aborted,"Nothing selected");
665 } else if ( (typeid(*selection) != typeid(BranchObj) &&
666 typeid(*selection) != typeid(MapCenterObj)) )
668 api.setError (Aborted,"Type of selection is not a branch");
669 } else if (api.checkParamCount(0))
673 } else if (com=="deleteChilds")
677 api.setError (Aborted,"Nothing selected");
678 } else if ( (typeid(*selection) != typeid(BranchObj) &&
679 typeid(*selection) != typeid(MapCenterObj)) )
681 api.setError (Aborted,"Type of selection is not a branch");
682 } else if (api.checkParamCount(0))
686 } else if (com=="linkBranchToPos")
690 api.setError (Aborted,"Nothing selected");
691 } else if ( (typeid(*selection) != typeid(BranchObj) &&
692 typeid(*selection) != typeid(MapCenterObj)) )
694 api.setError (Aborted,"Type of selection is not a branch");
695 } else if (api.checkParamCount(4))
697 // 0 selectstring of parent
698 // 1 num in parent (for branches)
699 // 2,3 x,y of mainbranch or mapcenter
700 s=api.parString(ok,0);
701 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
704 if (typeid(*dst) == typeid(BranchObj) )
706 // Get number in parent
709 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),x);
710 } else if (typeid(*dst) == typeid(MapCenterObj) )
712 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),-1);
713 // Get coordinates of mainbranch
718 if (ok) ((BranchObj*)selection)->move (x,y);
723 } else if (com=="moveBranchUp")
727 api.setError (Aborted,"Nothing selected");
728 } else if ( (typeid(*selection) != typeid(BranchObj) &&
729 typeid(*selection) != typeid(MapCenterObj)) )
731 api.setError (Aborted,"Type of selection is not a branch");
732 } else if (api.checkParamCount(0))
736 } else if (com=="moveBranchDown")
740 api.setError (Aborted,"Nothing selected");
741 } else if ( (typeid(*selection) != typeid(BranchObj) &&
742 typeid(*selection) != typeid(MapCenterObj)) )
744 api.setError (Aborted,"Type of selection is not a branch");
745 } else if (api.checkParamCount(0))
749 } else if (com=="move")
753 api.setError (Aborted,"Nothing selected");
754 } else if ( typeid(*selection) != typeid(BranchObj) &&
755 typeid(*selection) != typeid(MapCenterObj) &&
756 typeid(*selection) != typeid(FloatImageObj) )
758 api.setError (Aborted,"Type of selection is not a branch or floatimage");
759 } else if (api.checkParamCount(2))
768 } else if (com=="moveRel")
772 api.setError (Aborted,"Nothing selected");
773 } else if ( typeid(*selection) != typeid(BranchObj) &&
774 typeid(*selection) != typeid(MapCenterObj) &&
775 typeid(*selection) != typeid(FloatImageObj) )
777 api.setError (Aborted,"Type of selection is not a branch or floatimage");
778 } else if (api.checkParamCount(2))
784 if (ok) moveRel (x,y);
787 } else if (com=="paste")
791 api.setError (Aborted,"Nothing selected");
792 } else if ( typeid(*selection) != typeid(BranchObj) &&
793 typeid(*selection) != typeid(MapCenterObj) )
795 api.setError (Aborted,"Type of selection is not a branch");
796 } else if (api.checkParamCount(0))
800 } else if (com=="select")
802 if (api.checkParamCount(1))
804 s=api.parString(ok,0);
807 } else if (com=="setMapAuthor")
809 if (api.checkParamCount(1))
811 s=api.parString(ok,0);
812 if (ok) setMapAuthor (s);
814 } else if (com=="setMapComment")
816 if (api.checkParamCount(1))
818 s=api.parString(ok,0);
819 if (ok) setMapComment(s);
821 } else if (com=="setMapBackgroundColor")
825 api.setError (Aborted,"Nothing selected");
826 } else if ( (typeid(*selection) != typeid(BranchObj) &&
827 typeid(*selection) != typeid(MapCenterObj)) )
829 api.setError (Aborted,"Type of selection is not a branch");
830 } else if (api.checkParamCount(1))
832 QColor c=api.parColor (ok,0);
833 if (ok) setMapBackgroundColor (c);
835 } else if (com=="setMapDefLinkColor")
839 api.setError (Aborted,"Nothing selected");
840 } else if ( (typeid(*selection) != typeid(BranchObj) &&
841 typeid(*selection) != typeid(MapCenterObj)) )
843 api.setError (Aborted,"Type of selection is not a branch");
844 } else if (api.checkParamCount(1))
846 QColor c=api.parColor (ok,0);
847 if (ok) setMapDefLinkColor (c);
849 } else if (com=="setMapLinkStyle")
851 if (api.checkParamCount(1))
853 s=api.parString (ok,0);
854 if (ok) setMapLinkStyle(s);
856 } else if (com=="setHeading")
860 api.setError (Aborted,"Nothing selected");
861 } else if ( (typeid(*selection) != typeid(BranchObj) &&
862 typeid(*selection) != typeid(MapCenterObj)) )
864 api.setError (Aborted,"Type of selection is not a branch");
865 } else if (api.checkParamCount(1))
867 s=api.parString (ok,0);
871 } else if (com=="setHideExport")
875 api.setError (Aborted,"Nothing selected");
876 } else if ( typeid(*selection) != typeid(BranchObj) &&
877 typeid(*selection) != typeid(FloatImageObj) )
879 api.setError (Aborted,"Type of selection is not a branch or floatimage");
880 } else if (api.checkParamCount(1))
883 if (ok) setHideExport (b);
885 } else if (com=="setURL")
889 api.setError (Aborted,"Nothing selected");
890 } else if ( (typeid(*selection) != typeid(BranchObj) &&
891 typeid(*selection) != typeid(MapCenterObj)) )
893 api.setError (Aborted,"Type of selection is not a branch");
894 } else if (api.checkParamCount(1))
896 s=api.parString (ok,0);
897 if (ok) setURLInt(s);
899 } else if (com=="setVymLink")
903 api.setError (Aborted,"Nothing selected");
904 } else if ( (typeid(*selection) != typeid(BranchObj) &&
905 typeid(*selection) != typeid(MapCenterObj)) )
907 api.setError (Aborted,"Type of selection is not a branch");
908 } else if (api.checkParamCount(1))
910 s=api.parString (ok,0);
911 if (ok) setVymLinkInt(s);
914 else if (com=="setFlag")
918 api.setError (Aborted,"Nothing selected");
919 } else if ( (typeid(*selection) != typeid(BranchObj) &&
920 typeid(*selection) != typeid(MapCenterObj)) )
922 api.setError (Aborted,"Type of selection is not a branch");
923 } else if (api.checkParamCount(1))
925 s=api.parString(ok,0);
928 BranchObj* bo=(BranchObj*)selection;
929 bo->activateStandardFlag(s);
930 bo->updateFlagsToolbar();
934 else if (com=="unsetFlag")
938 api.setError (Aborted,"Nothing selected");
939 } else if ( (typeid(*selection) != typeid(BranchObj) &&
940 typeid(*selection) != typeid(MapCenterObj)) )
942 api.setError (Aborted,"Type of selection is not a branch");
943 } else if (api.checkParamCount(1))
945 s=api.parString(ok,0);
948 BranchObj* bo=(BranchObj*)selection;
949 bo->deactivateStandardFlag(s);
950 bo->updateFlagsToolbar();
955 api.setError (Aborted,"Unknown command");
959 if (api.errorLevel()==NoError)
963 // TODO Error handling
964 qWarning("MapEditor::parseAtom: Error!");
965 qWarning(api.errorMessage());
970 bool MapEditor::isDefault()
975 bool MapEditor::isUnsaved()
980 bool MapEditor::hasChanged()
985 void MapEditor::setChanged()
993 void MapEditor::closeMap()
995 // Unselect before disabling the toolbar actions
996 if (selection) selection->unselect();
1004 void MapEditor::setFilePath(QString fname)
1006 setFilePath (fname,fname);
1009 void MapEditor::setFilePath(QString fname, QString destname)
1011 if (fname.isEmpty() || fname=="")
1018 filePath=fname; // becomes absolute path
1019 fileName=fname; // gets stripped of path
1020 destPath=destname; // needed for vymlinks
1022 // If fname is not an absolute path, complete it
1023 filePath=QDir(fname).absPath();
1024 fileDir=filePath.left (1+filePath.findRev ("/"));
1026 // Set short name, too. Search from behind:
1027 int i=fileName.findRev("/");
1028 if (i>=0) fileName=fileName.remove (0,i+1);
1030 // Forget the .vym (or .xml) for name of map
1031 mapName=fileName.left(fileName.findRev(".",-1,true) );
1035 QString MapEditor::getFilePath()
1040 QString MapEditor::getFileName()
1045 QString MapEditor::getMapName()
1050 QString MapEditor::getDestPath()
1055 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1057 ErrorCode err=success;
1061 if (selection) selection->unselect();
1064 mapCenter->setMapEditor(this);
1065 // (map state is set later at end of load...)
1068 if (!selection || (typeid(*selection) != typeid(BranchObj) &&
1069 typeid(*selection) != typeid (MapCenterObj)))
1071 BranchObj *bo=(BranchObj*)selection;
1072 if (lmode==ImportAdd)
1073 saveStateChangingPart(
1076 QString("addMapInsert (%1)").arg(fname),
1077 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1079 saveStateChangingPart(
1082 QString("addMapReplace(%1)").arg(fname),
1083 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1087 mapBuilderHandler handler;
1088 QFile file( fname );
1090 // I am paranoid: file should exist anyway
1091 // according to check in mainwindow.
1092 if (!file.exists() )
1094 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1095 tr("Couldn't open map " +fname)+".");
1099 blockReposition=true;
1100 QXmlInputSource source( file);
1101 QXmlSimpleReader reader;
1102 reader.setContentHandler( &handler );
1103 reader.setErrorHandler( &handler );
1104 handler.setMapEditor( this );
1105 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1106 handler.setInputFile (file.name());
1107 handler.setLoadMode (lmode);
1108 blockSaveState=true;
1109 bool ok = reader.parse( source );
1110 blockReposition=false;
1111 blockSaveState=false;
1115 mapCenter->reposition();
1125 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1126 tr( handler.errorProtocol() ) );
1128 // Still return "success": the map maybe at least
1129 // partially read by the parser
1136 int MapEditor::save (const SaveMode &savemode)
1140 // Create mapName and fileDir
1141 makeSubDirs (fileDir);
1145 fname=mapName+".xml";
1147 // use name given by user, even if he chooses .doc
1152 if (savemode==CompleteMap || selection==NULL)
1153 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1155 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),selection);
1157 if (!saveStringToDisk(fileDir+fname,saveFile))
1170 void MapEditor::setZipped (bool z)
1175 bool MapEditor::saveZipped ()
1180 void MapEditor::print()
1184 printer = new QPrinter;
1185 printer->setColorMode (QPrinter::Color);
1186 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1189 QRectF totalBBox=mapCenter->getTotalBBox();
1191 // Try to set orientation automagically
1192 // Note: Interpretation of generated postscript is amibiguous, if
1193 // there are problems with landscape mode, see
1194 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1196 if (totalBBox.width()>totalBBox.height())
1197 // recommend landscape
1198 printer->setOrientation (QPrinter::Landscape);
1200 // recommend portrait
1201 printer->setOrientation (QPrinter::Portrait);
1203 if ( printer->setup(this) )
1204 // returns false, if printing is canceled
1206 QPainter pp(printer);
1208 // Don't print the visualisation of selection
1209 LinkableMapObj *oldselection=NULL;
1212 oldselection=selection;
1213 selection->unselect();
1216 // Handle sizes of map and paper:
1218 // setWindow defines which part of the scene will be transformed
1219 // setViewport defines area on paper in device coordinates (dpi)
1220 // e.g. (0,50,700,700) is upper part on A4
1221 // see also /usr/lib/qt3/doc/html/coordsys.html
1223 Q3PaintDeviceMetrics metrics (printer);
1225 double paperAspect = (double)metrics.width() / (double)metrics.height();
1226 double mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
1228 QRectF mapRect=totalBBox;
1229 /* FIXME todo for QT4
1230 Q3CanvasRectangle *frame=NULL;
1231 Q3CanvasText *footerFN=NULL;
1232 Q3CanvasText *footerDate=NULL;
1233 if (printFrame || printFooter)
1238 // Print frame around map
1239 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1240 totalBBox.width()+20, totalBBox.height()+20);
1241 frame=new Q3CanvasRectangle (mapRect,mapScene);
1242 frame->setBrush (QColor(Qt::white));
1243 frame->setPen (QColor(Qt::black));
1247 // TODO remove after testing
1248 //QCanvasLine *l=new QCanvasLine (mapScene);
1249 //l->setPoints (0,0,mapRect.width(),mapRect.height());
1250 //l->setPen (QPen(QColor(black), 1));
1256 // Print footer below map
1258 font.setPointSize(10);
1259 footerFN=new Q3CanvasText (mapScene);
1260 footerFN->setText ("VYM - " + fileName);
1261 footerFN->setFont(font);
1262 footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
1263 footerFN->setZ(Z_TEXT);
1265 footerDate=new Q3CanvasText (mapScene);
1266 footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
1267 footerDate->setFont(font);
1268 footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
1269 footerDate->setZ(Z_TEXT);
1272 pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()+20);
1275 pp.setWindow (mapRect);
1279 if (mapAspect>=paperAspect)
1281 // Fit horizontally to paper width
1282 pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );
1285 // Fit vertically to paper height
1286 pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());
1289 mapScene->render(&pp); // draw scene to printer
1292 // Delete Frame and footer
1296 delete (footerDate);
1298 if (frame) delete (frame);
1301 // Restore selection
1304 selection=oldselection;
1305 selection->select();
1308 // Save settings in vymrc
1309 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1313 void MapEditor::setAntiAlias (bool b)
1315 setRenderHint(QPainter::Antialiasing,b);
1318 void MapEditor::setSmoothPixmap(bool b)
1320 setRenderHint(QPainter::SmoothPixmapTransform,b);
1323 QPixmap MapEditor::getPixmap()
1325 /* FIXME not ported yet to QT4
1326 QRectF mapRect=mapCenter->getTotalBBox();
1327 QPixmap pix (mapRect.size());
1330 // Don't print the visualisation of selection
1331 LinkableMapObj *oldselection=NULL;
1334 oldselection=selection;
1335 selection->unselect();
1338 pp.setWindow (mapRect);
1340 mapScene->drawArea(mapRect, &pp); // draw scene to painter
1343 // Restore selection
1346 selection=oldselection;
1347 selection->select();
1355 void MapEditor::setHideTmpMode (HideTmpMode mode)
1358 mapCenter->setHideTmp (hidemode);
1359 mapCenter->reposition();
1364 HideTmpMode MapEditor::getHideTmpMode()
1369 void MapEditor::exportImage(QString fn)
1371 setExportMode (true);
1372 QPixmap pix (getPixmap());
1373 pix.save(fn, "PNG");
1374 setExportMode (false);
1377 void MapEditor::setExportMode (bool b)
1379 // should be called before and after exports
1380 // depending on the settings
1381 if (b && settings.value("/export/useHideExport","yes")=="yes")
1382 setHideTmpMode (HideExport);
1384 setHideTmpMode (HideNone);
1387 void MapEditor::exportImage(QString fn, QString format)
1389 setExportMode (true);
1390 QPixmap pix (getPixmap());
1391 pix.save(fn, format);
1392 setExportMode (false);
1395 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1399 ex.setMapCenter(mapCenter);
1400 if (ex.setConfigFile(cf))
1402 setExportMode (true);
1403 ex.exportPresentation();
1404 setExportMode (false);
1410 void MapEditor::exportXML(const QString &dir)
1412 // Hide stuff during export, if settings want this
1413 setExportMode (true);
1415 // Create subdirectories
1418 // write to directory
1419 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1422 file.setName ( dir + "/"+mapName+".xml");
1423 if ( !file.open( QIODevice::WriteOnly ) )
1425 // This should neverever happen
1426 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1430 // Write it finally, and write in UTF8, no matter what
1431 QTextStream ts( &file );
1432 ts.setEncoding (QTextStream::UnicodeUTF8);
1436 // Now write image, too
1437 exportImage (dir+"/images/"+mapName+".png");
1439 setExportMode (false);
1442 void MapEditor::clear()
1446 selection->unselect();
1453 void MapEditor::copy()
1457 // write to directory
1458 QString clipfile="part";
1459 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPointF(),selection);
1462 file.setName ( clipboardDir + "/"+clipfile+".xml");
1463 if ( !file.open( QIODevice::WriteOnly ) )
1465 // This should neverever happen
1466 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1470 // Write it finally, and write in UTF8, no matter what
1471 QTextStream ts( &file );
1472 ts.setEncoding (QTextStream::UnicodeUTF8);
1476 clipboardEmpty=false;
1481 void MapEditor::redo()
1483 blockSaveState=true;
1485 // Restore variables
1486 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1487 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1488 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1489 // Can we undo at all?
1490 if (redosAvail<1) return;
1493 if (undosAvail<stepsTotal) undosAvail++;
1495 if (curStep>stepsTotal) curStep=1;
1496 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1497 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1498 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1499 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1500 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1501 QString version=undoSet.readEntry ("/history/version");
1503 if (!checkVersion(version))
1504 QMessageBox::warning(0,tr("Warning"),
1505 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1508 // Find out current undo directory
1509 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1511 /* TODO remove testing
1513 cout << "ME::redo() begin\n";
1514 cout << " undosAvail="<<undosAvail<<endl;
1515 cout << " redosAvail="<<redosAvail<<endl;
1516 cout << " curStep="<<curStep<<endl;
1517 cout << " ---------------------------"<<endl;
1518 cout << " comment="<<comment.toStdString()<<endl;
1519 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1520 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1521 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1522 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1523 cout << " ---------------------------"<<endl<<endl;
1525 // select object before redo
1526 if (!redoSelection.isEmpty())
1527 select (redoSelection);
1530 parseAtom (redoCommand);
1531 mapCenter->reposition();
1533 blockSaveState=false;
1535 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1536 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1537 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1538 undoSet.writeSettings(histPath);
1540 mainWindow->updateHistory (undoSet);
1543 /* TODO remove testing
1544 cout << "ME::redo() end\n";
1545 cout << " undosAvail="<<undosAvail<<endl;
1546 cout << " redosAvail="<<redosAvail<<endl;
1547 cout << " curStep="<<curStep<<endl;
1548 cout << " ---------------------------"<<endl<<endl;
1554 bool MapEditor::isRedoAvailable()
1556 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1562 void MapEditor::undo()
1564 blockSaveState=true;
1566 // Restore variables
1567 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1568 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1569 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1571 // Can we undo at all?
1572 if (undosAvail<1) return;
1574 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1575 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1576 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1577 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1578 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1579 QString version=undoSet.readEntry ("/history/version");
1581 if (!checkVersion(version))
1582 QMessageBox::warning(0,tr("Warning"),
1583 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1585 // Find out current undo directory
1586 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1588 // select object before undo
1589 if (!undoSelection.isEmpty())
1590 select (undoSelection);
1594 cout << "ME::undo() begin\n";
1595 cout << " undosAvail="<<undosAvail<<endl;
1596 cout << " redosAvail="<<redosAvail<<endl;
1597 cout << " curStep="<<curStep<<endl;
1598 cout << " ---------------------------"<<endl;
1599 cout << " comment="<<comment.toStdString()<<endl;
1600 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1601 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1602 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1603 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1604 cout << " ---------------------------"<<endl<<endl;
1605 parseAtom (undoCommand);
1606 mapCenter->reposition();
1610 if (curStep<1) curStep=stepsTotal;
1614 blockSaveState=false;
1615 /* TODO remove testing
1616 cout << "ME::undo() end\n";
1617 cout << " undosAvail="<<undosAvail<<endl;
1618 cout << " redosAvail="<<redosAvail<<endl;
1619 cout << " curStep="<<curStep<<endl;
1620 cout << " ---------------------------"<<endl<<endl;
1623 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1624 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1625 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1626 undoSet.writeSettings(histPath);
1628 mainWindow->updateHistory (undoSet);
1632 bool MapEditor::isUndoAvailable()
1634 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1640 void MapEditor::gotoHistoryStep (int i)
1642 // Restore variables
1643 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1644 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1646 if (i<0) i=undosAvail+redosAvail;
1648 // Clicking above current step makes us undo things
1651 for (int j=0; j<undosAvail-i; j++) undo();
1654 // Clicking below current step makes us redo things
1656 for (int j=undosAvail; j<i; j++) redo();
1658 // And ignore clicking the current row ;-)
1661 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1663 QString pathDir=path.left(path.findRev("/"));
1669 // We need to parse saved XML data
1670 mapBuilderHandler handler;
1671 QXmlInputSource source( file);
1672 QXmlSimpleReader reader;
1673 reader.setContentHandler( &handler );
1674 reader.setErrorHandler( &handler );
1675 handler.setMapEditor( this );
1676 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1677 if (undoSel.isEmpty())
1681 handler.setLoadMode (NewMap);
1685 handler.setLoadMode (ImportReplace);
1687 blockReposition=true;
1688 bool ok = reader.parse( source );
1689 blockReposition=false;
1692 // This should never ever happen
1693 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1694 handler.errorProtocol());
1697 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1700 void MapEditor::addMapInsertInt (const QString &path, int pos)
1702 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1703 typeid(*selection) == typeid(MapCenterObj)))
1705 QString pathDir=path.left(path.findRev("/"));
1711 // We need to parse saved XML data
1712 mapBuilderHandler handler;
1713 QXmlInputSource source( file);
1714 QXmlSimpleReader reader;
1715 reader.setContentHandler( &handler );
1716 reader.setErrorHandler( &handler );
1717 handler.setMapEditor( this );
1718 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1719 handler.setLoadMode (ImportAdd);
1720 blockReposition=true;
1721 bool ok = reader.parse( source );
1722 blockReposition=false;
1725 // This should never ever happen
1726 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1727 handler.errorProtocol());
1729 if (selection!=mapCenter)
1730 ((BranchObj*)selection)->getLastBranch()->moveBranchTo ((BranchObj*)(selection),pos);
1732 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1736 void MapEditor::pasteNoSave()
1738 load (clipboardDir+"/part.xml",ImportAdd);
1741 void MapEditor::cutNoSave()
1747 void MapEditor::paste()
1749 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1750 typeid(*selection) == typeid(MapCenterObj)))
1753 saveStateChangingPart(
1757 QString("Paste to %1").arg( getName(selection))
1759 mapCenter->reposition();
1764 void MapEditor::cut()
1766 saveStateChangingPart(
1767 selection->getParObj(),
1770 QString("Cut %1").arg(getName(selection))
1774 mapCenter->reposition();
1778 void MapEditor::move(const int &x, const int &y)
1782 QString ps=qpointfToString (selection->getAbsPos());
1783 QString s=selection->getSelectString();
1786 s, "move "+qpointfToString (QPointF (x,y)),
1787 QString("Move %1 to %2").arg(getName(selection)).arg(ps));
1788 selection->move(x,y);
1789 mapCenter->reposition();
1795 void MapEditor::moveRel (const int &x, const int &y)
1797 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1798 typeid(*selection) == typeid(MapCenterObj) ||
1799 typeid(*selection) == typeid (FloatImageObj)))
1801 QString ps=qpointfToString (selection->getRelPos());
1802 QString s=selection->getSelectString();
1805 s, "moveRel "+qpointfToString (QPointF (x,y)),
1806 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(ps));
1807 ((OrnamentedObj*)selection)->move2RelPos (x,y);
1808 mapCenter->reposition();
1813 void MapEditor::moveBranchUp()
1817 if (typeid(*selection) == typeid(BranchObj) )
1819 bo=(BranchObj*)selection;
1820 if (!bo->canMoveBranchUp()) return;
1821 par=(BranchObj*)(bo->getParObj());
1822 selection->unselect();
1823 bo=par->moveBranchUp (bo); // bo will be the one below selection
1824 selection->select();
1825 saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1826 mapCenter->reposition();
1827 ensureSelectionVisible();
1831 void MapEditor::moveBranchDown()
1835 if (typeid(*selection) == typeid(BranchObj) )
1837 bo=(BranchObj*)selection;
1838 if (!bo->canMoveBranchDown()) return;
1839 par=(BranchObj*)(bo->getParObj());
1840 selection->unselect();
1841 bo=par->moveBranchDown(bo); // bo will be the one above selection
1842 selection->select();
1843 saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1844 mapCenter->reposition();
1845 ensureSelectionVisible();
1849 QString MapEditor::getHeading(bool &ok, QPoint &p)
1852 (typeid(*selection) == typeid(BranchObj) ||
1853 typeid(*selection) == typeid(MapCenterObj) ) )
1856 ensureSelectionVisible();
1857 p=mapFromScene(selection->getAbsPos());
1858 return ((BranchObj*)selection)->getHeading();
1864 void MapEditor::setHeading(const QString &s)
1867 (typeid(*selection) == typeid(BranchObj) ||
1868 typeid(*selection) == typeid(MapCenterObj) ) )
1870 editingBO=(BranchObj*)selection;
1873 "setHeading (\""+editingBO->getHeading()+"\")",
1875 "setHeading (\""+s+"\")",
1876 QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(s) );
1877 editingBO->setHeading(s );
1879 mapCenter->reposition();
1881 ensureSelectionVisible();
1885 void MapEditor::setURLInt (const QString &s)
1887 // Internal function, no saveState needed
1889 (typeid(*selection) == typeid(BranchObj) ||
1890 typeid(*selection) == typeid(MapCenterObj) ) )
1892 ((BranchObj*)selection)->setURL(s);
1893 mapCenter->reposition();
1895 ensureSelectionVisible();
1899 void MapEditor::setHeadingInt(const QString &s)
1902 (typeid(*selection) == typeid(BranchObj) ||
1903 typeid(*selection) == typeid(MapCenterObj) ) )
1905 ((BranchObj*)selection)->setHeading(s);
1906 mapCenter->reposition();
1908 ensureSelectionVisible();
1912 void MapEditor::setVymLinkInt (const QString &s)
1914 // Internal function, no saveState needed
1916 (typeid(*selection) == typeid(BranchObj) ||
1917 typeid(*selection) == typeid(MapCenterObj) ) )
1919 ((BranchObj*)selection)->setVymLink(s);
1920 mapCenter->reposition();
1922 ensureSelectionVisible();
1926 BranchObj* MapEditor::addNewBranchInt(int num)
1928 // Depending on pos:
1929 // -3 insert in childs of parent above selection
1930 // -2 add branch to selection
1931 // -1 insert in childs of parent below selection
1932 // 0..n insert in childs of parent at pos
1933 BranchObj *newbo=NULL;
1935 (typeid(*selection) == typeid(BranchObj) ||
1936 typeid(*selection) == typeid(MapCenterObj) ) )
1938 BranchObj* bo = (BranchObj*) selection;
1941 // save scroll state. If scrolled, automatically select
1942 // new branch in order to tmp unscroll parent...
1943 return bo->addBranch();
1948 bo=(BranchObj*)bo->getParObj();
1952 bo=(BranchObj*)bo->getParObj();
1955 newbo=bo->insertBranch(num);
1960 BranchObj* MapEditor::addNewBranch(int pos)
1962 // Different meaning than num in addNewBranchInt!
1966 BranchObj *bo = (BranchObj*) selection;
1967 BranchObj *newbo=NULL;
1970 (typeid(*selection) == typeid(BranchObj) ||
1971 typeid(*selection) == typeid(MapCenterObj) ) )
1973 newbo=addNewBranchInt (pos-2);
1978 selection, // FIXME sholdnt newbo be deleted here???
1981 QString ("addBranch (%1)").arg(pos-2),
1982 QString ("Add new branch to %1").arg(getName(bo)));
1984 mapCenter->reposition();
1992 BranchObj* MapEditor::addNewBranchBefore()
1994 BranchObj *newbo=NULL;
1996 (typeid(*selection) == typeid(BranchObj) ) )
1997 // We accept no MapCenterObj here, so we _have_ a parent
1999 BranchObj* bo = (BranchObj*) selection;
2000 QPointF p=bo->getRelPos();
2003 BranchObj *parbo=(BranchObj*)(selection->getParObj());
2005 // add below selection
2006 newbo=parbo->insertBranch(bo->getNum()+1);
2009 newbo->move2RelPos (p);
2011 // Move selection to new branch
2012 ((BranchObj*)selection)->moveBranchTo (newbo,-1);
2014 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2015 QString ("Add branch before %1").arg(getName(bo)));
2017 mapCenter->reposition();
2024 void MapEditor::deleteSelection()
2026 if (selection && typeid(*selection) ==typeid(BranchObj) )
2028 BranchObj* bo=(BranchObj*)selection;
2029 BranchObj* par=(BranchObj*)(bo->getParObj());
2031 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2033 par->removeBranch(bo);
2035 selection->select();
2036 ensureSelectionVisible();
2037 mapCenter->reposition();
2040 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
2042 FloatImageObj* fio=(FloatImageObj*)selection;
2043 BranchObj* par=(BranchObj*)(fio->getParObj());
2044 saveStateChangingPart(
2048 QString("Delete %1").arg(getName(fio))
2052 par->removeFloatImage(fio);
2054 selection->select();
2055 ensureSelectionVisible();
2056 mapCenter->reposition();
2061 LinkableMapObj* MapEditor::getSelection()
2066 void MapEditor::unselect()
2070 selectionLast=selection;
2071 selection->unselect();
2076 void MapEditor::reselect()
2080 selection=selectionLast;
2081 selection->select();
2086 bool MapEditor::select (const QString &s)
2088 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2090 // Finally select the found object
2093 if (selection) unselect();
2095 selection->select();
2097 ensureSelectionVisible();
2103 QString MapEditor::getSelectString()
2105 if (selection) return selection->getSelectString();
2109 void MapEditor::selectInt (LinkableMapObj *lmo)
2111 if (lmo && selection != lmo)
2113 // select the MapObj
2114 if (selection) selection->unselect();
2116 selection->select();
2122 void MapEditor::selectNextBranchInt()
2124 // Increase number of branch
2127 QString s=selection->getSelectString();
2133 part=s.section(",",-1);
2135 num=part.right(part.length() - 3);
2137 s=s.left (s.length() -num.length());
2140 num=QString ("%1").arg(num.toUInt()+1);
2144 // Try to select this one
2145 if (select (s)) return;
2147 // We have no direct successor,
2148 // try to increase the parental number in order to
2149 // find a successor with same depth
2151 int d=selection->getDepth();
2156 while (!found && d>0)
2158 s=s.section (",",0,d-1);
2159 // replace substring of current depth in s with "1"
2160 part=s.section(",",-1);
2162 num=part.right(part.length() - 3);
2166 // increase number of parent
2167 num=QString ("%1").arg(num.toUInt()+1);
2168 s=s.section (",",0,d-2) + ","+ typ+num;
2171 // Special case, look at orientation
2172 if (selection->getOrientation()==OrientRightOfCenter)
2173 num=QString ("%1").arg(num.toUInt()+1);
2175 num=QString ("%1").arg(num.toUInt()-1);
2180 // pad to oldDepth, select the first branch for each depth
2181 for (i=d;i<oldDepth;i++)
2186 if ( ((BranchObj*)selection)->countBranches()>0)
2194 // try to select the freshly built string
2202 void MapEditor::selectPrevBranchInt()
2204 // Decrease number of branch
2207 QString s=selection->getSelectString();
2213 part=s.section(",",-1);
2215 num=part.right(part.length() - 3);
2217 s=s.left (s.length() -num.length());
2220 num=QString ("%1").arg(num.toUInt()-1);
2224 // Try to select this one
2225 if (select (s)) return;
2227 // We have no direct precessor,
2228 // try to decrease the parental number in order to
2229 // find a precessor with same depth
2231 int d=selection->getDepth();
2236 while (!found && d>0)
2238 s=s.section (",",0,d-1);
2239 // replace substring of current depth in s with "1"
2240 part=s.section(",",-1);
2242 num=part.right(part.length() - 3);
2246 // decrease number of parent
2247 num=QString ("%1").arg(num.toUInt()-1);
2248 s=s.section (",",0,d-2) + ","+ typ+num;
2251 // Special case, look at orientation
2252 if (selection->getOrientation()==OrientRightOfCenter)
2253 num=QString ("%1").arg(num.toUInt()-1);
2255 num=QString ("%1").arg(num.toUInt()+1);
2260 // pad to oldDepth, select the last branch for each depth
2261 for (i=d;i<oldDepth;i++)
2265 if ( ((BranchObj*)selection)->countBranches()>0)
2266 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
2273 // try to select the freshly built string
2281 void MapEditor::selectUpperBranch()
2285 if (typeid(*selection) == typeid(BranchObj))
2287 if (selection->getOrientation()==OrientRightOfCenter)
2288 selectPrevBranchInt();
2290 if (selection->getDepth()==1)
2291 selectNextBranchInt();
2293 selectPrevBranchInt();
2298 void MapEditor::selectLowerBranch()
2302 if (typeid(*selection) == typeid(BranchObj))
2304 if (selection->getOrientation()==OrientRightOfCenter)
2305 selectNextBranchInt();
2307 if (selection->getDepth()==1)
2308 selectPrevBranchInt();
2310 selectNextBranchInt();
2316 void MapEditor::selectLeftBranch()
2322 if (typeid(*selection) == typeid(MapCenterObj))
2324 par= (BranchObj*) selection;
2325 bo=par->getLastSelectedBranch();
2328 // Workaround for reselecting on left and right side
2329 if (bo->getOrientation()==OrientRightOfCenter)
2331 bo=par->getLastBranch();
2337 selection->select();
2339 ensureSelectionVisible();
2344 par=(BranchObj*)(selection->getParObj());
2345 if (selection->getOrientation()==OrientRightOfCenter)
2347 if (typeid(*selection) == typeid(BranchObj) ||
2348 typeid(*selection) == typeid(FloatImageObj))
2350 selection->unselect();
2352 selection->select();
2354 ensureSelectionVisible();
2358 if (typeid(*selection) == typeid(BranchObj) )
2360 bo=((BranchObj*)selection)->getLastSelectedBranch();
2363 selection->unselect();
2365 selection->select();
2367 ensureSelectionVisible();
2375 void MapEditor::selectRightBranch()
2382 if (typeid(*selection) == typeid(MapCenterObj))
2384 par= (BranchObj*) selection;
2385 bo=par->getLastSelectedBranch();
2388 // Workaround for reselecting on left and right side
2389 if (bo->getOrientation()==OrientLeftOfCenter)
2390 bo=par->getFirstBranch();
2395 selection->select();
2396 ensureSelectionVisible();
2401 par=(BranchObj*)(selection->getParObj());
2402 if (selection->getOrientation()==OrientLeftOfCenter)
2404 if (typeid(*selection) == typeid(BranchObj) ||
2405 typeid(*selection) == typeid(FloatImageObj))
2407 selection->unselect();
2409 selection->select();
2411 ensureSelectionVisible();
2415 if (typeid(*selection) == typeid(BranchObj) )
2417 bo=((BranchObj*)selection)->getLastSelectedBranch();
2420 selection->unselect();
2422 selection->select();
2424 ensureSelectionVisible();
2432 void MapEditor::selectFirstBranch()
2438 if (typeid(*selection) == typeid(BranchObj))
2440 bo1= (BranchObj*) selection;
2441 par=(BranchObj*)(bo1->getParObj());
2442 bo2=par->getFirstBranch();
2446 selection->select();
2447 ensureSelectionVisible();
2454 void MapEditor::selectLastBranch()
2460 if (typeid(*selection) == typeid(BranchObj))
2462 bo1= (BranchObj*) selection;
2463 par=(BranchObj*)(bo1->getParObj());
2464 bo2=par->getLastBranch();
2468 selection->select();
2469 ensureSelectionVisible();
2476 void MapEditor::selectMapBackgroundImage ()
2478 Q3FileDialog *fd=new Q3FileDialog( this);
2479 fd->setMode (Q3FileDialog::ExistingFile);
2480 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2481 ImagePreview *p =new ImagePreview (fd);
2482 fd->setContentsPreviewEnabled( TRUE );
2483 fd->setContentsPreview( p, p );
2484 fd->setPreviewMode( Q3FileDialog::Contents );
2485 fd->setCaption(vymName+" - " +tr("Load background image"));
2486 fd->setDir (lastImageDir);
2489 if ( fd->exec() == QDialog::Accepted )
2491 // FIXME in QT4 use: lastImageDir=fd->directory();
2492 lastImageDir=QDir (fd->dirPath());
2493 setMapBackgroundImage (fd->selectedFile());
2497 void MapEditor::setMapBackgroundImage (const QString &fn)
2499 QColor oldcol=mapScene->backgroundBrush().color();
2503 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2505 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2506 QString("Set background color of map to %1").arg(col.name()));
2508 cout << "Trying to load "<<fn.ascii()<<endl;
2510 brush.setTextureImage (QPixmap (fn));
2511 mapScene->setBackgroundBrush(brush);
2514 void MapEditor::selectMapBackgroundColor()
2516 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2517 if ( !col.isValid() ) return;
2518 setMapBackgroundColor( col );
2522 void MapEditor::setMapBackgroundColor(QColor col)
2524 QColor oldcol=mapScene->backgroundBrush().color();
2527 QString ("setMapBackgroundColor (%1)").arg(oldcol.name()),
2529 QString ("setMapBackgroundColor (%1)").arg(col.name()),
2530 QString("Set background color of map to %1").arg(col.name()));
2531 mapScene->setBackgroundBrush(col);
2534 QColor MapEditor::getMapBackgroundColor()
2536 return mapScene->backgroundBrush().color();
2539 QColor MapEditor::getCurrentHeadingColor()
2543 if (typeid(*selection) == typeid(BranchObj) ||
2544 typeid(*selection) == typeid(MapCenterObj))
2546 BranchObj *bo=(BranchObj*)selection;
2547 return bo->getColor();
2551 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2555 void MapEditor::colorItem(QColor c)
2559 if (typeid(*selection) == typeid(BranchObj) ||
2560 typeid(*selection) == typeid(MapCenterObj))
2562 BranchObj *bo=(BranchObj*)selection;
2565 QString ("colorItem (%1)").arg(bo->getColor().name()),
2567 QString ("colorItem (%1)").arg(c.name()),
2568 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2570 bo->setColor(c); // color branch
2575 void MapEditor::colorBranch(QColor c)
2579 if (typeid(*selection) == typeid(BranchObj) ||
2580 typeid(*selection) == typeid(MapCenterObj))
2582 BranchObj *bo=(BranchObj*)selection;
2583 saveStateChangingPart(
2586 QString ("colorBranch (%1)").arg(c.name()),
2587 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2589 bo->setColorChilds(c); // color links, color childs
2595 void MapEditor::toggleStandardFlag(QString f)
2599 if (typeid(*selection) == typeid(BranchObj) ||
2600 typeid(*selection) == typeid(MapCenterObj))
2602 BranchObj *bo=(BranchObj*)selection;
2604 if (bo->isSetStandardFlag(f))
2616 QString("%1 (\"%2\")").arg(u).arg(f),
2618 QString("%1 (\"%2\")").arg(r).arg(f),
2619 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2620 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2626 void MapEditor::setViewCenter()
2628 // transform to sceneView Coord:
2629 QPointF p=matrix().map(movingCenter);
2630 //FIXME not ported yet to QT4 (center ist TextStream there)
2631 //center ( p.x(), p.y());
2635 BranchObj* MapEditor::findText (QString s, bool cs)
2637 QTextDocument::FindFlags flags=0;
2638 if (cs) flags=QTextDocument::FindCaseSensitively;
2641 { // Nothing found or new find process
2643 // nothing found, start again
2645 itFind=mapCenter->first();
2647 bool searching=true;
2648 bool foundNote=false;
2649 while (searching && !EOFind)
2653 // Searching in Note
2654 if (itFind->getNote().contains(s,cs))
2656 if (selection!=itFind)
2658 if (selection) ((BranchObj*)selection)->unselect();
2660 selection->select();
2662 ensureSelectionVisible();
2664 if (textEditor->findText(s,flags))
2670 // Searching in Heading
2671 if (searching && itFind->getHeading().contains (s,cs) )
2673 if (selection) ((BranchObj*)selection)->unselect();
2675 selection->select();
2677 ensureSelectionVisible();
2683 itFind=itFind->next();
2684 if (!itFind) EOFind=true;
2690 return (BranchObj*)selection;
2695 void MapEditor::findReset()
2696 { // Necessary if text to find changes during a find process
2700 void MapEditor::setURL(const QString &url)
2702 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2703 typeid(*selection) == typeid(MapCenterObj)) )
2705 BranchObj *bo=(BranchObj*)selection;
2706 QString oldurl=bo->getURL();
2710 QString ("setURL (\"%1\")").arg(oldurl),
2712 QString ("setURL (\"%1\")").arg(url),
2713 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2719 void MapEditor::editURL()
2721 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2722 typeid(*selection) == typeid(MapCenterObj)) )
2725 BranchObj *bo=(BranchObj*)selection;
2726 QString text = QInputDialog::getText(
2727 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2728 bo->getURL(), &ok, this );
2730 // user entered something and pressed OK
2735 QString MapEditor::getURL()
2737 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2738 typeid(*selection) == typeid(MapCenterObj)) )
2739 return ((BranchObj*)selection)->getURL();
2744 QStringList MapEditor::getURLs()
2747 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2748 typeid(*selection) == typeid(MapCenterObj)) )
2750 BranchObj *bo=(BranchObj*)selection;
2754 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2762 void MapEditor::editHeading2URL()
2764 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2765 typeid(*selection) == typeid(MapCenterObj)) )
2766 setURL (((BranchObj*)selection)->getHeading());
2769 void MapEditor::editBugzilla2URL()
2771 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2772 typeid(*selection) == typeid(MapCenterObj)) )
2774 BranchObj *bo=(BranchObj*)selection;
2775 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2780 void MapEditor::editFATE2URL()
2782 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2783 typeid(*selection) == typeid(MapCenterObj)) )
2785 BranchObj *bo=(BranchObj*)selection;
2786 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2789 "setURL (\""+bo->getURL()+"\")",
2791 "setURL (\""+url+"\")",
2792 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2799 void MapEditor::editVymLink()
2801 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2802 typeid(*selection) == typeid(MapCenterObj)) )
2804 BranchObj *bo=(BranchObj*)selection;
2805 QStringList filters;
2806 filters <<"VYM map (*.vym)";
2807 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2808 fd->setFilters (filters);
2809 fd->setCaption(vymName+" - " +tr("Link to another map"));
2810 if (! bo->getVymLink().isEmpty() )
2811 fd->selectFile( bo->getVymLink() );
2815 if ( fd->exec() == QDialog::Accepted )
2819 "setVymLink (\""+bo->getVymLink()+"\")",
2821 "setVymLink (\""+fd->selectedFile()+"\")",
2822 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2824 bo->setVymLink (fd->selectedFile() );
2826 mapCenter->reposition();
2833 void MapEditor::deleteVymLink()
2835 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2836 typeid(*selection) == typeid(MapCenterObj)) )
2838 BranchObj *bo=(BranchObj*)selection;
2841 "setVymLink (\""+bo->getVymLink()+"\")",
2843 "setVymLink (\"\")",
2844 QString("Unset vymlink of %1").arg(getName(bo))
2846 bo->setVymLink ("" );
2848 mapCenter->reposition();
2854 void MapEditor::setHideExport(bool b)
2856 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2857 typeid(*selection)==typeid(FloatImageObj)))
2859 OrnamentedObj *oo=(OrnamentedObj*)selection;
2860 oo->setHideInExport (b);
2861 QString u= b ? "false" : "true";
2862 QString r=!b ? "false" : "true";
2866 QString ("setHideExport (%1)").arg(u),
2868 QString ("setHideExport (%1)").arg(r),
2869 QString ("Set HideExport flag of %1 to %2").arg(getName(oo)).arg (r)
2872 mapCenter->reposition();
2878 void MapEditor::toggleHideExport()
2880 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2881 typeid(*selection)==typeid(FloatImageObj)))
2882 setHideExport ( !((OrnamentedObj*)selection)->hideInExport() );
2885 QString MapEditor::getVymLink()
2887 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2888 typeid(*selection) == typeid(MapCenterObj)) )
2890 return ((BranchObj*)selection)->getVymLink();
2896 QStringList MapEditor::getVymLinks()
2899 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2900 typeid(*selection) == typeid(MapCenterObj)) )
2902 BranchObj *bo=(BranchObj*)selection;
2906 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2914 void MapEditor::deleteKeepChilds()
2916 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2918 BranchObj* bo=(BranchObj*)selection;
2919 BranchObj* par=(BranchObj*)(bo->getParObj());
2920 QPointF p=bo->getRelPos();
2921 saveStateChangingPart(
2922 selection->getParObj(),
2924 "deleteKeepChilds ()",
2925 QString("Remove %1 and keep its childs").arg(getName(bo))
2928 QString sel=selection->getSelectString();
2930 par->removeBranchHere(bo);
2931 mapCenter->reposition();
2933 ((BranchObj*)selection)->move2RelPos (p);
2934 mapCenter->reposition();
2939 void MapEditor::deleteChilds()
2941 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2942 typeid(*selection)==typeid(MapCenterObj)))
2944 saveStateChangingPart(
2945 selection->getParObj(),
2948 QString( "Remove childs of branch %1").arg(getName(selection))
2950 ((BranchObj*)selection)->removeChilds();
2951 mapCenter->reposition();
2955 void MapEditor::editMapInfo()
2957 ExtraInfoDialog dia;
2958 dia.setMapName (getFileName() );
2959 dia.setAuthor (mapCenter->getAuthor() );
2960 dia.setComment(mapCenter->getComment() );
2964 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
2971 bo=mapCenter->first();
2974 if (!bo->getNote().isEmpty() ) n++;
2975 f+= bo->countFloatImages();
2977 xl+=bo->countXLinks();
2980 stats+=QString ("%1 branches\n").arg (b-1,6);
2981 stats+=QString ("%1 xLinks \n").arg (xl,6);
2982 stats+=QString ("%1 notes\n").arg (n,6);
2983 stats+=QString ("%1 images\n").arg (f,6);
2984 dia.setStats (stats);
2986 // Finally show dialog
2987 if (dia.exec() == QDialog::Accepted)
2989 setMapAuthor (dia.getAuthor() );
2990 setMapComment (dia.getComment() );
2994 void MapEditor::updateActions()
2996 mainWindow->updateActions();
2997 // FIXME maybe don't update if blockReposition is set
3000 void MapEditor::updateNoteFlag()
3003 if ( (typeid(*selection) == typeid(BranchObj)) ||
3004 (typeid(*selection) == typeid(MapCenterObj)) )
3005 ((BranchObj*)selection)->updateNoteFlag();
3008 void MapEditor::setMapAuthor (const QString &s)
3012 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3014 QString ("setMapAuthor (\"%1\")").arg(s),
3015 QString ("Set author of map to \"%1\"").arg(s)
3017 mapCenter->setAuthor (s);
3020 void MapEditor::setMapComment (const QString &s)
3024 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3026 QString ("setMapComment (\"%1\")").arg(s),
3027 QString ("Set comment of map")
3029 mapCenter->setComment (s);
3032 void MapEditor::setMapLinkStyle (const QString & s)
3034 saveStateChangingPart (
3037 QString("setMapLinkStyle (\"%1\")").arg(s),
3038 QString("Set map link style (\"%1\")").arg(s)
3042 linkstyle=StyleLine;
3043 else if (s=="StyleParabel")
3044 linkstyle=StyleParabel;
3045 else if (s=="StylePolyLine")
3046 linkstyle=StylePolyLine;
3048 linkstyle=StylePolyParabel;
3051 bo=mapCenter->first();
3055 bo->setLinkStyle(bo->getDefLinkStyle());
3058 mapCenter->reposition();
3061 LinkStyle MapEditor::getMapLinkStyle ()
3066 void MapEditor::setMapDefLinkColor(QColor c)
3072 void MapEditor::setMapLinkColorHintInt()
3074 // called from setMapLinkColorHint(lch) or at end of parse
3076 bo=mapCenter->first();
3084 void MapEditor::setMapLinkColorHint(LinkColorHint lch)
3087 setMapLinkColorHintInt();
3090 void MapEditor::toggleMapLinkColorHint()
3092 if (linkcolorhint==HeadingColor)
3093 linkcolorhint=DefaultColor;
3095 linkcolorhint=HeadingColor;
3097 bo=mapCenter->first();
3105 LinkColorHint MapEditor::getMapLinkColorHint()
3107 return linkcolorhint;
3110 QColor MapEditor::getMapDefLinkColor()
3112 return defLinkColor;
3115 void MapEditor::setMapDefXLinkColor(QColor col)
3120 QColor MapEditor::getMapDefXLinkColor()
3122 return defXLinkColor;
3125 void MapEditor::setMapDefXLinkWidth (int w)
3130 int MapEditor::getMapDefXLinkWidth()
3132 return defXLinkWidth;
3135 void MapEditor::selectMapLinkColor()
3137 QColor col = QColorDialog::getColor( defLinkColor, this );
3138 if ( !col.isValid() ) return;
3141 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3143 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3144 QString("Set link color to %1").arg(col.name())
3146 setMapDefLinkColor( col );
3150 void MapEditor::toggleScroll()
3152 if (selection && (typeid(*selection) == typeid(BranchObj)) )
3154 BranchObj *bo=((BranchObj*)selection);
3155 if (bo->countBranches()==0) return;
3156 if (bo->getDepth()==0) return;
3158 if (bo->isScrolled())
3170 QString ("%1 ()").arg(u),
3172 QString ("%1 ()").arg(r),
3173 QString ("%1 %2").arg(r).arg(getName(bo))
3181 void MapEditor::unScrollAll()
3184 bo=mapCenter->first();
3187 if (bo->isScrolled()) bo->toggleScroll();
3192 void MapEditor::loadFloatImage ()
3195 (typeid(*selection) == typeid(BranchObj)) ||
3196 (typeid(*selection) == typeid(MapCenterObj)) )
3198 BranchObj *bo=((BranchObj*)selection);
3200 Q3FileDialog *fd=new Q3FileDialog( this);
3201 fd->setMode (Q3FileDialog::ExistingFiles);
3202 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3203 ImagePreview *p =new ImagePreview (fd);
3204 fd->setContentsPreviewEnabled( TRUE );
3205 fd->setContentsPreview( p, p );
3206 fd->setPreviewMode( Q3FileDialog::Contents );
3207 fd->setCaption(vymName+" - " +tr("Load image"));
3208 fd->setDir (lastImageDir);
3212 if ( fd->exec() == QDialog::Accepted )
3214 // FIXME in QT4 use: lastImageDir=fd->directory();
3215 lastImageDir=QDir (fd->dirPath());
3216 QStringList flist = fd->selectedFiles();
3217 QStringList::Iterator it = flist.begin();
3219 while( it != flist.end() )
3222 bo->addFloatImage();
3223 fio=bo->getLastFloatImage();
3225 // FIXME check if load of fio was successful
3227 (LinkableMapObj*)fio,
3230 QString ("loadFloatImage (%1)").arg(*it),
3231 QString("Add floatimage %1 to %2").arg(*it).arg(getName(selection))
3233 bo->getLastFloatImage()->setOriginalFilename(fn);
3237 mapCenter->reposition();
3246 void MapEditor::saveFloatImage ()
3249 (typeid(*selection) == typeid(FloatImageObj)) )
3251 FloatImageObj *fio=((FloatImageObj*)selection);
3252 QFileDialog *fd=new QFileDialog( this);
3253 fd->setFilters (imageIO.getFilters());
3254 fd->setCaption(vymName+" - " +tr("Save image"));
3255 fd->setFileMode( QFileDialog::AnyFile );
3256 fd->setDirectory (lastImageDir);
3257 // fd->setSelection (fio->getOriginalFilename());
3261 if ( fd->exec() == QDialog::Accepted )
3263 if (QFile (fd->selectedFile()).exists() )
3265 QMessageBox mb( vymName,
3266 tr("The file %1 exists already.\n"
3267 "Do you want to overwrite it?").arg(fd->selectedFile()),
3268 QMessageBox::Warning,
3269 QMessageBox::Yes | QMessageBox::Default,
3270 QMessageBox::Cancel | QMessageBox::Escape,
3271 QMessageBox::QMessageBox::NoButton );
3273 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3274 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3277 case QMessageBox::Yes:
3280 case QMessageBox::Cancel:
3287 fio->save (fd->selectedFile(),imageIO.getType (fd->selectedFilter() ) );
3293 void MapEditor::setFrame(const FrameType &t)
3296 (typeid(*selection) == typeid(BranchObj)) ||
3297 (typeid(*selection) == typeid(MapCenterObj)) )
3299 selection->setFrameType (t);
3300 mapCenter->reposition();
3301 selection->updateLink();
3305 void MapEditor::setIncludeImagesVer(bool b)
3308 (typeid(*selection) == typeid(BranchObj)) ||
3309 (typeid(*selection) == typeid(MapCenterObj)) )
3310 ((BranchObj*)selection)->setIncludeImagesVer(b);
3311 mapCenter->reposition();
3314 void MapEditor::setIncludeImagesHor(bool b)
3317 (typeid(*selection) == typeid(BranchObj)) ||
3318 (typeid(*selection) == typeid(MapCenterObj)) )
3319 ((BranchObj*)selection)->setIncludeImagesHor(b);
3320 mapCenter->reposition();
3323 void MapEditor::setHideLinkUnselected (bool b)
3326 (typeid(*selection) == typeid(BranchObj)) ||
3327 (typeid(*selection) == typeid(MapCenterObj)) ||
3328 (typeid(*selection) == typeid(FloatImageObj)) )
3329 selection->setHideLinkUnselected(b);
3332 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3335 (typeid(*selection) == typeid(BranchObj)) ||
3336 (typeid(*selection) == typeid(MapCenterObj)) )
3340 // Traverse directories
3341 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3342 QFileInfoList list = d.entryInfoList();
3345 for (int i = 0; i < list.size(); ++i)
3348 if (fi.fileName() != "." && fi.fileName() != ".." )
3351 bo=dst->getLastBranch();
3352 bo->setHeading (fi.fileName() );
3353 bo->setColor (QColor("blue"));
3355 if ( !d.cd(fi.fileName()) )
3356 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3359 // Recursively add subdirs
3360 importDirInt (bo,d);
3366 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3367 list = d.entryInfoList();
3369 for (int i = 0; i < list.size(); ++i)
3373 bo=dst->getLastBranch();
3374 bo->setHeading (fi.fileName() );
3375 bo->setColor (QColor("black"));
3376 if (fi.fileName().right(4) == ".vym" )
3377 bo->setVymLink (fi.filePath());
3382 void MapEditor::importDir()
3385 (typeid(*selection) == typeid(BranchObj)) ||
3386 (typeid(*selection) == typeid(MapCenterObj)) )
3388 QStringList filters;
3389 filters <<"VYM map (*.vym)";
3390 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3391 fd->setMode (QFileDialog::DirectoryOnly);
3392 fd->setFilters (filters);
3393 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3397 if ( fd->exec() == QDialog::Accepted )
3399 BranchObj *bo=((BranchObj*)selection);
3400 importDirInt (bo,QDir(fd->selectedFile()) );
3401 mapCenter->reposition();
3408 void MapEditor::followXLink(int i)
3411 (typeid(*selection) == typeid(BranchObj)) ||
3412 (typeid(*selection) == typeid(MapCenterObj)) )
3414 BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
3417 selection->unselect();
3419 selection->select();
3420 ensureSelectionVisible();
3425 void MapEditor::editXLink(int i)
3428 (typeid(*selection) == typeid(BranchObj)) ||
3429 (typeid(*selection) == typeid(MapCenterObj)) )
3431 XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
3434 EditXLinkDialog dia;
3436 dia.setSelection(selection);
3437 if (dia.exec() == QDialog::Accepted)
3439 if (dia.useSettingsGlobal() )
3441 setMapDefXLinkColor (xlo->getColor() );
3442 setMapDefXLinkWidth (xlo->getWidth() );
3444 if (dia.deleteXLink())
3445 ((BranchObj*)selection)->deleteXLinkAt(i);
3446 //saveStateComplete("Edit xLink"); //FIXME undoCommand
3452 void MapEditor::testFunction()
3455 dia.showCancelButton (true);
3456 dia.setText("This is a longer \nWarning");
3458 dia.setCaption("Warning: Flux problem");
3459 dia.setShowAgainName("/warnings/mapeditor");
3461 if (dia.exec()==QDialog::Accepted)
3462 cout << "accepted!\n";
3464 cout << "canceled!\n";
3467 /* Hide hidden stuff temporary, maybe add this as regular function somewhere
3468 if (hidemode==HideNone)
3470 setHideTmpMode (HideExport);
3471 mapCenter->calcBBoxSizeWithChilds();
3472 QRectF totalBBox=mapCenter->getTotalBBox();
3473 QRectF mapRect=totalBBox;
3474 QCanvasRectangle *frame=NULL;
3476 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3478 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3479 totalBBox.width(), totalBBox.height());
3480 frame=new QCanvasRectangle (mapRect,mapScene);
3481 frame->setBrush (QColor(white));
3482 frame->setPen (QColor(black));
3483 frame->setZValue(0);
3488 setHideTmpMode (HideNone);
3490 cout <<" hidemode="<<hidemode<<endl;
3494 void MapEditor::ensureSelectionVisible()
3498 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
3500 if (selection->getOrientation() == OrientLeftOfCenter)
3501 p= matrix().map(QPointF (lmo->x(),lmo->y()));
3503 p= matrix().map(QPointF (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
3504 ensureVisible (QRectF(p.x(), p.y(),0,0 ));
3510 void MapEditor::updateViewCenter()
3512 /* FIXME still to port to QT4 inverseworldmatrix
3513 // Update movingCenter, so that we can zoom comfortably later
3514 QRectF rc = QRectF( contentsX(), contentsY(),
3515 visibleWidth(), visibleHeight() );
3516 QRectF canvasRect = inverseWorldMatrix().mapRect(rc);
3517 movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
3518 movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
3522 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
3524 // Lineedits are already closed by preceding
3525 // mouseEvent, we don't need to close here.
3527 QPointF p = mapToScene(e->pos());
3528 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3531 { // MapObj was found
3532 if (selection != lmo)
3534 // select the MapObj
3535 if (selection) selection->unselect();
3537 selection->select();
3543 if (typeid(*selection)==typeid(BranchObj) ||
3544 typeid(*selection)==typeid(MapCenterObj) )
3546 // Context Menu on branch or mapcenter
3548 branchContextMenu->popup(e->globalPos() );
3550 if (typeid(*selection)==typeid(FloatImageObj))
3552 // Context Menu on floatimage
3554 floatimageContextMenu->popup(e->globalPos() );
3558 { // No MapObj found, we are on the Canvas itself
3559 // Context Menu on scene
3561 canvasContextMenu->popup(e->globalPos() );
3566 void MapEditor::keyPressEvent(QKeyEvent* e)
3568 if (e->modifiers() && Qt::ControlModifier)
3570 switch (mainWindow->getModMode())
3573 setCursor (PickColorCursor);
3576 setCursor (CopyCursor);
3579 setCursor (XLinkCursor);
3582 setCursor (Qt::ArrowCursor);
3588 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3590 if (!(e->modifiers() && Qt::ControlModifier))
3591 setCursor (Qt::ArrowCursor);
3594 void MapEditor::mousePressEvent(QMouseEvent* e)
3596 // Ignore right clicks, these will go to context menus
3597 if (e->button() == Qt::RightButton )
3603 QPointF p = mapToScene(e->pos());
3604 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3608 //Take care of clickdesystem flags _or_ modifier modes
3610 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3611 typeid(*lmo)==typeid(MapCenterObj) ))
3613 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3614 if (!foname.isEmpty())
3616 // systemFlag clicked
3620 if (e->state() & Qt::ControlModifier)
3621 mainWindow->editOpenURLTab();
3623 mainWindow->editOpenURL();
3625 else if (foname=="vymLink")
3627 mainWindow->editOpenVymLink();
3628 // tabWidget may change, better return now
3629 // before segfaulting...
3630 } else if (foname=="note")
3631 mainWindow->windowToggleNoteEditor();
3632 else if (foname=="hideInExport")
3637 // No system flag clicked, take care of modmodes
3639 // Special case: CTRL is pressed
3640 if (e->state() & Qt::ControlModifier)
3642 if (mainWindow->getModMode()==ModModeColor)
3645 setCursor (PickColorCursor);
3648 if (mainWindow->getModMode()==ModModeXLink)
3650 BranchObj *bo_begin=NULL;
3652 bo_begin=(BranchObj*)(lmo);
3655 ((typeid(*selection) == typeid(BranchObj)) ||
3656 (typeid(*selection) == typeid(MapCenterObj))) )
3657 bo_begin=(BranchObj*)selection;
3661 linkingObj_src=bo_begin;
3662 tmpXLink=new XLinkObj (mapScene);
3663 tmpXLink->setBegin (bo_begin);
3664 tmpXLink->setEnd (p);
3665 tmpXLink->setColor(defXLinkColor);
3666 tmpXLink->setWidth(defXLinkWidth);
3667 tmpXLink->updateXLink();
3668 tmpXLink->setVisibility (true);
3676 // Left Button Move Branches
3677 if (e->button() == Qt::LeftButton )
3679 movingObj_start.setX( p.x() - selection->x() );
3680 movingObj_start.setY( p.y() - selection->y() );
3681 movingObj_orgPos.setX (lmo->x() );
3682 movingObj_orgPos.setY (lmo->y() );
3683 movingObj_orgRelPos=lmo->getRelPos();
3685 // If modMode==copy, then we want to "move" the _new_ object around
3686 // then we need the offset from p to the _old_ selection, because of tmp
3687 if (mainWindow->getModMode()==ModModeCopy &&
3688 e->state() & Qt::ControlModifier)
3690 if (typeid(*selection)==typeid(BranchObj) )
3693 mapCenter->addBranch ((BranchObj*)selection);
3695 selection=mapCenter->getLastBranch();
3696 selection->select();
3697 mapCenter->reposition();
3700 movingObj=selection;
3702 // Middle Button Toggle Scroll
3703 // (On Mac OS X this won't work, but we still have
3704 // a button in the toolbar)
3705 if (e->button() == Qt::MidButton )
3709 { // No MapObj found, we are on the scene itself
3710 // Left Button move Pos of sceneView
3711 if (e->button() == Qt::LeftButton )
3713 movingObj=NULL; // move Content not Obj
3714 movingObj_start=e->globalPos();
3715 // FIXME not ported to QT4 yet (move canvasView)
3716 //movingCont_start=QPointF (contentsX(), contentsY() );
3717 movingCont_start=QPointF (
3718 horizontalScrollBar()->value(),
3719 verticalScrollBar()->value());
3720 movingVec=QPointF(0,0);
3721 setCursor(HandOpenCursor);
3726 void MapEditor::mouseMoveEvent(QMouseEvent* e)
3728 QPointF p = mapToScene(e->pos());
3730 // Move the selected MapObj
3731 if ( selection && movingObj)
3733 // To avoid jumping of the sceneView, only
3734 // ensureSelectionVisible, if not tmp linked
3735 if (!selection->hasParObjTmp())
3736 ensureSelectionVisible ();
3738 // Now move the selection, but add relative position
3739 // (movingObj_start) where selection was chosen with
3740 // mousepointer. (This avoids flickering resp. jumping
3741 // of selection back to absPos)
3743 LinkableMapObj *lmosel;
3744 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3746 // Check if we could link
3747 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3750 if (typeid(*selection) == typeid(FloatImageObj))
3752 FloatObj *fo=(FloatObj*)selection;
3753 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3755 fo->updateLink(); //no need for reposition, if we update link here
3757 // Relink float to new mapcenter or branch, if shift is pressed
3758 // Only relink, if selection really has a new parent
3759 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3760 ( (typeid(*lmo)==typeid(BranchObj)) ||
3761 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3762 ( lmo != fo->getParObj())
3765 if (typeid(*fo) == typeid(FloatImageObj))
3767 //FIXME undocom for relinking of floats
3769 //saveStateComplete(QString("Relink %1 to %2").arg(getName(fo)).arg(getName(lmo) ) );
3770 FloatImageObj *fio=(FloatImageObj*)(fo);
3771 ((BranchObj*)(lmo))->addFloatImage (fio);
3773 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
3774 fio=((BranchObj*)(lmo))->getLastFloatImage();
3777 selection=(LinkableMapObj*)(fio);
3778 selection->select();
3779 movingObj=(MapObj*)(fio);
3783 { // selection != a FloatObj
3784 if (lmosel->getDepth()==0)
3787 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3788 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3790 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3791 mapCenter->updateRelPositions();
3794 if (lmosel->getDepth()==1)
3797 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3798 lmosel->setRelPos();
3801 // Move ordinary branch
3802 if (lmosel->getOrientation() == OrientLeftOfCenter)
3803 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3804 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3805 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3807 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3809 // reposition subbranch
3810 lmosel->reposition();
3812 if (lmo && (lmo!=selection) &&
3813 (typeid(*lmo) == typeid(BranchObj) ||
3814 (typeid(*lmo) == typeid(MapCenterObj) )
3817 if (e->modifiers()==Qt::ControlModifier)
3819 // Special case: CTRL to link below lmo
3820 lmosel->setParObjTmp (lmo,p,+1);
3822 else if (e->modifiers()==Qt::ShiftModifier)
3823 lmosel->setParObjTmp (lmo,p,-1);
3825 lmosel->setParObjTmp (lmo,p,0);
3828 lmosel->unsetParObjTmp();
3832 } // no FloatImageObj
3836 } // selection && moving_obj
3838 // Draw a link from one branch to another
3841 tmpXLink->setEnd (p);
3842 tmpXLink->updateXLink();
3846 //if (!movingObj && !pickingColor &&!drawingLink && e->button() == Qt::LeftButton )
3847 if (e->buttons() == Qt::LeftButton )
3849 QPointF p=e->globalPos();
3850 movingVec.setX(-p.x() + movingObj_start.x() );
3851 movingVec.setY(-p.y() + movingObj_start.y() );
3852 // FIXME not ported to QT4 yet (move canvasView)
3853 //setContentsPos( movingCont_start.x() + movingVec.x(),
3854 //movingCont_start.y() + movingVec.y();
3855 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
3856 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
3861 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
3863 QPointF p = mapToScene(e->pos());
3864 LinkableMapObj *dst;
3865 // Have we been picking color?
3869 setCursor (Qt::ArrowCursor);
3870 // Check if we are over another branch
3871 dst=mapCenter->findMapObj(p, NULL);
3872 if (dst && selection)
3874 if (e->state() & Qt::ShiftModifier)
3876 ((BranchObj*)selection)->setColor (((BranchObj*)(dst))->getColor());
3877 ((BranchObj*)selection)->setLinkColor ();
3881 ((BranchObj*)selection)->setColorChilds (((BranchObj*)(dst))->getColor());
3882 ((BranchObj*)selection)->setLinkColor ();
3888 // Have we been drawing a link?
3892 // Check if we are over another branch
3893 dst=mapCenter->findMapObj(p, NULL);
3894 if (dst && selection)
3896 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3897 tmpXLink->updateXLink();
3898 tmpXLink->activate();
3899 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //FIXME undoCommand
3908 // Have we been moving something?
3909 if ( selection && movingObj )
3911 if(typeid(*selection)==typeid (FloatImageObj))
3913 // Moved FloatObj. Maybe we need to reposition
3914 FloatImageObj *fo=(FloatImageObj*)selection;
3915 QString pold=qpointfToString(movingObj_orgRelPos);
3916 QString pnow=qpointfToString(fo->getRelPos());
3922 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(pnow));
3924 // FIXME Why calling parObj here?
3925 selection->getParObj()->requestReposition();
3926 mapCenter->reposition();
3929 // Check if we are over another branch, but ignore
3930 // any found LMOs, which are FloatObjs
3931 dst=mapCenter->findMapObj(mapToScene(e->pos() ),
3932 ((LinkableMapObj*)selection) );
3934 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3937 if (typeid(*selection) == typeid(MapCenterObj) )
3938 { // The MapCenter was moved
3939 cout << "FIXME missing savestate...\n";
3942 if (typeid(*selection) == typeid(BranchObj) )
3943 { // A branch was moved
3945 // save the position in case we link to mapcenter
3946 QPointF savePos=QPointF (selection->x(),selection->y() );
3948 // Reset the temporary drawn link to the original one
3949 ((LinkableMapObj*)selection)->unsetParObjTmp();
3951 // For Redo we may need to save original selection
3952 QString preSelStr=selection->getSelectString();
3957 BranchObj* bsel=(BranchObj*)selection;
3958 BranchObj* bdst=(BranchObj*)dst;
3960 QString preParStr=(bsel->getParObj())->getSelectString();
3961 QString preNum=QString::number (bsel->getNum(),10);
3962 QString preDstParStr;
3964 if (e->state() & Qt::ShiftModifier && dst->getParObj())
3966 preDstParStr=dst->getParObj()->getSelectString();
3967 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
3969 if (e->state() & Qt::ControlModifier && dst->getParObj())
3972 preDstParStr=dst->getParObj()->getSelectString();
3973 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
3976 preDstParStr=dst->getSelectString();
3977 bsel->moveBranchTo (bdst,-1);
3978 if (dst->getDepth()==0) bsel->move (savePos);
3980 QString postSelStr=selection->getSelectString();
3981 QString postNum=QString::number (bsel->getNum(),10);
3983 QString undoCom="linkBranchToPos (\""+
3984 preParStr+ "\"," + preNum +"," +
3985 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
3987 QString redoCom="linkBranchToPos (\""+
3988 preDstParStr + "\"," + postNum + "," +
3989 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
3994 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
3996 if (selection->getDepth()==1)
3998 // The select string might be different _after_ moving around.
3999 // Therefor reposition and then use string of old selection, too
4000 mapCenter->reposition();
4002 QString ps=qpointfToString ( ((BranchObj*)selection)->getRelPos() );
4004 selection->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4005 preSelStr, "moveRel "+ps,
4006 QString("Move %1 to relative position %2").arg(getName(selection)).arg(ps));
4009 // Draw the original link, before selection was moved around
4010 mapCenter->reposition();
4012 // Finally resize scene, if needed
4017 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4020 // maybe we moved View: set old cursor
4021 setCursor (Qt::ArrowCursor);
4025 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4027 if (e->button() == Qt::LeftButton )
4029 QPointF p = mapToScene(e->pos());
4030 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4031 if (lmo) { // MapObj was found
4032 // First select the MapObj than edit heading
4033 if (selection) selection->unselect();
4035 selection->select();
4036 mainWindow->editHeading();
4041 void MapEditor::resizeEvent (QResizeEvent* e)
4043 QGraphicsView::resizeEvent( e );
4047 void MapEditor::contentsDragEnterEvent(QDragEnterEvent *event)
4049 //FIXME not ported to QT4 yet
4051 // for (unsigned int i=0;event->format(i);i++) // Debug mime type
4052 // cerr << event->format(i) << endl;
4055 (typeid(*selection) == typeid(BranchObj)) ||
4056 (typeid(*selection) == typeid(MapCenterObj))) {
4058 // If QImageDrag can decode mime type
4059 if (Q3ImageDrag::canDecode(event)) {
4064 // If image are dragged from firefox
4065 if (event->provides("application/x-moz-file-promise-url") &&
4066 event->provides("application/x-moz-nativeimage")) {
4067 event->accept(true);
4071 // If QUriDrag can decode mime type
4072 if (Q3UriDrag::canDecode(event)) {
4077 // If Uri are dragged from firefox
4078 if (event->provides("_NETSCAPE_URL")){
4083 // If QTextDrag can decode mime type
4084 if (Q3TextDrag::canDecode(event)) {
4093 bool isUnicode16(const QByteArray &d)
4095 // TODO: make more precise check for unicode 16.
4096 // Guess unicode16 if any of second bytes are zero
4097 unsigned int length = max(0,d.size()-2)/2;
4098 for (unsigned int i = 0; i<length ; i++)
4099 if (d.at(i*2+1)==0) return true;
4103 void MapEditor::contentsDropEvent(QDropEvent *event)
4105 //FIXME not ported to QT4 yet
4107 (typeid(*selection) == typeid(BranchObj)) ||
4108 (typeid(*selection) == typeid(MapCenterObj)))
4115 if (event->mimeData()->hasFormat("image/png"))
4117 event->acceptProposedAction();
4118 addFloatImageInt(event->mimeData()->imageData().value<QPixmap>());
4119 cout << "accepted drop\n";
4123 if (event->provides("image/png"))
4126 if (Q3ImageDrag::decode(event, pix))
4128 addFloatImageInt(pix);
4134 } else if (event->provides("application/x-moz-file-promise-url") &&
4135 event->provides("application/x-moz-nativeimage"))
4137 // Contains url to the img src in unicode16
4138 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4139 QString url = QString((const QChar*)d.data(),d.size()/2);
4143 } else if (event->provides ("text/uri-list"))
4144 { // Uris provided e.g. by konqueror
4145 Q3UriDrag::decode (event,uris);
4146 } else if (event->provides ("_NETSCAPE_URL"))
4147 { // Uris provided by Mozilla
4148 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4151 } else if (event->provides("text/html")) {
4153 // Handels text mime types
4154 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4155 QByteArray d = event->encodedData("text/html");
4158 text = QString((const QChar*)d.data(),d.size()/2);
4162 textEditor->setText(text);
4166 } else if (event->provides("text/plain")) {
4167 QByteArray d = event->encodedData("text/plain");
4170 text = QString((const QChar*)d.data(),d.size()/2);
4174 textEditor->setText(text);
4181 /* FIXME not ported yet QSTRINGLIST has no next...
4188 for (const char* u=uris.first(); u; u=uris.next())
4190 bo=((BranchObj*)selection)->addBranch();
4193 s=Q3UriDrag::uriToLocalFile(u);
4196 QString file = QDir::convertSeparators(s);
4197 heading = QFileInfo(file).baseName();
4199 if (file.endsWith(".vym", false))
4200 bo->setVymLink(file);
4209 if (!heading.isEmpty())
4210 bo->setHeading(heading);
4220 //FIXME saveState has to be called earlier for each of the drops...
4221 //saveStateComplete("Drop Event"); //TODO undo Command
4222 mapCenter->reposition();
4229 void MapEditor::addFloatImageInt (const QPixmap &img)
4232 (typeid(*selection) == typeid(BranchObj)) ||
4233 (typeid(*selection) == typeid(MapCenterObj)) )
4235 BranchObj *bo=((BranchObj*)selection);
4236 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4237 //QString fn=fd->selectedFile();
4238 //lastImageDir=fn.left(fn.findRev ("/"));
4239 FloatImageObj *fio=bo->addFloatImage();
4241 fio->setOriginalFilename("Image added by Drag and Drop");
4242 mapCenter->reposition();
4249 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation */*nop*/)
4251 if (!imageBuffer) imageBuffer = new QBuffer();
4252 if (!imageBuffer->isOpen()) {
4253 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4255 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4259 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4261 if (nop->state()==Q3NetworkProtocol::StDone) {
4262 QPixmap img(imageBuffer->buffer());
4263 addFloatImageInt (img);
4267 imageBuffer->close();
4269 imageBuffer->close();
4276 void MapEditor::fetchImage(const QString &url)
4279 urlOperator->stop();
4280 disconnect(urlOperator);
4284 urlOperator = new Q3UrlOperator(url);
4285 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4286 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4288 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4289 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));