historywindow moved to mainwindow. Started to get rid of Q3PtrList finally
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 ///////////////////////////////////////////////////////////////////////
61 QWidget* parent, const char* name, Qt::WFlags f) :
62 Q3CanvasView(parent,name,f), urlOperator(0), imageBuffer(0)
64 //cout << "Constructor ME "<<this<<endl;
67 viewport()->setAcceptDrops(true);
69 mapCanvas = new Q3Canvas(width(),height());
70 mapCanvas->setAdvancePeriod(30);
71 mapCanvas->setBackgroundColor (Qt::white);
73 setCanvas (mapCanvas);
75 // Always show scroll bars (automatic would flicker sometimes)
76 setVScrollBarMode ( Q3ScrollView::AlwaysOn );
77 setHScrollBarMode ( Q3ScrollView::AlwaysOn );
79 mapCenter = new MapCenterObj(mapCanvas);
80 mapCenter->setVisibility (true);
81 mapCenter->setMapEditor (this);
82 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
83 mapCenter->move(mapCanvas->width()/2-mapCenter->width()/2,mapCanvas->height()/2-mapCenter->height()/2);
87 defLinkColor=QColor (0,0,255);
88 defXLinkColor=QColor (180,180,180);
89 linkcolorhint=DefaultColor;
90 linkstyle=StylePolyParabel;
92 // Create bitmap cursors, platform dependant
93 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
94 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
95 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
96 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
98 setFocusPolicy (Qt::StrongFocus);
109 xelection.setMapCenter (mapCenter);
112 defXLinkColor=QColor (230,230,230);
120 fileName=tr("unnamed");
123 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
124 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
126 // Initialize find routine
133 blockReposition=false;
134 blockSaveState=false;
138 // Create temporary files
141 // Initially set movingCentre
144 mapCenter->reposition(); // for positioning heading
148 MapEditor::~MapEditor()
150 if (imageBuffer) delete imageBuffer;
156 //cout <<"Destructor MapEditor\n";
159 MapCenterObj* MapEditor::getMapCenter()
164 Q3Canvas* MapEditor::getCanvas()
169 void MapEditor::adjustCanvasSize()
171 // To adjust the canvas to map, viewport size and position, we have to
172 // do some coordinate magic...
174 // Get rectangle of (scroll-)view.
175 // We want to be in canvas coords, so
176 // we map. Important if view is zoomed...
177 QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(),
178 visibleWidth(), visibleHeight()) );
180 // Now we need the bounding box of view AND map to calc the correct canvas size.
181 // Why? Because if the map itself is moved out of view, the view has to be enlarged
182 // to avoid jumping aroung...
183 QRect map=mapCenter->getTotalBBox();
185 // right edge - left edge
186 int cw= max(map.x() + map.width(), view.x() + view.width()) - min(map.x(), view.x());
187 int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
190 if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) ||
191 !mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight())
194 // move the map on canvas (in order to not move it on screen) this is neccessary
195 // a) if topleft corner of canvas is left or above topleft corner of view and also left of
196 // above topleft corner of map. E.g. if map is completly inside view, but it would be possible
197 // to scroll to an empty area of canvas to the left.
198 // b) if topleft corner of map left of or above topleft of canvas
202 if (cw > mapCanvas->width() )
204 if (map.x()<0) dx=-map.x();
206 if (cw < mapCanvas->width() )
207 dx=-min (view.x(),map.x());
208 if (ch > mapCanvas->height() )
210 if (map.y()<0) dy=-map.y();
212 if (ch < mapCanvas->height() )
214 dy=-min (view.y(),map.y());
216 // We really have to resize now. Let's go...
217 mapCanvas->resize (cw,ch);
218 if ( (dx!=0) || (dy!=0) )
220 mapCenter->moveAllBy(dx,dy);
221 mapCenter->reposition();
222 // mapCenter->positionBBox(); // To move float
224 // scroll the view (in order to not move map on screen)
230 bool MapEditor::isRepositionBlocked()
232 return blockReposition;
235 QString MapEditor::getName (LinkableMapObj *lmo)
238 if (!lmo) return QString("Error: NULL has no name!");
240 if ((typeid(*lmo) == typeid(BranchObj) ||
241 typeid(*lmo) == typeid(MapCenterObj)))
244 s=(((BranchObj*)lmo)->getHeading());
245 if (s=="") s="unnamed";
246 return QString("branch (%1)").arg(s);
247 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
249 if ((typeid(*lmo) == typeid(FloatImageObj) ))
250 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
251 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
252 return QString("Unknown type has no name!");
255 void MapEditor::makeTmpDirs()
257 // Create unique temporary directories
258 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
259 histPath=QDir::convertSeparators (tmpMapDir+"/history");
264 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, LinkableMapObj *saveSel)
266 // tmpdir temporary directory to which data will be written
267 // prefix mapname, which will be appended to images etc.
268 // writeflags Only write flags for "real" save of map, not undo
269 // offset offset of bbox of whole map in canvas.
270 // Needed for XML export
286 ls="StylePolyParabel";
290 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
292 if (linkcolorhint==HeadingColor)
293 colhint=attribut("linkColorHint","HeadingColor");
295 QString mapAttr=attribut("version",vymVersion);
296 if (!saveSel || saveSel==mapCenter)
297 mapAttr+= attribut("author",mapCenter->getAuthor()) +
298 attribut("comment",mapCenter->getComment()) +
299 attribut("date",mapCenter->getDate()) +
300 attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
301 attribut("linkStyle", ls ) +
302 attribut("linkColor", defLinkColor.name() ) +
303 attribut("defXLinkColor", defXLinkColor.name() ) +
304 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
306 s+=beginElement("vymmap",mapAttr);
309 // Find the used flags while traversing the tree
310 standardFlagsDefault->resetUsedCounter();
312 // Reset the counters before saving
313 FloatImageObj (mapCanvas).resetSaveCounter();
315 // Build xml recursivly
316 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
317 // Save complete map, if saveSel not set
318 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
321 if ( typeid(*saveSel) == typeid(BranchObj) )
323 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
324 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
326 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
328 else if (selection && typeid(*selection)==typeid(BranchObj))
329 // Save selected branch is saved from mainwindow //FIXME maybe use "subtree" above?
330 // FIXME is this possible at all? BO is already above...
331 s+=((BranchObj*)selection)->saveToDir(tmpdir,prefix,offset);
334 // Save local settings
335 s+=settings.getXMLData (destPath);
338 if (selection && !saveSel )
339 s+=valueElement("select",selection->getSelectString());
342 s+=endElement("vymmap");
345 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
349 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
351 // save the selected part of the map, Undo will replace part of map
352 QString undoSelection="";
354 undoSelection=undoSel->getSelectString();
356 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
357 QString redoSelection="";
359 redoSelection=undoSel->getSelectString();
361 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
364 saveState (PartOfMap,
365 undoSelection, "addMapReplace (\"PATH\")",
371 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
375 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
378 QString undoSelection=redoSel->getParObj()->getSelectString();
379 QString redoSelection=redoSel->getSelectString();
380 if (typeid(*redoSel) == typeid(BranchObj) )
382 // save the selected branch of the map, Undo will insert part of map
383 saveState (PartOfMap,
384 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
385 redoSelection, "delete ()",
392 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
394 // "Normal" savestate: save commands, selections and comment
395 // so just save commands for undo and redo
396 // and use current selection
398 QString redoSelection="";
399 if (redoSel) redoSelection=redoSel->getSelectString();
400 QString undoSelection="";
401 if (undoSel) undoSelection=undoSel->getSelectString();
403 saveState (UndoCommand,
410 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
412 // "Normal" savestate: save commands, selections and comment
413 // so just save commands for undo and redo
414 // and use current selection
415 saveState (UndoCommand,
423 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
427 if (blockSaveState) return;
429 /* TODO remove after testing
431 cout << "ME::saveState() "<<endl;
433 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
434 int redosAvail=undoSet.readNumEntry ("/history/redosAvail",0);
435 int curStep=undoSet.readNumEntry ("/history/curStep",0);
436 // Find out current undo directory
437 if (undosAvail<stepsTotal) undosAvail++;
439 if (curStep>stepsTotal) curStep=1;
441 QString backupXML="";
442 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
443 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
444 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
446 // Create bakMapDir if not available
449 makeSubDirs (bakMapDir);
451 // Save depending on how much needs to be saved
453 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),saveSel);
455 QString undoCommand="";
456 if (savemode==UndoCommand)
460 else if (savemode==PartOfMap )
463 undoCommand.replace ("PATH",bakMapPath);
466 if (!backupXML.isEmpty())
467 // Write XML Data to disk
468 saveStringToDisk (QString(bakMapPath),backupXML);
470 // We would have to save all actions in a tree, to keep track of
471 // possible redos after a action. Possible, but we are too lazy: forget about redos.
474 // Write the current state to disk
475 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
476 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
477 undoSet.setEntry ("/history/curStep",QString::number(curStep));
478 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
479 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
480 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
481 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
482 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
483 undoSet.setEntry (QString("/history/version"),vymVersion);
484 undoSet.writeSettings(histPath);
486 /* TODO remove after testing
488 //cout << " into="<< histPath.toStdString()<<endl;
489 cout << " stepsTotal="<<stepsTotal<<
490 ", undosAvail="<<undosAvail<<
491 ", redosAvail="<<redosAvail<<
492 ", curStep="<<curStep<<endl;
493 cout << " ---------------------------"<<endl;
494 cout << " comment="<<comment.toStdString()<<endl;
495 cout << " undoCom="<<undoCommand.toStdString()<<endl;
496 cout << " undoSel="<<undoSelection.toStdString()<<endl;
497 cout << " redoCom="<<redoCom.toStdString()<<endl;
498 cout << " redoSel="<<redoSelection.toStdString()<<endl;
499 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
500 cout << " ---------------------------"<<endl;
502 mainWindow->updateHistory (undoSet);
507 void MapEditor::parseAtom(const QString &atom)
514 // Split string s into command and parameters
515 api.parseInput (atom);
516 QString com=api.command();
519 if (com=="addBranch")
523 api.setError (Aborted,"Nothing selected");
524 } else if ( (typeid(*selection) != typeid(BranchObj) &&
525 typeid(*selection) != typeid(MapCenterObj)) )
527 api.setError (Aborted,"Type of selection is not a branch");
532 if (api.checkParamCount(pl))
534 if (api.paramCount()==0)
535 addNewBranchInt (-2);
539 if (ok ) addNewBranchInt (y);
543 } else if (com=="addBranchBefore")
547 api.setError (Aborted,"Nothing selected");
548 } else if ( (typeid(*selection) != typeid(BranchObj) &&
549 typeid(*selection) != typeid(MapCenterObj)) )
551 api.setError (Aborted,"Type of selection is not a branch");
554 if (api.paramCount()==0)
556 addNewBranchBefore ();
559 } else if (com==QString("addMapReplace"))
563 api.setError (Aborted,"Nothing selected");
564 } else if ( (typeid(*selection) != typeid(BranchObj) &&
565 typeid(*selection) != typeid(MapCenterObj)) )
567 api.setError (Aborted,"Type of selection is not a branch");
568 } else if (api.checkParamCount(1))
570 //s=api.parString (ok,0); // selection
571 t=api.parString (ok,0); // path to map
572 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
573 addMapReplaceInt(selection->getSelectString(),t);
575 } else if (com==QString("addMapInsert"))
579 api.setError (Aborted,"Nothing selected");
580 } else if ( (typeid(*selection) != typeid(BranchObj) &&
581 typeid(*selection) != typeid(MapCenterObj)) )
583 api.setError (Aborted,"Type of selection is not a branch");
586 if (api.checkParamCount(2))
588 t=api.parString (ok,0); // path to map
589 y=api.parInt(ok,1); // position
590 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
591 addMapInsertInt(t,y);
594 } else if (com=="colorItem")
598 api.setError (Aborted,"Nothing selected");
599 } else if ( typeid(*selection) != typeid(BranchObj) &&
600 typeid(*selection) != typeid(MapCenterObj))
602 api.setError (Aborted,"Type of selection is not a branch");
603 } else if (api.checkParamCount(1))
605 QColor c=api.parColor (ok,0);
606 if (ok) colorItem (c);
608 } else if (com=="colorBranch")
612 api.setError (Aborted,"Nothing selected");
613 } else if ( typeid(*selection) != typeid(BranchObj) &&
614 typeid(*selection) != typeid(MapCenterObj))
616 api.setError (Aborted,"Type of selection is not a branch");
617 } else if (api.checkParamCount(1))
619 QColor c=api.parColor (ok,0);
620 if (ok) colorBranch (c);
622 } else if (com=="cut")
626 api.setError (Aborted,"Nothing selected");
627 } else if ( typeid(*selection) != typeid(BranchObj) &&
628 typeid(*selection) != typeid(MapCenterObj) &&
629 typeid(*selection) != typeid(FloatImageObj) )
631 api.setError (Aborted,"Type of selection is not a branch or floatimage");
632 } else if (api.checkParamCount(0))
636 } else if (com=="delete")
640 api.setError (Aborted,"Nothing selected");
641 } else if ( (typeid(*selection) != typeid(BranchObj) &&
642 typeid(*selection) != typeid(MapCenterObj)) )
644 api.setError (Aborted,"Type of selection is not a branch");
645 } else if (api.checkParamCount(0))
649 } else if (com=="deleteKeepChilds")
653 api.setError (Aborted,"Nothing selected");
654 } else if ( (typeid(*selection) != typeid(BranchObj) &&
655 typeid(*selection) != typeid(MapCenterObj)) )
657 api.setError (Aborted,"Type of selection is not a branch");
658 } else if (api.checkParamCount(0))
662 } else if (com=="deleteChilds")
666 api.setError (Aborted,"Nothing selected");
667 } else if ( (typeid(*selection) != typeid(BranchObj) &&
668 typeid(*selection) != typeid(MapCenterObj)) )
670 api.setError (Aborted,"Type of selection is not a branch");
671 } else if (api.checkParamCount(0))
675 } else if (com=="linkBranchToPos")
679 api.setError (Aborted,"Nothing selected");
680 } else if ( (typeid(*selection) != typeid(BranchObj) &&
681 typeid(*selection) != typeid(MapCenterObj)) )
683 api.setError (Aborted,"Type of selection is not a branch");
684 } else if (api.checkParamCount(4))
686 // 0 selectstring of parent
687 // 1 num in parent (for branches)
688 // 2,3 x,y of mainbranch or mapcenter
689 s=api.parString(ok,0);
690 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
693 if (typeid(*dst) == typeid(BranchObj) )
695 // Get number in parent
698 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),x);
699 } else if (typeid(*dst) == typeid(MapCenterObj) )
701 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),-1);
702 // Get coordinates of mainbranch
707 if (ok) ((BranchObj*)selection)->move (x,y);
712 } else if (com=="moveBranchUp")
716 api.setError (Aborted,"Nothing selected");
717 } else if ( (typeid(*selection) != typeid(BranchObj) &&
718 typeid(*selection) != typeid(MapCenterObj)) )
720 api.setError (Aborted,"Type of selection is not a branch");
721 } else if (api.checkParamCount(0))
725 } else if (com=="moveBranchDown")
729 api.setError (Aborted,"Nothing selected");
730 } else if ( (typeid(*selection) != typeid(BranchObj) &&
731 typeid(*selection) != typeid(MapCenterObj)) )
733 api.setError (Aborted,"Type of selection is not a branch");
734 } else if (api.checkParamCount(0))
738 } else if (com=="move")
742 api.setError (Aborted,"Nothing selected");
743 } else if ( typeid(*selection) != typeid(BranchObj) &&
744 typeid(*selection) != typeid(MapCenterObj) &&
745 typeid(*selection) != typeid(FloatImageObj) )
747 api.setError (Aborted,"Type of selection is not a branch or floatimage");
748 } else if (api.checkParamCount(2))
757 } else if (com=="moveRel")
761 api.setError (Aborted,"Nothing selected");
762 } else if ( typeid(*selection) != typeid(BranchObj) &&
763 typeid(*selection) != typeid(MapCenterObj) &&
764 typeid(*selection) != typeid(FloatImageObj) )
766 api.setError (Aborted,"Type of selection is not a branch or floatimage");
767 } else if (api.checkParamCount(2))
773 if (ok) moveRel (x,y);
776 } else if (com=="paste")
780 api.setError (Aborted,"Nothing selected");
781 } else if ( typeid(*selection) != typeid(BranchObj) &&
782 typeid(*selection) != typeid(MapCenterObj) )
784 api.setError (Aborted,"Type of selection is not a branch");
785 } else if (api.checkParamCount(0))
789 } else if (com=="select")
791 if (api.checkParamCount(1))
793 s=api.parString(ok,0);
796 } else if (com=="setMapAuthor")
798 if (api.checkParamCount(1))
800 s=api.parString(ok,0);
801 if (ok) setMapAuthor (s);
803 } else if (com=="setMapComment")
805 if (api.checkParamCount(1))
807 s=api.parString(ok,0);
808 if (ok) setMapComment(s);
810 } else if (com=="setMapBackgroundColor")
814 api.setError (Aborted,"Nothing selected");
815 } else if ( (typeid(*selection) != typeid(BranchObj) &&
816 typeid(*selection) != typeid(MapCenterObj)) )
818 api.setError (Aborted,"Type of selection is not a branch");
819 } else if (api.checkParamCount(1))
821 QColor c=api.parColor (ok,0);
822 if (ok) setMapBackgroundColor (c);
824 } else if (com=="setMapDefLinkColor")
828 api.setError (Aborted,"Nothing selected");
829 } else if ( (typeid(*selection) != typeid(BranchObj) &&
830 typeid(*selection) != typeid(MapCenterObj)) )
832 api.setError (Aborted,"Type of selection is not a branch");
833 } else if (api.checkParamCount(1))
835 QColor c=api.parColor (ok,0);
836 if (ok) setMapDefLinkColor (c);
838 } else if (com=="setMapLinkStyle")
840 if (api.checkParamCount(1))
842 s=api.parString (ok,0);
843 if (ok) setMapLinkStyle(s);
845 } else if (com=="setHeading")
849 api.setError (Aborted,"Nothing selected");
850 } else if ( (typeid(*selection) != typeid(BranchObj) &&
851 typeid(*selection) != typeid(MapCenterObj)) )
853 api.setError (Aborted,"Type of selection is not a branch");
854 } else if (api.checkParamCount(1))
856 s=api.parString (ok,0);
860 } else if (com=="setHideExport")
864 api.setError (Aborted,"Nothing selected");
865 } else if ( typeid(*selection) != typeid(BranchObj) &&
866 typeid(*selection) != typeid(FloatImageObj) )
868 api.setError (Aborted,"Type of selection is not a branch or floatimage");
869 } else if (api.checkParamCount(1))
872 if (ok) setHideExport (b);
874 } else if (com=="setURL")
878 api.setError (Aborted,"Nothing selected");
879 } else if ( (typeid(*selection) != typeid(BranchObj) &&
880 typeid(*selection) != typeid(MapCenterObj)) )
882 api.setError (Aborted,"Type of selection is not a branch");
883 } else if (api.checkParamCount(1))
885 s=api.parString (ok,0);
886 if (ok) setURLInt(s);
888 } else if (com=="setVymLink")
892 api.setError (Aborted,"Nothing selected");
893 } else if ( (typeid(*selection) != typeid(BranchObj) &&
894 typeid(*selection) != typeid(MapCenterObj)) )
896 api.setError (Aborted,"Type of selection is not a branch");
897 } else if (api.checkParamCount(1))
899 s=api.parString (ok,0);
900 if (ok) setVymLinkInt(s);
903 else if (com=="setFlag")
907 api.setError (Aborted,"Nothing selected");
908 } else if ( (typeid(*selection) != typeid(BranchObj) &&
909 typeid(*selection) != typeid(MapCenterObj)) )
911 api.setError (Aborted,"Type of selection is not a branch");
912 } else if (api.checkParamCount(1))
914 s=api.parString(ok,0);
917 BranchObj* bo=(BranchObj*)selection;
918 bo->activateStandardFlag(s);
919 bo->updateFlagsToolbar();
923 else if (com=="unsetFlag")
927 api.setError (Aborted,"Nothing selected");
928 } else if ( (typeid(*selection) != typeid(BranchObj) &&
929 typeid(*selection) != typeid(MapCenterObj)) )
931 api.setError (Aborted,"Type of selection is not a branch");
932 } else if (api.checkParamCount(1))
934 s=api.parString(ok,0);
937 BranchObj* bo=(BranchObj*)selection;
938 bo->deactivateStandardFlag(s);
939 bo->updateFlagsToolbar();
944 api.setError (Aborted,"Unknown command");
948 if (api.errorLevel()==NoError)
952 // TODO Error handling
953 qWarning("MapEditor::parseAtom: Error!");
954 qWarning(api.errorMessage());
959 bool MapEditor::isDefault()
964 bool MapEditor::isUnsaved()
969 bool MapEditor::hasChanged()
974 void MapEditor::setChanged()
982 void MapEditor::closeMap()
984 // Unselect before disabling the toolbar actions
985 if (selection) selection->unselect();
993 void MapEditor::setFilePath(QString fname)
995 setFilePath (fname,fname);
998 void MapEditor::setFilePath(QString fname, QString destname)
1000 if (fname.isEmpty() || fname=="")
1007 filePath=fname; // becomes absolute path
1008 fileName=fname; // gets stripped of path
1009 destPath=destname; // needed for vymlinks
1011 // If fname is not an absolute path, complete it
1012 filePath=QDir(fname).absPath();
1013 fileDir=filePath.left (1+filePath.findRev ("/"));
1015 // Set short name, too. Search from behind:
1016 int i=fileName.findRev("/");
1017 if (i>=0) fileName=fileName.remove (0,i+1);
1019 // Forget the .vym (or .xml) for name of map
1020 mapName=fileName.left(fileName.findRev(".",-1,true) );
1024 QString MapEditor::getFilePath()
1029 QString MapEditor::getFileName()
1034 QString MapEditor::getMapName()
1039 QString MapEditor::getDestPath()
1044 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1046 ErrorCode err=success;
1050 if (selection) selection->unselect();
1053 mapCenter->setMapEditor(this);
1054 // (map state is set later at end of load...)
1057 if (!selection || (typeid(*selection) != typeid(BranchObj) &&
1058 typeid(*selection) != typeid (MapCenterObj)))
1060 BranchObj *bo=(BranchObj*)selection;
1061 if (lmode==ImportAdd)
1062 saveStateChangingPart(
1065 QString("addMapInsert (%1)").arg(fname),
1066 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1068 saveStateChangingPart(
1071 QString("addMapReplace(%1)").arg(fname),
1072 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1076 mapBuilderHandler handler;
1077 QFile file( fname );
1079 // I am paranoid: file should exist anyway
1080 // according to check in mainwindow.
1081 if (!file.exists() )
1083 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1084 tr("Couldn't open map " +fname)+".");
1088 blockReposition=true;
1089 QXmlInputSource source( file);
1090 QXmlSimpleReader reader;
1091 reader.setContentHandler( &handler );
1092 reader.setErrorHandler( &handler );
1093 handler.setMapEditor( this );
1094 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
1095 handler.setInputFile (file.name());
1096 handler.setLoadMode (lmode);
1097 blockSaveState=true;
1098 bool ok = reader.parse( source );
1099 blockReposition=false;
1100 blockSaveState=false;
1104 mapCenter->reposition();
1114 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1115 tr( handler.errorProtocol() ) );
1117 // Still return "success": the map maybe at least
1118 // partially read by the parser
1125 int MapEditor::save (const SaveMode &savemode)
1129 // Create mapName and fileDir
1130 makeSubDirs (fileDir);
1134 fname=mapName+".xml";
1136 // use name given by user, even if he chooses .doc
1141 if (savemode==CompleteMap || selection==NULL)
1142 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),NULL);
1144 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),selection);
1146 if (!saveStringToDisk(fileDir+fname,saveFile))
1159 void MapEditor::setZipped (bool z)
1164 bool MapEditor::saveZipped ()
1169 void MapEditor::print()
1173 printer = new QPrinter;
1174 printer->setColorMode (QPrinter::Color);
1175 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1178 QRect totalBBox=mapCenter->getTotalBBox();
1180 // Try to set orientation automagically
1181 // Note: Interpretation of generated postscript is amibiguous, if
1182 // there are problems with landscape mode, see
1183 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1185 if (totalBBox.width()>totalBBox.height())
1186 // recommend landscape
1187 printer->setOrientation (QPrinter::Landscape);
1189 // recommend portrait
1190 printer->setOrientation (QPrinter::Portrait);
1192 if ( printer->setup(this) )
1193 // returns false, if printing is canceled
1195 QPainter pp(printer);
1197 // Don't print the visualisation of selection
1198 LinkableMapObj *oldselection=NULL;
1201 oldselection=selection;
1202 selection->unselect();
1205 // Handle sizes of map and paper:
1207 // setWindow defines which part of the canvas will be transformed
1208 // setViewport defines area on paper in device coordinates (dpi)
1209 // e.g. (0,50,700,700) is upper part on A4
1210 // see also /usr/lib/qt3/doc/html/coordsys.html
1212 Q3PaintDeviceMetrics metrics (printer);
1214 double paperAspect = (double)metrics.width() / (double)metrics.height();
1215 double mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
1217 QRect mapRect=totalBBox;
1218 Q3CanvasRectangle *frame=NULL;
1219 Q3CanvasText *footerFN=NULL;
1220 Q3CanvasText *footerDate=NULL;
1221 if (printFrame || printFooter)
1226 // Print frame around map
1227 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1228 totalBBox.width()+20, totalBBox.height()+20);
1229 frame=new Q3CanvasRectangle (mapRect,mapCanvas);
1230 frame->setBrush (QColor(Qt::white));
1231 frame->setPen (QColor(Qt::black));
1235 /* TODO remove after testing
1236 QCanvasLine *l=new QCanvasLine (mapCanvas);
1237 l->setPoints (0,0,mapRect.width(),mapRect.height());
1238 l->setPen (QPen(QColor(black), 1));
1245 // Print footer below map
1247 font.setPointSize(10);
1248 footerFN=new Q3CanvasText (mapCanvas);
1249 footerFN->setText ("VYM - " + fileName);
1250 footerFN->setFont(font);
1251 footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
1252 footerFN->setZ(Z_TEXT);
1254 footerDate=new Q3CanvasText (mapCanvas);
1255 footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
1256 footerDate->setFont(font);
1257 footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
1258 footerDate->setZ(Z_TEXT);
1261 pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()+20);
1264 pp.setWindow (mapRect);
1267 if (mapAspect>=paperAspect)
1269 // Fit horizontally to paper width
1270 pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );
1273 // Fit vertically to paper height
1274 pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());
1277 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to printer
1279 // Delete Frame and footer
1283 delete (footerDate);
1285 if (frame) delete (frame);
1287 // Restore selection
1290 selection=oldselection;
1291 selection->select();
1294 // Save settings in vymrc
1295 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1299 QPixmap MapEditor::getPixmap()
1301 QRect mapRect=mapCenter->getTotalBBox();
1302 QPixmap pix (mapRect.size());
1305 // Don't print the visualisation of selection
1306 LinkableMapObj *oldselection=NULL;
1309 oldselection=selection;
1310 selection->unselect();
1313 pp.setWindow (mapRect);
1315 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to painter
1318 // Restore selection
1321 selection=oldselection;
1322 selection->select();
1328 void MapEditor::setHideTmpMode (HideTmpMode mode)
1331 mapCenter->setHideTmp (hidemode);
1332 mapCenter->reposition();
1337 HideTmpMode MapEditor::getHideTmpMode()
1342 void MapEditor::exportImage(QString fn)
1344 setExportMode (true);
1345 QPixmap pix (getPixmap());
1346 pix.save(fn, "PNG");
1347 setExportMode (false);
1350 void MapEditor::setExportMode (bool b)
1352 // should be called before and after exports
1353 // depending on the settings
1354 if (b && settings.value("/export/useHideExport","yes")=="yes")
1355 setHideTmpMode (HideExport);
1357 setHideTmpMode (HideNone);
1360 void MapEditor::exportImage(QString fn, QString format)
1362 setExportMode (true);
1363 QPixmap pix (getPixmap());
1364 pix.save(fn, format);
1365 setExportMode (false);
1368 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1372 ex.setMapCenter(mapCenter);
1373 if (ex.setConfigFile(cf))
1375 setExportMode (true);
1376 ex.exportPresentation();
1377 setExportMode (false);
1383 void MapEditor::exportXML(const QString &dir)
1385 // Hide stuff during export, if settings want this
1386 setExportMode (true);
1388 // Create subdirectories
1391 // write to directory
1392 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1395 file.setName ( dir + "/"+mapName+".xml");
1396 if ( !file.open( QIODevice::WriteOnly ) )
1398 // This should neverever happen
1399 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1403 // Write it finally, and write in UTF8, no matter what
1404 QTextStream ts( &file );
1405 ts.setEncoding (QTextStream::UnicodeUTF8);
1409 // Now write image, too
1410 exportImage (dir+"/images/"+mapName+".png");
1412 setExportMode (false);
1415 void MapEditor::clear()
1419 selection->unselect();
1426 void MapEditor::copy()
1430 // write to directory
1431 QString clipfile="part";
1432 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPoint(),selection);
1435 file.setName ( clipboardDir + "/"+clipfile+".xml");
1436 if ( !file.open( QIODevice::WriteOnly ) )
1438 // This should neverever happen
1439 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1443 // Write it finally, and write in UTF8, no matter what
1444 QTextStream ts( &file );
1445 ts.setEncoding (QTextStream::UnicodeUTF8);
1449 clipboardEmpty=false;
1454 void MapEditor::redo()
1456 blockSaveState=true;
1458 // Restore variables
1459 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1460 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1461 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1462 // Can we undo at all?
1463 if (redosAvail<1) return;
1466 if (undosAvail<stepsTotal) undosAvail++;
1468 if (curStep>stepsTotal) curStep=1;
1469 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1470 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1471 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1472 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1473 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1474 QString version=undoSet.readEntry ("/history/version");
1476 if (!checkVersion(version))
1477 QMessageBox::warning(0,tr("Warning"),
1478 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1481 // Find out current undo directory
1482 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1484 /* TODO remove testing
1486 cout << "ME::redo() begin\n";
1487 cout << " undosAvail="<<undosAvail<<endl;
1488 cout << " redosAvail="<<redosAvail<<endl;
1489 cout << " curStep="<<curStep<<endl;
1490 cout << " ---------------------------"<<endl;
1491 cout << " comment="<<comment.toStdString()<<endl;
1492 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1493 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1494 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1495 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1496 cout << " ---------------------------"<<endl<<endl;
1498 // select object before redo
1499 if (!redoSelection.isEmpty())
1500 select (redoSelection);
1503 parseAtom (redoCommand);
1504 mapCenter->reposition();
1506 blockSaveState=false;
1508 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1509 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1510 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1511 undoSet.writeSettings(histPath);
1513 mainWindow->updateHistory (undoSet);
1516 /* TODO remove testing
1517 cout << "ME::redo() end\n";
1518 cout << " undosAvail="<<undosAvail<<endl;
1519 cout << " redosAvail="<<redosAvail<<endl;
1520 cout << " curStep="<<curStep<<endl;
1521 cout << " ---------------------------"<<endl<<endl;
1527 bool MapEditor::isRedoAvailable()
1529 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
1535 void MapEditor::undo()
1537 blockSaveState=true;
1539 // Restore variables
1540 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1541 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1542 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1544 // Can we undo at all?
1545 if (undosAvail<1) return;
1547 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1548 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1549 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1550 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1551 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1552 QString version=undoSet.readEntry ("/history/version");
1554 if (!checkVersion(version))
1555 QMessageBox::warning(0,tr("Warning"),
1556 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1558 // Find out current undo directory
1559 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1561 // select object before undo
1562 if (!undoSelection.isEmpty())
1563 select (undoSelection);
1567 cout << "ME::undo() begin\n";
1568 cout << " undosAvail="<<undosAvail<<endl;
1569 cout << " redosAvail="<<redosAvail<<endl;
1570 cout << " curStep="<<curStep<<endl;
1571 cout << " ---------------------------"<<endl;
1572 cout << " comment="<<comment.toStdString()<<endl;
1573 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1574 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1575 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1576 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1577 cout << " ---------------------------"<<endl<<endl;
1578 parseAtom (undoCommand);
1579 mapCenter->reposition();
1583 if (curStep<1) curStep=stepsTotal;
1587 blockSaveState=false;
1588 /* TODO remove testing
1589 cout << "ME::undo() end\n";
1590 cout << " undosAvail="<<undosAvail<<endl;
1591 cout << " redosAvail="<<redosAvail<<endl;
1592 cout << " curStep="<<curStep<<endl;
1593 cout << " ---------------------------"<<endl<<endl;
1596 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1597 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1598 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1599 undoSet.writeSettings(histPath);
1601 mainWindow->updateHistory (undoSet);
1605 bool MapEditor::isUndoAvailable()
1607 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
1613 void MapEditor::gotoHistoryStep (int i)
1615 // Restore variables
1616 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1617 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1619 if (i<0) i=undosAvail+redosAvail;
1621 // Clicking above current step makes us undo things
1624 for (int j=0; j<undosAvail-i; j++) undo();
1627 // Clicking below current step makes us redo things
1629 for (int j=undosAvail; j<i; j++) redo();
1631 // And ignore clicking the current row ;-)
1634 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
1636 QString pathDir=path.left(path.findRev("/"));
1642 // We need to parse saved XML data
1643 mapBuilderHandler handler;
1644 QXmlInputSource source( file);
1645 QXmlSimpleReader reader;
1646 reader.setContentHandler( &handler );
1647 reader.setErrorHandler( &handler );
1648 handler.setMapEditor( this );
1649 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1650 if (undoSel.isEmpty())
1654 handler.setLoadMode (NewMap);
1658 handler.setLoadMode (ImportReplace);
1660 blockReposition=true;
1661 bool ok = reader.parse( source );
1662 blockReposition=false;
1665 // This should never ever happen
1666 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1667 handler.errorProtocol());
1670 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1673 void MapEditor::addMapInsertInt (const QString &path, int pos)
1675 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1676 typeid(*selection) == typeid(MapCenterObj)))
1678 QString pathDir=path.left(path.findRev("/"));
1684 // We need to parse saved XML data
1685 mapBuilderHandler handler;
1686 QXmlInputSource source( file);
1687 QXmlSimpleReader reader;
1688 reader.setContentHandler( &handler );
1689 reader.setErrorHandler( &handler );
1690 handler.setMapEditor( this );
1691 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
1692 handler.setLoadMode (ImportAdd);
1693 blockReposition=true;
1694 bool ok = reader.parse( source );
1695 blockReposition=false;
1698 // This should never ever happen
1699 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
1700 handler.errorProtocol());
1702 if (selection!=mapCenter)
1703 ((BranchObj*)selection)->getLastBranch()->moveBranchTo ((BranchObj*)(selection),pos);
1705 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
1709 void MapEditor::pasteNoSave()
1711 load (clipboardDir+"/part.xml",ImportAdd);
1714 void MapEditor::cutNoSave()
1720 void MapEditor::paste()
1722 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1723 typeid(*selection) == typeid(MapCenterObj)))
1726 saveStateChangingPart(
1730 QString("Paste to %1").arg( getName(selection))
1732 mapCenter->reposition();
1737 void MapEditor::cut()
1739 saveStateChangingPart(
1740 selection->getParObj(),
1743 QString("Cut %1").arg(getName(selection))
1747 mapCenter->reposition();
1751 void MapEditor::move(const int &x, const int &y)
1755 QString ps=qpointToString (selection->getAbsPos());
1756 QString s=selection->getSelectString();
1759 s, "move "+qpointToString (QPoint (x,y)),
1760 QString("Move %1 to %2").arg(getName(selection)).arg(ps));
1761 selection->move(x,y);
1762 mapCenter->reposition();
1768 void MapEditor::moveRel (const int &x, const int &y)
1770 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1771 typeid(*selection) == typeid(MapCenterObj) ||
1772 typeid(*selection) == typeid (FloatImageObj)))
1774 QString ps=qpointToString (selection->getRelPos());
1775 QString s=selection->getSelectString();
1778 s, "moveRel "+qpointToString (QPoint (x,y)),
1779 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(ps));
1780 ((OrnamentedObj*)selection)->move2RelPos (x,y);
1781 mapCenter->reposition();
1786 void MapEditor::moveBranchUp()
1790 if (typeid(*selection) == typeid(BranchObj) )
1792 bo=(BranchObj*)selection;
1793 if (!bo->canMoveBranchUp()) return;
1794 par=(BranchObj*)(bo->getParObj());
1795 selection->unselect();
1796 bo=par->moveBranchUp (bo); // bo will be the one below selection
1797 selection->select();
1798 saveState (selection,"moveBranchDown ()",bo,"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
1799 mapCenter->reposition();
1800 ensureSelectionVisible();
1804 void MapEditor::moveBranchDown()
1808 if (typeid(*selection) == typeid(BranchObj) )
1810 bo=(BranchObj*)selection;
1811 if (!bo->canMoveBranchDown()) return;
1812 par=(BranchObj*)(bo->getParObj());
1813 selection->unselect();
1814 bo=par->moveBranchDown(bo); // bo will be the one above selection
1815 selection->select();
1816 saveState(selection,"moveBranchUp ()",bo,"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
1817 mapCenter->reposition();
1818 ensureSelectionVisible();
1822 QString MapEditor::getHeading(bool &ok, QPoint &p)
1825 (typeid(*selection) == typeid(BranchObj) ||
1826 typeid(*selection) == typeid(MapCenterObj) ) )
1829 ensureSelectionVisible();
1830 p = ((BranchObj*)selection)->getAbsPos();
1831 p.setX (p.x() - contentsX());
1832 p.setY (p.y() - contentsY() + ((BranchObj*)selection)->height()/2);
1833 return ((BranchObj*)selection)->getHeading();
1839 void MapEditor::setHeading(const QString &s)
1842 (typeid(*selection) == typeid(BranchObj) ||
1843 typeid(*selection) == typeid(MapCenterObj) ) )
1845 editingBO=(BranchObj*)selection;
1848 "setHeading (\""+editingBO->getHeading()+"\")",
1850 "setHeading (\""+s+"\")",
1851 QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(s) );
1852 editingBO->setHeading(s );
1854 mapCenter->reposition();
1856 ensureSelectionVisible();
1860 void MapEditor::setURLInt (const QString &s)
1862 // Internal function, no saveState needed
1864 (typeid(*selection) == typeid(BranchObj) ||
1865 typeid(*selection) == typeid(MapCenterObj) ) )
1867 ((BranchObj*)selection)->setURL(s);
1868 mapCenter->reposition();
1870 ensureSelectionVisible();
1874 void MapEditor::setHeadingInt(const QString &s)
1877 (typeid(*selection) == typeid(BranchObj) ||
1878 typeid(*selection) == typeid(MapCenterObj) ) )
1880 ((BranchObj*)selection)->setHeading(s);
1881 mapCenter->reposition();
1883 ensureSelectionVisible();
1887 void MapEditor::setVymLinkInt (const QString &s)
1889 // Internal function, no saveState needed
1891 (typeid(*selection) == typeid(BranchObj) ||
1892 typeid(*selection) == typeid(MapCenterObj) ) )
1894 ((BranchObj*)selection)->setVymLink(s);
1895 mapCenter->reposition();
1897 ensureSelectionVisible();
1901 BranchObj* MapEditor::addNewBranchInt(int num)
1903 // Depending on pos:
1904 // -3 insert in childs of parent above selection
1905 // -2 add branch to selection
1906 // -1 insert in childs of parent below selection
1907 // 0..n insert in childs of parent at pos
1908 BranchObj *newbo=NULL;
1910 (typeid(*selection) == typeid(BranchObj) ||
1911 typeid(*selection) == typeid(MapCenterObj) ) )
1913 BranchObj* bo = (BranchObj*) selection;
1916 // save scroll state. If scrolled, automatically select
1917 // new branch in order to tmp unscroll parent...
1918 return bo->addBranch();
1923 bo=(BranchObj*)bo->getParObj();
1927 bo=(BranchObj*)bo->getParObj();
1930 newbo=bo->insertBranch(num);
1935 BranchObj* MapEditor::addNewBranch(int pos)
1937 // Different meaning than num in addNewBranchInt!
1941 BranchObj *bo = (BranchObj*) selection;
1942 BranchObj *newbo=NULL;
1945 (typeid(*selection) == typeid(BranchObj) ||
1946 typeid(*selection) == typeid(MapCenterObj) ) )
1948 newbo=addNewBranchInt (pos-2);
1953 selection, // FIXME sholdnt newbo be deleted here???
1956 QString ("addBranch (%1)").arg(pos-2),
1957 QString ("Add new branch to %1").arg(getName(bo)));
1959 mapCenter->reposition();
1967 BranchObj* MapEditor::addNewBranchBefore()
1969 BranchObj *newbo=NULL;
1971 (typeid(*selection) == typeid(BranchObj) ) )
1972 // We accept no MapCenterObj here, so we _have_ a parent
1974 BranchObj* bo = (BranchObj*) selection;
1975 QPoint p=bo->getRelPos();
1978 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1980 // add below selection
1981 newbo=parbo->insertBranch(bo->getNum()+1);
1984 newbo->move2RelPos (p);
1986 // Move selection to new branch
1987 ((BranchObj*)selection)->moveBranchTo (newbo,-1);
1989 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
1990 QString ("Add branch before %1").arg(getName(bo)));
1992 mapCenter->reposition();
1999 void MapEditor::deleteSelection()
2001 if (selection && typeid(*selection) ==typeid(BranchObj) )
2003 BranchObj* bo=(BranchObj*)selection;
2004 BranchObj* par=(BranchObj*)(bo->getParObj());
2006 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2008 par->removeBranch(bo);
2010 selection->select();
2011 ensureSelectionVisible();
2012 mapCenter->reposition();
2015 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
2017 FloatImageObj* fio=(FloatImageObj*)selection;
2018 BranchObj* par=(BranchObj*)(fio->getParObj());
2019 saveStateChangingPart(
2023 QString("Delete %1").arg(getName(fio))
2027 par->removeFloatImage(fio);
2029 selection->select();
2030 ensureSelectionVisible();
2031 mapCenter->reposition();
2036 LinkableMapObj* MapEditor::getSelection()
2041 void MapEditor::unselect()
2045 selectionLast=selection;
2046 selection->unselect();
2051 void MapEditor::reselect()
2055 selection=selectionLast;
2056 selection->select();
2061 bool MapEditor::select (const QString &s)
2063 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2065 // Finally select the found object
2068 if (selection) unselect();
2070 selection->select();
2072 ensureSelectionVisible();
2078 QString MapEditor::getSelectString()
2080 if (selection) return selection->getSelectString();
2084 void MapEditor::selectInt (LinkableMapObj *lmo)
2086 if (lmo && selection != lmo)
2088 // select the MapObj
2089 if (selection) selection->unselect();
2091 selection->select();
2097 void MapEditor::selectNextBranchInt()
2099 // Increase number of branch
2102 QString s=selection->getSelectString();
2108 part=s.section(",",-1);
2110 num=part.right(part.length() - 3);
2112 s=s.left (s.length() -num.length());
2115 num=QString ("%1").arg(num.toUInt()+1);
2119 // Try to select this one
2120 if (select (s)) return;
2122 // We have no direct successor,
2123 // try to increase the parental number in order to
2124 // find a successor with same depth
2126 int d=selection->getDepth();
2131 while (!found && d>0)
2133 s=s.section (",",0,d-1);
2134 // replace substring of current depth in s with "1"
2135 part=s.section(",",-1);
2137 num=part.right(part.length() - 3);
2141 // increase number of parent
2142 num=QString ("%1").arg(num.toUInt()+1);
2143 s=s.section (",",0,d-2) + ","+ typ+num;
2146 // Special case, look at orientation
2147 if (selection->getOrientation()==OrientRightOfCenter)
2148 num=QString ("%1").arg(num.toUInt()+1);
2150 num=QString ("%1").arg(num.toUInt()-1);
2155 // pad to oldDepth, select the first branch for each depth
2156 for (i=d;i<oldDepth;i++)
2161 if ( ((BranchObj*)selection)->countBranches()>0)
2169 // try to select the freshly built string
2177 void MapEditor::selectPrevBranchInt()
2179 // Decrease number of branch
2182 QString s=selection->getSelectString();
2188 part=s.section(",",-1);
2190 num=part.right(part.length() - 3);
2192 s=s.left (s.length() -num.length());
2195 num=QString ("%1").arg(num.toUInt()-1);
2199 // Try to select this one
2200 if (select (s)) return;
2202 // We have no direct precessor,
2203 // try to decrease the parental number in order to
2204 // find a precessor with same depth
2206 int d=selection->getDepth();
2211 while (!found && d>0)
2213 s=s.section (",",0,d-1);
2214 // replace substring of current depth in s with "1"
2215 part=s.section(",",-1);
2217 num=part.right(part.length() - 3);
2221 // decrease number of parent
2222 num=QString ("%1").arg(num.toUInt()-1);
2223 s=s.section (",",0,d-2) + ","+ typ+num;
2226 // Special case, look at orientation
2227 if (selection->getOrientation()==OrientRightOfCenter)
2228 num=QString ("%1").arg(num.toUInt()-1);
2230 num=QString ("%1").arg(num.toUInt()+1);
2235 // pad to oldDepth, select the last branch for each depth
2236 for (i=d;i<oldDepth;i++)
2240 if ( ((BranchObj*)selection)->countBranches()>0)
2241 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
2248 // try to select the freshly built string
2256 void MapEditor::selectUpperBranch()
2260 if (typeid(*selection) == typeid(BranchObj))
2262 if (selection->getOrientation()==OrientRightOfCenter)
2263 selectPrevBranchInt();
2265 if (selection->getDepth()==1)
2266 selectNextBranchInt();
2268 selectPrevBranchInt();
2273 void MapEditor::selectLowerBranch()
2277 if (typeid(*selection) == typeid(BranchObj))
2279 if (selection->getOrientation()==OrientRightOfCenter)
2280 selectNextBranchInt();
2282 if (selection->getDepth()==1)
2283 selectPrevBranchInt();
2285 selectNextBranchInt();
2291 void MapEditor::selectLeftBranch()
2297 if (typeid(*selection) == typeid(MapCenterObj))
2299 par= (BranchObj*) selection;
2300 bo=par->getLastSelectedBranch();
2303 // Workaround for reselecting on left and right side
2304 if (bo->getOrientation()==OrientRightOfCenter)
2306 bo=par->getLastBranch();
2312 selection->select();
2314 ensureSelectionVisible();
2319 par=(BranchObj*)(selection->getParObj());
2320 if (selection->getOrientation()==OrientRightOfCenter)
2322 if (typeid(*selection) == typeid(BranchObj) ||
2323 typeid(*selection) == typeid(FloatImageObj))
2325 selection->unselect();
2327 selection->select();
2329 ensureSelectionVisible();
2333 if (typeid(*selection) == typeid(BranchObj) )
2335 bo=((BranchObj*)selection)->getLastSelectedBranch();
2338 selection->unselect();
2340 selection->select();
2342 ensureSelectionVisible();
2350 void MapEditor::selectRightBranch()
2357 if (typeid(*selection) == typeid(MapCenterObj))
2359 par= (BranchObj*) selection;
2360 bo=par->getLastSelectedBranch();
2363 // Workaround for reselecting on left and right side
2364 if (bo->getOrientation()==OrientLeftOfCenter)
2365 bo=par->getFirstBranch();
2370 selection->select();
2371 ensureSelectionVisible();
2376 par=(BranchObj*)(selection->getParObj());
2377 if (selection->getOrientation()==OrientLeftOfCenter)
2379 if (typeid(*selection) == typeid(BranchObj) ||
2380 typeid(*selection) == typeid(FloatImageObj))
2382 selection->unselect();
2384 selection->select();
2386 ensureSelectionVisible();
2390 if (typeid(*selection) == typeid(BranchObj) )
2392 bo=((BranchObj*)selection)->getLastSelectedBranch();
2395 selection->unselect();
2397 selection->select();
2399 ensureSelectionVisible();
2407 void MapEditor::selectFirstBranch()
2413 if (typeid(*selection) == typeid(BranchObj))
2415 bo1= (BranchObj*) selection;
2416 par=(BranchObj*)(bo1->getParObj());
2417 bo2=par->getFirstBranch();
2421 selection->select();
2422 ensureSelectionVisible();
2429 void MapEditor::selectLastBranch()
2435 if (typeid(*selection) == typeid(BranchObj))
2437 bo1= (BranchObj*) selection;
2438 par=(BranchObj*)(bo1->getParObj());
2439 bo2=par->getLastBranch();
2443 selection->select();
2444 ensureSelectionVisible();
2451 void MapEditor::selectMapBackgroundColor()
2453 QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
2454 if ( !col.isValid() ) return;
2455 setBackgroundColor( col );
2459 void MapEditor::setMapBackgroundColor(QColor col)
2461 QColor oldcol=mapCanvas->backgroundColor();
2464 QString ("setMapBackgroundColor (%1)").arg(oldcol.name()),
2466 QString ("setMapBackgroundColor (%1)").arg(col.name()),
2467 QString("Set background color of map to %1").arg(col.name()));
2468 mapCanvas->setBackgroundColor (col);
2471 QColor MapEditor::getMapBackgroundColor()
2473 return mapCanvas->backgroundColor();
2476 QColor MapEditor::getCurrentHeadingColor()
2480 if (typeid(*selection) == typeid(BranchObj) ||
2481 typeid(*selection) == typeid(MapCenterObj))
2483 BranchObj *bo=(BranchObj*)selection;
2484 return bo->getColor();
2488 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
2492 void MapEditor::colorItem(QColor c)
2496 if (typeid(*selection) == typeid(BranchObj) ||
2497 typeid(*selection) == typeid(MapCenterObj))
2499 BranchObj *bo=(BranchObj*)selection;
2502 QString ("colorItem (%1)").arg(bo->getColor().name()),
2504 QString ("colorItem (%1)").arg(c.name()),
2505 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
2507 bo->setColor(c); // color branch
2512 void MapEditor::colorBranch(QColor c)
2516 if (typeid(*selection) == typeid(BranchObj) ||
2517 typeid(*selection) == typeid(MapCenterObj))
2519 BranchObj *bo=(BranchObj*)selection;
2520 saveStateChangingPart(
2523 QString ("colorBranch (%1)").arg(c.name()),
2524 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
2526 bo->setColorChilds(c); // color links, color childs
2532 void MapEditor::toggleStandardFlag(QString f)
2536 if (typeid(*selection) == typeid(BranchObj) ||
2537 typeid(*selection) == typeid(MapCenterObj))
2539 BranchObj *bo=(BranchObj*)selection;
2541 if (bo->isSetStandardFlag(f))
2553 QString("%1 (\"%2\")").arg(u).arg(f),
2555 QString("%1 (\"%2\")").arg(r).arg(f),
2556 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2557 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
2563 void MapEditor::setViewCenter()
2565 // transform to CanvasView Coord:
2566 QPoint p=worldMatrix().map(movingCenter);
2567 center ( p.x(), p.y());
2571 BranchObj* MapEditor::findText (QString s, bool cs)
2573 QTextDocument::FindFlags flags=0;
2574 if (cs) flags=QTextDocument::FindCaseSensitively;
2577 { // Nothing found or new find process
2579 // nothing found, start again
2581 itFind=mapCenter->first();
2583 bool searching=true;
2584 bool foundNote=false;
2585 while (searching && !EOFind)
2589 // Searching in Note
2590 if (itFind->getNote().contains(s,cs))
2592 if (selection!=itFind)
2594 if (selection) ((BranchObj*)selection)->unselect();
2596 selection->select();
2598 ensureSelectionVisible();
2600 if (textEditor->findText(s,flags))
2606 // Searching in Heading
2607 if (searching && itFind->getHeading().contains (s,cs) )
2609 if (selection) ((BranchObj*)selection)->unselect();
2611 selection->select();
2613 ensureSelectionVisible();
2619 itFind=itFind->next();
2620 if (!itFind) EOFind=true;
2626 return (BranchObj*)selection;
2631 void MapEditor::findReset()
2632 { // Necessary if text to find changes during a find process
2636 void MapEditor::setURL(const QString &url)
2638 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2639 typeid(*selection) == typeid(MapCenterObj)) )
2641 BranchObj *bo=(BranchObj*)selection;
2642 QString oldurl=bo->getURL();
2646 QString ("setURL (\"%1\")").arg(oldurl),
2648 QString ("setURL (\"%1\")").arg(url),
2649 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
2655 void MapEditor::editURL()
2657 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2658 typeid(*selection) == typeid(MapCenterObj)) )
2661 BranchObj *bo=(BranchObj*)selection;
2662 QString text = QInputDialog::getText(
2663 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2664 bo->getURL(), &ok, this );
2666 // user entered something and pressed OK
2671 QString MapEditor::getURL()
2673 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2674 typeid(*selection) == typeid(MapCenterObj)) )
2675 return ((BranchObj*)selection)->getURL();
2680 QStringList MapEditor::getURLs()
2683 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2684 typeid(*selection) == typeid(MapCenterObj)) )
2686 BranchObj *bo=(BranchObj*)selection;
2690 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
2698 void MapEditor::editHeading2URL()
2700 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2701 typeid(*selection) == typeid(MapCenterObj)) )
2702 setURL (((BranchObj*)selection)->getHeading());
2705 void MapEditor::editBugzilla2URL()
2707 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2708 typeid(*selection) == typeid(MapCenterObj)) )
2710 BranchObj *bo=(BranchObj*)selection;
2711 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2716 void MapEditor::editFATE2URL()
2718 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2719 typeid(*selection) == typeid(MapCenterObj)) )
2721 BranchObj *bo=(BranchObj*)selection;
2722 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2725 "setURL (\""+bo->getURL()+"\")",
2727 "setURL (\""+url+"\")",
2728 QString("Use heading of %1 as link to FATE").arg(getName(bo))
2735 void MapEditor::editVymLink()
2737 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2738 typeid(*selection) == typeid(MapCenterObj)) )
2740 BranchObj *bo=(BranchObj*)selection;
2741 QStringList filters;
2742 filters <<"VYM map (*.vym)";
2743 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
2744 fd->setFilters (filters);
2745 fd->setCaption(vymName+" - " +tr("Link to another map"));
2746 if (! bo->getVymLink().isEmpty() )
2747 fd->selectFile( bo->getVymLink() );
2751 if ( fd->exec() == QDialog::Accepted )
2755 "setVymLink (\""+bo->getVymLink()+"\")",
2757 "setVymLink (\""+fd->selectedFile()+"\")",
2758 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
2760 bo->setVymLink (fd->selectedFile() );
2762 mapCenter->reposition();
2769 void MapEditor::deleteVymLink()
2771 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2772 typeid(*selection) == typeid(MapCenterObj)) )
2774 BranchObj *bo=(BranchObj*)selection;
2777 "setVymLink (\""+bo->getVymLink()+"\")",
2779 "setVymLink (\"\")",
2780 QString("Unset vymlink of %1").arg(getName(bo))
2782 bo->setVymLink ("" );
2784 mapCenter->reposition();
2790 void MapEditor::setHideExport(bool b)
2792 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2793 typeid(*selection)==typeid(FloatImageObj)))
2795 OrnamentedObj *oo=(OrnamentedObj*)selection;
2796 oo->setHideInExport (b);
2797 QString u= b ? "false" : "true";
2798 QString r=!b ? "false" : "true";
2802 QString ("setHideExport (%1)").arg(u),
2804 QString ("setHideExport (%1)").arg(r),
2805 QString ("Set HideExport flag of %1 to %2").arg(getName(oo)).arg (r)
2808 mapCenter->reposition();
2814 void MapEditor::toggleHideExport()
2816 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2817 typeid(*selection)==typeid(FloatImageObj)))
2818 setHideExport ( !((OrnamentedObj*)selection)->hideInExport() );
2821 QString MapEditor::getVymLink()
2823 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2824 typeid(*selection) == typeid(MapCenterObj)) )
2826 return ((BranchObj*)selection)->getVymLink();
2832 QStringList MapEditor::getVymLinks()
2835 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2836 typeid(*selection) == typeid(MapCenterObj)) )
2838 BranchObj *bo=(BranchObj*)selection;
2842 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
2850 void MapEditor::deleteKeepChilds()
2852 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2854 BranchObj* bo=(BranchObj*)selection;
2855 BranchObj* par=(BranchObj*)(bo->getParObj());
2856 QPoint p=bo->getRelPos();
2857 saveStateChangingPart(
2858 selection->getParObj(),
2860 "deleteKeepChilds ()",
2861 QString("Remove %1 and keep its childs").arg(getName(bo))
2864 QString sel=selection->getSelectString();
2866 par->removeBranchHere(bo);
2867 mapCenter->reposition();
2869 ((BranchObj*)selection)->move2RelPos (p);
2870 mapCenter->reposition();
2875 void MapEditor::deleteChilds()
2877 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2878 typeid(*selection)==typeid(MapCenterObj)))
2880 saveStateChangingPart(
2881 selection->getParObj(),
2884 QString( "Remove childs of branch %1").arg(getName(selection))
2886 ((BranchObj*)selection)->removeChilds();
2887 mapCenter->reposition();
2891 void MapEditor::editMapInfo()
2893 ExtraInfoDialog dia;
2894 dia.setMapName (getFileName() );
2895 dia.setAuthor (mapCenter->getAuthor() );
2896 dia.setComment(mapCenter->getComment() );
2901 Q3CanvasItemList l=canvas()->allItems();
2902 for (Q3CanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
2904 stats+=QString ("%1 items on canvas\n").arg (i,6);
2911 bo=mapCenter->first();
2914 if (!bo->getNote().isEmpty() ) n++;
2915 f+= bo->countFloatImages();
2917 xl+=bo->countXLinks();
2920 stats+=QString ("%1 branches\n").arg (b-1,6);
2921 stats+=QString ("%1 xLinks \n").arg (xl,6);
2922 stats+=QString ("%1 notes\n").arg (n,6);
2923 stats+=QString ("%1 images\n").arg (f,6);
2924 dia.setStats (stats);
2926 // Finally show dialog
2927 if (dia.exec() == QDialog::Accepted)
2929 setMapAuthor (dia.getAuthor() );
2930 setMapComment (dia.getComment() );
2934 void MapEditor::updateActions()
2936 mainWindow->updateActions();
2937 // FIXME maybe don't update if blockReposition is set
2940 void MapEditor::updateNoteFlag()
2943 if ( (typeid(*selection) == typeid(BranchObj)) ||
2944 (typeid(*selection) == typeid(MapCenterObj)) )
2945 ((BranchObj*)selection)->updateNoteFlag();
2948 void MapEditor::setMapAuthor (const QString &s)
2952 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
2954 QString ("setMapAuthor (\"%1\")").arg(s),
2955 QString ("Set author of map to \"%1\"").arg(s)
2957 mapCenter->setAuthor (s);
2960 void MapEditor::setMapComment (const QString &s)
2964 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
2966 QString ("setMapComment (\"%1\")").arg(s),
2967 QString ("Set comment of map")
2969 mapCenter->setComment (s);
2972 void MapEditor::setMapLinkStyle (const QString & s)
2974 saveStateChangingPart (
2977 QString("setMapLinkStyle (\"%1\")").arg(s),
2978 QString("Set map link style (\"%1\")").arg(s)
2982 linkstyle=StyleLine;
2983 else if (s=="StyleParabel")
2984 linkstyle=StyleParabel;
2985 else if (s=="StylePolyLine")
2986 linkstyle=StylePolyLine;
2988 linkstyle=StylePolyParabel;
2991 bo=mapCenter->first();
2995 bo->setLinkStyle(bo->getDefLinkStyle());
2998 mapCenter->reposition();
3001 LinkStyle MapEditor::getMapLinkStyle ()
3006 void MapEditor::setMapDefLinkColor(QColor c)
3012 void MapEditor::setMapLinkColorHintInt()
3014 // called from setMapLinkColorHint(lch) or at end of parse
3016 bo=mapCenter->first();
3024 void MapEditor::setMapLinkColorHint(LinkColorHint lch)
3027 setMapLinkColorHintInt();
3030 void MapEditor::toggleMapLinkColorHint()
3032 if (linkcolorhint==HeadingColor)
3033 linkcolorhint=DefaultColor;
3035 linkcolorhint=HeadingColor;
3037 bo=mapCenter->first();
3045 LinkColorHint MapEditor::getMapLinkColorHint()
3047 return linkcolorhint;
3050 QColor MapEditor::getMapDefLinkColor()
3052 return defLinkColor;
3055 void MapEditor::setMapDefXLinkColor(QColor col)
3060 QColor MapEditor::getMapDefXLinkColor()
3062 return defXLinkColor;
3065 void MapEditor::setMapDefXLinkWidth (int w)
3070 int MapEditor::getMapDefXLinkWidth()
3072 return defXLinkWidth;
3075 void MapEditor::selectMapLinkColor()
3077 QColor col = QColorDialog::getColor( defLinkColor, this );
3078 if ( !col.isValid() ) return;
3081 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3083 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3084 QString("Set link color to %1").arg(col.name())
3086 setMapDefLinkColor( col );
3090 void MapEditor::toggleScroll()
3092 if (selection && (typeid(*selection) == typeid(BranchObj)) )
3094 BranchObj *bo=((BranchObj*)selection);
3095 if (bo->countBranches()==0) return;
3096 if (bo->getDepth()==0) return;
3098 if (bo->isScrolled())
3110 QString ("%1 ()").arg(u),
3112 QString ("%1 ()").arg(r),
3113 QString ("%1 %2").arg(r).arg(getName(bo))
3121 void MapEditor::unScrollAll()
3124 bo=mapCenter->first();
3127 if (bo->isScrolled()) bo->toggleScroll();
3132 void MapEditor::loadFloatImage ()
3135 (typeid(*selection) == typeid(BranchObj)) ||
3136 (typeid(*selection) == typeid(MapCenterObj)) )
3138 BranchObj *bo=((BranchObj*)selection);
3140 Q3FileDialog *fd=new Q3FileDialog( this);
3141 fd->setMode (Q3FileDialog::ExistingFiles);
3142 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3143 ImagePreview *p =new ImagePreview (fd);
3144 fd->setContentsPreviewEnabled( TRUE );
3145 fd->setContentsPreview( p, p );
3146 fd->setPreviewMode( Q3FileDialog::Contents );
3147 fd->setCaption(vymName+" - " +tr("Load image"));
3148 fd->setDir (lastImageDir);
3152 if ( fd->exec() == QDialog::Accepted )
3154 // FIXME in QT4 use: lastImageDir=fd->directory();
3155 lastImageDir=QDir (fd->dirPath());
3156 QStringList flist = fd->selectedFiles();
3157 QStringList::Iterator it = flist.begin();
3159 while( it != flist.end() )
3162 bo->addFloatImage();
3163 fio=bo->getLastFloatImage();
3165 // FIXME check if load of fio was successful
3167 (LinkableMapObj*)fio,
3170 QString ("loadFloatImage (%1)").arg(*it),
3171 QString("Add floatimage %1 to %2").arg(*it).arg(getName(selection))
3173 bo->getLastFloatImage()->setOriginalFilename(fn);
3177 mapCenter->reposition();
3186 void MapEditor::saveFloatImage ()
3189 (typeid(*selection) == typeid(FloatImageObj)) )
3191 FloatImageObj *fio=((FloatImageObj*)selection);
3192 QFileDialog *fd=new QFileDialog( this);
3193 fd->setFilters (imageIO.getFilters());
3194 fd->setCaption(vymName+" - " +tr("Save image"));
3195 fd->setFileMode( QFileDialog::AnyFile );
3196 fd->setDirectory (lastImageDir);
3197 // fd->setSelection (fio->getOriginalFilename());
3201 if ( fd->exec() == QDialog::Accepted )
3203 if (QFile (fd->selectedFile()).exists() )
3205 QMessageBox mb( vymName,
3206 tr("The file %1 exists already.\n"
3207 "Do you want to overwrite it?").arg(fd->selectedFile()),
3208 QMessageBox::Warning,
3209 QMessageBox::Yes | QMessageBox::Default,
3210 QMessageBox::Cancel | QMessageBox::Escape,
3211 QMessageBox::QMessageBox::NoButton );
3213 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3214 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3217 case QMessageBox::Yes:
3220 case QMessageBox::Cancel:
3227 fio->save (fd->selectedFile(),imageIO.getType (fd->selectedFilter() ) );
3233 void MapEditor::setFrame(const FrameType &t)
3236 (typeid(*selection) == typeid(BranchObj)) ||
3237 (typeid(*selection) == typeid(MapCenterObj)) )
3239 selection->setFrameType (t);
3240 mapCenter->reposition();
3241 selection->updateLink();
3245 void MapEditor::setIncludeImagesVer(bool b)
3248 (typeid(*selection) == typeid(BranchObj)) ||
3249 (typeid(*selection) == typeid(MapCenterObj)) )
3250 ((BranchObj*)selection)->setIncludeImagesVer(b);
3251 mapCenter->reposition();
3254 void MapEditor::setIncludeImagesHor(bool b)
3257 (typeid(*selection) == typeid(BranchObj)) ||
3258 (typeid(*selection) == typeid(MapCenterObj)) )
3259 ((BranchObj*)selection)->setIncludeImagesHor(b);
3260 mapCenter->reposition();
3263 void MapEditor::setHideLinkUnselected (bool b)
3266 (typeid(*selection) == typeid(BranchObj)) ||
3267 (typeid(*selection) == typeid(MapCenterObj)) ||
3268 (typeid(*selection) == typeid(FloatImageObj)) )
3269 selection->setHideLinkUnselected(b);
3272 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3275 (typeid(*selection) == typeid(BranchObj)) ||
3276 (typeid(*selection) == typeid(MapCenterObj)) )
3280 // Traverse directories
3281 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3282 QFileInfoList list = d.entryInfoList();
3285 for (int i = 0; i < list.size(); ++i)
3288 if (fi.fileName() != "." && fi.fileName() != ".." )
3291 bo=dst->getLastBranch();
3292 bo->setHeading (fi.fileName() );
3293 bo->setColor (QColor("blue"));
3295 if ( !d.cd(fi.fileName()) )
3296 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3299 // Recursively add subdirs
3300 importDirInt (bo,d);
3306 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3307 list = d.entryInfoList();
3309 for (int i = 0; i < list.size(); ++i)
3313 bo=dst->getLastBranch();
3314 bo->setHeading (fi.fileName() );
3315 bo->setColor (QColor("black"));
3316 if (fi.fileName().right(4) == ".vym" )
3317 bo->setVymLink (fi.filePath());
3322 void MapEditor::importDir()
3325 (typeid(*selection) == typeid(BranchObj)) ||
3326 (typeid(*selection) == typeid(MapCenterObj)) )
3328 QStringList filters;
3329 filters <<"VYM map (*.vym)";
3330 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
3331 fd->setMode (QFileDialog::DirectoryOnly);
3332 fd->setFilters (filters);
3333 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
3337 if ( fd->exec() == QDialog::Accepted )
3339 BranchObj *bo=((BranchObj*)selection);
3340 importDirInt (bo,QDir(fd->selectedFile()) );
3341 mapCenter->reposition();
3348 void MapEditor::followXLink(int i)
3351 (typeid(*selection) == typeid(BranchObj)) ||
3352 (typeid(*selection) == typeid(MapCenterObj)) )
3354 BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
3357 selection->unselect();
3359 selection->select();
3360 ensureSelectionVisible();
3365 void MapEditor::editXLink(int i)
3368 (typeid(*selection) == typeid(BranchObj)) ||
3369 (typeid(*selection) == typeid(MapCenterObj)) )
3371 XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
3374 EditXLinkDialog dia;
3376 dia.setSelection(selection);
3377 if (dia.exec() == QDialog::Accepted)
3379 if (dia.useSettingsGlobal() )
3381 setMapDefXLinkColor (xlo->getColor() );
3382 setMapDefXLinkWidth (xlo->getWidth() );
3384 if (dia.deleteXLink())
3385 ((BranchObj*)selection)->deleteXLinkAt(i);
3386 //saveStateComplete("Edit xLink"); //FIXME undoCommand
3392 void MapEditor::testFunction()
3394 cout << "MapEditor::testFunction() called\n";
3397 (typeid(*selection) == typeid(BranchObj)) ||
3398 (typeid(*selection) == typeid(MapCenterObj)) )
3400 BranchObj* bo=(BranchObj*)selection;
3401 cout << bo->getHeading().ascii() <<" is scrolled: "<<bo->isScrolled()<<endl;
3406 dia.showCancelButton (true);
3407 dia.setText("This is a longer \nWarning");
3409 dia.setCaption("Warning: Flux problem");
3410 dia.setShowAgainName("/warnings/mapeditor");
3412 if (dia.exec()==QDialog::Accepted)
3413 cout << "accepted!\n";
3415 cout << "canceled!\n";
3418 /* Hide hidden stuff temporary, maybe add this as regular function somewhere
3419 if (hidemode==HideNone)
3421 setHideTmpMode (HideExport);
3422 mapCenter->calcBBoxSizeWithChilds();
3423 QRect totalBBox=mapCenter->getTotalBBox();
3424 QRect mapRect=totalBBox;
3425 QCanvasRectangle *frame=NULL;
3427 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3429 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3430 totalBBox.width(), totalBBox.height());
3431 frame=new QCanvasRectangle (mapRect,mapCanvas);
3432 frame->setBrush (QColor(white));
3433 frame->setPen (QColor(black));
3439 setHideTmpMode (HideNone);
3441 cout <<" hidemode="<<hidemode<<endl;
3445 void MapEditor::ensureSelectionVisible()
3449 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
3451 if (selection->getOrientation() == OrientLeftOfCenter)
3452 p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
3454 p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
3455 ensureVisible (p.x(), p.y() );
3460 void MapEditor::updateViewCenter()
3462 // Update movingCenter, so that we can zoom comfortably later
3463 QRect rc = QRect( contentsX(), contentsY(),
3464 visibleWidth(), visibleHeight() );
3465 QRect canvasRect = inverseWorldMatrix().mapRect(rc);
3466 movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
3467 movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
3470 void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e )
3472 // Lineedits are already closed by preceding
3473 // mouseEvent, we don't need to close here.
3475 QPoint p = inverseWorldMatrix().map(e->pos());
3476 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3479 { // MapObj was found
3480 if (selection != lmo)
3482 // select the MapObj
3483 if (selection) selection->unselect();
3485 selection->select();
3491 if (typeid(*selection)==typeid(BranchObj) ||
3492 typeid(*selection)==typeid(MapCenterObj) )
3494 // Context Menu on branch or mapcenter
3496 branchContextMenu->popup(e->globalPos() );
3498 if (typeid(*selection)==typeid(FloatImageObj))
3500 // Context Menu on floatimage
3502 floatimageContextMenu->popup(e->globalPos() );
3506 { // No MapObj found, we are on the Canvas itself
3507 // Context Menu on Canvas
3509 canvasContextMenu->popup(e->globalPos() );
3514 void MapEditor::keyPressEvent(QKeyEvent* e)
3516 if (e->modifiers() && Qt::ControlModifier)
3518 switch (mainWindow->getModMode())
3521 setCursor (PickColorCursor);
3524 setCursor (CopyCursor);
3527 setCursor (XLinkCursor);
3530 setCursor (Qt::ArrowCursor);
3536 void MapEditor::keyReleaseEvent(QKeyEvent* e)
3538 if (!(e->modifiers() && Qt::ControlModifier))
3539 setCursor (Qt::ArrowCursor);
3542 void MapEditor::contentsMousePressEvent(QMouseEvent* e)
3544 // Ignore right clicks, these will go to context menus
3545 if (e->button() == Qt::RightButton )
3551 QPoint p = inverseWorldMatrix().map(e->pos());
3552 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3556 //Take care of clickdesystem flags _or_ modifier modes
3558 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3559 typeid(*lmo)==typeid(MapCenterObj) ))
3561 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3562 if (!foname.isEmpty())
3564 // systemFlag clicked
3568 if (e->state() & Qt::ControlModifier)
3569 mainWindow->editOpenURLTab();
3571 mainWindow->editOpenURL();
3573 else if (foname=="vymLink")
3575 mainWindow->editOpenVymLink();
3576 // tabWidget may change, better return now
3577 // before segfaulting...
3578 } else if (foname=="note")
3579 mainWindow->windowToggleNoteEditor();
3580 else if (foname=="hideInExport")
3585 // No system flag clicked, take care of modmodes
3587 // Special case: CTRL is pressed
3588 if (e->state() & Qt::ControlModifier)
3590 if (mainWindow->getModMode()==ModModeColor)
3593 setCursor (PickColorCursor);
3596 if (mainWindow->getModMode()==ModModeXLink)
3598 BranchObj *bo_begin=NULL;
3600 bo_begin=(BranchObj*)(lmo);
3603 ((typeid(*selection) == typeid(BranchObj)) ||
3604 (typeid(*selection) == typeid(MapCenterObj))) )
3605 bo_begin=(BranchObj*)selection;
3609 linkingObj_src=bo_begin;
3610 tmpXLink=new XLinkObj (mapCanvas);
3611 tmpXLink->setBegin (bo_begin);
3612 tmpXLink->setEnd (p);
3613 tmpXLink->setColor(defXLinkColor);
3614 tmpXLink->setWidth(defXLinkWidth);
3615 tmpXLink->updateXLink();
3616 tmpXLink->setVisibility (true);
3624 // Left Button Move Branches
3625 if (e->button() == Qt::LeftButton )
3627 movingObj_start.setX( p.x() - selection->x() );
3628 movingObj_start.setY( p.y() - selection->y() );
3629 movingObj_orgPos.setX (lmo->x() );
3630 movingObj_orgPos.setY (lmo->y() );
3631 movingObj_orgRelPos=lmo->getRelPos();
3633 // If modMode==copy, then we want to "move" the _new_ object around
3634 // then we need the offset from p to the _old_ selection, because of tmp
3635 if (mainWindow->getModMode()==ModModeCopy &&
3636 e->state() & Qt::ControlModifier)
3638 if (typeid(*selection)==typeid(BranchObj) )
3641 mapCenter->addBranch ((BranchObj*)selection);
3643 selection=mapCenter->getLastBranch();
3644 selection->select();
3645 mapCenter->reposition();
3648 movingObj=selection;
3650 // Middle Button Toggle Scroll
3651 // (On Mac OS X this won't work, but we still have
3652 // a button in the toolbar)
3653 if (e->button() == Qt::MidButton )
3657 { // No MapObj found, we are on the Canvas itself
3658 // Left Button move Pos of CanvasView
3659 if (e->button() == Qt::LeftButton )
3661 movingObj=NULL; // move Content not Obj
3662 movingObj_start=e->globalPos();
3663 movingCont_start=QPoint (contentsX(), contentsY() );
3664 movingVec=QPoint(0,0);
3665 setCursor(HandOpenCursor);
3670 void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
3672 QPoint p = inverseWorldMatrix().map(e->pos());
3674 // Move the selected MapObj
3675 if ( selection && movingObj)
3677 // To avoid jumping of the CanvasView, only
3678 // ensureSelectionVisible, if not tmp linked
3679 if (!selection->hasParObjTmp())
3680 ensureSelectionVisible ();
3682 // Now move the selection, but add relative position
3683 // (movingObj_start) where selection was chosen with
3684 // mousepointer. (This avoids flickering resp. jumping
3685 // of selection back to absPos)
3687 LinkableMapObj *lmosel;
3688 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3690 // Check if we could link
3691 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3694 if (typeid(*selection) == typeid(FloatImageObj))
3696 FloatObj *fo=(FloatObj*)selection;
3697 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3701 // Relink float to new mapcenter or branch, if shift is pressed
3702 // Only relink, if selection really has a new parent
3703 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
3704 ( (typeid(*lmo)==typeid(BranchObj)) ||
3705 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3706 ( lmo != fo->getParObj())
3709 if (typeid(*fo) == typeid(FloatImageObj))
3712 //saveStateComplete(QString("Relink %1 to %2").arg(getName(fo)).arg(getName(lmo) ) );
3713 FloatImageObj *fio=(FloatImageObj*)(fo);
3714 ((BranchObj*)(lmo))->addFloatImage (fio);
3716 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
3717 fio=((BranchObj*)(lmo))->getLastFloatImage();
3720 selection=(LinkableMapObj*)(fio);
3721 selection->select();
3722 movingObj=(MapObj*)(fio);
3726 { // selection != a FloatObj
3727 if (lmosel->getDepth()==0)
3730 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3731 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3733 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3734 mapCenter->updateRelPositions();
3737 if (lmosel->getDepth()==1)
3740 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3741 lmosel->setRelPos();
3744 // Move ordinary branch
3745 if (lmosel->getOrientation() == OrientLeftOfCenter)
3746 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3747 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3748 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3750 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3752 // reposition subbranch
3753 lmosel->reposition();
3755 if (lmo && (lmo!=selection) &&
3756 (typeid(*lmo) == typeid(BranchObj) ||
3757 (typeid(*lmo) == typeid(MapCenterObj) )
3760 if (e->modifiers()==Qt::ControlModifier)
3762 // Special case: CTRL to link below lmo
3763 lmosel->setParObjTmp (lmo,p,+1);
3765 else if (e->modifiers()==Qt::ShiftModifier)
3766 lmosel->setParObjTmp (lmo,p,-1);
3768 lmosel->setParObjTmp (lmo,p,0);
3771 lmosel->unsetParObjTmp();
3775 } // no FloatImageObj
3779 } // selection && moving_obj
3781 // Draw a link from one branch to another
3784 tmpXLink->setEnd (p);
3785 tmpXLink->updateXLink();
3789 if (!movingObj && !pickingColor &&!drawingLink)
3791 QPoint p=e->globalPos();
3792 movingVec.setX(-p.x() + movingObj_start.x() );
3793 movingVec.setY(-p.y() + movingObj_start.y() );
3794 setContentsPos( movingCont_start.x() + movingVec.x(),
3795 movingCont_start.y() + movingVec.y());
3802 void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e)
3804 LinkableMapObj *dst;
3805 // Have we been picking color?
3809 setCursor (Qt::ArrowCursor);
3810 // Check if we are over another branch
3811 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3812 if (dst && selection)
3814 if (e->state() & Qt::ShiftModifier)
3816 ((BranchObj*)selection)->setColor (((BranchObj*)(dst))->getColor());
3817 ((BranchObj*)selection)->setLinkColor ();
3821 ((BranchObj*)selection)->setColorChilds (((BranchObj*)(dst))->getColor());
3822 ((BranchObj*)selection)->setLinkColor ();
3828 // Have we been drawing a link?
3832 // Check if we are over another branch
3833 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3834 if (dst && selection)
3836 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3837 tmpXLink->updateXLink();
3838 tmpXLink->activate();
3839 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //FIXME undoCommand
3848 // Have we been moving something?
3849 if ( selection && movingObj )
3851 if(typeid(*selection)==typeid (FloatImageObj))
3853 // Moved FloatObj. Maybe we need to reposition
3854 FloatImageObj *fo=(FloatImageObj*)selection;
3855 QString pold=qpointToString(movingObj_orgRelPos);
3856 QString pnow=qpointToString(fo->getRelPos());
3862 QString("Move %1 to relativ position %2").arg(getName(selection)).arg(pnow));
3864 // FIXME Why calling parObj here?
3865 selection->getParObj()->requestReposition();
3866 mapCenter->reposition();
3869 // Check if we are over another branch, but ignore
3870 // any found LMOs, which are FloatObjs
3871 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ),
3872 ((LinkableMapObj*)selection) );
3874 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3877 if (typeid(*selection) == typeid(MapCenterObj) )
3878 { // The MapCenter was moved
3879 cout << "FIXME missing savestate...\n";
3882 if (typeid(*selection) == typeid(BranchObj) )
3883 { // A branch was moved
3885 // save the position in case we link to mapcenter
3886 QPoint savePos=QPoint (selection->x(),selection->y() );
3888 // Reset the temporary drawn link to the original one
3889 ((LinkableMapObj*)selection)->unsetParObjTmp();
3891 // For Redo we may need to save original selection
3892 QString preSelStr=selection->getSelectString();
3897 BranchObj* bsel=(BranchObj*)selection;
3898 BranchObj* bdst=(BranchObj*)dst;
3900 QString preParStr=(bsel->getParObj())->getSelectString();
3901 QString preNum=QString::number (bsel->getNum(),10);
3902 QString preDstParStr;
3904 if (e->state() & Qt::ShiftModifier && dst->getParObj())
3906 preDstParStr=dst->getParObj()->getSelectString();
3907 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
3909 if (e->state() & Qt::ControlModifier && dst->getParObj())
3912 preDstParStr=dst->getParObj()->getSelectString();
3913 bsel->moveBranchTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
3916 preDstParStr=dst->getSelectString();
3917 bsel->moveBranchTo (bdst,-1);
3918 if (dst->getDepth()==0) bsel->move (savePos);
3920 QString postSelStr=selection->getSelectString();
3921 QString postNum=QString::number (bsel->getNum(),10);
3923 QString undoCom="linkBranchToPos (\""+
3924 preParStr+ "\"," + preNum +"," +
3925 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
3927 QString redoCom="linkBranchToPos (\""+
3928 preDstParStr + "\"," + postNum + "," +
3929 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
3934 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
3936 if (selection->getDepth()==1)
3938 // The select string might be different _after_ moving around.
3939 // Therefor reposition and then use string of old selection, too
3940 mapCenter->reposition();
3942 QString ps=qpointToString ( ((BranchObj*)selection)->getRelPos() );
3944 selection->getSelectString(), "moveRel "+qpointToString(movingObj_orgRelPos),
3945 preSelStr, "moveRel "+ps,
3946 QString("Move %1 to relative position %2").arg(getName(selection)).arg(ps));
3949 // Draw the original link, before selection was moved around
3950 mapCenter->reposition();
3952 // Finally resize canvas, if needed
3957 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
3960 // maybe we moved View: set old cursor
3961 setCursor (Qt::ArrowCursor);
3965 void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
3967 if (e->button() == Qt::LeftButton )
3969 QPoint p = inverseWorldMatrix().map(e->pos());
3970 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3971 if (lmo) { // MapObj was found
3972 // First select the MapObj than edit heading
3973 if (selection) selection->unselect();
3975 selection->select();
3976 mainWindow->editHeading();
3981 void MapEditor::resizeEvent (QResizeEvent* e)
3983 Q3CanvasView::resizeEvent( e );
3987 void MapEditor::contentsDragEnterEvent(QDragEnterEvent *event)
3990 // for (unsigned int i=0;event->format(i);i++) // Debug mime type
3991 // cerr << event->format(i) << endl;
3994 (typeid(*selection) == typeid(BranchObj)) ||
3995 (typeid(*selection) == typeid(MapCenterObj))) {
3997 // If QImageDrag can decode mime type
3998 if (Q3ImageDrag::canDecode(event)) {
4003 // If image are dragged from firefox
4004 if (event->provides("application/x-moz-file-promise-url") &&
4005 event->provides("application/x-moz-nativeimage")) {
4006 event->accept(true);
4010 // If QUriDrag can decode mime type
4011 if (Q3UriDrag::canDecode(event)) {
4016 // If Uri are dragged from firefox
4017 if (event->provides("_NETSCAPE_URL")){
4022 // If QTextDrag can decode mime type
4023 if (Q3TextDrag::canDecode(event)) {
4032 bool isUnicode16(const QByteArray &d)
4034 // TODO: make more precise check for unicode 16.
4035 // Guess unicode16 if any of second bytes are zero
4036 unsigned int length = max(0,d.size()-2)/2;
4037 for (unsigned int i = 0; i<length ; i++)
4038 if (d.at(i*2+1)==0) return true;
4042 void MapEditor::contentsDropEvent(QDropEvent *event)
4045 (typeid(*selection) == typeid(BranchObj)) ||
4046 (typeid(*selection) == typeid(MapCenterObj)))
4051 if (event->provides("image/png"))
4054 if (Q3ImageDrag::decode(event, pix))
4056 addFloatImageInt(pix);
4062 } else if (event->provides("application/x-moz-file-promise-url") &&
4063 event->provides("application/x-moz-nativeimage"))
4065 // Contains url to the img src in unicode16
4066 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4067 QString url = QString((const QChar*)d.data(),d.size()/2);
4071 } else if (event->provides ("text/uri-list"))
4072 { // Uris provided e.g. by konqueror
4073 Q3UriDrag::decode (event,uris);
4074 } else if (event->provides ("_NETSCAPE_URL"))
4075 { // Uris provided by Mozilla
4076 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4079 } else if (event->provides("text/html")) {
4081 // Handels text mime types
4082 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4083 QByteArray d = event->encodedData("text/html");
4086 text = QString((const QChar*)d.data(),d.size()/2);
4090 textEditor->setText(text);
4094 } else if (event->provides("text/plain")) {
4095 QByteArray d = event->encodedData("text/plain");
4098 text = QString((const QChar*)d.data(),d.size()/2);
4102 textEditor->setText(text);
4114 for (const char* u=uris.first(); u; u=uris.next())
4116 bo=((BranchObj*)selection)->addBranch();
4119 s=Q3UriDrag::uriToLocalFile(u);
4122 QString file = QDir::convertSeparators(s);
4123 heading = QFileInfo(file).baseName();
4125 if (file.endsWith(".vym", false))
4126 bo->setVymLink(file);
4135 if (!heading.isEmpty())
4136 bo->setHeading(heading);
4146 //FIXME saveState has to be called earlier for each of the drops...
4147 //saveStateComplete("Drop Event"); //TODO undo Command
4148 mapCenter->reposition();
4155 void MapEditor::addFloatImageInt (const QPixmap &img)
4158 (typeid(*selection) == typeid(BranchObj)) ||
4159 (typeid(*selection) == typeid(MapCenterObj)) )
4161 BranchObj *bo=((BranchObj*)selection);
4162 //FIXME XXX saveStateChangingPart(selection,QString("Add floatimage to %1").arg(getName(bo)));
4163 //QString fn=fd->selectedFile();
4164 //lastImageDir=fn.left(fn.findRev ("/"));
4165 FloatImageObj *fio=bo->addFloatImage();
4167 fio->setOriginalFilename("Image added by Drag and Drop");
4168 mapCenter->reposition();
4175 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation */*nop*/)
4177 if (!imageBuffer) imageBuffer = new QBuffer();
4178 if (!imageBuffer->isOpen()) {
4179 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4181 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4185 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4187 if (nop->state()==Q3NetworkProtocol::StDone) {
4188 QPixmap img(imageBuffer->buffer());
4189 addFloatImageInt (img);
4193 imageBuffer->close();
4195 imageBuffer->close();
4202 void MapEditor::fetchImage(const QString &url)
4205 urlOperator->stop();
4206 disconnect(urlOperator);
4210 urlOperator = new Q3UrlOperator(url);
4211 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4212 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4214 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4215 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));