3 #include <q3filedialog.h>
12 #include "editxlinkdialog.h"
14 #include "exportxhtmldialog.h"
15 #include "extrainfodialog.h"
17 #include "linkablemapobj.h"
18 #include "mainwindow.h"
20 #include "texteditor.h"
21 #include "warningdialog.h"
25 extern TextEditor *textEditor;
26 extern int statusbarTime;
27 extern Main *mainWindow;
28 extern QString tmpVymDir;
29 extern QString clipboardDir;
30 extern QString clipboardFile;
31 extern bool clipboardEmpty;
33 extern FlagRowObj *standardFlagsDefault;
35 extern QMenu* branchContextMenu;
36 extern QMenu* branchAddContextMenu;
37 extern QMenu* branchRemoveContextMenu;
38 extern QMenu* branchLinksContextMenu;
39 extern QMenu* branchXLinksContextMenuEdit;
40 extern QMenu* branchXLinksContextMenuFollow;
41 extern QMenu* floatimageContextMenu;
42 extern QMenu* canvasContextMenu;
45 extern Settings settings;
46 extern ImageIO imageIO;
48 extern QString vymName;
49 extern QString vymVersion;
51 extern QString iconPath;
52 extern QDir vymBaseDir;
53 extern QDir lastImageDir;
54 extern QDir lastFileDir;
56 int MapEditor::mapNum=0; // make instance
58 ///////////////////////////////////////////////////////////////////////
59 ///////////////////////////////////////////////////////////////////////
60 MapEditor::MapEditor( QWidget* parent) :
63 //cout << "Constructor ME "<<this<<endl;
67 mapScene= new QGraphicsScene(parent);
68 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
69 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
74 mapCenter = new MapCenterObj(mapScene);
75 mapCenter->setVisibility (true);
76 mapCenter->setMapEditor (this);
77 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
78 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
83 defLinkColor=QColor (0,0,255);
84 defXLinkColor=QColor (180,180,180);
85 linkcolorhint=LinkableMapObj::DefaultColor;
86 linkstyle=LinkableMapObj::PolyParabel;
88 // Create bitmap cursors, platform dependant
89 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
90 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
91 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
92 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
94 setFocusPolicy (Qt::StrongFocus);
103 xelection.setMapEditor (this);
104 xelection.unselect();
107 defXLinkColor=QColor (230,230,230);
115 fileName=tr("unnamed");
118 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
119 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
120 mainWindow->updateHistory (undoSet);
122 // Initialize find routine
129 blockReposition=false;
130 blockSaveState=false;
132 hidemode=BranchObj::HideNone;
134 // Create temporary files
141 setAcceptDrops (true);
143 mapCenter->reposition(); // for positioning heading
147 //timerId = startTimer(100);
150 autosaveTimer=new QTimer (this);
151 connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
154 MapEditor::~MapEditor()
156 //cout <<"Destructor MapEditor\n";
157 autosaveTimer->stop();
160 MapCenterObj* MapEditor::getMapCenter()
165 QGraphicsScene * MapEditor::getScene()
170 MapEditor::State MapEditor::getState()
175 void MapEditor::setStateEditHeading(bool s)
179 if (state==Idle) state=EditHeading;
185 bool MapEditor::isRepositionBlocked()
187 return blockReposition;
190 void MapEditor::setSaveStateBlocked(bool b)
195 bool MapEditor::isSelectBlocked()
197 if (state==EditHeading)
203 QString MapEditor::getName (const LinkableMapObj *lmo)
206 if (!lmo) return QString("Error: NULL has no name!");
208 if ((typeid(*lmo) == typeid(BranchObj) ||
209 typeid(*lmo) == typeid(MapCenterObj)))
212 s=(((BranchObj*)lmo)->getHeading());
213 if (s=="") s="unnamed";
214 return QString("branch (%1)").arg(s);
215 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
217 if ((typeid(*lmo) == typeid(FloatImageObj) ))
218 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
219 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
220 return QString("Unknown type has no name!");
223 void MapEditor::makeTmpDirs()
225 // Create unique temporary directories
226 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
227 histPath=QDir::convertSeparators (tmpMapDir+"/history");
232 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
234 // tmpdir temporary directory to which data will be written
235 // prefix mapname, which will be appended to images etc.
236 // writeflags Only write flags for "real" save of map, not undo
237 // offset offset of bbox of whole map in scene.
238 // Needed for XML export
244 case LinkableMapObj::Line:
247 case LinkableMapObj::Parabel:
250 case LinkableMapObj::PolyLine:
254 ls="StylePolyParabel";
258 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
260 if (linkcolorhint==LinkableMapObj::HeadingColor)
261 colhint=attribut("linkColorHint","HeadingColor");
263 QString mapAttr=attribut("version",vymVersion);
264 if (!saveSel || saveSel==mapCenter)
265 mapAttr+= attribut("author",mapCenter->getAuthor()) +
266 attribut("comment",mapCenter->getComment()) +
267 attribut("date",mapCenter->getDate()) +
268 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
269 attribut("selectionColor", xelection.getColor().name() ) +
270 attribut("linkStyle", ls ) +
271 attribut("linkColor", defLinkColor.name() ) +
272 attribut("defXLinkColor", defXLinkColor.name() ) +
273 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
275 s+=beginElement("vymmap",mapAttr);
278 // Find the used flags while traversing the tree
279 standardFlagsDefault->resetUsedCounter();
281 // Reset the counters before saving
282 // TODO constr. of FIO creates lots of objects, better do this in some other way...
283 FloatImageObj (mapScene).resetSaveCounter();
285 // Build xml recursivly
286 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
287 // Save complete map, if saveSel not set
288 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
291 if ( typeid(*saveSel) == typeid(BranchObj) )
293 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
294 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
296 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
299 // Save local settings
300 s+=settings.getXMLData (destPath);
303 if (!xelection.isEmpty() && !saveSel )
304 s+=valueElement("select",xelection.getSelectString());
307 s+=endElement("vymmap");
310 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
314 QString MapEditor::getHistoryDir()
316 QString histName=QDir::convertSeparators (QString("history-%1").arg(curStep));
317 return QDir::convertSeparators (tmpMapDir +"/"+histName);
320 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
322 sendData(redoCom); //FIXME testing
327 if (blockSaveState) return;
329 if (debug) cout << "ME::saveState() for "<<mapName.ascii()<<endl;
331 // Find out current undo directory
332 if (undosAvail<stepsTotal) undosAvail++;
334 if (curStep>stepsTotal) curStep=1;
336 QString backupXML="";
337 QString histDir=getHistoryDir();
338 QString bakMapPath=QDir::convertSeparators(histDir+"/map.xml");
340 // Create histDir if not available
343 makeSubDirs (histDir);
345 // Save depending on how much needs to be saved
347 backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
349 QString undoCommand="";
350 if (savemode==UndoCommand)
354 else if (savemode==PartOfMap )
357 undoCommand.replace ("PATH",bakMapPath);
360 if (!backupXML.isEmpty())
361 // Write XML Data to disk
362 saveStringToDisk (QString(bakMapPath),backupXML);
364 // We would have to save all actions in a tree, to keep track of
365 // possible redos after a action. Possible, but we are too lazy: forget about redos.
368 // Write the current state to disk
369 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
370 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
371 undoSet.setEntry ("/history/curStep",QString::number(curStep));
372 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
373 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
374 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
375 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
376 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
377 undoSet.setEntry (QString("/history/version"),vymVersion);
378 undoSet.writeSettings(histPath);
382 // TODO remove after testing
383 //cout << " into="<< histPath.toStdString()<<endl;
384 cout << " stepsTotal="<<stepsTotal<<
385 ", undosAvail="<<undosAvail<<
386 ", redosAvail="<<redosAvail<<
387 ", curStep="<<curStep<<endl;
388 cout << " ---------------------------"<<endl;
389 cout << " comment="<<comment.toStdString()<<endl;
390 cout << " undoCom="<<undoCommand.toStdString()<<endl;
391 cout << " undoSel="<<undoSelection.toStdString()<<endl;
392 cout << " redoCom="<<redoCom.toStdString()<<endl;
393 cout << " redoSel="<<redoSelection.toStdString()<<endl;
394 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
395 cout << " ---------------------------"<<endl;
398 mainWindow->updateHistory (undoSet);
404 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
406 // save the selected part of the map, Undo will replace part of map
407 QString undoSelection="";
409 undoSelection=undoSel->getSelectString();
411 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
412 QString redoSelection="";
414 redoSelection=undoSel->getSelectString();
416 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
419 saveState (PartOfMap,
420 undoSelection, "addMapReplace (\"PATH\")",
426 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
430 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
433 QString undoSelection=redoSel->getParObj()->getSelectString();
434 QString redoSelection=redoSel->getSelectString();
435 if (typeid(*redoSel) == typeid(BranchObj) )
437 // save the selected branch of the map, Undo will insert part of map
438 saveState (PartOfMap,
439 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
440 redoSelection, "delete ()",
447 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
449 // "Normal" savestate: save commands, selections and comment
450 // so just save commands for undo and redo
451 // and use current selection
453 QString redoSelection="";
454 if (redoSel) redoSelection=redoSel->getSelectString();
455 QString undoSelection="";
456 if (undoSel) undoSelection=undoSel->getSelectString();
458 saveState (UndoCommand,
465 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
467 // "Normal" savestate: save commands, selections and comment
468 // so just save commands for undo and redo
469 // and use current selection
470 saveState (UndoCommand,
478 void MapEditor::parseAtom(const QString &atom)
480 BranchObj *selb=xelection.getBranch();
485 // Split string s into command and parameters
486 parser.parseAtom (atom);
487 QString com=parser.getCommand();
490 /////////////////////////////////////////////////////////////////////
491 if (com=="addBranch")
493 if (xelection.isEmpty())
495 parser.setError (Aborted,"Nothing selected");
498 parser.setError (Aborted,"Type of selection is not a branch");
503 if (parser.checkParCount(pl))
505 if (parser.parCount()==0)
506 addNewBranchInt (-2);
509 y=parser.parInt (ok,0);
510 if (ok ) addNewBranchInt (y);
514 /////////////////////////////////////////////////////////////////////
515 } else if (com=="addBranchBefore")
517 if (xelection.isEmpty())
519 parser.setError (Aborted,"Nothing selected");
522 parser.setError (Aborted,"Type of selection is not a branch");
525 if (parser.parCount()==0)
527 addNewBranchBefore ();
530 /////////////////////////////////////////////////////////////////////
531 } else if (com==QString("addMapReplace"))
533 if (xelection.isEmpty())
535 parser.setError (Aborted,"Nothing selected");
538 parser.setError (Aborted,"Type of selection is not a branch");
539 } else if (parser.checkParCount(1))
541 //s=parser.parString (ok,0); // selection
542 t=parser.parString (ok,0); // path to map
543 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
544 addMapReplaceInt(selb->getSelectString(),t);
546 /////////////////////////////////////////////////////////////////////
547 } else if (com==QString("addMapInsert"))
549 if (xelection.isEmpty())
551 parser.setError (Aborted,"Nothing selected");
554 parser.setError (Aborted,"Type of selection is not a branch");
557 if (parser.checkParCount(2))
559 t=parser.parString (ok,0); // path to map
560 y=parser.parInt(ok,1); // position
561 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
562 addMapInsertInt(t,y);
565 /////////////////////////////////////////////////////////////////////
566 } else if (com=="clearFlags")
568 if (xelection.isEmpty() )
570 parser.setError (Aborted,"Nothing selected");
573 parser.setError (Aborted,"Type of selection is not a branch");
574 } else if (parser.checkParCount(0))
576 selb->clearStandardFlags();
577 selb->updateFlagsToolbar();
579 /////////////////////////////////////////////////////////////////////
580 } else if (com=="colorBranch")
582 if (xelection.isEmpty())
584 parser.setError (Aborted,"Nothing selected");
587 parser.setError (Aborted,"Type of selection is not a branch");
588 } else if (parser.checkParCount(1))
590 QColor c=parser.parColor (ok,0);
591 if (ok) colorBranch (c);
593 /////////////////////////////////////////////////////////////////////
594 } else if (com=="colorSubtree")
596 if (xelection.isEmpty())
598 parser.setError (Aborted,"Nothing selected");
601 parser.setError (Aborted,"Type of selection is not a branch");
602 } else if (parser.checkParCount(1))
604 QColor c=parser.parColor (ok,0);
605 if (ok) colorSubtree (c);
607 /////////////////////////////////////////////////////////////////////
608 } else if (com=="copy")
610 if (xelection.isEmpty())
612 parser.setError (Aborted,"Nothing selected");
615 parser.setError (Aborted,"Type of selection is not a branch");
616 } else if (parser.checkParCount(0))
618 //FIXME missing action for copy
620 /////////////////////////////////////////////////////////////////////
621 } else if (com=="cut")
623 if (xelection.isEmpty())
625 parser.setError (Aborted,"Nothing selected");
626 } else if ( xelection.type()!=Selection::Branch &&
627 xelection.type()!=Selection::MapCenter &&
628 xelection.type()!=Selection::FloatImage )
630 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
631 } else if (parser.checkParCount(0))
635 /////////////////////////////////////////////////////////////////////
636 } else if (com=="delete")
638 if (xelection.isEmpty())
640 parser.setError (Aborted,"Nothing selected");
641 } else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage )
643 parser.setError (Aborted,"Type of selection is wrong.");
644 } else if (parser.checkParCount(0))
648 /////////////////////////////////////////////////////////////////////
649 } else if (com=="deleteKeepChilds")
651 if (xelection.isEmpty())
653 parser.setError (Aborted,"Nothing selected");
656 parser.setError (Aborted,"Type of selection is not a branch");
657 } else if (parser.checkParCount(0))
661 /////////////////////////////////////////////////////////////////////
662 } else if (com=="deleteChilds")
664 if (xelection.isEmpty())
666 parser.setError (Aborted,"Nothing selected");
669 parser.setError (Aborted,"Type of selection is not a branch");
670 } else if (parser.checkParCount(0))
674 /////////////////////////////////////////////////////////////////////
675 } else if (com=="exportASCII")
679 if (parser.parCount()>=2)
680 // Hey, we even have a filename
681 fname=parser.parString(ok,1);
684 parser.setError (Aborted,"Could not read filename");
687 exportASCII (fname,false);
689 /////////////////////////////////////////////////////////////////////
690 } else if (com=="exportImage")
694 if (parser.parCount()>=2)
695 // Hey, we even have a filename
696 fname=parser.parString(ok,1);
699 parser.setError (Aborted,"Could not read filename");
702 QString format="PNG";
703 if (parser.parCount()>2)
705 format=parser.parString(ok,2);
707 exportImage (fname,false,format);
709 /////////////////////////////////////////////////////////////////////
710 } else if (com=="exportXHTML")
714 if (parser.parCount()>=2)
715 // Hey, we even have a filename
716 fname=parser.parString(ok,1);
719 parser.setError (Aborted,"Could not read filename");
722 exportXHTML (fname,false);
724 /////////////////////////////////////////////////////////////////////
725 } else if (com=="exportXML")
729 if (parser.parCount()>=2)
730 // Hey, we even have a filename
731 fname=parser.parString(ok,1);
734 parser.setError (Aborted,"Could not read filename");
737 exportXML (fname,false);
739 /////////////////////////////////////////////////////////////////////
740 } else if (com=="importDir")
742 if (xelection.isEmpty())
744 parser.setError (Aborted,"Nothing selected");
747 parser.setError (Aborted,"Type of selection is not a branch");
748 } else if (parser.checkParCount(1))
750 s=parser.parString(ok,0);
751 if (ok) importDirInt(s);
753 /////////////////////////////////////////////////////////////////////
754 } else if (com=="linkTo")
756 if (xelection.isEmpty())
758 parser.setError (Aborted,"Nothing selected");
761 if (parser.checkParCount(4))
763 // 0 selectstring of parent
764 // 1 num in parent (for branches)
765 // 2,3 x,y of mainbranch or mapcenter
766 s=parser.parString(ok,0);
767 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
770 if (typeid(*dst) == typeid(BranchObj) )
772 // Get number in parent
773 x=parser.parInt (ok,1);
775 selb->linkTo ((BranchObj*)(dst),x);
776 } else if (typeid(*dst) == typeid(MapCenterObj) )
778 selb->linkTo ((BranchObj*)(dst),-1);
779 // Get coordinates of mainbranch
780 x=parser.parInt (ok,2);
783 y=parser.parInt (ok,3);
784 if (ok) selb->move (x,y);
789 } else if ( xelection.type() == Selection::FloatImage)
791 if (parser.checkParCount(1))
793 // 0 selectstring of parent
794 s=parser.parString(ok,0);
795 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
798 if (typeid(*dst) == typeid(BranchObj) ||
799 typeid(*dst) == typeid(MapCenterObj))
800 linkTo (dst->getSelectString());
802 parser.setError (Aborted,"Destination is not a branch");
805 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
806 /////////////////////////////////////////////////////////////////////
807 } else if (com=="loadImage")
809 if (xelection.isEmpty())
811 parser.setError (Aborted,"Nothing selected");
814 parser.setError (Aborted,"Type of selection is not a branch");
815 } else if (parser.checkParCount(1))
817 s=parser.parString(ok,0);
818 if (ok) loadFloatImageInt (s);
820 /////////////////////////////////////////////////////////////////////
821 } else if (com=="moveBranchUp")
823 if (xelection.isEmpty() )
825 parser.setError (Aborted,"Nothing selected");
828 parser.setError (Aborted,"Type of selection is not a branch");
829 } else if (parser.checkParCount(0))
833 /////////////////////////////////////////////////////////////////////
834 } else if (com=="moveBranchDown")
836 if (xelection.isEmpty() )
838 parser.setError (Aborted,"Nothing selected");
841 parser.setError (Aborted,"Type of selection is not a branch");
842 } else if (parser.checkParCount(0))
846 /////////////////////////////////////////////////////////////////////
847 } else if (com=="move")
849 if (xelection.isEmpty() )
851 parser.setError (Aborted,"Nothing selected");
852 } else if ( xelection.type()!=Selection::Branch &&
853 xelection.type()!=Selection::MapCenter &&
854 xelection.type()!=Selection::FloatImage )
856 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
857 } else if (parser.checkParCount(2))
859 x=parser.parInt (ok,0);
862 y=parser.parInt (ok,1);
866 /////////////////////////////////////////////////////////////////////
867 } else if (com=="moveRel")
869 if (xelection.isEmpty() )
871 parser.setError (Aborted,"Nothing selected");
872 } else if ( xelection.type()!=Selection::Selection::Branch &&
873 xelection.type()!=Selection::Selection::MapCenter &&
874 xelection.type()!=Selection::Selection::FloatImage )
876 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
877 } else if (parser.checkParCount(2))
879 x=parser.parInt (ok,0);
882 y=parser.parInt (ok,1);
883 if (ok) moveRel (x,y);
886 /////////////////////////////////////////////////////////////////////
887 } else if (com=="nop")
889 /////////////////////////////////////////////////////////////////////
890 } else if (com=="paste")
892 if (xelection.isEmpty() )
894 parser.setError (Aborted,"Nothing selected");
897 parser.setError (Aborted,"Type of selection is not a branch");
898 } else if (parser.checkParCount(1))
900 x=parser.parInt (ok,0);
901 if (ok) pasteNoSave(x);
903 /////////////////////////////////////////////////////////////////////
904 } else if (com=="qa")
906 if (xelection.isEmpty() )
908 parser.setError (Aborted,"Nothing selected");
911 parser.setError (Aborted,"Type of selection is not a branch");
912 } else if (parser.checkParCount(4))
915 c=parser.parString (ok,0);
918 parser.setError (Aborted,"No comment given");
921 s=parser.parString (ok,1);
924 parser.setError (Aborted,"First parameter is not a string");
927 t=parser.parString (ok,2);
930 parser.setError (Aborted,"Condition is not a string");
933 u=parser.parString (ok,3);
936 parser.setError (Aborted,"Third parameter is not a string");
941 parser.setError (Aborted,"Unknown type: "+s);
946 parser.setError (Aborted,"Unknown operator: "+t);
951 parser.setError (Aborted,"Type of selection is not a branch");
954 if (selb->getHeading() == u)
956 cout << "PASSED: " << c.ascii() << endl;
959 cout << "FAILED: " << c.ascii() << endl;
969 /////////////////////////////////////////////////////////////////////
970 } else if (com=="saveImage")
972 FloatImageObj *fio=xelection.getFloatImage();
975 parser.setError (Aborted,"Type of selection is not an image");
976 } else if (parser.checkParCount(2))
978 s=parser.parString(ok,0);
981 t=parser.parString(ok,1);
982 if (ok) saveFloatImageInt (fio,t,s);
985 /////////////////////////////////////////////////////////////////////
986 } else if (com=="scroll")
988 if (xelection.isEmpty() )
990 parser.setError (Aborted,"Nothing selected");
993 parser.setError (Aborted,"Type of selection is not a branch");
994 } else if (parser.checkParCount(0))
996 if (!scrollBranch (selb))
997 parser.setError (Aborted,"Could not scroll branch");
999 /////////////////////////////////////////////////////////////////////
1000 } else if (com=="select")
1002 if (parser.checkParCount(1))
1004 s=parser.parString(ok,0);
1007 /////////////////////////////////////////////////////////////////////
1008 } else if (com=="selectLastBranch")
1010 if (xelection.isEmpty() )
1012 parser.setError (Aborted,"Nothing selected");
1015 parser.setError (Aborted,"Type of selection is not a branch");
1016 } else if (parser.checkParCount(0))
1018 BranchObj *bo=selb->getLastBranch();
1020 parser.setError (Aborted,"Could not select last branch");
1024 /////////////////////////////////////////////////////////////////////
1025 } else if (com=="selectLastImage")
1027 if (xelection.isEmpty() )
1029 parser.setError (Aborted,"Nothing selected");
1032 parser.setError (Aborted,"Type of selection is not a branch");
1033 } else if (parser.checkParCount(0))
1035 FloatImageObj *fio=selb->getLastFloatImage();
1037 parser.setError (Aborted,"Could not select last image");
1041 /////////////////////////////////////////////////////////////////////
1042 } else if (com=="setFrameType")
1044 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1046 parser.setError (Aborted,"Type of selection does not allow setting frame type");
1048 else if (parser.checkParCount(1))
1050 s=parser.parString(ok,0);
1051 if (ok) setFrameType (s);
1053 /////////////////////////////////////////////////////////////////////
1054 } else if (com=="setFramePenColor")
1056 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1058 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
1060 else if (parser.checkParCount(1))
1062 QColor c=parser.parColor(ok,0);
1063 if (ok) setFramePenColor (c);
1065 /////////////////////////////////////////////////////////////////////
1066 } else if (com=="setFrameBrushColor")
1068 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1070 parser.setError (Aborted,"Type of selection does not allow setting brush color");
1072 else if (parser.checkParCount(1))
1074 QColor c=parser.parColor(ok,0);
1075 if (ok) setFrameBrushColor (c);
1077 /////////////////////////////////////////////////////////////////////
1078 } else if (com=="setFramePadding")
1080 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1082 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
1084 else if (parser.checkParCount(1))
1086 x=parser.parInt(ok,0);
1087 if (ok) setFramePadding(x);
1089 /////////////////////////////////////////////////////////////////////
1090 } else if (com=="setFrameBorderWidth")
1092 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1094 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
1096 else if (parser.checkParCount(1))
1098 x=parser.parInt(ok,0);
1099 if (ok) setFrameBorderWidth (x);
1101 /////////////////////////////////////////////////////////////////////
1102 } else if (com=="setMapAuthor")
1104 if (parser.checkParCount(1))
1106 s=parser.parString(ok,0);
1107 if (ok) setMapAuthor (s);
1109 /////////////////////////////////////////////////////////////////////
1110 } else if (com=="setMapComment")
1112 if (parser.checkParCount(1))
1114 s=parser.parString(ok,0);
1115 if (ok) setMapComment(s);
1117 /////////////////////////////////////////////////////////////////////
1118 } else if (com=="setMapBackgroundColor")
1120 if (xelection.isEmpty() )
1122 parser.setError (Aborted,"Nothing selected");
1123 } else if (! xelection.getBranch() )
1125 parser.setError (Aborted,"Type of selection is not a branch");
1126 } else if (parser.checkParCount(1))
1128 QColor c=parser.parColor (ok,0);
1129 if (ok) setMapBackgroundColor (c);
1131 /////////////////////////////////////////////////////////////////////
1132 } else if (com=="setMapDefLinkColor")
1134 if (xelection.isEmpty() )
1136 parser.setError (Aborted,"Nothing selected");
1139 parser.setError (Aborted,"Type of selection is not a branch");
1140 } else if (parser.checkParCount(1))
1142 QColor c=parser.parColor (ok,0);
1143 if (ok) setMapDefLinkColor (c);
1145 /////////////////////////////////////////////////////////////////////
1146 } else if (com=="setMapLinkStyle")
1148 if (parser.checkParCount(1))
1150 s=parser.parString (ok,0);
1151 if (ok) setMapLinkStyle(s);
1153 /////////////////////////////////////////////////////////////////////
1154 } else if (com=="setHeading")
1156 if (xelection.isEmpty() )
1158 parser.setError (Aborted,"Nothing selected");
1161 parser.setError (Aborted,"Type of selection is not a branch");
1162 } else if (parser.checkParCount(1))
1164 s=parser.parString (ok,0);
1168 /////////////////////////////////////////////////////////////////////
1169 } else if (com=="setHideExport")
1171 if (xelection.isEmpty() )
1173 parser.setError (Aborted,"Nothing selected");
1174 } else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage)
1176 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1177 } else if (parser.checkParCount(1))
1179 b=parser.parBool(ok,0);
1180 if (ok) setHideExport (b);
1182 /////////////////////////////////////////////////////////////////////
1183 } else if (com=="setIncludeImagesHorizontally")
1185 if (xelection.isEmpty() )
1187 parser.setError (Aborted,"Nothing selected");
1190 parser.setError (Aborted,"Type of selection is not a branch");
1191 } else if (parser.checkParCount(1))
1193 b=parser.parBool(ok,0);
1194 if (ok) setIncludeImagesHor(b);
1196 /////////////////////////////////////////////////////////////////////
1197 } else if (com=="setIncludeImagesVertically")
1199 if (xelection.isEmpty() )
1201 parser.setError (Aborted,"Nothing selected");
1204 parser.setError (Aborted,"Type of selection is not a branch");
1205 } else if (parser.checkParCount(1))
1207 b=parser.parBool(ok,0);
1208 if (ok) setIncludeImagesVer(b);
1210 /////////////////////////////////////////////////////////////////////
1211 } else if (com=="setHideLinkUnselected")
1213 if (xelection.isEmpty() )
1215 parser.setError (Aborted,"Nothing selected");
1216 } else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1218 parser.setError (Aborted,"Type of selection does not allow hiding the link");
1219 } else if (parser.checkParCount(1))
1221 b=parser.parBool(ok,0);
1222 if (ok) setHideLinkUnselected(b);
1224 /////////////////////////////////////////////////////////////////////
1225 } else if (com=="setSelectionColor")
1227 if (parser.checkParCount(1))
1229 QColor c=parser.parColor (ok,0);
1230 if (ok) setSelectionColorInt (c);
1232 /////////////////////////////////////////////////////////////////////
1233 } else if (com=="setURL")
1235 if (xelection.isEmpty() )
1237 parser.setError (Aborted,"Nothing selected");
1240 parser.setError (Aborted,"Type of selection is not a branch");
1241 } else if (parser.checkParCount(1))
1243 s=parser.parString (ok,0);
1246 /////////////////////////////////////////////////////////////////////
1247 } else if (com=="setVymLink")
1249 if (xelection.isEmpty() )
1251 parser.setError (Aborted,"Nothing selected");
1254 parser.setError (Aborted,"Type of selection is not a branch");
1255 } else if (parser.checkParCount(1))
1257 s=parser.parString (ok,0);
1258 if (ok) setVymLinkInt(s);
1261 /////////////////////////////////////////////////////////////////////
1262 else if (com=="setFlag")
1264 if (xelection.isEmpty() )
1266 parser.setError (Aborted,"Nothing selected");
1269 parser.setError (Aborted,"Type of selection is not a branch");
1270 } else if (parser.checkParCount(1))
1272 s=parser.parString(ok,0);
1275 selb->activateStandardFlag(s);
1276 selb->updateFlagsToolbar();
1279 /////////////////////////////////////////////////////////////////////
1280 } else if (com=="setFrameType")
1282 if (xelection.isEmpty() )
1284 parser.setError (Aborted,"Nothing selected");
1287 parser.setError (Aborted,"Type of selection is not a branch");
1288 } else if (parser.checkParCount(1))
1290 s=parser.parString(ok,0);
1294 /////////////////////////////////////////////////////////////////////
1295 } else if (com=="toggleFlag")
1297 if (xelection.isEmpty() )
1299 parser.setError (Aborted,"Nothing selected");
1302 parser.setError (Aborted,"Type of selection is not a branch");
1303 } else if (parser.checkParCount(1))
1305 s=parser.parString(ok,0);
1308 selb->toggleStandardFlag(s);
1309 selb->updateFlagsToolbar();
1312 /////////////////////////////////////////////////////////////////////
1313 } else if (com=="unscroll")
1315 if (xelection.isEmpty() )
1317 parser.setError (Aborted,"Nothing selected");
1320 parser.setError (Aborted,"Type of selection is not a branch");
1321 } else if (parser.checkParCount(0))
1323 if (!unscrollBranch (selb))
1324 parser.setError (Aborted,"Could not unscroll branch");
1326 /////////////////////////////////////////////////////////////////////
1327 } else if (com=="unscrollChilds")
1329 if (xelection.isEmpty() )
1331 parser.setError (Aborted,"Nothing selected");
1334 parser.setError (Aborted,"Type of selection is not a branch");
1335 } else if (parser.checkParCount(0))
1339 /////////////////////////////////////////////////////////////////////
1340 } else if (com=="unsetFlag")
1342 if (xelection.isEmpty() )
1344 parser.setError (Aborted,"Nothing selected");
1347 parser.setError (Aborted,"Type of selection is not a branch");
1348 } else if (parser.checkParCount(1))
1350 s=parser.parString(ok,0);
1353 selb->deactivateStandardFlag(s);
1354 selb->updateFlagsToolbar();
1358 parser.setError (Aborted,"Unknown command");
1361 if (parser.errorLevel()==NoError)
1364 mapCenter->reposition();
1368 // TODO Error handling
1369 qWarning("MapEditor::parseAtom: Error!");
1370 qWarning(parser.errorMessage());
1374 void MapEditor::runScript (QString script)
1376 parser.setScript (script);
1378 while (parser.next() )
1379 parseAtom(parser.getAtom());
1382 bool MapEditor::isDefault()
1387 bool MapEditor::hasChanged()
1392 void MapEditor::setChanged()
1395 autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
1403 void MapEditor::closeMap()
1405 // Unselect before disabling the toolbar actions
1406 if (!xelection.isEmpty() ) xelection.unselect();
1414 void MapEditor::setFilePath(QString fpath, QString destname)
1416 if (fpath.isEmpty() || fpath=="")
1423 filePath=fpath; // becomes absolute path
1424 fileName=fpath; // gets stripped of path
1425 destPath=destname; // needed for vymlinks
1427 // If fpath is not an absolute path, complete it
1428 filePath=QDir(fpath).absPath();
1429 fileDir=filePath.left (1+filePath.findRev ("/"));
1431 // Set short name, too. Search from behind:
1432 int i=fileName.findRev("/");
1433 if (i>=0) fileName=fileName.remove (0,i+1);
1435 // Forget the .vym (or .xml) for name of map
1436 mapName=fileName.left(fileName.findRev(".",-1,true) );
1440 void MapEditor::setFilePath(QString fpath)
1442 setFilePath (fpath,fpath);
1445 QString MapEditor::getFilePath()
1450 QString MapEditor::getFileName()
1455 QString MapEditor::getMapName()
1460 QString MapEditor::getDestPath()
1465 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1467 ErrorCode err=success;
1471 if (xelection.isEmpty() ) xelection.unselect();
1474 mapCenter->setMapEditor(this);
1475 // (map state is set later at end of load...)
1478 BranchObj *bo=xelection.getBranch();
1479 if (!bo) return aborted;
1480 if (lmode==ImportAdd)
1481 saveStateChangingPart(
1484 QString("addMapInsert (%1)").arg(fname),
1485 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1487 saveStateChangingPart(
1490 QString("addMapReplace(%1)").arg(fname),
1491 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1495 mapBuilderHandler handler;
1496 QFile file( fname );
1498 // I am paranoid: file should exist anyway
1499 // according to check in mainwindow.
1500 if (!file.exists() )
1502 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1503 tr("Couldn't open map " +fname)+".");
1507 bool blockSaveStateOrg=blockSaveState;
1508 blockReposition=true;
1509 blockSaveState=true;
1510 QXmlInputSource source( file);
1511 QXmlSimpleReader reader;
1512 reader.setContentHandler( &handler );
1513 reader.setErrorHandler( &handler );
1514 handler.setMapEditor( this );
1517 // We need to set the tmpDir in order to load files with rel. path
1518 QString tmpdir= fname.left(fname.findRev("/",-1));
1519 handler.setTmpDir (tmpdir);
1520 handler.setInputFile (file.name());
1521 handler.setLoadMode (lmode);
1522 bool ok = reader.parse( source );
1523 blockReposition=false;
1524 blockSaveState=blockSaveStateOrg;
1528 mapCenter->reposition();
1535 autosaveTimer->stop();
1539 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1540 tr( handler.errorProtocol() ) );
1542 // Still return "success": the map maybe at least
1543 // partially read by the parser
1550 int MapEditor::save (const SaveMode &savemode)
1554 // Create mapName and fileDir
1555 makeSubDirs (fileDir);
1559 fname=mapName+".xml";
1561 // use name given by user, even if he chooses .doc
1566 if (savemode==CompleteMap || xelection.isEmpty())
1567 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1570 // TODO take care of multiselections
1571 if (xelection.type()==Selection::FloatImage)
1574 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());
1577 if (!saveStringToDisk(fileDir+fname,saveFile))
1584 autosaveTimer->stop();
1591 void MapEditor::setZipped (bool z)
1596 bool MapEditor::saveZipped ()
1601 void MapEditor::print()
1605 printer = new QPrinter;
1606 printer->setColorMode (QPrinter::Color);
1607 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1608 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1609 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1612 QRectF totalBBox=mapCenter->getTotalBBox();
1614 // Try to set orientation automagically
1615 // Note: Interpretation of generated postscript is amibiguous, if
1616 // there are problems with landscape mode, see
1617 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1619 if (totalBBox.width()>totalBBox.height())
1620 // recommend landscape
1621 printer->setOrientation (QPrinter::Landscape);
1623 // recommend portrait
1624 printer->setOrientation (QPrinter::Portrait);
1626 if ( printer->setup(this) )
1627 // returns false, if printing is canceled
1629 QPainter pp(printer);
1631 pp.setRenderHint(QPainter::Antialiasing,true);
1633 // Don't print the visualisation of selection
1634 xelection.unselect();
1636 QRectF mapRect=totalBBox;
1637 QGraphicsRectItem *frame=NULL;
1641 // Print frame around map
1642 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1643 totalBBox.width()+20, totalBBox.height()+20);
1644 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1645 frame->setZValue(0);
1650 double paperAspect = (double)printer->width() / (double)printer->height();
1651 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1653 if (mapAspect>=paperAspect)
1655 // Fit horizontally to paper width
1656 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1657 viewBottom=(int)(printer->width()/mapAspect);
1660 // Fit vertically to paper height
1661 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1662 viewBottom=printer->height();
1667 // Print footer below map
1669 font.setPointSize(10);
1671 QRectF footerBox(0,viewBottom,printer->width(),15);
1672 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1673 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1677 QRectF (0,0,printer->width(),printer->height()-15),
1678 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1681 // Viewport has paper dimension
1682 if (frame) delete (frame);
1684 // Restore selection
1685 xelection.reselect();
1687 // Save settings in vymrc
1688 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1689 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1690 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1694 void MapEditor::setAntiAlias (bool b)
1696 setRenderHint(QPainter::Antialiasing,b);
1699 void MapEditor::setSmoothPixmap(bool b)
1701 setRenderHint(QPainter::SmoothPixmapTransform,b);
1704 QPixmap MapEditor::getPixmap()
1706 QRectF mapRect=mapCenter->getTotalBBox();
1707 QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+2);
1710 pp.setRenderHints(renderHints());
1712 // Don't print the visualisation of selection
1713 xelection.unselect();
1715 mapScene->render ( &pp,
1716 QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1717 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1719 // Restore selection
1720 xelection.reselect();
1725 void MapEditor::setHideTmpMode (BranchObj::HideTmpMode mode)
1728 mapCenter->setHideTmp (hidemode);
1729 mapCenter->reposition();
1733 BranchObj::HideTmpMode MapEditor::getHideTmpMode()
1738 void MapEditor::setExportMode (bool b)
1740 // should be called before and after exports
1741 // depending on the settings
1742 if (b && settings.value("/export/useHideExport","yes")=="yes")
1743 setHideTmpMode (BranchObj::HideExport);
1745 setHideTmpMode (BranchObj::HideNone);
1748 void MapEditor::exportASCII(QString fname,bool askName)
1751 ex.setMapCenter(mapCenter);
1753 ex.setFile (mapName+".txt");
1759 //ex.addFilter ("TXT (*.txt)");
1760 ex.setDir(lastImageDir);
1761 //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
1766 setExportMode(true);
1768 setExportMode(false);
1772 void MapEditor::exportImage(QString fname, bool askName, QString format)
1776 fname=mapName+".png";
1783 QFileDialog *fd=new QFileDialog (this);
1784 fd->setCaption (tr("Export map as image"));
1785 fd->setDirectory (lastImageDir);
1786 fd->setFileMode(QFileDialog::AnyFile);
1787 fd->setFilters (imageIO.getFilters() );
1790 fl=fd->selectedFiles();
1792 format=imageIO.getType(fd->selectedFilter());
1796 setExportMode (true);
1797 QPixmap pix (getPixmap());
1798 pix.save(fname, format);
1799 setExportMode (false);
1802 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1806 ex.setMapCenter(mapCenter);
1807 if (ex.setConfigFile(cf))
1809 setExportMode (true);
1810 ex.exportPresentation();
1811 setExportMode (false);
1815 void MapEditor::exportXHTML (const QString &dir, bool askForName)
1817 ExportXHTMLDialog dia(this);
1818 dia.setFilePath (filePath );
1819 dia.setMapName (mapName );
1821 if (dir!="") dia.setDir (dir);
1827 if (dia.exec()!=QDialog::Accepted)
1831 QDir d (dia.getDir());
1832 // Check, if warnings should be used before overwriting
1833 // the output directory
1834 if (d.exists() && d.count()>0)
1837 warn.showCancelButton (true);
1838 warn.setText(QString(
1839 "The directory %1 is not empty.\n"
1840 "Do you risk to overwrite some of its contents?").arg(d.path() ));
1841 warn.setCaption("Warning: Directory not empty");
1842 warn.setShowAgainName("mainwindow/overwrite-dir-xhtml");
1844 if (warn.exec()!=QDialog::Accepted) ok=false;
1851 exportXML (dia.getDir(),false );
1852 dia.doExport(mapName );
1853 //if (dia.hasChanged()) setChanged();
1857 void MapEditor::exportXML(QString dir, bool askForName)
1861 dir=browseDirectory(this,tr("Export XML to directory"));
1862 if (dir =="" && !reallyWriteDirectory(dir) )
1866 // Hide stuff during export, if settings want this
1867 setExportMode (true);
1869 // Create subdirectories
1872 // write to directory
1873 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1876 file.setName ( dir + "/"+mapName+".xml");
1877 if ( !file.open( QIODevice::WriteOnly ) )
1879 // This should neverever happen
1880 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1884 // Write it finally, and write in UTF8, no matter what
1885 QTextStream ts( &file );
1886 ts.setEncoding (QTextStream::UnicodeUTF8);
1890 // Now write image, too
1891 exportImage (dir+"/images/"+mapName+".png",false,"PNG");
1893 setExportMode (false);
1896 void MapEditor::clear()
1898 xelection.unselect();
1902 void MapEditor::copy()
1904 LinkableMapObj *sel=xelection.single();
1907 if (redosAvail == 0)
1910 QString s=sel->getSelectString();
1911 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel );
1912 curClipboard=curStep;
1915 // Copy also to global clipboard, because we are at last step in history
1916 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
1917 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
1918 copyDir (bakMapDir,clipboardDir );
1920 clipboardEmpty=false;
1925 void MapEditor::redo()
1927 // Can we undo at all?
1928 if (redosAvail<1) return;
1930 bool blockSaveStateOrg=blockSaveState;
1931 blockSaveState=true;
1935 if (undosAvail<stepsTotal) undosAvail++;
1937 if (curStep>stepsTotal) curStep=1;
1938 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1939 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1940 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1941 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1942 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1943 QString version=undoSet.readEntry ("/history/version");
1945 if (!checkVersion(version))
1946 QMessageBox::warning(0,tr("Warning"),
1947 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1950 // Find out current undo directory
1951 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1955 cout << "ME::redo() begin\n";
1956 cout << " undosAvail="<<undosAvail<<endl;
1957 cout << " redosAvail="<<redosAvail<<endl;
1958 cout << " curStep="<<curStep<<endl;
1959 cout << " ---------------------------"<<endl;
1960 cout << " comment="<<comment.toStdString()<<endl;
1961 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1962 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1963 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1964 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1965 cout << " ---------------------------"<<endl<<endl;
1968 // select object before redo
1969 if (!redoSelection.isEmpty())
1970 select (redoSelection);
1973 parseAtom (redoCommand);
1974 mapCenter->reposition();
1976 blockSaveState=blockSaveStateOrg;
1978 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1979 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1980 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1981 undoSet.writeSettings(histPath);
1983 mainWindow->updateHistory (undoSet);
1986 /* TODO remove testing
1987 cout << "ME::redo() end\n";
1988 cout << " undosAvail="<<undosAvail<<endl;
1989 cout << " redosAvail="<<redosAvail<<endl;
1990 cout << " curStep="<<curStep<<endl;
1991 cout << " ---------------------------"<<endl<<endl;
1997 bool MapEditor::isRedoAvailable()
1999 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
2005 void MapEditor::undo()
2007 // Can we undo at all?
2008 if (undosAvail<1) return;
2010 mainWindow->statusMessage (tr("Autosave disabled during undo."));
2012 bool blockSaveStateOrg=blockSaveState;
2013 blockSaveState=true;
2015 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
2016 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2017 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2018 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2019 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2020 QString version=undoSet.readEntry ("/history/version");
2022 if (!checkVersion(version))
2023 QMessageBox::warning(0,tr("Warning"),
2024 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2026 // Find out current undo directory
2027 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
2029 // select object before undo
2030 if (!undoSelection.isEmpty())
2031 select (undoSelection);
2035 cout << "ME::undo() begin\n";
2036 cout << " undosAvail="<<undosAvail<<endl;
2037 cout << " redosAvail="<<redosAvail<<endl;
2038 cout << " curStep="<<curStep<<endl;
2039 cout << " ---------------------------"<<endl;
2040 cout << " comment="<<comment.toStdString()<<endl;
2041 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2042 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2043 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2044 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2045 cout << " ---------------------------"<<endl<<endl;
2047 parseAtom (undoCommand);
2048 mapCenter->reposition();
2052 if (curStep<1) curStep=stepsTotal;
2056 blockSaveState=blockSaveStateOrg;
2057 /* TODO remove testing
2058 cout << "ME::undo() end\n";
2059 cout << " undosAvail="<<undosAvail<<endl;
2060 cout << " redosAvail="<<redosAvail<<endl;
2061 cout << " curStep="<<curStep<<endl;
2062 cout << " ---------------------------"<<endl<<endl;
2065 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2066 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2067 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2068 undoSet.writeSettings(histPath);
2070 mainWindow->updateHistory (undoSet);
2073 ensureSelectionVisible();
2076 bool MapEditor::isUndoAvailable()
2078 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
2084 void MapEditor::gotoHistoryStep (int i)
2086 // Restore variables
2087 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
2088 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
2090 if (i<0) i=undosAvail+redosAvail;
2092 // Clicking above current step makes us undo things
2095 for (int j=0; j<undosAvail-i; j++) undo();
2098 // Clicking below current step makes us redo things
2100 for (int j=undosAvail; j<i; j++)
2102 cout << "redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
2106 // And ignore clicking the current row ;-)
2109 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
2111 QString pathDir=path.left(path.findRev("/"));
2117 // We need to parse saved XML data
2118 mapBuilderHandler handler;
2119 QXmlInputSource source( file);
2120 QXmlSimpleReader reader;
2121 reader.setContentHandler( &handler );
2122 reader.setErrorHandler( &handler );
2123 handler.setMapEditor( this );
2124 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2125 if (undoSel.isEmpty())
2129 handler.setLoadMode (NewMap);
2133 handler.setLoadMode (ImportReplace);
2135 blockReposition=true;
2136 bool ok = reader.parse( source );
2137 blockReposition=false;
2140 // This should never ever happen
2141 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2142 handler.errorProtocol());
2145 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2148 void MapEditor::addMapInsertInt (const QString &path, int pos)
2150 BranchObj *sel=xelection.getBranch();
2153 QString pathDir=path.left(path.findRev("/"));
2159 // We need to parse saved XML data
2160 mapBuilderHandler handler;
2161 QXmlInputSource source( file);
2162 QXmlSimpleReader reader;
2163 reader.setContentHandler( &handler );
2164 reader.setErrorHandler( &handler );
2165 handler.setMapEditor( this );
2166 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2167 handler.setLoadMode (ImportAdd);
2168 blockReposition=true;
2169 bool ok = reader.parse( source );
2170 blockReposition=false;
2173 // This should never ever happen
2174 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2175 handler.errorProtocol());
2178 sel->getLastBranch()->linkTo (sel,pos);
2180 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2184 void MapEditor::pasteNoSave(const int &n)
2186 bool old=blockSaveState;
2187 blockSaveState=true;
2188 if (redosAvail > 0 || n!=0)
2190 // Use the "historical" buffer
2191 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(n));
2192 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
2193 load (bakMapDir+"/"+clipboardFile,ImportAdd);
2195 // Use the global buffer
2196 load (clipboardDir+"/"+clipboardFile,ImportAdd);
2200 void MapEditor::paste()
2202 BranchObj *sel=xelection.getBranch();
2205 saveStateChangingPart(
2208 QString ("paste (%1)").arg(curClipboard),
2209 QString("Paste to %1").arg( getName(sel))
2212 mapCenter->reposition();
2216 void MapEditor::cut()
2218 LinkableMapObj *sel=xelection.single();
2219 if ( sel && (xelection.type() == Selection::Branch ||
2220 xelection.type()==Selection::MapCenter ||
2221 xelection.type()==Selection::FloatImage))
2223 /* No savestate! savestate is called in cutNoSave
2224 saveStateChangingPart(
2228 QString("Cut %1").arg(getName(sel ))
2233 mapCenter->reposition();
2237 void MapEditor::move(const int &x, const int &y)
2239 LinkableMapObj *sel=xelection.single();
2242 QString ps=qpointfToString (sel->getAbsPos());
2243 QString s=xelection.single()->getSelectString();
2246 s, "move "+qpointfToString (QPointF (x,y)),
2247 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
2249 mapCenter->reposition();
2255 void MapEditor::moveRel (const int &x, const int &y)
2257 LinkableMapObj *sel=xelection.single();
2260 QString ps=qpointfToString (sel->getRelPos());
2261 QString s=sel->getSelectString();
2264 s, "moveRel "+qpointfToString (QPointF (x,y)),
2265 QString("Move %1 to relativ position %2").arg(getName(sel)).arg(ps));
2266 ((OrnamentedObj*)sel)->move2RelPos (x,y);
2267 mapCenter->reposition();
2273 void MapEditor::moveBranchUp()
2275 BranchObj* bo=xelection.getBranch();
2279 if (!bo->canMoveBranchUp()) return;
2280 par=(BranchObj*)(bo->getParObj());
2281 BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
2282 saveState (bo->getSelectString(),"moveBranchDown ()",obo->getSelectString(),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
2283 mapCenter->reposition();
2286 ensureSelectionVisible();
2290 void MapEditor::moveBranchDown()
2292 BranchObj* bo=xelection.getBranch();
2296 if (!bo->canMoveBranchDown()) return;
2297 par=(BranchObj*)(bo->getParObj());
2298 BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
2299 saveState(bo->getSelectString(),"moveBranchUp ()",obo->getSelectString(),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
2300 mapCenter->reposition();
2303 ensureSelectionVisible();
2307 void MapEditor::linkTo(const QString &dstString)
2309 FloatImageObj *fio=xelection.getFloatImage();
2312 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
2313 if (dst && (typeid(*dst)==typeid (BranchObj) ||
2314 typeid(*dst)==typeid (MapCenterObj)))
2316 LinkableMapObj *dstPar=dst->getParObj();
2317 QString parString=dstPar->getSelectString();
2318 QString fioPreSelectString=fio->getSelectString();
2319 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
2320 ((BranchObj*)(dst))->addFloatImage (fio);
2321 xelection.unselect();
2322 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
2323 fio=((BranchObj*)(dst))->getLastFloatImage();
2326 xelection.select(fio);
2328 fio->getSelectString(),
2329 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
2331 QString ("linkTo (\"%1\")").arg(dstString),
2332 QString ("Link floatimage to %1").arg(getName(dst)));
2337 QString MapEditor::getHeading(bool &ok, QPoint &p)
2339 BranchObj *bo=xelection.getBranch();
2343 p=mapFromScene(bo->getAbsPos());
2344 return bo->getHeading();
2350 void MapEditor::setHeading(const QString &s)
2352 BranchObj *sel=xelection.getBranch();
2357 "setHeading (\""+sel->getHeading()+"\")",
2359 "setHeading (\""+s+"\")",
2360 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
2361 sel->setHeading(s );
2362 mapCenter->reposition();
2364 ensureSelectionVisible();
2368 void MapEditor::setHeadingInt(const QString &s)
2370 BranchObj *bo=xelection.getBranch();
2374 mapCenter->reposition();
2376 ensureSelectionVisible();
2380 void MapEditor::setVymLinkInt (const QString &s)
2382 // Internal function, no saveState needed
2383 BranchObj *bo=xelection.getBranch();
2387 mapCenter->reposition();
2390 ensureSelectionVisible();
2394 BranchObj* MapEditor::addNewBranchInt(int num)
2396 // Depending on pos:
2397 // -3 insert in childs of parent above selection
2398 // -2 add branch to selection
2399 // -1 insert in childs of parent below selection
2400 // 0..n insert in childs of parent at pos
2401 BranchObj *newbo=NULL;
2402 BranchObj *bo=xelection.getBranch();
2407 // save scroll state. If scrolled, automatically select
2408 // new branch in order to tmp unscroll parent...
2409 return bo->addBranch();
2414 bo=(BranchObj*)bo->getParObj();
2418 bo=(BranchObj*)bo->getParObj();
2421 newbo=bo->insertBranch(num);
2426 BranchObj* MapEditor::addNewBranch(int pos)
2428 // Different meaning than num in addNewBranchInt!
2432 BranchObj *bo = xelection.getBranch();
2433 BranchObj *newbo=NULL;
2437 setCursor (Qt::ArrowCursor);
2439 newbo=addNewBranchInt (pos-2);
2447 QString ("addBranch (%1)").arg(pos-2),
2448 QString ("Add new branch to %1").arg(getName(bo)));
2450 mapCenter->reposition();
2458 BranchObj* MapEditor::addNewBranchBefore()
2460 BranchObj *newbo=NULL;
2461 BranchObj *bo = xelection.getBranch();
2462 if (bo && xelection.type()==Selection::Branch)
2463 // We accept no MapCenterObj here, so we _have_ a parent
2465 QPointF p=bo->getRelPos();
2468 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2470 // add below selection
2471 newbo=parbo->insertBranch(bo->getNum()+1);
2474 newbo->move2RelPos (p);
2476 // Move selection to new branch
2477 bo->linkTo (newbo,-1);
2479 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2480 QString ("Add branch before %1").arg(getName(bo)));
2482 mapCenter->reposition();
2489 void MapEditor::deleteSelection()
2491 BranchObj *bo = xelection.getBranch();
2492 if (bo && xelection.type()==Selection::Branch)
2494 BranchObj* par=(BranchObj*)(bo->getParObj());
2495 xelection.unselect();
2496 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2497 par->removeBranch(bo);
2498 xelection.select (par);
2499 ensureSelectionVisible();
2500 mapCenter->reposition();
2505 FloatImageObj *fio=xelection.getFloatImage();
2508 BranchObj* par=(BranchObj*)(fio->getParObj());
2509 saveStateChangingPart(
2513 QString("Delete %1").arg(getName(fio))
2515 xelection.unselect();
2516 par->removeFloatImage(fio);
2517 xelection.select (par);
2518 mapCenter->reposition();
2520 ensureSelectionVisible();
2525 LinkableMapObj* MapEditor::getSelection()
2527 return xelection.single();
2530 BranchObj* MapEditor::getSelectedBranch()
2532 return xelection.getBranch();
2535 FloatImageObj* MapEditor::getSelectedFloatImage()
2537 return xelection.getFloatImage();
2540 void MapEditor::unselect()
2542 xelection.unselect();
2545 void MapEditor::reselect()
2547 xelection.reselect();
2550 bool MapEditor::select (const QString &s)
2552 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2554 // Finally select the found object
2557 xelection.unselect();
2558 xelection.select(lmo);
2560 ensureSelectionVisible();
2567 QString MapEditor::getSelectString()
2569 return xelection.getSelectString();
2572 void MapEditor::selectInt (LinkableMapObj *lmo)
2574 if (lmo && xelection.single()!= lmo && isSelectBlocked()==false )
2576 xelection.select(lmo);
2582 void MapEditor::selectNextBranchInt()
2584 // Increase number of branch
2585 LinkableMapObj *sel=xelection.single();
2588 QString s=sel->getSelectString();
2594 part=s.section(",",-1);
2596 num=part.right(part.length() - 3);
2598 s=s.left (s.length() -num.length());
2601 num=QString ("%1").arg(num.toUInt()+1);
2605 // Try to select this one
2606 if (select (s)) return;
2608 // We have no direct successor,
2609 // try to increase the parental number in order to
2610 // find a successor with same depth
2612 int d=xelection.single()->getDepth();
2617 while (!found && d>0)
2619 s=s.section (",",0,d-1);
2620 // replace substring of current depth in s with "1"
2621 part=s.section(",",-1);
2623 num=part.right(part.length() - 3);
2627 // increase number of parent
2628 num=QString ("%1").arg(num.toUInt()+1);
2629 s=s.section (",",0,d-2) + ","+ typ+num;
2632 // Special case, look at orientation
2633 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2634 num=QString ("%1").arg(num.toUInt()+1);
2636 num=QString ("%1").arg(num.toUInt()-1);
2641 // pad to oldDepth, select the first branch for each depth
2642 for (i=d;i<oldDepth;i++)
2647 if ( xelection.getBranch()->countBranches()>0)
2655 // try to select the freshly built string
2663 void MapEditor::selectPrevBranchInt()
2665 // Decrease number of branch
2666 BranchObj *bo=xelection.getBranch();
2669 QString s=bo->getSelectString();
2675 part=s.section(",",-1);
2677 num=part.right(part.length() - 3);
2679 s=s.left (s.length() -num.length());
2681 int n=num.toInt()-1;
2684 num=QString ("%1").arg(n);
2687 // Try to select this one
2688 if (n>=0 && select (s)) return;
2690 // We have no direct precessor,
2691 // try to decrease the parental number in order to
2692 // find a precessor with same depth
2694 int d=xelection.single()->getDepth();
2699 while (!found && d>0)
2701 s=s.section (",",0,d-1);
2702 // replace substring of current depth in s with "1"
2703 part=s.section(",",-1);
2705 num=part.right(part.length() - 3);
2709 // decrease number of parent
2710 num=QString ("%1").arg(num.toInt()-1);
2711 s=s.section (",",0,d-2) + ","+ typ+num;
2714 // Special case, look at orientation
2715 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2716 num=QString ("%1").arg(num.toInt()-1);
2718 num=QString ("%1").arg(num.toInt()+1);
2723 // pad to oldDepth, select the last branch for each depth
2724 for (i=d;i<oldDepth;i++)
2728 if ( xelection.getBranch()->countBranches()>0)
2729 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2736 // try to select the freshly built string
2744 void MapEditor::selectUpperBranch()
2746 if (isSelectBlocked() ) return;
2748 BranchObj *bo=xelection.getBranch();
2749 if (bo && xelection.type()==Selection::Branch)
2751 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2752 selectPrevBranchInt();
2754 if (bo->getDepth()==1)
2755 selectNextBranchInt();
2757 selectPrevBranchInt();
2761 void MapEditor::selectLowerBranch()
2763 if (isSelectBlocked() ) return;
2765 BranchObj *bo=xelection.getBranch();
2766 if (bo && xelection.type()==Selection::Branch)
2767 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2768 selectNextBranchInt();
2770 if (bo->getDepth()==1)
2771 selectPrevBranchInt();
2773 selectNextBranchInt();
2777 void MapEditor::selectLeftBranch()
2779 if (isSelectBlocked() ) return;
2783 LinkableMapObj *sel=xelection.single();
2786 if (xelection.type()== Selection::MapCenter)
2788 par=xelection.getBranch();
2789 bo=par->getLastSelectedBranch();
2792 // Workaround for reselecting on left and right side
2793 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2794 bo=par->getLastBranch();
2797 bo=par->getLastBranch();
2798 xelection.select(bo);
2800 ensureSelectionVisible();
2806 par=(BranchObj*)(sel->getParObj());
2807 if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
2809 if (xelection.type() == Selection::Branch ||
2810 xelection.type() == Selection::FloatImage)
2812 xelection.select(par);
2814 ensureSelectionVisible();
2819 if (xelection.type() == Selection::Branch )
2821 bo=xelection.getBranch()->getLastSelectedBranch();
2824 xelection.select(bo);
2826 ensureSelectionVisible();
2835 void MapEditor::selectRightBranch()
2837 if (isSelectBlocked() ) return;
2841 LinkableMapObj *sel=xelection.single();
2844 if (xelection.type()==Selection::MapCenter)
2846 par=xelection.getBranch();
2847 bo=par->getLastSelectedBranch();
2850 // Workaround for reselecting on left and right side
2851 if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
2852 bo=par->getFirstBranch();
2855 xelection.select(bo);
2857 ensureSelectionVisible();
2863 par=(BranchObj*)(xelection.single()->getParObj());
2864 if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
2866 if (xelection.type() == Selection::Branch ||
2867 xelection.type() == Selection::FloatImage)
2869 xelection.select(par);
2871 ensureSelectionVisible();
2876 if (xelection.type() == Selection::Branch)
2878 bo=xelection.getBranch()->getLastSelectedBranch();
2881 xelection.select(bo);
2883 ensureSelectionVisible();
2892 void MapEditor::selectFirstBranch()
2894 BranchObj *bo1=xelection.getBranch();
2899 par=(BranchObj*)(bo1->getParObj());
2900 bo2=par->getFirstBranch();
2902 xelection.select(bo2);
2904 ensureSelectionVisible();
2910 void MapEditor::selectLastBranch()
2912 BranchObj *bo1=xelection.getBranch();
2917 par=(BranchObj*)(bo1->getParObj());
2918 bo2=par->getLastBranch();
2921 xelection.select(bo2);
2923 ensureSelectionVisible();
2929 void MapEditor::selectMapBackgroundImage ()
2931 Q3FileDialog *fd=new Q3FileDialog( this);
2932 fd->setMode (Q3FileDialog::ExistingFile);
2933 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2934 ImagePreview *p =new ImagePreview (fd);
2935 fd->setContentsPreviewEnabled( TRUE );
2936 fd->setContentsPreview( p, p );
2937 fd->setPreviewMode( Q3FileDialog::Contents );
2938 fd->setCaption(vymName+" - " +tr("Load background image"));
2939 fd->setDir (lastImageDir);
2942 if ( fd->exec() == QDialog::Accepted )
2944 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2945 lastImageDir=QDir (fd->dirPath());
2946 setMapBackgroundImage (fd->selectedFile());
2950 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
2952 QColor oldcol=mapScene->backgroundBrush().color();
2956 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2958 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2959 QString("Set background color of map to %1").arg(col.name()));
2962 brush.setTextureImage (QPixmap (fn));
2963 mapScene->setBackgroundBrush(brush);
2966 void MapEditor::selectMapBackgroundColor()
2968 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2969 if ( !col.isValid() ) return;
2970 setMapBackgroundColor( col );
2974 void MapEditor::setMapBackgroundColor(QColor col)
2976 QColor oldcol=mapScene->backgroundBrush().color();
2979 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
2981 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
2982 QString("Set background color of map to %1").arg(col.name()));
2983 mapScene->setBackgroundBrush(col);
2986 QColor MapEditor::getMapBackgroundColor()
2988 return mapScene->backgroundBrush().color();
2991 QColor MapEditor::getCurrentHeadingColor()
2993 BranchObj *bo=xelection.getBranch();
2994 if (bo) return bo->getColor();
2996 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
3000 void MapEditor::colorBranch (QColor c)
3002 BranchObj *bo=xelection.getBranch();
3007 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
3009 QString ("colorBranch (\"%1\")").arg(c.name()),
3010 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
3012 bo->setColor(c); // color branch
3016 void MapEditor::colorSubtree (QColor c)
3018 BranchObj *bo=xelection.getBranch();
3021 saveStateChangingPart(
3024 QString ("colorSubtree (\"%1\")").arg(c.name()),
3025 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
3027 bo->setColorSubtree (c); // color links, color childs
3032 void MapEditor::toggleStandardFlag(QString f)
3034 BranchObj *bo=xelection.getBranch();
3038 if (bo->isSetStandardFlag(f))
3050 QString("%1 (\"%2\")").arg(u).arg(f),
3052 QString("%1 (\"%2\")").arg(r).arg(f),
3053 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
3054 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
3060 BranchObj* MapEditor::findText (QString s, bool cs)
3062 QTextDocument::FindFlags flags=0;
3063 if (cs) flags=QTextDocument::FindCaseSensitively;
3066 { // Nothing found or new find process
3068 // nothing found, start again
3070 itFind=mapCenter->first();
3072 bool searching=true;
3073 bool foundNote=false;
3074 while (searching && !EOFind)
3078 // Searching in Note
3079 if (itFind->getNote().contains(s,cs))
3081 if (xelection.single()!=itFind)
3083 xelection.select(itFind);
3084 ensureSelectionVisible();
3086 if (textEditor->findText(s,flags))
3092 // Searching in Heading
3093 if (searching && itFind->getHeading().contains (s,cs) )
3095 xelection.select(itFind);
3096 ensureSelectionVisible();
3102 itFind=itFind->next();
3103 if (!itFind) EOFind=true;
3107 return xelection.getBranch();
3112 void MapEditor::findReset()
3113 { // Necessary if text to find changes during a find process
3117 void MapEditor::setURL(const QString &url)
3119 BranchObj *bo=xelection.getBranch();
3122 QString oldurl=bo->getURL();
3126 QString ("setURL (\"%1\")").arg(oldurl),
3128 QString ("setURL (\"%1\")").arg(url),
3129 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
3132 mapCenter->reposition();
3134 ensureSelectionVisible();
3138 void MapEditor::editURL()
3140 BranchObj *bo=xelection.getBranch();
3144 QString text = QInputDialog::getText(
3145 "VYM", tr("Enter URL:"), QLineEdit::Normal,
3146 bo->getURL(), &ok, this );
3148 // user entered something and pressed OK
3153 void MapEditor::editLocalURL()
3155 BranchObj *bo=xelection.getBranch();
3158 QStringList filters;
3159 filters <<"All files (*)";
3160 filters << tr("Text","Filedialog") + " (*.txt)";
3161 filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
3162 filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
3163 filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
3164 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Set URL to a local file"));
3165 fd->setFilters (filters);
3166 fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
3167 fd->setDirectory (lastFileDir);
3168 if (! bo->getVymLink().isEmpty() )
3169 fd->selectFile( bo->getURL() );
3172 if ( fd->exec() == QDialog::Accepted )
3174 lastFileDir=QDir (fd->directory().path());
3175 setURL (fd->selectedFile() );
3180 QString MapEditor::getURL()
3182 BranchObj *bo=xelection.getBranch();
3184 return bo->getURL();
3189 QStringList MapEditor::getURLs()
3192 BranchObj *bo=xelection.getBranch();
3198 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
3206 void MapEditor::editHeading2URL()
3208 BranchObj *bo=xelection.getBranch();
3210 setURL (bo->getHeading());
3213 void MapEditor::editBugzilla2URL()
3215 BranchObj *bo=xelection.getBranch();
3218 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
3223 void MapEditor::editFATE2URL()
3225 BranchObj *bo=xelection.getBranch();
3228 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
3231 "setURL (\""+bo->getURL()+"\")",
3233 "setURL (\""+url+"\")",
3234 QString("Use heading of %1 as link to FATE").arg(getName(bo))
3241 void MapEditor::editVymLink()
3243 BranchObj *bo=xelection.getBranch();
3246 QStringList filters;
3247 filters <<"VYM map (*.vym)";
3248 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
3249 fd->setFilters (filters);
3250 fd->setCaption(vymName+" - " +tr("Link to another map"));
3251 fd->setDirectory (lastFileDir);
3252 if (! bo->getVymLink().isEmpty() )
3253 fd->selectFile( bo->getVymLink() );
3257 if ( fd->exec() == QDialog::Accepted )
3259 lastFileDir=QDir (fd->directory().path());
3262 "setVymLink (\""+bo->getVymLink()+"\")",
3264 "setVymLink (\""+fd->selectedFile()+"\")",
3265 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
3267 setVymLinkInt (fd->selectedFile() );
3272 void MapEditor::deleteVymLink()
3274 BranchObj *bo=xelection.getBranch();
3279 "setVymLink (\""+bo->getVymLink()+"\")",
3281 "setVymLink (\"\")",
3282 QString("Unset vymlink of %1").arg(getName(bo))
3284 bo->setVymLink ("" );
3286 mapCenter->reposition();
3291 void MapEditor::setHideExport(bool b)
3293 BranchObj *bo=xelection.getBranch();
3296 bo->setHideInExport (b);
3297 QString u= b ? "false" : "true";
3298 QString r=!b ? "false" : "true";
3302 QString ("setHideExport (%1)").arg(u),
3304 QString ("setHideExport (%1)").arg(r),
3305 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
3308 mapCenter->reposition();
3314 void MapEditor::toggleHideExport()
3316 BranchObj *bo=xelection.getBranch();
3318 setHideExport ( !bo->hideInExport() );
3321 QString MapEditor::getVymLink()
3323 BranchObj *bo=xelection.getBranch();
3325 return bo->getVymLink();
3331 QStringList MapEditor::getVymLinks()
3334 BranchObj *bo=xelection.getBranch();
3340 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
3348 void MapEditor::deleteKeepChilds()
3350 BranchObj *bo=xelection.getBranch();
3354 par=(BranchObj*)(bo->getParObj());
3355 QPointF p=bo->getRelPos();
3356 saveStateChangingPart(
3359 "deleteKeepChilds ()",
3360 QString("Remove %1 and keep its childs").arg(getName(bo))
3363 QString sel=bo->getSelectString();
3365 par->removeBranchHere(bo);
3366 mapCenter->reposition();
3368 xelection.getBranch()->move2RelPos (p);
3369 mapCenter->reposition();
3373 void MapEditor::deleteChilds()
3375 BranchObj *bo=xelection.getBranch();
3378 saveStateChangingPart(
3382 QString( "Remove childs of branch %1").arg(getName(bo))
3385 mapCenter->reposition();
3389 void MapEditor::editMapInfo()
3391 ExtraInfoDialog dia;
3392 dia.setMapName (getFileName() );
3393 dia.setAuthor (mapCenter->getAuthor() );
3394 dia.setComment(mapCenter->getComment() );
3398 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
3405 bo=mapCenter->first();
3408 if (!bo->getNote().isEmpty() ) n++;
3409 f+= bo->countFloatImages();
3411 xl+=bo->countXLinks();
3414 stats+=QString ("%1 branches\n").arg (b-1,6);
3415 stats+=QString ("%1 xLinks \n").arg (xl,6);
3416 stats+=QString ("%1 notes\n").arg (n,6);
3417 stats+=QString ("%1 images\n").arg (f,6);
3418 dia.setStats (stats);
3420 // Finally show dialog
3421 if (dia.exec() == QDialog::Accepted)
3423 setMapAuthor (dia.getAuthor() );
3424 setMapComment (dia.getComment() );
3428 void MapEditor::ensureSelectionVisible()
3430 LinkableMapObj *lmo=xelection.single();
3431 if (lmo) ensureVisible (lmo->getBBox() );
3435 void MapEditor::updateSelection()
3437 // Tell selection to update geometries
3441 void MapEditor::updateActions()
3443 // Tell mainwindow to update states of actions
3444 mainWindow->updateActions();
3445 // TODO maybe don't update if blockReposition is set
3448 void MapEditor::updateNoteFlag()
3451 BranchObj *bo=xelection.getBranch();
3454 bo->updateNoteFlag();
3455 mainWindow->updateActions();
3459 void MapEditor::setMapAuthor (const QString &s)
3463 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3465 QString ("setMapAuthor (\"%1\")").arg(s),
3466 QString ("Set author of map to \"%1\"").arg(s)
3468 mapCenter->setAuthor (s);
3471 void MapEditor::setMapComment (const QString &s)
3475 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3477 QString ("setMapComment (\"%1\")").arg(s),
3478 QString ("Set comment of map")
3480 mapCenter->setComment (s);
3483 void MapEditor::setMapLinkStyle (const QString & s)
3485 saveStateChangingPart (
3488 QString("setMapLinkStyle (\"%1\")").arg(s),
3489 QString("Set map link style (\"%1\")").arg(s)
3493 linkstyle=LinkableMapObj::Line;
3494 else if (s=="StyleParabel")
3495 linkstyle=LinkableMapObj::Parabel;
3496 else if (s=="StylePolyLine")
3497 linkstyle=LinkableMapObj::PolyLine;
3499 linkstyle=LinkableMapObj::PolyParabel;
3502 bo=mapCenter->first();
3506 bo->setLinkStyle(bo->getDefLinkStyle());
3509 mapCenter->reposition();
3512 LinkableMapObj::Style MapEditor::getMapLinkStyle ()
3517 void MapEditor::setMapDefLinkColor(QColor c)
3521 bo=mapCenter->first();
3530 void MapEditor::setMapLinkColorHintInt()
3532 // called from setMapLinkColorHint(lch) or at end of parse
3534 bo=mapCenter->first();
3542 void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
3545 setMapLinkColorHintInt();
3548 void MapEditor::toggleMapLinkColorHint()
3550 if (linkcolorhint==LinkableMapObj::HeadingColor)
3551 linkcolorhint=LinkableMapObj::DefaultColor;
3553 linkcolorhint=LinkableMapObj::HeadingColor;
3555 bo=mapCenter->first();
3563 LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
3565 return linkcolorhint;
3568 QColor MapEditor::getMapDefLinkColor()
3570 return defLinkColor;
3573 void MapEditor::setMapDefXLinkColor(QColor col)
3578 QColor MapEditor::getMapDefXLinkColor()
3580 return defXLinkColor;
3583 void MapEditor::setMapDefXLinkWidth (int w)
3588 int MapEditor::getMapDefXLinkWidth()
3590 return defXLinkWidth;
3593 void MapEditor::selectMapLinkColor()
3595 QColor col = QColorDialog::getColor( defLinkColor, this );
3596 if ( !col.isValid() ) return;
3599 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3601 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3602 QString("Set map link color to %1").arg(col.name())
3604 setMapDefLinkColor( col );
3607 void MapEditor::selectMapSelectionColor()
3609 QColor col = QColorDialog::getColor( defLinkColor, this );
3610 setSelectionColor (col);
3613 void MapEditor::setSelectionColorInt (QColor col)
3615 if ( !col.isValid() ) return;
3616 xelection.setColor (col);
3619 void MapEditor::setSelectionColor(QColor col)
3621 if ( !col.isValid() ) return;
3624 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3626 QString("setSelectionColor (%1)").arg(col.name()),
3627 QString("Set color of selection box to %1").arg(col.name())
3629 setSelectionColorInt (col);
3632 QColor MapEditor::getSelectionColor()
3634 return xelection.getColor();
3637 bool MapEditor::scrollBranch(BranchObj *bo)
3641 if (bo->isScrolled()) return false;
3642 if (bo->countBranches()==0) return false;
3643 if (bo->getDepth()==0) return false;
3649 QString ("%1 ()").arg(u),
3651 QString ("%1 ()").arg(r),
3652 QString ("%1 %2").arg(r).arg(getName(bo))
3662 bool MapEditor::unscrollBranch(BranchObj *bo)
3666 if (!bo->isScrolled()) return false;
3667 if (bo->countBranches()==0) return false;
3668 if (bo->getDepth()==0) return false;
3674 QString ("%1 ()").arg(u),
3676 QString ("%1 ()").arg(r),
3677 QString ("%1 %2").arg(r).arg(getName(bo))
3687 void MapEditor::toggleScroll()
3689 BranchObj *bo=xelection.getBranch();
3690 if (xelection.type()==Selection::Branch )
3692 if (bo->isScrolled())
3693 unscrollBranch (bo);
3699 void MapEditor::unscrollChilds()
3701 BranchObj *bo=xelection.getBranch();
3707 if (bo->isScrolled()) unscrollBranch (bo);
3713 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3715 BranchObj *bo=xelection.getBranch();
3719 bo->addFloatImage();
3720 fio=bo->getLastFloatImage();
3722 mapCenter->reposition();
3729 void MapEditor::loadFloatImage ()
3731 BranchObj *bo=xelection.getBranch();
3735 Q3FileDialog *fd=new Q3FileDialog( this);
3736 fd->setMode (Q3FileDialog::ExistingFiles);
3737 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3738 ImagePreview *p =new ImagePreview (fd);
3739 fd->setContentsPreviewEnabled( TRUE );
3740 fd->setContentsPreview( p, p );
3741 fd->setPreviewMode( Q3FileDialog::Contents );
3742 fd->setCaption(vymName+" - " +tr("Load image"));
3743 fd->setDir (lastImageDir);
3746 if ( fd->exec() == QDialog::Accepted )
3748 // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
3749 lastImageDir=QDir (fd->dirPath());
3752 for (int j=0; j<fd->selectedFiles().count(); j++)
3754 s=fd->selectedFiles().at(j);
3755 fio=loadFloatImageInt (s);
3758 (LinkableMapObj*)fio,
3761 QString ("loadImage (%1)").arg(s ),
3762 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3765 // TODO loadFIO error handling
3766 qWarning ("Failed to load "+s);
3774 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3776 fio->save (fn,type);
3779 void MapEditor::saveFloatImage ()
3781 FloatImageObj *fio=xelection.getFloatImage();
3784 QFileDialog *fd=new QFileDialog( this);
3785 fd->setFilters (imageIO.getFilters());
3786 fd->setCaption(vymName+" - " +tr("Save image"));
3787 fd->setFileMode( QFileDialog::AnyFile );
3788 fd->setDirectory (lastImageDir);
3789 // fd->setSelection (fio->getOriginalFilename());
3793 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3795 fn=fd->selectedFiles().at(0);
3796 if (QFile (fn).exists() )
3798 QMessageBox mb( vymName,
3799 tr("The file %1 exists already.\n"
3800 "Do you want to overwrite it?").arg(fn),
3801 QMessageBox::Warning,
3802 QMessageBox::Yes | QMessageBox::Default,
3803 QMessageBox::Cancel | QMessageBox::Escape,
3804 QMessageBox::QMessageBox::NoButton );
3806 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3807 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3810 case QMessageBox::Yes:
3813 case QMessageBox::Cancel:
3820 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3826 void MapEditor::setFrameType(const FrameObj::FrameType &t)
3828 BranchObj *bo=xelection.getBranch();
3831 QString s=bo->getFrameTypeName();
3832 bo->setFrameType (t);
3833 saveState (bo, QString("setFrameType (\"%1\")").arg(s),
3834 bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
3835 mapCenter->reposition();
3840 void MapEditor::setFrameType(const QString &s)
3842 BranchObj *bo=xelection.getBranch();
3845 saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
3846 bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
3847 bo->setFrameType (s);
3848 mapCenter->reposition();
3853 void MapEditor::setFramePenColor(const QColor &c)
3855 BranchObj *bo=xelection.getBranch();
3858 saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
3859 bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
3860 bo->setFramePenColor (c);
3864 void MapEditor::setFrameBrushColor(const QColor &c)
3866 BranchObj *bo=xelection.getBranch();
3869 saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
3870 bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
3871 bo->setFrameBrushColor (c);
3875 void MapEditor::setFramePadding (const int &i)
3877 BranchObj *bo=xelection.getBranch();
3880 saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
3881 bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
3882 bo->setFramePadding (i);
3883 mapCenter->reposition();
3888 void MapEditor::setFrameBorderWidth(const int &i)
3890 BranchObj *bo=xelection.getBranch();
3893 saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
3894 bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
3895 bo->setFrameBorderWidth (i);
3896 mapCenter->reposition();
3901 void MapEditor::setIncludeImagesVer(bool b)
3903 BranchObj *bo=xelection.getBranch();
3906 QString u= b ? "false" : "true";
3907 QString r=!b ? "false" : "true";
3911 QString("setIncludeImagesVertically (%1)").arg(u),
3913 QString("setIncludeImagesVertically (%1)").arg(r),
3914 QString("Include images vertically in %1").arg(getName(bo))
3916 bo->setIncludeImagesVer(b);
3917 mapCenter->reposition();
3921 void MapEditor::setIncludeImagesHor(bool b)
3923 BranchObj *bo=xelection.getBranch();
3926 QString u= b ? "false" : "true";
3927 QString r=!b ? "false" : "true";
3931 QString("setIncludeImagesHorizontally (%1)").arg(u),
3933 QString("setIncludeImagesHorizontally (%1)").arg(r),
3934 QString("Include images horizontally in %1").arg(getName(bo))
3936 bo->setIncludeImagesHor(b);
3937 mapCenter->reposition();
3941 void MapEditor::setHideLinkUnselected (bool b)
3943 LinkableMapObj *sel=xelection.single();
3945 (xelection.type() == Selection::Branch ||
3946 xelection.type() == Selection::MapCenter ||
3947 xelection.type() == Selection::FloatImage ))
3949 QString u= b ? "false" : "true";
3950 QString r=!b ? "false" : "true";
3954 QString("setHideLinkUnselected (%1)").arg(u),
3956 QString("setHideLinkUnselected (%1)").arg(r),
3957 QString("Hide link of %1 if unselected").arg(getName(sel))
3959 sel->setHideLinkUnselected(b);
3963 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3965 BranchObj *bo=xelection.getBranch();
3968 // Traverse directories
3969 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3970 QFileInfoList list = d.entryInfoList();
3973 for (int i = 0; i < list.size(); ++i)
3976 if (fi.fileName() != "." && fi.fileName() != ".." )
3979 bo=dst->getLastBranch();
3980 bo->setHeading (fi.fileName() );
3981 bo->setColor (QColor("blue"));
3983 if ( !d.cd(fi.fileName()) )
3984 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3987 // Recursively add subdirs
3988 importDirInt (bo,d);
3994 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3995 list = d.entryInfoList();
3997 for (int i = 0; i < list.size(); ++i)
4001 bo=dst->getLastBranch();
4002 bo->setHeading (fi.fileName() );
4003 bo->setColor (QColor("black"));
4004 if (fi.fileName().right(4) == ".vym" )
4005 bo->setVymLink (fi.filePath());
4010 void MapEditor::importDirInt (const QString &s)
4012 BranchObj *bo=xelection.getBranch();
4015 saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
4018 importDirInt (bo,d);
4022 void MapEditor::importDir()
4024 BranchObj *bo=xelection.getBranch();
4027 QStringList filters;
4028 filters <<"VYM map (*.vym)";
4029 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
4030 fd->setMode (QFileDialog::DirectoryOnly);
4031 fd->setFilters (filters);
4032 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
4036 if ( fd->exec() == QDialog::Accepted )
4038 importDirInt (fd->selectedFile() );
4039 mapCenter->reposition();
4045 void MapEditor::followXLink(int i)
4047 BranchObj *bo=xelection.getBranch();
4050 bo=bo->XLinkTargetAt(i);
4053 xelection.select(bo);
4054 ensureSelectionVisible();
4059 void MapEditor::editXLink(int i) // FIXME missing saveState
4061 BranchObj *bo=xelection.getBranch();
4064 XLinkObj *xlo=bo->XLinkAt(i);
4067 EditXLinkDialog dia;
4069 dia.setSelection(bo);
4070 if (dia.exec() == QDialog::Accepted)
4072 if (dia.useSettingsGlobal() )
4074 setMapDefXLinkColor (xlo->getColor() );
4075 setMapDefXLinkWidth (xlo->getWidth() );
4077 if (dia.deleteXLink())
4078 bo->deleteXLinkAt(i);
4084 void MapEditor::testFunction1()
4089 BranchObj *bo=xelection.getBranch();
4090 if (bo) animObjList.append( bo );
4095 dia.showCancelButton (true);
4096 dia.setText("This is a longer \nWarning");
4097 dia.setCaption("Warning: Flux problem");
4098 dia.setShowAgainName("mapeditor/testDialog");
4099 if (dia.exec()==QDialog::Accepted)
4100 cout << "accepted!\n";
4102 cout << "canceled!\n";
4106 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
4107 if (hidemode==HideNone)
4109 setHideTmpMode (HideExport);
4110 mapCenter->calcBBoxSizeWithChilds();
4111 QRectF totalBBox=mapCenter->getTotalBBox();
4112 QRectF mapRect=totalBBox;
4113 QCanvasRectangle *frame=NULL;
4115 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
4117 mapRect.setRect (totalBBox.x(), totalBBox.y(),
4118 totalBBox.width(), totalBBox.height());
4119 frame=new QCanvasRectangle (mapRect,mapScene);
4120 frame->setBrush (QColor(white));
4121 frame->setPen (QColor(black));
4122 frame->setZValue(0);
4127 setHideTmpMode (HideNone);
4129 cout <<" hidemode="<<hidemode<<endl;
4133 void MapEditor::testFunction2()
4138 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
4140 // Lineedits are already closed by preceding
4141 // mouseEvent, we don't need to close here.
4143 QPointF p = mapToScene(e->pos());
4144 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4147 { // MapObj was found
4148 if (xelection.single() != lmo)
4150 // select the MapObj
4151 xelection.select(lmo);
4154 if (xelection.getBranch() )
4156 // Context Menu on branch or mapcenter
4158 branchContextMenu->popup(e->globalPos() );
4161 if (xelection.getFloatImage() )
4163 // Context Menu on floatimage
4165 floatimageContextMenu->popup(e->globalPos() );
4169 { // No MapObj found, we are on the Canvas itself
4170 // Context Menu on scene
4172 canvasContextMenu->popup(e->globalPos() );
4177 void MapEditor::keyPressEvent(QKeyEvent* e)
4179 if (e->modifiers() & Qt::ControlModifier)
4181 switch (mainWindow->getModMode())
4183 case Main::ModModeColor:
4184 setCursor (PickColorCursor);
4186 case Main::ModModeCopy:
4187 setCursor (CopyCursor);
4189 case Main::ModModeXLink:
4190 setCursor (XLinkCursor);
4193 setCursor (Qt::ArrowCursor);
4199 void MapEditor::keyReleaseEvent(QKeyEvent* e)
4201 if (!(e->modifiers() & Qt::ControlModifier))
4202 setCursor (Qt::ArrowCursor);
4205 void MapEditor::mousePressEvent(QMouseEvent* e)
4207 // Ignore right clicks, these will go to context menus
4208 if (e->button() == Qt::RightButton )
4214 //Ignore clicks while editing heading
4215 if (isSelectBlocked() )
4221 QPointF p = mapToScene(e->pos());
4222 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4226 //Take care of system flags _or_ modifier modes
4228 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
4229 typeid(*lmo)==typeid(MapCenterObj) ))
4231 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
4232 if (!foname.isEmpty())
4234 // systemFlag clicked
4238 if (e->state() & Qt::ControlModifier)
4239 mainWindow->editOpenURLTab();
4241 mainWindow->editOpenURL();
4243 else if (foname=="vymLink")
4245 mainWindow->editOpenVymLink();
4246 // tabWidget may change, better return now
4247 // before segfaulting...
4248 } else if (foname=="note")
4249 mainWindow->windowToggleNoteEditor();
4250 else if (foname=="hideInExport")
4257 // No system flag clicked, take care of modmodes (CTRL-Click)
4258 if (e->state() & Qt::ControlModifier)
4260 if (mainWindow->getModMode()==Main::ModModeColor)
4263 setCursor (PickColorCursor);
4266 if (mainWindow->getModMode()==Main::ModModeXLink)
4268 BranchObj *bo_begin=NULL;
4270 bo_begin=(BranchObj*)(lmo);
4272 if (xelection.getBranch() )
4273 bo_begin=xelection.getBranch();
4277 linkingObj_src=bo_begin;
4278 tmpXLink=new XLinkObj (mapScene);
4279 tmpXLink->setBegin (bo_begin);
4280 tmpXLink->setEnd (p);
4281 tmpXLink->setColor(defXLinkColor);
4282 tmpXLink->setWidth(defXLinkWidth);
4283 tmpXLink->updateXLink();
4284 tmpXLink->setVisibility (true);
4288 } // End of modmodes
4292 // Select the clicked object
4295 // Left Button Move Branches
4296 if (e->button() == Qt::LeftButton )
4298 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
4299 //movingObj_start.setY( p.y() - selection->y() );
4300 movingObj_start.setX( p.x() - lmo->x() );
4301 movingObj_start.setY( p.y() - lmo->y() );
4302 movingObj_orgPos.setX (lmo->x() );
4303 movingObj_orgPos.setY (lmo->y() );
4304 movingObj_orgRelPos=lmo->getRelPos();
4306 // If modMode==copy, then we want to "move" the _new_ object around
4307 // then we need the offset from p to the _old_ selection, because of tmp
4308 if (mainWindow->getModMode()==Main::ModModeCopy &&
4309 e->state() & Qt::ControlModifier)
4311 if (xelection.type()==Selection::Branch)
4314 mapCenter->addBranch ((BranchObj*)xelection.single());
4316 xelection.select(mapCenter->getLastBranch());
4317 mapCenter->reposition();
4321 movingObj=xelection.single();
4323 // Middle Button Toggle Scroll
4324 // (On Mac OS X this won't work, but we still have
4325 // a button in the toolbar)
4326 if (e->button() == Qt::MidButton )
4331 { // No MapObj found, we are on the scene itself
4332 // Left Button move Pos of sceneView
4333 if (e->button() == Qt::LeftButton )
4335 movingObj=NULL; // move Content not Obj
4336 movingObj_start=e->globalPos();
4337 movingCont_start=QPointF (
4338 horizontalScrollBar()->value(),
4339 verticalScrollBar()->value());
4340 movingVec=QPointF(0,0);
4341 setCursor(HandOpenCursor);
4346 void MapEditor::mouseMoveEvent(QMouseEvent* e)
4348 QPointF p = mapToScene(e->pos());
4349 LinkableMapObj *lmosel=xelection.single();
4351 // Move the selected MapObj
4352 if ( lmosel && movingObj)
4354 // reset cursor if we are moving and don't copy
4355 if (mainWindow->getModMode()!=Main::ModModeCopy)
4356 setCursor (Qt::ArrowCursor);
4358 // To avoid jumping of the sceneView, only
4359 // ensureSelectionVisible, if not tmp linked
4360 if (!lmosel->hasParObjTmp())
4361 ensureSelectionVisible ();
4363 // Now move the selection, but add relative position
4364 // (movingObj_start) where selection was chosen with
4365 // mousepointer. (This avoids flickering resp. jumping
4366 // of selection back to absPos)
4368 // Check if we could link
4369 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
4372 FloatObj *fio=xelection.getFloatImage();
4375 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4377 fio->updateLink(); //no need for reposition, if we update link here
4380 // Relink float to new mapcenter or branch, if shift is pressed
4381 // Only relink, if selection really has a new parent
4382 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
4383 ( (typeid(*lmo)==typeid(BranchObj)) ||
4384 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
4385 ( lmo != fio->getParObj())
4388 if (typeid(*fio) == typeid(FloatImageObj) &&
4389 ( (typeid(*lmo)==typeid(BranchObj) ||
4390 typeid(*lmo)==typeid(MapCenterObj)) ))
4393 // Also save the move which was done so far
4394 QString pold=qpointfToString(movingObj_orgRelPos);
4395 QString pnow=qpointfToString(fio->getRelPos());
4401 QString("Move %1 to relativ position %2").arg(getName(fio)).arg(pnow));
4402 fio->getParObj()->requestReposition();
4403 mapCenter->reposition();
4405 linkTo (lmo->getSelectString());
4407 //movingObj_orgRelPos=lmosel->getRelPos();
4409 mapCenter->reposition();
4413 { // selection != a FloatObj
4414 if (lmosel->getDepth()==0)
4417 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
4418 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4420 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4421 mapCenter->updateRelPositions();
4424 if (lmosel->getDepth()==1)
4427 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4428 lmosel->setRelPos();
4431 // Move ordinary branch
4432 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
4433 // Add width of bbox here, otherwise alignRelTo will cause jumping around
4434 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
4435 p.y()-movingObj_start.y() +lmosel->getTopPad() );
4437 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
4440 // Maybe we can relink temporary?
4441 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
4442 (typeid(*lmo)==typeid(BranchObj) ||
4443 typeid(*lmo)==typeid(MapCenterObj)) )
4446 if (e->modifiers()==Qt::ControlModifier)
4448 // Special case: CTRL to link below lmo
4449 lmosel->setParObjTmp (lmo,p,+1);
4451 else if (e->modifiers()==Qt::ShiftModifier)
4452 lmosel->setParObjTmp (lmo,p,-1);
4454 lmosel->setParObjTmp (lmo,p,0);
4457 lmosel->unsetParObjTmp();
4459 // reposition subbranch
4460 lmosel->reposition();
4464 } // no FloatImageObj
4468 } // selection && moving_obj
4470 // Draw a link from one branch to another
4473 tmpXLink->setEnd (p);
4474 tmpXLink->updateXLink();
4478 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
4480 QPointF p=e->globalPos();
4481 movingVec.setX(-p.x() + movingObj_start.x() );
4482 movingVec.setY(-p.y() + movingObj_start.y() );
4483 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
4484 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
4489 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
4491 QPointF p = mapToScene(e->pos());
4492 LinkableMapObj *dst;
4493 LinkableMapObj *lmosel=xelection.single();
4494 // Have we been picking color?
4498 setCursor (Qt::ArrowCursor);
4499 // Check if we are over another branch
4500 dst=mapCenter->findMapObj(p, NULL);
4503 if (e->state() & Qt::ShiftModifier)
4504 colorBranch (((BranchObj*)(dst))->getColor());
4506 colorSubtree (((BranchObj*)(dst))->getColor());
4511 // Have we been drawing a link?
4515 // Check if we are over another branch
4516 dst=mapCenter->findMapObj(p, NULL);
4519 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
4520 tmpXLink->updateXLink();
4521 tmpXLink->activate(); //FIXME savestate missing
4522 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );
4531 // Have we been moving something?
4532 if ( lmosel && movingObj )
4534 FloatImageObj *fo=xelection.getFloatImage();
4537 // Moved FloatObj. Maybe we need to reposition
4538 QString pold=qpointfToString(movingObj_orgRelPos);
4539 QString pnow=qpointfToString(fo->getRelPos());
4545 QString("Move %1 to relativ position %2").arg(getName(fo)).arg(pnow));
4547 fo->getParObj()->requestReposition();
4548 mapCenter->reposition();
4551 // Check if we are over another branch, but ignore
4552 // any found LMOs, which are FloatObjs
4553 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
4555 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4558 if (xelection.type() == Selection::MapCenter )
4560 // TODO: Check for problems if graphicsview is resized for
4562 QString pold=qpointfToString(movingObj_orgPos);
4563 QString pnow=qpointfToString(mapCenter->getAbsPos());
4569 QString("Move mapcenter %1 to position %2").arg(getName(mapCenter)).arg(pnow));
4572 if (xelection.type() == Selection::Branch )
4573 { // A branch was moved
4575 // save the position in case we link to mapcenter
4576 QPointF savePos=QPointF (lmosel->getAbsPos() );
4578 // Reset the temporary drawn link to the original one
4579 lmosel->unsetParObjTmp();
4581 // For Redo we may need to save original selection
4582 QString preSelStr=lmosel->getSelectString();
4587 BranchObj* bsel=xelection.getBranch();
4588 BranchObj* bdst=(BranchObj*)dst;
4590 QString preParStr=(bsel->getParObj())->getSelectString();
4591 QString preNum=QString::number (bsel->getNum(),10);
4592 QString preDstParStr;
4594 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4596 preDstParStr=dst->getParObj()->getSelectString();
4597 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4599 if (e->state() & Qt::ControlModifier && dst->getParObj())
4602 preDstParStr=dst->getParObj()->getSelectString();
4603 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4606 preDstParStr=dst->getSelectString();
4607 bsel->linkTo (bdst,-1);
4608 if (dst->getDepth()==0) bsel->move (savePos);
4610 QString postSelStr=lmosel->getSelectString();
4611 QString postNum=QString::number (bsel->getNum(),10);
4613 QString undoCom="linkTo (\""+
4614 preParStr+ "\"," + preNum +"," +
4615 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4617 QString redoCom="linkTo (\""+
4618 preDstParStr + "\"," + postNum + "," +
4619 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4624 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4626 if (lmosel->getDepth()==1)
4628 // The select string might be different _after_ moving around.
4629 // Therefor reposition and then use string of old selection, too
4630 mapCenter->reposition();
4632 QString ps=qpointfToString ( lmosel->getRelPos() );
4634 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4635 preSelStr, "moveRel "+ps,
4636 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4639 // Draw the original link, before selection was moved around
4640 mapCenter->reposition();
4643 // Finally resize scene, if needed
4647 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4650 // maybe we moved View: set old cursor
4651 setCursor (Qt::ArrowCursor);
4655 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4657 if (isSelectBlocked() )
4663 if (e->button() == Qt::LeftButton )
4665 QPointF p = mapToScene(e->pos());
4666 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4667 if (lmo) { // MapObj was found
4668 // First select the MapObj than edit heading
4669 xelection.select(lmo);
4670 mainWindow->editHeading();
4675 void MapEditor::resizeEvent (QResizeEvent* e)
4677 QGraphicsView::resizeEvent( e );
4680 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4682 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4683 // cerr << event->format(i) << endl;
4685 if (event->mimeData()->hasImage())
4686 event->acceptProposedAction();
4688 if (event->mimeData()->hasUrls())
4689 event->acceptProposedAction();
4692 void MapEditor::dragMoveEvent(QDragMoveEvent *event)
4696 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4701 void MapEditor::dropEvent(QDropEvent *event)
4703 BranchObj *sel=xelection.getBranch();
4707 foreach (QString format,event->mimeData()->formats())
4708 cout << "MapEditor: Dropped format: "<<format.ascii()<<endl;
4712 if (event->mimeData()->hasImage())
4714 QVariant imageData = event->mimeData()->imageData();
4715 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4717 if (event->mimeData()->hasUrls())
4718 uris=event->mimeData()->urls();
4726 for (int i=0; i<uris.count();i++)
4728 // Workaround to avoid adding empty branches
4729 if (!uris.at(i).toString().isEmpty())
4731 bo=sel->addBranch();
4734 s=uris.at(i).toLocalFile();
4737 QString file = QDir::convertSeparators(s);
4738 heading = QFileInfo(file).baseName();
4740 if (file.endsWith(".vym", false))
4741 bo->setVymLink(file);
4743 bo->setURL(uris.at(i).toString());
4746 bo->setURL(uris.at(i).toString());
4749 if (!heading.isEmpty())
4750 bo->setHeading(heading);
4752 bo->setHeading(uris.at(i).toString());
4756 mapCenter->reposition();
4759 event->acceptProposedAction();
4762 void MapEditor::timerEvent(QTimerEvent *event) //TODO animation
4766 cout << "ME::timerEvent\n";
4768 for (int i=0; i<animObjList.size(); ++i)
4770 animObjList.at(i)->animate();
4771 ((BranchObj*)animObjList.at(i))->move2RelPos (((BranchObj*)animObjList.at(i))->getRelPos() );
4773 mapCenter->reposition();
4777 void MapEditor::sendSelection()
4779 sendData (xelection.getSelectString() );
4782 void MapEditor::newServer()
4784 tcpServer = new QTcpServer(this);
4785 if (!tcpServer->listen(QHostAddress::Any,54321)) {
4786 QMessageBox::critical(this, "vym server",
4787 QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
4791 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
4793 cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
4796 void MapEditor::newClient()
4799 QDataStream out(&block, QIODevice::WriteOnly);
4800 out.setVersion(QDataStream::Qt_4_0);
4802 out << xelection.getSelectString();
4803 out.device()->seek(0);
4804 out << (quint16)(block.size() - sizeof(quint16));
4806 QTcpSocket *newClient = tcpServer->nextPendingConnection();
4807 connect(newClient, SIGNAL(disconnected()),
4808 newClient, SLOT(deleteLater()));
4810 cout <<"ME::newClient at "<<newClient->peerAddress().toString().ascii()<<endl;
4812 clientList.append (newClient);
4814 newClient->write(block);
4815 //newClient->disconnectFromHost();
4819 void MapEditor::sendData(const QString &s)
4821 // Create bytearray to send
4823 QDataStream out(&block, QIODevice::WriteOnly);
4824 out.setVersion(QDataStream::Qt_4_0);
4826 // Reserve some space for blocksize
4832 // Go back and write blocksize so far
4833 out.device()->seek(0);
4834 out << (quint16)(block.size() - sizeof(quint16));
4836 for (int i=0; i<clientList.size(); ++i)
4838 cout << "Sending to "<<clientList.at(i)->peerAddress().toString().ascii()<<endl;
4839 clientList.at(i)->write (block);
4842 void MapEditor::autosave()
4844 // Disable autosave, while we have gone back in history
4845 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
4846 if (redosAvail>0) return;
4849 if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() )
4850 mainWindow->fileSave (this);
4854 /*TODO not needed? void MapEditor::contentsDropEvent(QDropEvent *event)
4857 } else if (event->provides("application/x-moz-file-promise-url") &&
4858 event->provides("application/x-moz-nativeimage"))
4860 // Contains url to the img src in unicode16
4861 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4862 QString url = QString((const QChar*)d.data(),d.size()/2);
4866 } else if (event->provides ("text/uri-list"))
4867 { // Uris provided e.g. by konqueror
4868 Q3UriDrag::decode (event,uris);
4869 } else if (event->provides ("_NETSCAPE_URL"))
4870 { // Uris provided by Mozilla
4871 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4874 } else if (event->provides("text/html")) {
4876 // Handels text mime types
4877 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4878 QByteArray d = event->encodedData("text/html");
4881 text = QString((const QChar*)d.data(),d.size()/2);
4885 textEditor->setText(text);
4889 } else if (event->provides("text/plain")) {
4890 QByteArray d = event->encodedData("text/plain");
4893 text = QString((const QChar*)d.data(),d.size()/2);
4897 textEditor->setText(text);
4907 bool isUnicode16(const QByteArray &d)
4909 // TODO: make more precise check for unicode 16.
4910 // Guess unicode16 if any of second bytes are zero
4911 unsigned int length = max(0,d.size()-2)/2;
4912 for (unsigned int i = 0; i<length ; i++)
4913 if (d.at(i*2+1)==0) return true;
4917 void MapEditor::addFloatImageInt (const QPixmap &img)
4919 BranchObj *bo=xelection.getBranch();
4922 FloatImageObj *fio=bo->addFloatImage();
4924 fio->setOriginalFilename("No original filename (image added by dropevent)");
4925 QString s=bo->getSelectString();
4926 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio );
4927 saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image");
4928 mapCenter->reposition();
4935 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
4937 if (!imageBuffer) imageBuffer = new QBuffer();
4938 if (!imageBuffer->isOpen()) {
4939 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
4941 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
4945 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
4947 if (nop->state()==Q3NetworkProtocol::StDone) {
4948 QPixmap img(imageBuffer->buffer());
4949 addFloatImageInt (img);
4953 imageBuffer->close();
4955 imageBuffer->close();
4962 void MapEditor::fetchImage(const QString &url)
4965 urlOperator->stop();
4966 disconnect(urlOperator);
4970 urlOperator = new Q3UrlOperator(url);
4971 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
4972 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
4974 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
4975 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));