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"
26 extern TextEditor *textEditor;
27 extern int statusbarTime;
28 extern Main *mainWindow;
29 extern QString tmpVymDir;
30 extern QString clipboardDir;
31 extern QString clipboardFile;
32 extern bool clipboardEmpty;
34 extern FlagRowObj *standardFlagsDefault;
36 extern QMenu* branchContextMenu;
37 extern QMenu* branchAddContextMenu;
38 extern QMenu* branchRemoveContextMenu;
39 extern QMenu* branchLinksContextMenu;
40 extern QMenu* branchXLinksContextMenuEdit;
41 extern QMenu* branchXLinksContextMenuFollow;
42 extern QMenu* floatimageContextMenu;
43 extern QMenu* canvasContextMenu;
46 extern Settings settings;
47 extern ImageIO imageIO;
49 extern QString vymName;
50 extern QString vymVersion;
52 extern QString iconPath;
53 extern QDir vymBaseDir;
54 extern QDir lastImageDir;
55 extern QDir lastFileDir;
57 int MapEditor::mapNum=0; // make instance
59 ///////////////////////////////////////////////////////////////////////
60 ///////////////////////////////////////////////////////////////////////
61 MapEditor::MapEditor( QWidget* parent) :
64 //cout << "Constructor ME "<<this<<endl;
68 mapScene= new QGraphicsScene(parent);
69 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
70 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
75 mapCenter = new MapCenterObj(mapScene);
76 mapCenter->setVisibility (true);
77 mapCenter->setMapEditor (this);
78 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
79 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
84 defLinkColor=QColor (0,0,255);
85 defXLinkColor=QColor (180,180,180);
86 linkcolorhint=LinkableMapObj::DefaultColor;
87 linkstyle=LinkableMapObj::PolyParabel;
89 // Create bitmap cursors, platform dependant
90 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
91 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
92 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
93 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
95 setFocusPolicy (Qt::StrongFocus);
104 xelection.setMapEditor (this);
105 xelection.unselect();
108 defXLinkColor=QColor (230,230,230);
116 fileName=tr("unnamed");
119 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
120 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
121 mainWindow->updateHistory (undoSet);
123 // Initialize find routine
130 blockReposition=false;
131 blockSaveState=false;
133 hidemode=BranchObj::HideNone;
135 // Create temporary files
142 setAcceptDrops (true);
144 mapCenter->reposition(); // for positioning heading
148 //timerId = startTimer(100);
151 autosaveTimer=new QTimer (this);
152 connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
158 MapEditor::~MapEditor()
160 //cout <<"Destructor MapEditor\n";
161 autosaveTimer->stop();
164 MapCenterObj* MapEditor::getMapCenter()
169 QGraphicsScene * MapEditor::getScene()
174 MapEditor::State MapEditor::getState()
179 void MapEditor::setStateEditHeading(bool s)
183 if (state==Idle) state=EditHeading;
189 bool MapEditor::isRepositionBlocked()
191 return blockReposition;
194 void MapEditor::setSaveStateBlocked(bool b)
199 bool MapEditor::isSelectBlocked()
201 if (state==EditHeading)
207 QString MapEditor::getName (const LinkableMapObj *lmo)
210 if (!lmo) return QString("Error: NULL has no name!");
212 if ((typeid(*lmo) == typeid(BranchObj) ||
213 typeid(*lmo) == typeid(MapCenterObj)))
216 s=(((BranchObj*)lmo)->getHeading());
217 if (s=="") s="unnamed";
218 return QString("branch (%1)").arg(s);
219 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
221 if ((typeid(*lmo) == typeid(FloatImageObj) ))
222 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
223 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
224 return QString("Unknown type has no name!");
227 void MapEditor::makeTmpDirs()
229 // Create unique temporary directories
230 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
231 histPath=QDir::convertSeparators (tmpMapDir+"/history");
236 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
238 // tmpdir temporary directory to which data will be written
239 // prefix mapname, which will be appended to images etc.
240 // writeflags Only write flags for "real" save of map, not undo
241 // offset offset of bbox of whole map in scene.
242 // Needed for XML export
248 case LinkableMapObj::Line:
251 case LinkableMapObj::Parabel:
254 case LinkableMapObj::PolyLine:
258 ls="StylePolyParabel";
262 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
264 if (linkcolorhint==LinkableMapObj::HeadingColor)
265 colhint=attribut("linkColorHint","HeadingColor");
267 QString mapAttr=attribut("version",vymVersion);
268 if (!saveSel || saveSel==mapCenter)
269 mapAttr+= attribut("author",mapCenter->getAuthor()) +
270 attribut("comment",mapCenter->getComment()) +
271 attribut("date",mapCenter->getDate()) +
272 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
273 attribut("selectionColor", xelection.getColor().name() ) +
274 attribut("linkStyle", ls ) +
275 attribut("linkColor", defLinkColor.name() ) +
276 attribut("defXLinkColor", defXLinkColor.name() ) +
277 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
279 s+=beginElement("vymmap",mapAttr);
282 // Find the used flags while traversing the tree
283 standardFlagsDefault->resetUsedCounter();
285 // Reset the counters before saving
286 // TODO constr. of FIO creates lots of objects, better do this in some other way...
287 FloatImageObj (mapScene).resetSaveCounter();
289 // Build xml recursivly
290 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
291 // Save complete map, if saveSel not set
292 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
295 if ( typeid(*saveSel) == typeid(BranchObj) )
297 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
298 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
300 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
303 // Save local settings
304 s+=settings.getXMLData (destPath);
307 if (!xelection.isEmpty() && !saveSel )
308 s+=valueElement("select",xelection.getSelectString());
311 s+=endElement("vymmap");
314 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
318 QString MapEditor::getHistoryDir()
320 QString histName=QDir::convertSeparators (QString("history-%1").arg(curStep));
321 return QDir::convertSeparators (tmpMapDir +"/"+histName);
324 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
326 sendData(redoCom); //FIXME testing
331 if (blockSaveState) return;
333 if (debug) cout << "ME::saveState() for "<<mapName.ascii()<<endl;
335 // Find out current undo directory
336 if (undosAvail<stepsTotal) undosAvail++;
338 if (curStep>stepsTotal) curStep=1;
340 QString backupXML="";
341 QString histDir=getHistoryDir();
342 QString bakMapPath=QDir::convertSeparators(histDir+"/map.xml");
344 // Create histDir if not available
347 makeSubDirs (histDir);
349 // Save depending on how much needs to be saved
351 backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
353 QString undoCommand="";
354 if (savemode==UndoCommand)
358 else if (savemode==PartOfMap )
361 undoCommand.replace ("PATH",bakMapPath);
364 if (!backupXML.isEmpty())
365 // Write XML Data to disk
366 saveStringToDisk (QString(bakMapPath),backupXML);
368 // We would have to save all actions in a tree, to keep track of
369 // possible redos after a action. Possible, but we are too lazy: forget about redos.
372 // Write the current state to disk
373 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
374 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
375 undoSet.setEntry ("/history/curStep",QString::number(curStep));
376 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
377 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
378 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
379 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
380 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
381 undoSet.setEntry (QString("/history/version"),vymVersion);
382 undoSet.writeSettings(histPath);
386 // TODO remove after testing
387 //cout << " into="<< histPath.toStdString()<<endl;
388 cout << " stepsTotal="<<stepsTotal<<
389 ", undosAvail="<<undosAvail<<
390 ", redosAvail="<<redosAvail<<
391 ", curStep="<<curStep<<endl;
392 cout << " ---------------------------"<<endl;
393 cout << " comment="<<comment.toStdString()<<endl;
394 cout << " undoCom="<<undoCommand.toStdString()<<endl;
395 cout << " undoSel="<<undoSelection.toStdString()<<endl;
396 cout << " redoCom="<<redoCom.toStdString()<<endl;
397 cout << " redoSel="<<redoSelection.toStdString()<<endl;
398 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
399 cout << " ---------------------------"<<endl;
402 mainWindow->updateHistory (undoSet);
408 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
410 // save the selected part of the map, Undo will replace part of map
411 QString undoSelection="";
413 undoSelection=undoSel->getSelectString();
415 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
416 QString redoSelection="";
418 redoSelection=undoSel->getSelectString();
420 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
423 saveState (PartOfMap,
424 undoSelection, "addMapReplace (\"PATH\")",
430 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
434 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
437 QString undoSelection=redoSel->getParObj()->getSelectString();
438 QString redoSelection=redoSel->getSelectString();
439 if (typeid(*redoSel) == typeid(BranchObj) )
441 // save the selected branch of the map, Undo will insert part of map
442 saveState (PartOfMap,
443 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
444 redoSelection, "delete ()",
451 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
453 // "Normal" savestate: save commands, selections and comment
454 // so just save commands for undo and redo
455 // and use current selection
457 QString redoSelection="";
458 if (redoSel) redoSelection=redoSel->getSelectString();
459 QString undoSelection="";
460 if (undoSel) undoSelection=undoSel->getSelectString();
462 saveState (UndoCommand,
469 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
471 // "Normal" savestate: save commands, selections and comment
472 // so just save commands for undo and redo
473 // and use current selection
474 saveState (UndoCommand,
482 void MapEditor::parseAtom(const QString &atom)
484 BranchObj *selb=xelection.getBranch();
490 // Split string s into command and parameters
491 parser.parseAtom (atom);
492 QString com=parser.getCommand();
495 /////////////////////////////////////////////////////////////////////
496 if (com=="addBranch")
498 if (xelection.isEmpty())
500 parser.setError (Aborted,"Nothing selected");
503 parser.setError (Aborted,"Type of selection is not a branch");
508 if (parser.checkParCount(pl))
510 if (parser.parCount()==0)
514 n=parser.parInt (ok,0);
515 if (ok ) addNewBranch (n);
519 /////////////////////////////////////////////////////////////////////
520 } else if (com=="addBranchBefore")
522 if (xelection.isEmpty())
524 parser.setError (Aborted,"Nothing selected");
527 parser.setError (Aborted,"Type of selection is not a branch");
530 if (parser.parCount()==0)
532 addNewBranchBefore ();
535 /////////////////////////////////////////////////////////////////////
536 } else if (com==QString("addMapReplace"))
538 if (xelection.isEmpty())
540 parser.setError (Aborted,"Nothing selected");
543 parser.setError (Aborted,"Type of selection is not a branch");
544 } else if (parser.checkParCount(1))
546 //s=parser.parString (ok,0); // selection
547 t=parser.parString (ok,0); // path to map
548 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
549 addMapReplaceInt(selb->getSelectString(),t);
551 /////////////////////////////////////////////////////////////////////
552 } else if (com==QString("addMapInsert"))
554 if (xelection.isEmpty())
556 parser.setError (Aborted,"Nothing selected");
559 parser.setError (Aborted,"Type of selection is not a branch");
562 if (parser.checkParCount(2))
564 t=parser.parString (ok,0); // path to map
565 n=parser.parInt(ok,1); // position
566 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
567 addMapInsertInt(t,n);
570 /////////////////////////////////////////////////////////////////////
571 } else if (com=="clearFlags")
573 if (xelection.isEmpty() )
575 parser.setError (Aborted,"Nothing selected");
578 parser.setError (Aborted,"Type of selection is not a branch");
579 } else if (parser.checkParCount(0))
581 selb->clearStandardFlags();
582 selb->updateFlagsToolbar();
584 /////////////////////////////////////////////////////////////////////
585 } else if (com=="colorBranch")
587 if (xelection.isEmpty())
589 parser.setError (Aborted,"Nothing selected");
592 parser.setError (Aborted,"Type of selection is not a branch");
593 } else if (parser.checkParCount(1))
595 QColor c=parser.parColor (ok,0);
596 if (ok) colorBranch (c);
598 /////////////////////////////////////////////////////////////////////
599 } else if (com=="colorSubtree")
601 if (xelection.isEmpty())
603 parser.setError (Aborted,"Nothing selected");
606 parser.setError (Aborted,"Type of selection is not a branch");
607 } else if (parser.checkParCount(1))
609 QColor c=parser.parColor (ok,0);
610 if (ok) colorSubtree (c);
612 /////////////////////////////////////////////////////////////////////
613 } else if (com=="copy")
615 if (xelection.isEmpty())
617 parser.setError (Aborted,"Nothing selected");
620 parser.setError (Aborted,"Type of selection is not a branch");
621 } else if (parser.checkParCount(0))
623 //FIXME missing action for copy
625 /////////////////////////////////////////////////////////////////////
626 } else if (com=="cut")
628 if (xelection.isEmpty())
630 parser.setError (Aborted,"Nothing selected");
631 } else if ( xelection.type()!=Selection::Branch &&
632 xelection.type()!=Selection::MapCenter &&
633 xelection.type()!=Selection::FloatImage )
635 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
636 } else if (parser.checkParCount(0))
640 /////////////////////////////////////////////////////////////////////
641 } else if (com=="delete")
643 if (xelection.isEmpty())
645 parser.setError (Aborted,"Nothing selected");
646 } else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage )
648 parser.setError (Aborted,"Type of selection is wrong.");
649 } else if (parser.checkParCount(0))
653 /////////////////////////////////////////////////////////////////////
654 } else if (com=="deleteKeepChilds")
656 if (xelection.isEmpty())
658 parser.setError (Aborted,"Nothing selected");
661 parser.setError (Aborted,"Type of selection is not a branch");
662 } else if (parser.checkParCount(0))
666 /////////////////////////////////////////////////////////////////////
667 } else if (com=="deleteChilds")
669 if (xelection.isEmpty())
671 parser.setError (Aborted,"Nothing selected");
674 parser.setError (Aborted,"Type of selection is not a branch");
675 } else if (parser.checkParCount(0))
679 /////////////////////////////////////////////////////////////////////
680 } else if (com=="exportASCII")
684 if (parser.parCount()>=2)
685 // Hey, we even have a filename
686 fname=parser.parString(ok,1);
689 parser.setError (Aborted,"Could not read filename");
692 exportASCII (fname,false);
694 /////////////////////////////////////////////////////////////////////
695 } else if (com=="exportImage")
699 if (parser.parCount()>=2)
700 // Hey, we even have a filename
701 fname=parser.parString(ok,1);
704 parser.setError (Aborted,"Could not read filename");
707 QString format="PNG";
708 if (parser.parCount()>2)
710 format=parser.parString(ok,2);
712 exportImage (fname,false,format);
714 /////////////////////////////////////////////////////////////////////
715 } else if (com=="exportXHTML")
719 if (parser.parCount()>=2)
720 // Hey, we even have a filename
721 fname=parser.parString(ok,1);
724 parser.setError (Aborted,"Could not read filename");
727 exportXHTML (fname,false);
729 /////////////////////////////////////////////////////////////////////
730 } else if (com=="exportXML")
734 if (parser.parCount()>=2)
735 // Hey, we even have a filename
736 fname=parser.parString(ok,1);
739 parser.setError (Aborted,"Could not read filename");
742 exportXML (fname,false);
744 /////////////////////////////////////////////////////////////////////
745 } else if (com=="importDir")
747 if (xelection.isEmpty())
749 parser.setError (Aborted,"Nothing selected");
752 parser.setError (Aborted,"Type of selection is not a branch");
753 } else if (parser.checkParCount(1))
755 s=parser.parString(ok,0);
756 if (ok) importDirInt(s);
758 /////////////////////////////////////////////////////////////////////
759 } else if (com=="linkTo")
761 if (xelection.isEmpty())
763 parser.setError (Aborted,"Nothing selected");
766 if (parser.checkParCount(4))
768 // 0 selectstring of parent
769 // 1 num in parent (for branches)
770 // 2,3 x,y of mainbranch or mapcenter
771 s=parser.parString(ok,0);
772 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
775 if (typeid(*dst) == typeid(BranchObj) )
777 // Get number in parent
778 n=parser.parInt (ok,1);
781 selb->linkTo ((BranchObj*)(dst),n);
784 } else if (typeid(*dst) == typeid(MapCenterObj) )
786 selb->linkTo ((BranchObj*)(dst),-1);
787 // Get coordinates of mainbranch
788 x=parser.parDouble(ok,2);
791 y=parser.parDouble(ok,3);
801 } else if ( xelection.type() == Selection::FloatImage)
803 if (parser.checkParCount(1))
805 // 0 selectstring of parent
806 s=parser.parString(ok,0);
807 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
810 if (typeid(*dst) == typeid(BranchObj) ||
811 typeid(*dst) == typeid(MapCenterObj))
812 linkTo (dst->getSelectString());
814 parser.setError (Aborted,"Destination is not a branch");
817 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
818 /////////////////////////////////////////////////////////////////////
819 } else if (com=="loadImage")
821 if (xelection.isEmpty())
823 parser.setError (Aborted,"Nothing selected");
826 parser.setError (Aborted,"Type of selection is not a branch");
827 } else if (parser.checkParCount(1))
829 s=parser.parString(ok,0);
830 if (ok) loadFloatImageInt (s);
832 /////////////////////////////////////////////////////////////////////
833 } else if (com=="moveBranchUp")
835 if (xelection.isEmpty() )
837 parser.setError (Aborted,"Nothing selected");
840 parser.setError (Aborted,"Type of selection is not a branch");
841 } else if (parser.checkParCount(0))
845 /////////////////////////////////////////////////////////////////////
846 } else if (com=="moveBranchDown")
848 if (xelection.isEmpty() )
850 parser.setError (Aborted,"Nothing selected");
853 parser.setError (Aborted,"Type of selection is not a branch");
854 } else if (parser.checkParCount(0))
858 /////////////////////////////////////////////////////////////////////
859 } else if (com=="move")
861 if (xelection.isEmpty() )
863 parser.setError (Aborted,"Nothing selected");
864 } else if ( xelection.type()!=Selection::Branch &&
865 xelection.type()!=Selection::MapCenter &&
866 xelection.type()!=Selection::FloatImage )
868 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
869 } else if (parser.checkParCount(2))
871 x=parser.parDouble (ok,0);
874 y=parser.parDouble (ok,1);
878 /////////////////////////////////////////////////////////////////////
879 } else if (com=="moveRel")
881 if (xelection.isEmpty() )
883 parser.setError (Aborted,"Nothing selected");
884 } else if ( xelection.type()!=Selection::Selection::Branch &&
885 xelection.type()!=Selection::Selection::MapCenter &&
886 xelection.type()!=Selection::Selection::FloatImage )
888 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
889 } else if (parser.checkParCount(2))
891 x=parser.parDouble (ok,0);
894 y=parser.parDouble (ok,1);
895 if (ok) moveRel (x,y);
898 /////////////////////////////////////////////////////////////////////
899 } else if (com=="nop")
901 /////////////////////////////////////////////////////////////////////
902 } else if (com=="paste")
904 if (xelection.isEmpty() )
906 parser.setError (Aborted,"Nothing selected");
909 parser.setError (Aborted,"Type of selection is not a branch");
910 } else if (parser.checkParCount(1))
912 n=parser.parInt (ok,0);
913 if (ok) pasteNoSave(n);
915 /////////////////////////////////////////////////////////////////////
916 } else if (com=="qa")
918 if (xelection.isEmpty() )
920 parser.setError (Aborted,"Nothing selected");
923 parser.setError (Aborted,"Type of selection is not a branch");
924 } else if (parser.checkParCount(4))
927 c=parser.parString (ok,0);
930 parser.setError (Aborted,"No comment given");
933 s=parser.parString (ok,1);
936 parser.setError (Aborted,"First parameter is not a string");
939 t=parser.parString (ok,2);
942 parser.setError (Aborted,"Condition is not a string");
945 u=parser.parString (ok,3);
948 parser.setError (Aborted,"Third parameter is not a string");
953 parser.setError (Aborted,"Unknown type: "+s);
958 parser.setError (Aborted,"Unknown operator: "+t);
963 parser.setError (Aborted,"Type of selection is not a branch");
966 if (selb->getHeading() == u)
968 cout << "PASSED: " << c.ascii() << endl;
971 cout << "FAILED: " << c.ascii() << endl;
981 /////////////////////////////////////////////////////////////////////
982 } else if (com=="saveImage")
984 FloatImageObj *fio=xelection.getFloatImage();
987 parser.setError (Aborted,"Type of selection is not an image");
988 } else if (parser.checkParCount(2))
990 s=parser.parString(ok,0);
993 t=parser.parString(ok,1);
994 if (ok) saveFloatImageInt (fio,t,s);
997 /////////////////////////////////////////////////////////////////////
998 } else if (com=="scroll")
1000 if (xelection.isEmpty() )
1002 parser.setError (Aborted,"Nothing selected");
1005 parser.setError (Aborted,"Type of selection is not a branch");
1006 } else if (parser.checkParCount(0))
1008 if (!scrollBranch (selb))
1009 parser.setError (Aborted,"Could not scroll branch");
1011 /////////////////////////////////////////////////////////////////////
1012 } else if (com=="select")
1014 if (parser.checkParCount(1))
1016 s=parser.parString(ok,0);
1019 /////////////////////////////////////////////////////////////////////
1020 } else if (com=="selectLastBranch")
1022 if (xelection.isEmpty() )
1024 parser.setError (Aborted,"Nothing selected");
1027 parser.setError (Aborted,"Type of selection is not a branch");
1028 } else if (parser.checkParCount(0))
1030 BranchObj *bo=selb->getLastBranch();
1032 parser.setError (Aborted,"Could not select last branch");
1036 /////////////////////////////////////////////////////////////////////
1037 } else if (com=="selectLastImage")
1039 if (xelection.isEmpty() )
1041 parser.setError (Aborted,"Nothing selected");
1044 parser.setError (Aborted,"Type of selection is not a branch");
1045 } else if (parser.checkParCount(0))
1047 FloatImageObj *fio=selb->getLastFloatImage();
1049 parser.setError (Aborted,"Could not select last image");
1053 /////////////////////////////////////////////////////////////////////
1054 } else if (com=="selectLatestAdded")
1056 if (latestSelection.isEmpty() )
1058 parser.setError (Aborted,"No latest added object");
1061 if (!select (latestSelection))
1062 parser.setError (Aborted,"Could not select latest added object "+latestSelection);
1064 /////////////////////////////////////////////////////////////////////
1065 } else if (com=="setFrameType")
1067 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1069 parser.setError (Aborted,"Type of selection does not allow setting frame type");
1071 else if (parser.checkParCount(1))
1073 s=parser.parString(ok,0);
1074 if (ok) setFrameType (s);
1076 /////////////////////////////////////////////////////////////////////
1077 } else if (com=="setFramePenColor")
1079 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1081 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
1083 else if (parser.checkParCount(1))
1085 QColor c=parser.parColor(ok,0);
1086 if (ok) setFramePenColor (c);
1088 /////////////////////////////////////////////////////////////////////
1089 } else if (com=="setFrameBrushColor")
1091 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1093 parser.setError (Aborted,"Type of selection does not allow setting brush color");
1095 else if (parser.checkParCount(1))
1097 QColor c=parser.parColor(ok,0);
1098 if (ok) setFrameBrushColor (c);
1100 /////////////////////////////////////////////////////////////////////
1101 } else if (com=="setFramePadding")
1103 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1105 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
1107 else if (parser.checkParCount(1))
1109 n=parser.parInt(ok,0);
1110 if (ok) setFramePadding(n);
1112 /////////////////////////////////////////////////////////////////////
1113 } else if (com=="setFrameBorderWidth")
1115 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1117 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
1119 else if (parser.checkParCount(1))
1121 n=parser.parInt(ok,0);
1122 if (ok) setFrameBorderWidth (n);
1124 /////////////////////////////////////////////////////////////////////
1125 } else if (com=="setMapAuthor")
1127 if (parser.checkParCount(1))
1129 s=parser.parString(ok,0);
1130 if (ok) setMapAuthor (s);
1132 /////////////////////////////////////////////////////////////////////
1133 } else if (com=="setMapComment")
1135 if (parser.checkParCount(1))
1137 s=parser.parString(ok,0);
1138 if (ok) setMapComment(s);
1140 /////////////////////////////////////////////////////////////////////
1141 } else if (com=="setMapBackgroundColor")
1143 if (xelection.isEmpty() )
1145 parser.setError (Aborted,"Nothing selected");
1146 } else if (! xelection.getBranch() )
1148 parser.setError (Aborted,"Type of selection is not a branch");
1149 } else if (parser.checkParCount(1))
1151 QColor c=parser.parColor (ok,0);
1152 if (ok) setMapBackgroundColor (c);
1154 /////////////////////////////////////////////////////////////////////
1155 } else if (com=="setMapDefLinkColor")
1157 if (xelection.isEmpty() )
1159 parser.setError (Aborted,"Nothing selected");
1162 parser.setError (Aborted,"Type of selection is not a branch");
1163 } else if (parser.checkParCount(1))
1165 QColor c=parser.parColor (ok,0);
1166 if (ok) setMapDefLinkColor (c);
1168 /////////////////////////////////////////////////////////////////////
1169 } else if (com=="setMapLinkStyle")
1171 if (parser.checkParCount(1))
1173 s=parser.parString (ok,0);
1174 if (ok) setMapLinkStyle(s);
1176 /////////////////////////////////////////////////////////////////////
1177 } else if (com=="setHeading")
1179 if (xelection.isEmpty() )
1181 parser.setError (Aborted,"Nothing selected");
1184 parser.setError (Aborted,"Type of selection is not a branch");
1185 } else if (parser.checkParCount(1))
1187 s=parser.parString (ok,0);
1191 /////////////////////////////////////////////////////////////////////
1192 } else if (com=="setHideExport")
1194 if (xelection.isEmpty() )
1196 parser.setError (Aborted,"Nothing selected");
1197 } else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage)
1199 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1200 } else if (parser.checkParCount(1))
1202 b=parser.parBool(ok,0);
1203 if (ok) setHideExport (b);
1205 /////////////////////////////////////////////////////////////////////
1206 } else if (com=="setIncludeImagesHorizontally")
1208 if (xelection.isEmpty() )
1210 parser.setError (Aborted,"Nothing selected");
1213 parser.setError (Aborted,"Type of selection is not a branch");
1214 } else if (parser.checkParCount(1))
1216 b=parser.parBool(ok,0);
1217 if (ok) setIncludeImagesHor(b);
1219 /////////////////////////////////////////////////////////////////////
1220 } else if (com=="setIncludeImagesVertically")
1222 if (xelection.isEmpty() )
1224 parser.setError (Aborted,"Nothing selected");
1227 parser.setError (Aborted,"Type of selection is not a branch");
1228 } else if (parser.checkParCount(1))
1230 b=parser.parBool(ok,0);
1231 if (ok) setIncludeImagesVer(b);
1233 /////////////////////////////////////////////////////////////////////
1234 } else if (com=="setHideLinkUnselected")
1236 if (xelection.isEmpty() )
1238 parser.setError (Aborted,"Nothing selected");
1239 } else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1241 parser.setError (Aborted,"Type of selection does not allow hiding the link");
1242 } else if (parser.checkParCount(1))
1244 b=parser.parBool(ok,0);
1245 if (ok) setHideLinkUnselected(b);
1247 /////////////////////////////////////////////////////////////////////
1248 } else if (com=="setSelectionColor")
1250 if (parser.checkParCount(1))
1252 QColor c=parser.parColor (ok,0);
1253 if (ok) setSelectionColorInt (c);
1255 /////////////////////////////////////////////////////////////////////
1256 } else if (com=="setURL")
1258 if (xelection.isEmpty() )
1260 parser.setError (Aborted,"Nothing selected");
1263 parser.setError (Aborted,"Type of selection is not a branch");
1264 } else if (parser.checkParCount(1))
1266 s=parser.parString (ok,0);
1269 /////////////////////////////////////////////////////////////////////
1270 } else if (com=="setVymLink")
1272 if (xelection.isEmpty() )
1274 parser.setError (Aborted,"Nothing selected");
1277 parser.setError (Aborted,"Type of selection is not a branch");
1278 } else if (parser.checkParCount(1))
1280 s=parser.parString (ok,0);
1281 if (ok) setVymLinkInt(s);
1284 /////////////////////////////////////////////////////////////////////
1285 else if (com=="setFlag")
1287 if (xelection.isEmpty() )
1289 parser.setError (Aborted,"Nothing selected");
1292 parser.setError (Aborted,"Type of selection is not a branch");
1293 } else if (parser.checkParCount(1))
1295 s=parser.parString(ok,0);
1298 selb->activateStandardFlag(s);
1299 selb->updateFlagsToolbar();
1302 /////////////////////////////////////////////////////////////////////
1303 } else if (com=="setFrameType")
1305 if (xelection.isEmpty() )
1307 parser.setError (Aborted,"Nothing selected");
1310 parser.setError (Aborted,"Type of selection is not a branch");
1311 } else if (parser.checkParCount(1))
1313 s=parser.parString(ok,0);
1317 /////////////////////////////////////////////////////////////////////
1318 } else if (com=="toggleFlag")
1320 if (xelection.isEmpty() )
1322 parser.setError (Aborted,"Nothing selected");
1325 parser.setError (Aborted,"Type of selection is not a branch");
1326 } else if (parser.checkParCount(1))
1328 s=parser.parString(ok,0);
1331 selb->toggleStandardFlag(s);
1332 selb->updateFlagsToolbar();
1335 /////////////////////////////////////////////////////////////////////
1336 } else if (com=="unscroll")
1338 if (xelection.isEmpty() )
1340 parser.setError (Aborted,"Nothing selected");
1343 parser.setError (Aborted,"Type of selection is not a branch");
1344 } else if (parser.checkParCount(0))
1346 if (!unscrollBranch (selb))
1347 parser.setError (Aborted,"Could not unscroll branch");
1349 /////////////////////////////////////////////////////////////////////
1350 } else if (com=="unscrollChilds")
1352 if (xelection.isEmpty() )
1354 parser.setError (Aborted,"Nothing selected");
1357 parser.setError (Aborted,"Type of selection is not a branch");
1358 } else if (parser.checkParCount(0))
1362 /////////////////////////////////////////////////////////////////////
1363 } else if (com=="unsetFlag")
1365 if (xelection.isEmpty() )
1367 parser.setError (Aborted,"Nothing selected");
1370 parser.setError (Aborted,"Type of selection is not a branch");
1371 } else if (parser.checkParCount(1))
1373 s=parser.parString(ok,0);
1376 selb->deactivateStandardFlag(s);
1377 selb->updateFlagsToolbar();
1381 parser.setError (Aborted,"Unknown command");
1384 if (parser.errorLevel()==NoError)
1387 mapCenter->reposition();
1391 // TODO Error handling
1392 qWarning("MapEditor::parseAtom: Error!");
1393 qWarning(parser.errorMessage());
1397 void MapEditor::runScript (QString script)
1399 parser.setScript (script);
1401 while (parser.next() )
1402 parseAtom(parser.getAtom());
1405 bool MapEditor::isDefault()
1410 bool MapEditor::hasChanged()
1415 void MapEditor::setChanged()
1418 autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
1426 void MapEditor::closeMap()
1428 // Unselect before disabling the toolbar actions
1429 if (!xelection.isEmpty() ) xelection.unselect();
1437 void MapEditor::setFilePath(QString fpath, QString destname)
1439 if (fpath.isEmpty() || fpath=="")
1446 filePath=fpath; // becomes absolute path
1447 fileName=fpath; // gets stripped of path
1448 destPath=destname; // needed for vymlinks
1450 // If fpath is not an absolute path, complete it
1451 filePath=QDir(fpath).absPath();
1452 fileDir=filePath.left (1+filePath.findRev ("/"));
1454 // Set short name, too. Search from behind:
1455 int i=fileName.findRev("/");
1456 if (i>=0) fileName=fileName.remove (0,i+1);
1458 // Forget the .vym (or .xml) for name of map
1459 mapName=fileName.left(fileName.findRev(".",-1,true) );
1463 void MapEditor::setFilePath(QString fpath)
1465 setFilePath (fpath,fpath);
1468 QString MapEditor::getFilePath()
1473 QString MapEditor::getFileName()
1478 QString MapEditor::getMapName()
1483 QString MapEditor::getDestPath()
1488 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1490 ErrorCode err=success;
1494 if (xelection.isEmpty() ) xelection.unselect();
1497 mapCenter->setMapEditor(this);
1498 // (map state is set later at end of load...)
1501 BranchObj *bo=xelection.getBranch();
1502 if (!bo) return aborted;
1503 if (lmode==ImportAdd)
1504 saveStateChangingPart(
1507 QString("addMapInsert (%1)").arg(fname),
1508 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1510 saveStateChangingPart(
1513 QString("addMapReplace(%1)").arg(fname),
1514 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1518 parseVYMHandler handler;
1519 QFile file( fname );
1521 // I am paranoid: file should exist anyway
1522 // according to check in mainwindow.
1523 if (!file.exists() )
1525 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1526 tr("Couldn't open map " +fname)+".");
1530 bool blockSaveStateOrg=blockSaveState;
1531 blockReposition=true;
1532 blockSaveState=true;
1533 QXmlInputSource source( file);
1534 QXmlSimpleReader reader;
1535 reader.setContentHandler( &handler );
1536 reader.setErrorHandler( &handler );
1537 handler.setMapEditor( this );
1540 // We need to set the tmpDir in order to load files with rel. path
1541 QString tmpdir= fname.left(fname.findRev("/",-1));
1542 handler.setTmpDir (tmpdir);
1543 handler.setInputFile (file.name());
1544 handler.setLoadMode (lmode);
1545 bool ok = reader.parse( source );
1546 blockReposition=false;
1547 blockSaveState=blockSaveStateOrg;
1551 mapCenter->reposition();
1558 autosaveTimer->stop();
1562 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1563 tr( handler.errorProtocol() ) );
1565 // Still return "success": the map maybe at least
1566 // partially read by the parser
1573 int MapEditor::save (const SaveMode &savemode)
1575 // Create mapName and fileDir
1576 makeSubDirs (fileDir);
1580 fname=mapName+".xml";
1582 // use name given by user, even if he chooses .doc
1587 if (savemode==CompleteMap || xelection.isEmpty())
1588 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1591 // TODO take care of multiselections
1592 if (xelection.type()==Selection::FloatImage)
1595 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());
1599 if (!saveStringToDisk(fileDir+fname,saveFile))
1604 autosaveTimer->stop();
1609 void MapEditor::setZipped (bool z)
1614 bool MapEditor::saveZipped ()
1619 void MapEditor::print()
1623 printer = new QPrinter;
1624 printer->setColorMode (QPrinter::Color);
1625 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1626 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1627 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1630 QRectF totalBBox=mapCenter->getTotalBBox();
1632 // Try to set orientation automagically
1633 // Note: Interpretation of generated postscript is amibiguous, if
1634 // there are problems with landscape mode, see
1635 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1637 if (totalBBox.width()>totalBBox.height())
1638 // recommend landscape
1639 printer->setOrientation (QPrinter::Landscape);
1641 // recommend portrait
1642 printer->setOrientation (QPrinter::Portrait);
1644 if ( printer->setup(this) )
1645 // returns false, if printing is canceled
1647 QPainter pp(printer);
1649 pp.setRenderHint(QPainter::Antialiasing,true);
1651 // Don't print the visualisation of selection
1652 xelection.unselect();
1654 QRectF mapRect=totalBBox;
1655 QGraphicsRectItem *frame=NULL;
1659 // Print frame around map
1660 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1661 totalBBox.width()+20, totalBBox.height()+20);
1662 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1663 frame->setZValue(0);
1668 double paperAspect = (double)printer->width() / (double)printer->height();
1669 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1671 if (mapAspect>=paperAspect)
1673 // Fit horizontally to paper width
1674 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1675 viewBottom=(int)(printer->width()/mapAspect);
1678 // Fit vertically to paper height
1679 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1680 viewBottom=printer->height();
1685 // Print footer below map
1687 font.setPointSize(10);
1689 QRectF footerBox(0,viewBottom,printer->width(),15);
1690 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1691 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1695 QRectF (0,0,printer->width(),printer->height()-15),
1696 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1699 // Viewport has paper dimension
1700 if (frame) delete (frame);
1702 // Restore selection
1703 xelection.reselect();
1705 // Save settings in vymrc
1706 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1707 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1708 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1712 void MapEditor::setAntiAlias (bool b)
1714 setRenderHint(QPainter::Antialiasing,b);
1717 void MapEditor::setSmoothPixmap(bool b)
1719 setRenderHint(QPainter::SmoothPixmapTransform,b);
1722 QPixmap MapEditor::getPixmap()
1724 QRectF mapRect=mapCenter->getTotalBBox();
1725 QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+1);
1728 pp.setRenderHints(renderHints());
1730 // Don't print the visualisation of selection
1731 xelection.unselect();
1733 mapScene->render ( &pp,
1734 QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1735 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1737 // Restore selection
1738 xelection.reselect();
1743 void MapEditor::setHideTmpMode (BranchObj::HideTmpMode mode)
1746 mapCenter->setHideTmp (hidemode);
1747 mapCenter->reposition();
1751 BranchObj::HideTmpMode MapEditor::getHideTmpMode()
1756 void MapEditor::setExportMode (bool b)
1758 // should be called before and after exports
1759 // depending on the settings
1760 if (b && settings.value("/export/useHideExport","yes")=="yes")
1761 setHideTmpMode (BranchObj::HideExport);
1763 setHideTmpMode (BranchObj::HideNone);
1766 void MapEditor::exportASCII(QString fname,bool askName)
1769 ex.setMapCenter(mapCenter);
1771 ex.setFile (mapName+".txt");
1777 //ex.addFilter ("TXT (*.txt)");
1778 ex.setDir(lastImageDir);
1779 //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
1784 setExportMode(true);
1786 setExportMode(false);
1790 void MapEditor::exportImage(QString fname, bool askName, QString format)
1794 fname=mapName+".png";
1801 QFileDialog *fd=new QFileDialog (this);
1802 fd->setCaption (tr("Export map as image"));
1803 fd->setDirectory (lastImageDir);
1804 fd->setFileMode(QFileDialog::AnyFile);
1805 fd->setFilters (imageIO.getFilters() );
1808 fl=fd->selectedFiles();
1810 format=imageIO.getType(fd->selectedFilter());
1814 setExportMode (true);
1815 QPixmap pix (getPixmap());
1816 pix.save(fname, format);
1817 setExportMode (false);
1820 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1824 ex.setMapCenter(mapCenter);
1825 if (ex.setConfigFile(cf))
1827 setExportMode (true);
1828 ex.exportPresentation();
1829 setExportMode (false);
1833 void MapEditor::exportXHTML (const QString &dir, bool askForName)
1835 ExportXHTMLDialog dia(this);
1836 dia.setFilePath (filePath );
1837 dia.setMapName (mapName );
1839 if (dir!="") dia.setDir (dir);
1845 if (dia.exec()!=QDialog::Accepted)
1849 QDir d (dia.getDir());
1850 // Check, if warnings should be used before overwriting
1851 // the output directory
1852 if (d.exists() && d.count()>0)
1855 warn.showCancelButton (true);
1856 warn.setText(QString(
1857 "The directory %1 is not empty.\n"
1858 "Do you risk to overwrite some of its contents?").arg(d.path() ));
1859 warn.setCaption("Warning: Directory not empty");
1860 warn.setShowAgainName("mainwindow/overwrite-dir-xhtml");
1862 if (warn.exec()!=QDialog::Accepted) ok=false;
1869 exportXML (dia.getDir(),false );
1870 dia.doExport(mapName );
1871 //if (dia.hasChanged()) setChanged();
1875 void MapEditor::exportXML(QString dir, bool askForName)
1879 dir=browseDirectory(this,tr("Export XML to directory"));
1880 if (dir =="" && !reallyWriteDirectory(dir) )
1884 // Hide stuff during export, if settings want this
1885 setExportMode (true);
1887 // Create subdirectories
1890 // write to directory
1891 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1894 file.setName ( dir + "/"+mapName+".xml");
1895 if ( !file.open( QIODevice::WriteOnly ) )
1897 // This should neverever happen
1898 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1902 // Write it finally, and write in UTF8, no matter what
1903 QTextStream ts( &file );
1904 ts.setEncoding (QTextStream::UnicodeUTF8);
1908 // Now write image, too
1909 exportImage (dir+"/images/"+mapName+".png",false,"PNG");
1911 setExportMode (false);
1914 void MapEditor::clear()
1916 xelection.unselect();
1920 void MapEditor::copy()
1922 LinkableMapObj *sel=xelection.single();
1925 if (redosAvail == 0)
1928 QString s=sel->getSelectString();
1929 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel );
1930 curClipboard=curStep;
1933 // Copy also to global clipboard, because we are at last step in history
1934 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
1935 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
1936 copyDir (bakMapDir,clipboardDir );
1938 clipboardEmpty=false;
1943 void MapEditor::redo()
1945 // Can we undo at all?
1946 if (redosAvail<1) return;
1948 bool blockSaveStateOrg=blockSaveState;
1949 blockSaveState=true;
1953 if (undosAvail<stepsTotal) undosAvail++;
1955 if (curStep>stepsTotal) curStep=1;
1956 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1957 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1958 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1959 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1960 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1961 QString version=undoSet.readEntry ("/history/version");
1963 if (!checkVersion(version))
1964 QMessageBox::warning(0,tr("Warning"),
1965 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1968 // Find out current undo directory
1969 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1973 cout << "ME::redo() begin\n";
1974 cout << " undosAvail="<<undosAvail<<endl;
1975 cout << " redosAvail="<<redosAvail<<endl;
1976 cout << " curStep="<<curStep<<endl;
1977 cout << " ---------------------------"<<endl;
1978 cout << " comment="<<comment.toStdString()<<endl;
1979 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1980 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1981 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1982 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1983 cout << " ---------------------------"<<endl<<endl;
1986 // select object before redo
1987 if (!redoSelection.isEmpty())
1988 select (redoSelection);
1991 parseAtom (redoCommand);
1992 mapCenter->reposition();
1994 blockSaveState=blockSaveStateOrg;
1996 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1997 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1998 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1999 undoSet.writeSettings(histPath);
2001 mainWindow->updateHistory (undoSet);
2004 /* TODO remove testing
2005 cout << "ME::redo() end\n";
2006 cout << " undosAvail="<<undosAvail<<endl;
2007 cout << " redosAvail="<<redosAvail<<endl;
2008 cout << " curStep="<<curStep<<endl;
2009 cout << " ---------------------------"<<endl<<endl;
2015 bool MapEditor::isRedoAvailable()
2017 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
2023 void MapEditor::undo()
2025 // Can we undo at all?
2026 if (undosAvail<1) return;
2028 mainWindow->statusMessage (tr("Autosave disabled during undo."));
2030 bool blockSaveStateOrg=blockSaveState;
2031 blockSaveState=true;
2033 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
2034 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2035 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2036 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2037 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2038 QString version=undoSet.readEntry ("/history/version");
2040 if (!checkVersion(version))
2041 QMessageBox::warning(0,tr("Warning"),
2042 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2044 // Find out current undo directory
2045 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
2047 // select object before undo
2048 if (!undoSelection.isEmpty())
2049 select (undoSelection);
2053 cout << "ME::undo() begin\n";
2054 cout << " undosAvail="<<undosAvail<<endl;
2055 cout << " redosAvail="<<redosAvail<<endl;
2056 cout << " curStep="<<curStep<<endl;
2057 cout << " ---------------------------"<<endl;
2058 cout << " comment="<<comment.toStdString()<<endl;
2059 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2060 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2061 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2062 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2063 cout << " ---------------------------"<<endl<<endl;
2065 parseAtom (undoCommand);
2066 mapCenter->reposition();
2070 if (curStep<1) curStep=stepsTotal;
2074 blockSaveState=blockSaveStateOrg;
2075 /* TODO remove testing
2076 cout << "ME::undo() end\n";
2077 cout << " undosAvail="<<undosAvail<<endl;
2078 cout << " redosAvail="<<redosAvail<<endl;
2079 cout << " curStep="<<curStep<<endl;
2080 cout << " ---------------------------"<<endl<<endl;
2083 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2084 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2085 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2086 undoSet.writeSettings(histPath);
2088 mainWindow->updateHistory (undoSet);
2091 ensureSelectionVisible();
2094 bool MapEditor::isUndoAvailable()
2096 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
2102 void MapEditor::gotoHistoryStep (int i)
2104 // Restore variables
2105 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
2106 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
2108 if (i<0) i=undosAvail+redosAvail;
2110 // Clicking above current step makes us undo things
2113 for (int j=0; j<undosAvail-i; j++) undo();
2116 // Clicking below current step makes us redo things
2118 for (int j=undosAvail; j<i; j++)
2120 cout << "redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
2124 // And ignore clicking the current row ;-)
2127 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
2129 QString pathDir=path.left(path.findRev("/"));
2135 // We need to parse saved XML data
2136 parseVYMHandler handler;
2137 QXmlInputSource source( file);
2138 QXmlSimpleReader reader;
2139 reader.setContentHandler( &handler );
2140 reader.setErrorHandler( &handler );
2141 handler.setMapEditor( this );
2142 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2143 if (undoSel.isEmpty())
2147 handler.setLoadMode (NewMap);
2151 handler.setLoadMode (ImportReplace);
2153 blockReposition=true;
2154 bool ok = reader.parse( source );
2155 blockReposition=false;
2158 // This should never ever happen
2159 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2160 handler.errorProtocol());
2163 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2166 void MapEditor::addMapInsertInt (const QString &path, int pos)
2168 BranchObj *sel=xelection.getBranch();
2171 QString pathDir=path.left(path.findRev("/"));
2177 // We need to parse saved XML data
2178 parseVYMHandler handler;
2179 QXmlInputSource source( file);
2180 QXmlSimpleReader reader;
2181 reader.setContentHandler( &handler );
2182 reader.setErrorHandler( &handler );
2183 handler.setMapEditor( this );
2184 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2185 handler.setLoadMode (ImportAdd);
2186 blockReposition=true;
2187 bool ok = reader.parse( source );
2188 blockReposition=false;
2191 // This should never ever happen
2192 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2193 handler.errorProtocol());
2196 sel->getLastBranch()->linkTo (sel,pos);
2198 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2202 void MapEditor::pasteNoSave(const int &n)
2204 bool old=blockSaveState;
2205 blockSaveState=true;
2206 if (redosAvail > 0 || n!=0)
2208 // Use the "historical" buffer
2209 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(n));
2210 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
2211 load (bakMapDir+"/"+clipboardFile,ImportAdd);
2213 // Use the global buffer
2214 load (clipboardDir+"/"+clipboardFile,ImportAdd);
2218 void MapEditor::paste()
2220 BranchObj *sel=xelection.getBranch();
2223 saveStateChangingPart(
2226 QString ("paste (%1)").arg(curClipboard),
2227 QString("Paste to %1").arg( getName(sel))
2230 mapCenter->reposition();
2234 void MapEditor::cut()
2236 LinkableMapObj *sel=xelection.single();
2237 if ( sel && (xelection.type() == Selection::Branch ||
2238 xelection.type()==Selection::MapCenter ||
2239 xelection.type()==Selection::FloatImage))
2241 /* No savestate! savestate is called in cutNoSave
2242 saveStateChangingPart(
2246 QString("Cut %1").arg(getName(sel ))
2251 mapCenter->reposition();
2255 void MapEditor::move(const double &x, const double &y)
2257 LinkableMapObj *sel=xelection.single();
2260 QString ps=qpointfToString (sel->getAbsPos());
2261 QString s=xelection.single()->getSelectString();
2264 s, "move "+qpointfToString (QPointF (x,y)),
2265 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
2267 mapCenter->reposition();
2273 void MapEditor::moveRel (const double &x, const double &y)
2275 LinkableMapObj *sel=xelection.single();
2278 QString ps=qpointfToString (sel->getRelPos());
2279 QString s=sel->getSelectString();
2282 s, "moveRel "+qpointfToString (QPointF (x,y)),
2283 QString("Move %1 to relativ position %2").arg(getName(sel)).arg(ps));
2284 ((OrnamentedObj*)sel)->move2RelPos (x,y);
2285 mapCenter->reposition();
2291 void MapEditor::moveBranchUp()
2293 BranchObj* bo=xelection.getBranch();
2297 if (!bo->canMoveBranchUp()) return;
2298 par=(BranchObj*)(bo->getParObj());
2299 BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
2300 saveState (bo->getSelectString(),"moveBranchDown ()",obo->getSelectString(),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
2301 mapCenter->reposition();
2304 ensureSelectionVisible();
2308 void MapEditor::moveBranchDown()
2310 BranchObj* bo=xelection.getBranch();
2314 if (!bo->canMoveBranchDown()) return;
2315 par=(BranchObj*)(bo->getParObj());
2316 BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
2317 saveState(bo->getSelectString(),"moveBranchUp ()",obo->getSelectString(),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
2318 mapCenter->reposition();
2321 ensureSelectionVisible();
2325 void MapEditor::linkTo(const QString &dstString)
2327 FloatImageObj *fio=xelection.getFloatImage();
2330 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
2331 if (dst && (typeid(*dst)==typeid (BranchObj) ||
2332 typeid(*dst)==typeid (MapCenterObj)))
2334 LinkableMapObj *dstPar=dst->getParObj();
2335 QString parString=dstPar->getSelectString();
2336 QString fioPreSelectString=fio->getSelectString();
2337 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
2338 ((BranchObj*)(dst))->addFloatImage (fio);
2339 xelection.unselect();
2340 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
2341 fio=((BranchObj*)(dst))->getLastFloatImage();
2344 xelection.select(fio);
2346 fio->getSelectString(),
2347 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
2349 QString ("linkTo (\"%1\")").arg(dstString),
2350 QString ("Link floatimage to %1").arg(getName(dst)));
2355 QString MapEditor::getHeading(bool &ok, QPoint &p)
2357 BranchObj *bo=xelection.getBranch();
2361 p=mapFromScene(bo->getAbsPos());
2362 return bo->getHeading();
2368 void MapEditor::setHeading(const QString &s)
2370 BranchObj *sel=xelection.getBranch();
2375 "setHeading (\""+sel->getHeading()+"\")",
2377 "setHeading (\""+s+"\")",
2378 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
2379 sel->setHeading(s );
2380 mapCenter->reposition();
2382 ensureSelectionVisible();
2386 void MapEditor::setHeadingInt(const QString &s)
2388 BranchObj *bo=xelection.getBranch();
2392 mapCenter->reposition();
2394 ensureSelectionVisible();
2398 void MapEditor::setVymLinkInt (const QString &s)
2400 // Internal function, no saveState needed
2401 BranchObj *bo=xelection.getBranch();
2405 mapCenter->reposition();
2408 ensureSelectionVisible();
2412 BranchObj* MapEditor::addNewBranchInt(int num)
2414 // Depending on pos:
2415 // -3 insert in childs of parent above selection
2416 // -2 add branch to selection
2417 // -1 insert in childs of parent below selection
2418 // 0..n insert in childs of parent at pos
2419 BranchObj *newbo=NULL;
2420 BranchObj *bo=xelection.getBranch();
2425 // save scroll state. If scrolled, automatically select
2426 // new branch in order to tmp unscroll parent...
2427 newbo=bo->addBranch();
2432 bo=(BranchObj*)bo->getParObj();
2433 if (bo) newbo=bo->insertBranch(num);
2437 bo=(BranchObj*)bo->getParObj();
2438 if (bo) newbo=bo->insertBranch(num);
2440 if (!newbo) return NULL;
2445 BranchObj* MapEditor::addNewBranch(int pos)
2447 // Different meaning than num in addNewBranchInt!
2451 BranchObj *bo = xelection.getBranch();
2452 BranchObj *newbo=NULL;
2456 setCursor (Qt::ArrowCursor);
2458 newbo=addNewBranchInt (pos-2);
2466 QString ("addBranch (%1)").arg(pos),
2467 QString ("Add new branch to %1").arg(getName(bo)));
2469 mapCenter->reposition();
2471 latestSelection=newbo->getSelectString();
2472 // In Network mode, the client needs to know where the new branch is,
2473 // so we have to pass on this information via saveState.
2474 // TODO: Get rid of this positioning workaround
2475 QString ps=qpointfToString (newbo->getAbsPos());
2476 sendData ("selectLatestAdded ()");
2477 sendData (QString("move %1").arg(ps));
2485 BranchObj* MapEditor::addNewBranchBefore()
2487 BranchObj *newbo=NULL;
2488 BranchObj *bo = xelection.getBranch();
2489 if (bo && xelection.type()==Selection::Branch)
2490 // We accept no MapCenterObj here, so we _have_ a parent
2492 QPointF p=bo->getRelPos();
2495 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2497 // add below selection
2498 newbo=parbo->insertBranch(bo->getNum()+1);
2501 newbo->move2RelPos (p);
2503 // Move selection to new branch
2504 bo->linkTo (newbo,-1);
2506 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2507 QString ("Add branch before %1").arg(getName(bo)));
2509 mapCenter->reposition();
2513 latestSelection=xelection.getSelectString();
2517 void MapEditor::deleteSelection()
2519 BranchObj *bo = xelection.getBranch();
2520 if (bo && xelection.type()==Selection::Branch)
2522 BranchObj* par=(BranchObj*)(bo->getParObj());
2523 xelection.unselect();
2524 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2525 par->removeBranch(bo);
2526 xelection.select (par);
2527 ensureSelectionVisible();
2528 mapCenter->reposition();
2533 FloatImageObj *fio=xelection.getFloatImage();
2536 BranchObj* par=(BranchObj*)(fio->getParObj());
2537 saveStateChangingPart(
2541 QString("Delete %1").arg(getName(fio))
2543 xelection.unselect();
2544 par->removeFloatImage(fio);
2545 xelection.select (par);
2546 mapCenter->reposition();
2548 ensureSelectionVisible();
2553 LinkableMapObj* MapEditor::getSelection()
2555 return xelection.single();
2558 BranchObj* MapEditor::getSelectedBranch()
2560 return xelection.getBranch();
2563 FloatImageObj* MapEditor::getSelectedFloatImage()
2565 return xelection.getFloatImage();
2568 void MapEditor::unselect()
2570 xelection.unselect();
2573 void MapEditor::reselect()
2575 xelection.reselect();
2578 bool MapEditor::select (const QString &s)
2580 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2582 // Finally select the found object
2585 xelection.unselect();
2586 xelection.select(lmo);
2588 ensureSelectionVisible();
2595 QString MapEditor::getSelectString()
2597 return xelection.getSelectString();
2600 void MapEditor::selectInt (LinkableMapObj *lmo)
2602 if (lmo && xelection.single()!= lmo && isSelectBlocked()==false )
2604 xelection.select(lmo);
2610 void MapEditor::selectNextBranchInt()
2612 // Increase number of branch
2613 LinkableMapObj *sel=xelection.single();
2616 QString s=sel->getSelectString();
2622 part=s.section(",",-1);
2624 num=part.right(part.length() - 3);
2626 s=s.left (s.length() -num.length());
2629 num=QString ("%1").arg(num.toUInt()+1);
2633 // Try to select this one
2634 if (select (s)) return;
2636 // We have no direct successor,
2637 // try to increase the parental number in order to
2638 // find a successor with same depth
2640 int d=xelection.single()->getDepth();
2645 while (!found && d>0)
2647 s=s.section (",",0,d-1);
2648 // replace substring of current depth in s with "1"
2649 part=s.section(",",-1);
2651 num=part.right(part.length() - 3);
2655 // increase number of parent
2656 num=QString ("%1").arg(num.toUInt()+1);
2657 s=s.section (",",0,d-2) + ","+ typ+num;
2660 // Special case, look at orientation
2661 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2662 num=QString ("%1").arg(num.toUInt()+1);
2664 num=QString ("%1").arg(num.toUInt()-1);
2669 // pad to oldDepth, select the first branch for each depth
2670 for (i=d;i<oldDepth;i++)
2675 if ( xelection.getBranch()->countBranches()>0)
2683 // try to select the freshly built string
2691 void MapEditor::selectPrevBranchInt()
2693 // Decrease number of branch
2694 BranchObj *bo=xelection.getBranch();
2697 QString s=bo->getSelectString();
2703 part=s.section(",",-1);
2705 num=part.right(part.length() - 3);
2707 s=s.left (s.length() -num.length());
2709 int n=num.toInt()-1;
2712 num=QString ("%1").arg(n);
2715 // Try to select this one
2716 if (n>=0 && select (s)) return;
2718 // We have no direct precessor,
2719 // try to decrease the parental number in order to
2720 // find a precessor with same depth
2722 int d=xelection.single()->getDepth();
2727 while (!found && d>0)
2729 s=s.section (",",0,d-1);
2730 // replace substring of current depth in s with "1"
2731 part=s.section(",",-1);
2733 num=part.right(part.length() - 3);
2737 // decrease number of parent
2738 num=QString ("%1").arg(num.toInt()-1);
2739 s=s.section (",",0,d-2) + ","+ typ+num;
2742 // Special case, look at orientation
2743 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2744 num=QString ("%1").arg(num.toInt()-1);
2746 num=QString ("%1").arg(num.toInt()+1);
2751 // pad to oldDepth, select the last branch for each depth
2752 for (i=d;i<oldDepth;i++)
2756 if ( xelection.getBranch()->countBranches()>0)
2757 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2764 // try to select the freshly built string
2772 void MapEditor::selectUpperBranch()
2774 if (isSelectBlocked() ) return;
2776 BranchObj *bo=xelection.getBranch();
2777 if (bo && xelection.type()==Selection::Branch)
2779 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2780 selectPrevBranchInt();
2782 if (bo->getDepth()==1)
2783 selectNextBranchInt();
2785 selectPrevBranchInt();
2789 void MapEditor::selectLowerBranch()
2791 if (isSelectBlocked() ) return;
2793 BranchObj *bo=xelection.getBranch();
2794 if (bo && xelection.type()==Selection::Branch)
2795 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2796 selectNextBranchInt();
2798 if (bo->getDepth()==1)
2799 selectPrevBranchInt();
2801 selectNextBranchInt();
2805 void MapEditor::selectLeftBranch()
2807 if (isSelectBlocked() ) return;
2811 LinkableMapObj *sel=xelection.single();
2814 if (xelection.type()== Selection::MapCenter)
2816 par=xelection.getBranch();
2817 bo=par->getLastSelectedBranch();
2820 // Workaround for reselecting on left and right side
2821 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2822 bo=par->getLastBranch();
2825 bo=par->getLastBranch();
2826 xelection.select(bo);
2828 ensureSelectionVisible();
2834 par=(BranchObj*)(sel->getParObj());
2835 if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
2837 if (xelection.type() == Selection::Branch ||
2838 xelection.type() == Selection::FloatImage)
2840 xelection.select(par);
2842 ensureSelectionVisible();
2847 if (xelection.type() == Selection::Branch )
2849 bo=xelection.getBranch()->getLastSelectedBranch();
2852 xelection.select(bo);
2854 ensureSelectionVisible();
2863 void MapEditor::selectRightBranch()
2865 if (isSelectBlocked() ) return;
2869 LinkableMapObj *sel=xelection.single();
2872 if (xelection.type()==Selection::MapCenter)
2874 par=xelection.getBranch();
2875 bo=par->getLastSelectedBranch();
2878 // Workaround for reselecting on left and right side
2879 if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
2880 bo=par->getFirstBranch();
2883 xelection.select(bo);
2885 ensureSelectionVisible();
2891 par=(BranchObj*)(xelection.single()->getParObj());
2892 if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
2894 if (xelection.type() == Selection::Branch ||
2895 xelection.type() == Selection::FloatImage)
2897 xelection.select(par);
2899 ensureSelectionVisible();
2904 if (xelection.type() == Selection::Branch)
2906 bo=xelection.getBranch()->getLastSelectedBranch();
2909 xelection.select(bo);
2911 ensureSelectionVisible();
2920 void MapEditor::selectFirstBranch()
2922 BranchObj *bo1=xelection.getBranch();
2927 par=(BranchObj*)(bo1->getParObj());
2928 bo2=par->getFirstBranch();
2930 xelection.select(bo2);
2932 ensureSelectionVisible();
2938 void MapEditor::selectLastBranch()
2940 BranchObj *bo1=xelection.getBranch();
2945 par=(BranchObj*)(bo1->getParObj());
2946 bo2=par->getLastBranch();
2949 xelection.select(bo2);
2951 ensureSelectionVisible();
2957 void MapEditor::selectMapBackgroundImage ()
2959 Q3FileDialog *fd=new Q3FileDialog( this);
2960 fd->setMode (Q3FileDialog::ExistingFile);
2961 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2962 ImagePreview *p =new ImagePreview (fd);
2963 fd->setContentsPreviewEnabled( TRUE );
2964 fd->setContentsPreview( p, p );
2965 fd->setPreviewMode( Q3FileDialog::Contents );
2966 fd->setCaption(vymName+" - " +tr("Load background image"));
2967 fd->setDir (lastImageDir);
2970 if ( fd->exec() == QDialog::Accepted )
2972 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2973 lastImageDir=QDir (fd->dirPath());
2974 setMapBackgroundImage (fd->selectedFile());
2978 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
2980 QColor oldcol=mapScene->backgroundBrush().color();
2984 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2986 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2987 QString("Set background color of map to %1").arg(col.name()));
2990 brush.setTextureImage (QPixmap (fn));
2991 mapScene->setBackgroundBrush(brush);
2994 void MapEditor::selectMapBackgroundColor()
2996 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2997 if ( !col.isValid() ) return;
2998 setMapBackgroundColor( col );
3002 void MapEditor::setMapBackgroundColor(QColor col)
3004 QColor oldcol=mapScene->backgroundBrush().color();
3007 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
3009 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
3010 QString("Set background color of map to %1").arg(col.name()));
3011 mapScene->setBackgroundBrush(col);
3014 QColor MapEditor::getMapBackgroundColor()
3016 return mapScene->backgroundBrush().color();
3019 QColor MapEditor::getCurrentHeadingColor()
3021 BranchObj *bo=xelection.getBranch();
3022 if (bo) return bo->getColor();
3024 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
3028 void MapEditor::colorBranch (QColor c)
3030 BranchObj *bo=xelection.getBranch();
3035 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
3037 QString ("colorBranch (\"%1\")").arg(c.name()),
3038 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
3040 bo->setColor(c); // color branch
3044 void MapEditor::colorSubtree (QColor c)
3046 BranchObj *bo=xelection.getBranch();
3049 saveStateChangingPart(
3052 QString ("colorSubtree (\"%1\")").arg(c.name()),
3053 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
3055 bo->setColorSubtree (c); // color links, color childs
3060 void MapEditor::toggleStandardFlag(QString f)
3062 BranchObj *bo=xelection.getBranch();
3066 if (bo->isSetStandardFlag(f))
3078 QString("%1 (\"%2\")").arg(u).arg(f),
3080 QString("%1 (\"%2\")").arg(r).arg(f),
3081 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
3082 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
3088 BranchObj* MapEditor::findText (QString s, bool cs)
3090 QTextDocument::FindFlags flags=0;
3091 if (cs) flags=QTextDocument::FindCaseSensitively;
3094 { // Nothing found or new find process
3096 // nothing found, start again
3098 itFind=mapCenter->first();
3100 bool searching=true;
3101 bool foundNote=false;
3102 while (searching && !EOFind)
3106 // Searching in Note
3107 if (itFind->getNote().contains(s,cs))
3109 if (xelection.single()!=itFind)
3111 xelection.select(itFind);
3112 ensureSelectionVisible();
3114 if (textEditor->findText(s,flags))
3120 // Searching in Heading
3121 if (searching && itFind->getHeading().contains (s,cs) )
3123 xelection.select(itFind);
3124 ensureSelectionVisible();
3130 itFind=itFind->next();
3131 if (!itFind) EOFind=true;
3135 return xelection.getBranch();
3140 void MapEditor::findReset()
3141 { // Necessary if text to find changes during a find process
3145 void MapEditor::setURL(const QString &url)
3147 BranchObj *bo=xelection.getBranch();
3150 QString oldurl=bo->getURL();
3154 QString ("setURL (\"%1\")").arg(oldurl),
3156 QString ("setURL (\"%1\")").arg(url),
3157 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
3160 mapCenter->reposition();
3162 ensureSelectionVisible();
3166 void MapEditor::editURL()
3168 BranchObj *bo=xelection.getBranch();
3172 QString text = QInputDialog::getText(
3173 "VYM", tr("Enter URL:"), QLineEdit::Normal,
3174 bo->getURL(), &ok, this );
3176 // user entered something and pressed OK
3181 void MapEditor::editLocalURL()
3183 BranchObj *bo=xelection.getBranch();
3186 QStringList filters;
3187 filters <<"All files (*)";
3188 filters << tr("Text","Filedialog") + " (*.txt)";
3189 filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
3190 filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
3191 filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
3192 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Set URL to a local file"));
3193 fd->setFilters (filters);
3194 fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
3195 fd->setDirectory (lastFileDir);
3196 if (! bo->getVymLink().isEmpty() )
3197 fd->selectFile( bo->getURL() );
3200 if ( fd->exec() == QDialog::Accepted )
3202 lastFileDir=QDir (fd->directory().path());
3203 setURL (fd->selectedFile() );
3208 QString MapEditor::getURL()
3210 BranchObj *bo=xelection.getBranch();
3212 return bo->getURL();
3217 QStringList MapEditor::getURLs()
3220 BranchObj *bo=xelection.getBranch();
3226 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
3234 void MapEditor::editHeading2URL()
3236 BranchObj *bo=xelection.getBranch();
3238 setURL (bo->getHeading());
3241 void MapEditor::editBugzilla2URL()
3243 BranchObj *bo=xelection.getBranch();
3246 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
3251 void MapEditor::editFATE2URL()
3253 BranchObj *bo=xelection.getBranch();
3256 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
3259 "setURL (\""+bo->getURL()+"\")",
3261 "setURL (\""+url+"\")",
3262 QString("Use heading of %1 as link to FATE").arg(getName(bo))
3269 void MapEditor::editVymLink()
3271 BranchObj *bo=xelection.getBranch();
3274 QStringList filters;
3275 filters <<"VYM map (*.vym)";
3276 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
3277 fd->setFilters (filters);
3278 fd->setCaption(vymName+" - " +tr("Link to another map"));
3279 fd->setDirectory (lastFileDir);
3280 if (! bo->getVymLink().isEmpty() )
3281 fd->selectFile( bo->getVymLink() );
3285 if ( fd->exec() == QDialog::Accepted )
3287 lastFileDir=QDir (fd->directory().path());
3290 "setVymLink (\""+bo->getVymLink()+"\")",
3292 "setVymLink (\""+fd->selectedFile()+"\")",
3293 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
3295 setVymLinkInt (fd->selectedFile() );
3300 void MapEditor::deleteVymLink()
3302 BranchObj *bo=xelection.getBranch();
3307 "setVymLink (\""+bo->getVymLink()+"\")",
3309 "setVymLink (\"\")",
3310 QString("Unset vymlink of %1").arg(getName(bo))
3312 bo->setVymLink ("" );
3314 mapCenter->reposition();
3319 void MapEditor::setHideExport(bool b)
3321 BranchObj *bo=xelection.getBranch();
3324 bo->setHideInExport (b);
3325 QString u= b ? "false" : "true";
3326 QString r=!b ? "false" : "true";
3330 QString ("setHideExport (%1)").arg(u),
3332 QString ("setHideExport (%1)").arg(r),
3333 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
3336 mapCenter->reposition();
3342 void MapEditor::toggleHideExport()
3344 BranchObj *bo=xelection.getBranch();
3346 setHideExport ( !bo->hideInExport() );
3349 QString MapEditor::getVymLink()
3351 BranchObj *bo=xelection.getBranch();
3353 return bo->getVymLink();
3359 QStringList MapEditor::getVymLinks()
3362 BranchObj *bo=xelection.getBranch();
3368 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
3376 void MapEditor::deleteKeepChilds()
3378 BranchObj *bo=xelection.getBranch();
3382 par=(BranchObj*)(bo->getParObj());
3383 QPointF p=bo->getRelPos();
3384 saveStateChangingPart(
3387 "deleteKeepChilds ()",
3388 QString("Remove %1 and keep its childs").arg(getName(bo))
3391 QString sel=bo->getSelectString();
3393 par->removeBranchHere(bo);
3394 mapCenter->reposition();
3396 xelection.getBranch()->move2RelPos (p);
3397 mapCenter->reposition();
3401 void MapEditor::deleteChilds()
3403 BranchObj *bo=xelection.getBranch();
3406 saveStateChangingPart(
3410 QString( "Remove childs of branch %1").arg(getName(bo))
3413 mapCenter->reposition();
3417 void MapEditor::editMapInfo()
3419 ExtraInfoDialog dia;
3420 dia.setMapName (getFileName() );
3421 dia.setAuthor (mapCenter->getAuthor() );
3422 dia.setComment(mapCenter->getComment() );
3426 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
3433 bo=mapCenter->first();
3436 if (!bo->getNote().isEmpty() ) n++;
3437 f+= bo->countFloatImages();
3439 xl+=bo->countXLinks();
3442 stats+=QString ("%1 branches\n").arg (b-1,6);
3443 stats+=QString ("%1 xLinks \n").arg (xl,6);
3444 stats+=QString ("%1 notes\n").arg (n,6);
3445 stats+=QString ("%1 images\n").arg (f,6);
3446 dia.setStats (stats);
3448 // Finally show dialog
3449 if (dia.exec() == QDialog::Accepted)
3451 setMapAuthor (dia.getAuthor() );
3452 setMapComment (dia.getComment() );
3456 void MapEditor::ensureSelectionVisible()
3458 LinkableMapObj *lmo=xelection.single();
3459 if (lmo) ensureVisible (lmo->getBBox() );
3463 void MapEditor::updateSelection()
3465 // Tell selection to update geometries
3469 void MapEditor::updateActions()
3471 // Tell mainwindow to update states of actions
3472 mainWindow->updateActions();
3473 // TODO maybe don't update if blockReposition is set
3476 void MapEditor::updateNoteFlag()
3479 BranchObj *bo=xelection.getBranch();
3482 bo->updateNoteFlag();
3483 mainWindow->updateActions();
3487 void MapEditor::setMapAuthor (const QString &s)
3491 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3493 QString ("setMapAuthor (\"%1\")").arg(s),
3494 QString ("Set author of map to \"%1\"").arg(s)
3496 mapCenter->setAuthor (s);
3499 void MapEditor::setMapComment (const QString &s)
3503 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3505 QString ("setMapComment (\"%1\")").arg(s),
3506 QString ("Set comment of map")
3508 mapCenter->setComment (s);
3511 void MapEditor::setMapLinkStyle (const QString & s)
3513 saveStateChangingPart (
3516 QString("setMapLinkStyle (\"%1\")").arg(s),
3517 QString("Set map link style (\"%1\")").arg(s)
3521 linkstyle=LinkableMapObj::Line;
3522 else if (s=="StyleParabel")
3523 linkstyle=LinkableMapObj::Parabel;
3524 else if (s=="StylePolyLine")
3525 linkstyle=LinkableMapObj::PolyLine;
3527 linkstyle=LinkableMapObj::PolyParabel;
3530 bo=mapCenter->first();
3534 bo->setLinkStyle(bo->getDefLinkStyle());
3537 mapCenter->reposition();
3540 LinkableMapObj::Style MapEditor::getMapLinkStyle ()
3545 void MapEditor::setMapDefLinkColor(QColor c)
3549 bo=mapCenter->first();
3558 void MapEditor::setMapLinkColorHintInt()
3560 // called from setMapLinkColorHint(lch) or at end of parse
3562 bo=mapCenter->first();
3570 void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
3573 setMapLinkColorHintInt();
3576 void MapEditor::toggleMapLinkColorHint()
3578 if (linkcolorhint==LinkableMapObj::HeadingColor)
3579 linkcolorhint=LinkableMapObj::DefaultColor;
3581 linkcolorhint=LinkableMapObj::HeadingColor;
3583 bo=mapCenter->first();
3591 LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
3593 return linkcolorhint;
3596 QColor MapEditor::getMapDefLinkColor()
3598 return defLinkColor;
3601 void MapEditor::setMapDefXLinkColor(QColor col)
3606 QColor MapEditor::getMapDefXLinkColor()
3608 return defXLinkColor;
3611 void MapEditor::setMapDefXLinkWidth (int w)
3616 int MapEditor::getMapDefXLinkWidth()
3618 return defXLinkWidth;
3621 void MapEditor::selectMapLinkColor()
3623 QColor col = QColorDialog::getColor( defLinkColor, this );
3624 if ( !col.isValid() ) return;
3627 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3629 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3630 QString("Set map link color to %1").arg(col.name())
3632 setMapDefLinkColor( col );
3635 void MapEditor::selectMapSelectionColor()
3637 QColor col = QColorDialog::getColor( defLinkColor, this );
3638 setSelectionColor (col);
3641 void MapEditor::setSelectionColorInt (QColor col)
3643 if ( !col.isValid() ) return;
3644 xelection.setColor (col);
3647 void MapEditor::setSelectionColor(QColor col)
3649 if ( !col.isValid() ) return;
3652 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3654 QString("setSelectionColor (%1)").arg(col.name()),
3655 QString("Set color of selection box to %1").arg(col.name())
3657 setSelectionColorInt (col);
3660 QColor MapEditor::getSelectionColor()
3662 return xelection.getColor();
3665 bool MapEditor::scrollBranch(BranchObj *bo)
3669 if (bo->isScrolled()) return false;
3670 if (bo->countBranches()==0) return false;
3671 if (bo->getDepth()==0) return false;
3677 QString ("%1 ()").arg(u),
3679 QString ("%1 ()").arg(r),
3680 QString ("%1 %2").arg(r).arg(getName(bo))
3690 bool MapEditor::unscrollBranch(BranchObj *bo)
3694 if (!bo->isScrolled()) return false;
3695 if (bo->countBranches()==0) return false;
3696 if (bo->getDepth()==0) return false;
3702 QString ("%1 ()").arg(u),
3704 QString ("%1 ()").arg(r),
3705 QString ("%1 %2").arg(r).arg(getName(bo))
3715 void MapEditor::toggleScroll()
3717 BranchObj *bo=xelection.getBranch();
3718 if (xelection.type()==Selection::Branch )
3720 if (bo->isScrolled())
3721 unscrollBranch (bo);
3727 void MapEditor::unscrollChilds()
3729 BranchObj *bo=xelection.getBranch();
3735 if (bo->isScrolled()) unscrollBranch (bo);
3741 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3743 BranchObj *bo=xelection.getBranch();
3747 bo->addFloatImage();
3748 fio=bo->getLastFloatImage();
3750 mapCenter->reposition();
3757 void MapEditor::loadFloatImage ()
3759 BranchObj *bo=xelection.getBranch();
3763 Q3FileDialog *fd=new Q3FileDialog( this);
3764 fd->setMode (Q3FileDialog::ExistingFiles);
3765 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3766 ImagePreview *p =new ImagePreview (fd);
3767 fd->setContentsPreviewEnabled( TRUE );
3768 fd->setContentsPreview( p, p );
3769 fd->setPreviewMode( Q3FileDialog::Contents );
3770 fd->setCaption(vymName+" - " +tr("Load image"));
3771 fd->setDir (lastImageDir);
3774 if ( fd->exec() == QDialog::Accepted )
3776 // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
3777 lastImageDir=QDir (fd->dirPath());
3780 for (int j=0; j<fd->selectedFiles().count(); j++)
3782 s=fd->selectedFiles().at(j);
3783 fio=loadFloatImageInt (s);
3786 (LinkableMapObj*)fio,
3789 QString ("loadImage (%1)").arg(s ),
3790 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3793 // TODO loadFIO error handling
3794 qWarning ("Failed to load "+s);
3802 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3804 fio->save (fn,type);
3807 void MapEditor::saveFloatImage ()
3809 FloatImageObj *fio=xelection.getFloatImage();
3812 QFileDialog *fd=new QFileDialog( this);
3813 fd->setFilters (imageIO.getFilters());
3814 fd->setCaption(vymName+" - " +tr("Save image"));
3815 fd->setFileMode( QFileDialog::AnyFile );
3816 fd->setDirectory (lastImageDir);
3817 // fd->setSelection (fio->getOriginalFilename());
3821 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3823 fn=fd->selectedFiles().at(0);
3824 if (QFile (fn).exists() )
3826 QMessageBox mb( vymName,
3827 tr("The file %1 exists already.\n"
3828 "Do you want to overwrite it?").arg(fn),
3829 QMessageBox::Warning,
3830 QMessageBox::Yes | QMessageBox::Default,
3831 QMessageBox::Cancel | QMessageBox::Escape,
3832 QMessageBox::QMessageBox::NoButton );
3834 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3835 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3838 case QMessageBox::Yes:
3841 case QMessageBox::Cancel:
3848 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3854 void MapEditor::setFrameType(const FrameObj::FrameType &t)
3856 BranchObj *bo=xelection.getBranch();
3859 QString s=bo->getFrameTypeName();
3860 bo->setFrameType (t);
3861 saveState (bo, QString("setFrameType (\"%1\")").arg(s),
3862 bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
3863 mapCenter->reposition();
3868 void MapEditor::setFrameType(const QString &s)
3870 BranchObj *bo=xelection.getBranch();
3873 saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
3874 bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
3875 bo->setFrameType (s);
3876 mapCenter->reposition();
3881 void MapEditor::setFramePenColor(const QColor &c)
3883 BranchObj *bo=xelection.getBranch();
3886 saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
3887 bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
3888 bo->setFramePenColor (c);
3892 void MapEditor::setFrameBrushColor(const QColor &c)
3894 BranchObj *bo=xelection.getBranch();
3897 saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
3898 bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
3899 bo->setFrameBrushColor (c);
3903 void MapEditor::setFramePadding (const int &i)
3905 BranchObj *bo=xelection.getBranch();
3908 saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
3909 bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
3910 bo->setFramePadding (i);
3911 mapCenter->reposition();
3916 void MapEditor::setFrameBorderWidth(const int &i)
3918 BranchObj *bo=xelection.getBranch();
3921 saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
3922 bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
3923 bo->setFrameBorderWidth (i);
3924 mapCenter->reposition();
3929 void MapEditor::setIncludeImagesVer(bool b)
3931 BranchObj *bo=xelection.getBranch();
3934 QString u= b ? "false" : "true";
3935 QString r=!b ? "false" : "true";
3939 QString("setIncludeImagesVertically (%1)").arg(u),
3941 QString("setIncludeImagesVertically (%1)").arg(r),
3942 QString("Include images vertically in %1").arg(getName(bo))
3944 bo->setIncludeImagesVer(b);
3945 mapCenter->reposition();
3949 void MapEditor::setIncludeImagesHor(bool b)
3951 BranchObj *bo=xelection.getBranch();
3954 QString u= b ? "false" : "true";
3955 QString r=!b ? "false" : "true";
3959 QString("setIncludeImagesHorizontally (%1)").arg(u),
3961 QString("setIncludeImagesHorizontally (%1)").arg(r),
3962 QString("Include images horizontally in %1").arg(getName(bo))
3964 bo->setIncludeImagesHor(b);
3965 mapCenter->reposition();
3969 void MapEditor::setHideLinkUnselected (bool b)
3971 LinkableMapObj *sel=xelection.single();
3973 (xelection.type() == Selection::Branch ||
3974 xelection.type() == Selection::MapCenter ||
3975 xelection.type() == Selection::FloatImage ))
3977 QString u= b ? "false" : "true";
3978 QString r=!b ? "false" : "true";
3982 QString("setHideLinkUnselected (%1)").arg(u),
3984 QString("setHideLinkUnselected (%1)").arg(r),
3985 QString("Hide link of %1 if unselected").arg(getName(sel))
3987 sel->setHideLinkUnselected(b);
3991 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3993 BranchObj *bo=xelection.getBranch();
3996 // Traverse directories
3997 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3998 QFileInfoList list = d.entryInfoList();
4001 for (int i = 0; i < list.size(); ++i)
4004 if (fi.fileName() != "." && fi.fileName() != ".." )
4007 bo=dst->getLastBranch();
4008 bo->setHeading (fi.fileName() );
4009 bo->setColor (QColor("blue"));
4011 if ( !d.cd(fi.fileName()) )
4012 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
4015 // Recursively add subdirs
4016 importDirInt (bo,d);
4022 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
4023 list = d.entryInfoList();
4025 for (int i = 0; i < list.size(); ++i)
4029 bo=dst->getLastBranch();
4030 bo->setHeading (fi.fileName() );
4031 bo->setColor (QColor("black"));
4032 if (fi.fileName().right(4) == ".vym" )
4033 bo->setVymLink (fi.filePath());
4038 void MapEditor::importDirInt (const QString &s)
4040 BranchObj *bo=xelection.getBranch();
4043 saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
4046 importDirInt (bo,d);
4050 void MapEditor::importDir()
4052 BranchObj *bo=xelection.getBranch();
4055 QStringList filters;
4056 filters <<"VYM map (*.vym)";
4057 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
4058 fd->setMode (QFileDialog::DirectoryOnly);
4059 fd->setFilters (filters);
4060 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
4064 if ( fd->exec() == QDialog::Accepted )
4066 importDirInt (fd->selectedFile() );
4067 mapCenter->reposition();
4073 void MapEditor::followXLink(int i)
4075 BranchObj *bo=xelection.getBranch();
4078 bo=bo->XLinkTargetAt(i);
4081 xelection.select(bo);
4082 ensureSelectionVisible();
4087 void MapEditor::editXLink(int i) // FIXME missing saveState
4089 BranchObj *bo=xelection.getBranch();
4092 XLinkObj *xlo=bo->XLinkAt(i);
4095 EditXLinkDialog dia;
4097 dia.setSelection(bo);
4098 if (dia.exec() == QDialog::Accepted)
4100 if (dia.useSettingsGlobal() )
4102 setMapDefXLinkColor (xlo->getColor() );
4103 setMapDefXLinkWidth (xlo->getWidth() );
4105 if (dia.deleteXLink())
4106 bo->deleteXLinkAt(i);
4112 void MapEditor::testFunction1()
4114 ErrorCode err=success;
4115 LoadMode lmode=NewMap;
4117 //QString fname="test/freemind/doc/freemind.xml";
4118 QString fname="test/freemind/doc/icons.mm";
4119 parseFMHandler handler;
4120 QFile file( fname );
4122 // I am paranoid: file should exist anyway
4123 // according to check in mainwindow.
4124 if (!file.exists() )
4126 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
4127 tr("Couldn't open map " +fname)+".");
4131 bool blockSaveStateOrg=blockSaveState;
4132 blockReposition=true;
4133 blockSaveState=true;
4134 QXmlInputSource source( file);
4135 QXmlSimpleReader reader;
4136 reader.setContentHandler( &handler );
4137 reader.setErrorHandler( &handler );
4138 handler.setMapEditor( this );
4141 // We need to set the tmpDir in order to load files with rel. path
4142 QString tmpdir= fname.left(fname.findRev("/",-1));
4143 handler.setTmpDir (tmpdir);
4144 handler.setInputFile (file.name());
4145 //handler.setLoadMode (lmode);
4146 bool ok = reader.parse( source );
4147 blockReposition=false;
4148 blockSaveState=blockSaveStateOrg;
4152 mapCenter->reposition();
4159 autosaveTimer->stop();
4163 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
4164 tr( handler.errorProtocol() ) );
4166 // Still return "success": the map maybe at least
4167 // partially read by the parser
4173 BranchObj *bo=xelection.getBranch();
4174 if (bo) animObjList.append( bo );
4179 dia.showCancelButton (true);
4180 dia.setText("This is a longer \nWarning");
4181 dia.setCaption("Warning: Flux problem");
4182 dia.setShowAgainName("mapeditor/testDialog");
4183 if (dia.exec()==QDialog::Accepted)
4184 cout << "accepted!\n";
4186 cout << "canceled!\n";
4190 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
4191 if (hidemode==HideNone)
4193 setHideTmpMode (HideExport);
4194 mapCenter->calcBBoxSizeWithChilds();
4195 QRectF totalBBox=mapCenter->getTotalBBox();
4196 QRectF mapRect=totalBBox;
4197 QCanvasRectangle *frame=NULL;
4199 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
4201 mapRect.setRect (totalBBox.x(), totalBBox.y(),
4202 totalBBox.width(), totalBBox.height());
4203 frame=new QCanvasRectangle (mapRect,mapScene);
4204 frame->setBrush (QColor(white));
4205 frame->setPen (QColor(black));
4206 frame->setZValue(0);
4211 setHideTmpMode (HideNone);
4213 cout <<" hidemode="<<hidemode<<endl;
4217 void MapEditor::testFunction2()
4221 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
4223 // Lineedits are already closed by preceding
4224 // mouseEvent, we don't need to close here.
4226 QPointF p = mapToScene(e->pos());
4227 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4230 { // MapObj was found
4231 if (xelection.single() != lmo)
4233 // select the MapObj
4234 xelection.select(lmo);
4237 if (xelection.getBranch() )
4239 // Context Menu on branch or mapcenter
4241 branchContextMenu->popup(e->globalPos() );
4244 if (xelection.getFloatImage() )
4246 // Context Menu on floatimage
4248 floatimageContextMenu->popup(e->globalPos() );
4252 { // No MapObj found, we are on the Canvas itself
4253 // Context Menu on scene
4255 canvasContextMenu->popup(e->globalPos() );
4260 void MapEditor::keyPressEvent(QKeyEvent* e)
4262 if (e->modifiers() & Qt::ControlModifier)
4264 switch (mainWindow->getModMode())
4266 case Main::ModModeColor:
4267 setCursor (PickColorCursor);
4269 case Main::ModModeCopy:
4270 setCursor (CopyCursor);
4272 case Main::ModModeXLink:
4273 setCursor (XLinkCursor);
4276 setCursor (Qt::ArrowCursor);
4282 void MapEditor::keyReleaseEvent(QKeyEvent* e)
4284 if (!(e->modifiers() & Qt::ControlModifier))
4285 setCursor (Qt::ArrowCursor);
4288 void MapEditor::mousePressEvent(QMouseEvent* e)
4290 // Ignore right clicks, these will go to context menus
4291 if (e->button() == Qt::RightButton )
4297 //Ignore clicks while editing heading
4298 if (isSelectBlocked() )
4304 QPointF p = mapToScene(e->pos());
4305 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4309 //Take care of system flags _or_ modifier modes
4311 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
4312 typeid(*lmo)==typeid(MapCenterObj) ))
4314 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
4315 if (!foname.isEmpty())
4317 // systemFlag clicked
4321 if (e->state() & Qt::ControlModifier)
4322 mainWindow->editOpenURLTab();
4324 mainWindow->editOpenURL();
4326 else if (foname=="vymLink")
4328 mainWindow->editOpenVymLink();
4329 // tabWidget may change, better return now
4330 // before segfaulting...
4331 } else if (foname=="note")
4332 mainWindow->windowToggleNoteEditor();
4333 else if (foname=="hideInExport")
4340 // No system flag clicked, take care of modmodes (CTRL-Click)
4341 if (e->state() & Qt::ControlModifier)
4343 if (mainWindow->getModMode()==Main::ModModeColor)
4346 setCursor (PickColorCursor);
4349 if (mainWindow->getModMode()==Main::ModModeXLink)
4351 BranchObj *bo_begin=NULL;
4353 bo_begin=(BranchObj*)(lmo);
4355 if (xelection.getBranch() )
4356 bo_begin=xelection.getBranch();
4360 linkingObj_src=bo_begin;
4361 tmpXLink=new XLinkObj (mapScene);
4362 tmpXLink->setBegin (bo_begin);
4363 tmpXLink->setEnd (p);
4364 tmpXLink->setColor(defXLinkColor);
4365 tmpXLink->setWidth(defXLinkWidth);
4366 tmpXLink->updateXLink();
4367 tmpXLink->setVisibility (true);
4371 } // End of modmodes
4375 // Select the clicked object
4378 // Left Button Move Branches
4379 if (e->button() == Qt::LeftButton )
4381 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
4382 //movingObj_start.setY( p.y() - selection->y() );
4383 movingObj_start.setX( p.x() - lmo->x() );
4384 movingObj_start.setY( p.y() - lmo->y() );
4385 movingObj_orgPos.setX (lmo->x() );
4386 movingObj_orgPos.setY (lmo->y() );
4387 movingObj_orgRelPos=lmo->getRelPos();
4389 // If modMode==copy, then we want to "move" the _new_ object around
4390 // then we need the offset from p to the _old_ selection, because of tmp
4391 if (mainWindow->getModMode()==Main::ModModeCopy &&
4392 e->state() & Qt::ControlModifier)
4394 if (xelection.type()==Selection::Branch)
4397 mapCenter->addBranch ((BranchObj*)xelection.single());
4399 xelection.select(mapCenter->getLastBranch());
4400 mapCenter->reposition();
4404 movingObj=xelection.single();
4406 // Middle Button Toggle Scroll
4407 // (On Mac OS X this won't work, but we still have
4408 // a button in the toolbar)
4409 if (e->button() == Qt::MidButton )
4414 { // No MapObj found, we are on the scene itself
4415 // Left Button move Pos of sceneView
4416 if (e->button() == Qt::LeftButton )
4418 movingObj=NULL; // move Content not Obj
4419 movingObj_start=e->globalPos();
4420 movingCont_start=QPointF (
4421 horizontalScrollBar()->value(),
4422 verticalScrollBar()->value());
4423 movingVec=QPointF(0,0);
4424 setCursor(HandOpenCursor);
4429 void MapEditor::mouseMoveEvent(QMouseEvent* e)
4431 QPointF p = mapToScene(e->pos());
4432 LinkableMapObj *lmosel=xelection.single();
4434 // Move the selected MapObj
4435 if ( lmosel && movingObj)
4437 // reset cursor if we are moving and don't copy
4438 if (mainWindow->getModMode()!=Main::ModModeCopy)
4439 setCursor (Qt::ArrowCursor);
4441 // To avoid jumping of the sceneView, only
4442 // ensureSelectionVisible, if not tmp linked
4443 if (!lmosel->hasParObjTmp())
4444 ensureSelectionVisible ();
4446 // Now move the selection, but add relative position
4447 // (movingObj_start) where selection was chosen with
4448 // mousepointer. (This avoids flickering resp. jumping
4449 // of selection back to absPos)
4451 // Check if we could link
4452 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
4455 FloatObj *fio=xelection.getFloatImage();
4458 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4460 fio->updateLink(); //no need for reposition, if we update link here
4463 // Relink float to new mapcenter or branch, if shift is pressed
4464 // Only relink, if selection really has a new parent
4465 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
4466 ( (typeid(*lmo)==typeid(BranchObj)) ||
4467 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
4468 ( lmo != fio->getParObj())
4471 if (typeid(*fio) == typeid(FloatImageObj) &&
4472 ( (typeid(*lmo)==typeid(BranchObj) ||
4473 typeid(*lmo)==typeid(MapCenterObj)) ))
4476 // Also save the move which was done so far
4477 QString pold=qpointfToString(movingObj_orgRelPos);
4478 QString pnow=qpointfToString(fio->getRelPos());
4484 QString("Move %1 to relativ position %2").arg(getName(fio)).arg(pnow));
4485 fio->getParObj()->requestReposition();
4486 mapCenter->reposition();
4488 linkTo (lmo->getSelectString());
4490 //movingObj_orgRelPos=lmosel->getRelPos();
4492 mapCenter->reposition();
4496 { // selection != a FloatObj
4497 if (lmosel->getDepth()==0)
4500 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
4501 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4503 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4504 mapCenter->updateRelPositions();
4507 if (lmosel->getDepth()==1)
4510 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4511 lmosel->setRelPos();
4514 // Move ordinary branch
4515 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
4516 // Add width of bbox here, otherwise alignRelTo will cause jumping around
4517 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
4518 p.y()-movingObj_start.y() +lmosel->getTopPad() );
4520 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
4523 // Maybe we can relink temporary?
4524 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
4525 (typeid(*lmo)==typeid(BranchObj) ||
4526 typeid(*lmo)==typeid(MapCenterObj)) )
4529 if (e->modifiers()==Qt::ControlModifier)
4531 // Special case: CTRL to link below lmo
4532 lmosel->setParObjTmp (lmo,p,+1);
4534 else if (e->modifiers()==Qt::ShiftModifier)
4535 lmosel->setParObjTmp (lmo,p,-1);
4537 lmosel->setParObjTmp (lmo,p,0);
4540 lmosel->unsetParObjTmp();
4542 // reposition subbranch
4543 lmosel->reposition();
4547 } // no FloatImageObj
4551 } // selection && moving_obj
4553 // Draw a link from one branch to another
4556 tmpXLink->setEnd (p);
4557 tmpXLink->updateXLink();
4561 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
4563 QPointF p=e->globalPos();
4564 movingVec.setX(-p.x() + movingObj_start.x() );
4565 movingVec.setY(-p.y() + movingObj_start.y() );
4566 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
4567 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
4572 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
4574 QPointF p = mapToScene(e->pos());
4575 LinkableMapObj *dst;
4576 LinkableMapObj *lmosel=xelection.single();
4577 // Have we been picking color?
4581 setCursor (Qt::ArrowCursor);
4582 // Check if we are over another branch
4583 dst=mapCenter->findMapObj(p, NULL);
4586 if (e->state() & Qt::ShiftModifier)
4587 colorBranch (((BranchObj*)(dst))->getColor());
4589 colorSubtree (((BranchObj*)(dst))->getColor());
4594 // Have we been drawing a link?
4598 // Check if we are over another branch
4599 dst=mapCenter->findMapObj(p, NULL);
4602 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
4603 tmpXLink->updateXLink();
4604 tmpXLink->activate(); //FIXME savestate missing
4605 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );
4614 // Have we been moving something?
4615 if ( lmosel && movingObj )
4617 FloatImageObj *fo=xelection.getFloatImage();
4620 // Moved FloatObj. Maybe we need to reposition
4621 QString pold=qpointfToString(movingObj_orgRelPos);
4622 QString pnow=qpointfToString(fo->getRelPos());
4628 QString("Move %1 to relativ position %2").arg(getName(fo)).arg(pnow));
4630 fo->getParObj()->requestReposition();
4631 mapCenter->reposition();
4634 // Check if we are over another branch, but ignore
4635 // any found LMOs, which are FloatObjs
4636 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
4638 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4641 if (xelection.type() == Selection::MapCenter )
4643 // TODO: Check for problems if graphicsview is resized for
4645 QString pold=qpointfToString(movingObj_orgPos);
4646 QString pnow=qpointfToString(mapCenter->getAbsPos());
4652 QString("Move mapcenter %1 to position %2").arg(getName(mapCenter)).arg(pnow));
4655 if (xelection.type() == Selection::Branch )
4656 { // A branch was moved
4658 // save the position in case we link to mapcenter
4659 QPointF savePos=QPointF (lmosel->getAbsPos() );
4661 // Reset the temporary drawn link to the original one
4662 lmosel->unsetParObjTmp();
4664 // For Redo we may need to save original selection
4665 QString preSelStr=lmosel->getSelectString();
4670 BranchObj* bsel=xelection.getBranch();
4671 BranchObj* bdst=(BranchObj*)dst;
4673 QString preParStr=(bsel->getParObj())->getSelectString();
4674 QString preNum=QString::number (bsel->getNum(),10);
4675 QString preDstParStr;
4677 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4679 preDstParStr=dst->getParObj()->getSelectString();
4680 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4682 if (e->state() & Qt::ControlModifier && dst->getParObj())
4685 preDstParStr=dst->getParObj()->getSelectString();
4686 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4689 preDstParStr=dst->getSelectString();
4690 bsel->linkTo (bdst,-1);
4691 if (dst->getDepth()==0) bsel->move (savePos);
4693 QString postSelStr=lmosel->getSelectString();
4694 QString postNum=QString::number (bsel->getNum(),10);
4696 QString undoCom="linkTo (\""+
4697 preParStr+ "\"," + preNum +"," +
4698 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4700 QString redoCom="linkTo (\""+
4701 preDstParStr + "\"," + postNum + "," +
4702 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4707 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4709 if (lmosel->getDepth()==1)
4711 // The select string might be different _after_ moving around.
4712 // Therefor reposition and then use string of old selection, too
4713 mapCenter->reposition();
4715 QString ps=qpointfToString ( lmosel->getRelPos() );
4717 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4718 preSelStr, "moveRel "+ps,
4719 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4722 // Draw the original link, before selection was moved around
4723 mapCenter->reposition();
4726 // Finally resize scene, if needed
4730 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4733 // maybe we moved View: set old cursor
4734 setCursor (Qt::ArrowCursor);
4738 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4740 if (isSelectBlocked() )
4746 if (e->button() == Qt::LeftButton )
4748 QPointF p = mapToScene(e->pos());
4749 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4750 if (lmo) { // MapObj was found
4751 // First select the MapObj than edit heading
4752 xelection.select(lmo);
4753 mainWindow->editHeading();
4758 void MapEditor::resizeEvent (QResizeEvent* e)
4760 QGraphicsView::resizeEvent( e );
4763 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4765 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4766 // cerr << event->format(i) << endl;
4768 if (event->mimeData()->hasImage())
4769 event->acceptProposedAction();
4771 if (event->mimeData()->hasUrls())
4772 event->acceptProposedAction();
4775 void MapEditor::dragMoveEvent(QDragMoveEvent *)
4779 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4784 void MapEditor::dropEvent(QDropEvent *event)
4786 BranchObj *sel=xelection.getBranch();
4790 foreach (QString format,event->mimeData()->formats())
4791 cout << "MapEditor: Dropped format: "<<format.ascii()<<endl;
4795 if (event->mimeData()->hasImage())
4797 QVariant imageData = event->mimeData()->imageData();
4798 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4800 if (event->mimeData()->hasUrls())
4801 uris=event->mimeData()->urls();
4809 for (int i=0; i<uris.count();i++)
4811 // Workaround to avoid adding empty branches
4812 if (!uris.at(i).toString().isEmpty())
4814 bo=sel->addBranch();
4817 s=uris.at(i).toLocalFile();
4820 QString file = QDir::convertSeparators(s);
4821 heading = QFileInfo(file).baseName();
4823 if (file.endsWith(".vym", false))
4824 bo->setVymLink(file);
4826 bo->setURL(uris.at(i).toString());
4829 bo->setURL(uris.at(i).toString());
4832 if (!heading.isEmpty())
4833 bo->setHeading(heading);
4835 bo->setHeading(uris.at(i).toString());
4839 mapCenter->reposition();
4842 event->acceptProposedAction();
4845 void MapEditor::timerEvent(QTimerEvent *event) //TODO animation
4849 cout << "ME::timerEvent\n";
4851 for (int i=0; i<animObjList.size(); ++i)
4853 animObjList.at(i)->animate();
4854 ((BranchObj*)animObjList.at(i))->move2RelPos (((BranchObj*)animObjList.at(i))->getRelPos() );
4856 mapCenter->reposition();
4860 void MapEditor::sendSelection()
4862 if (netstate!=Server) return;
4863 sendData (QString("select (\"%1\")").arg(xelection.getSelectString()) );
4866 void MapEditor::newServer()
4870 tcpServer = new QTcpServer(this);
4871 if (!tcpServer->listen(QHostAddress::Any,port)) {
4872 QMessageBox::critical(this, "vym server",
4873 QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
4877 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
4879 cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
4882 void MapEditor::connectToServer()
4885 server="salam.suse.de";
4887 clientSocket = new QTcpSocket (this);
4888 clientSocket->abort();
4889 clientSocket->connectToHost(server ,port);
4890 connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
4891 connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
4892 this, SLOT(displayNetworkError(QAbstractSocket::SocketError)));
4894 cout<<"connected to "<<server.ascii()<<" port "<<port<<endl;
4899 void MapEditor::newClient()
4901 QTcpSocket *newClient = tcpServer->nextPendingConnection();
4902 connect(newClient, SIGNAL(disconnected()),
4903 newClient, SLOT(deleteLater()));
4905 cout <<"ME::newClient at "<<newClient->peerAddress().toString().ascii()<<endl;
4907 clientList.append (newClient);
4911 void MapEditor::sendData(const QString &s)
4913 if (clientList.size()==0) return;
4915 // Create bytearray to send
4917 QDataStream out(&block, QIODevice::WriteOnly);
4918 out.setVersion(QDataStream::Qt_4_0);
4920 // Reserve some space for blocksize
4923 // Write sendCounter
4924 out << sendCounter++;
4929 // Go back and write blocksize so far
4930 out.device()->seek(0);
4931 quint16 bs=(quint16)(block.size() - 2*sizeof(quint16));
4935 cout << "ME::sendData bs="<<bs<<" counter="<<sendCounter<<" s="<<s.ascii()<<endl;
4937 for (int i=0; i<clientList.size(); ++i)
4939 //cout << "Sending \""<<s.ascii()<<"\" to "<<clientList.at(i)->peerAddress().toString().ascii()<<endl;
4940 clientList.at(i)->write (block);
4944 void MapEditor::readData ()
4946 while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) )
4949 cout <<"readData bytesAvail="<<clientSocket->bytesAvailable();
4953 QDataStream in(clientSocket);
4954 in.setVersion(QDataStream::Qt_4_0);
4962 cout << " t="<<t.ascii()<<endl;
4968 void MapEditor::displayNetworkError(QAbstractSocket::SocketError socketError)
4970 switch (socketError) {
4971 case QAbstractSocket::RemoteHostClosedError:
4973 case QAbstractSocket::HostNotFoundError:
4974 QMessageBox::information(this, __VYM_NAME " Network client",
4975 "The host was not found. Please check the "
4976 "host name and port settings.");
4978 case QAbstractSocket::ConnectionRefusedError:
4979 QMessageBox::information(this, __VYM_NAME " Network client",
4980 "The connection was refused by the peer. "
4981 "Make sure the fortune server is running, "
4982 "and check that the host name and port "
4983 "settings are correct.");
4986 QMessageBox::information(this, __VYM_NAME " Network client",
4987 QString("The following error occurred: %1.")
4988 .arg(clientSocket->errorString()));
4992 void MapEditor::autosave()
4994 // Disable autosave, while we have gone back in history
4995 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
4996 if (redosAvail>0) return;
4999 if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() )
5000 mainWindow->fileSave (this);
5004 /*TODO not needed? void MapEditor::contentsDropEvent(QDropEvent *event)
5007 } else if (event->provides("application/x-moz-file-promise-url") &&
5008 event->provides("application/x-moz-nativeimage"))
5010 // Contains url to the img src in unicode16
5011 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
5012 QString url = QString((const QChar*)d.data(),d.size()/2);
5016 } else if (event->provides ("text/uri-list"))
5017 { // Uris provided e.g. by konqueror
5018 Q3UriDrag::decode (event,uris);
5019 } else if (event->provides ("_NETSCAPE_URL"))
5020 { // Uris provided by Mozilla
5021 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
5024 } else if (event->provides("text/html")) {
5026 // Handels text mime types
5027 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
5028 QByteArray d = event->encodedData("text/html");
5031 text = QString((const QChar*)d.data(),d.size()/2);
5035 textEditor->setText(text);
5039 } else if (event->provides("text/plain")) {
5040 QByteArray d = event->encodedData("text/plain");
5043 text = QString((const QChar*)d.data(),d.size()/2);
5047 textEditor->setText(text);
5057 bool isUnicode16(const QByteArray &d)
5059 // TODO: make more precise check for unicode 16.
5060 // Guess unicode16 if any of second bytes are zero
5061 unsigned int length = max(0,d.size()-2)/2;
5062 for (unsigned int i = 0; i<length ; i++)
5063 if (d.at(i*2+1)==0) return true;
5067 void MapEditor::addFloatImageInt (const QPixmap &img)
5069 BranchObj *bo=xelection.getBranch();
5072 FloatImageObj *fio=bo->addFloatImage();
5074 fio->setOriginalFilename("No original filename (image added by dropevent)");
5075 QString s=bo->getSelectString();
5076 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio );
5077 saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image");
5078 mapCenter->reposition();
5085 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
5087 if (!imageBuffer) imageBuffer = new QBuffer();
5088 if (!imageBuffer->isOpen()) {
5089 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
5091 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
5095 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
5097 if (nop->state()==Q3NetworkProtocol::StDone) {
5098 QPixmap img(imageBuffer->buffer());
5099 addFloatImageInt (img);
5103 imageBuffer->close();
5105 imageBuffer->close();
5112 void MapEditor::fetchImage(const QString &url)
5115 urlOperator->stop();
5116 disconnect(urlOperator);
5120 urlOperator = new Q3UrlOperator(url);
5121 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
5122 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
5124 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
5125 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));