3 #include <q3filedialog.h>
12 #include "editxlinkdialog.h"
14 #include "exportxhtmldialog.h"
15 #include "extrainfodialog.h"
17 #include "linkablemapobj.h"
18 #include "mainwindow.h"
20 #include "texteditor.h"
21 #include "warningdialog.h"
25 extern TextEditor *textEditor;
26 extern int statusbarTime;
27 extern Main *mainWindow;
28 extern QString tmpVymDir;
29 extern QString clipboardDir;
30 extern QString clipboardFile;
31 extern bool clipboardEmpty;
33 extern FlagRowObj *standardFlagsDefault;
35 extern QMenu* branchContextMenu;
36 extern QMenu* branchAddContextMenu;
37 extern QMenu* branchRemoveContextMenu;
38 extern QMenu* branchLinksContextMenu;
39 extern QMenu* branchXLinksContextMenuEdit;
40 extern QMenu* branchXLinksContextMenuFollow;
41 extern QMenu* floatimageContextMenu;
42 extern QMenu* canvasContextMenu;
45 extern Settings settings;
46 extern ImageIO imageIO;
48 extern QString vymName;
49 extern QString vymVersion;
51 extern QString iconPath;
52 extern QDir vymBaseDir;
53 extern QDir lastImageDir;
54 extern QDir lastFileDir;
56 int MapEditor::mapNum=0; // make instance
58 ///////////////////////////////////////////////////////////////////////
59 ///////////////////////////////////////////////////////////////////////
60 MapEditor::MapEditor( QWidget* parent) :
63 //cout << "Constructor ME "<<this<<endl;
67 mapScene= new QGraphicsScene(parent);
68 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
69 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
74 mapCenter = new MapCenterObj(mapScene);
75 mapCenter->setVisibility (true);
76 mapCenter->setMapEditor (this);
77 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
78 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
83 defLinkColor=QColor (0,0,255);
84 defXLinkColor=QColor (180,180,180);
85 linkcolorhint=LinkableMapObj::DefaultColor;
86 linkstyle=LinkableMapObj::PolyParabel;
88 // Create bitmap cursors, platform dependant
89 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
90 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
91 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
92 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
94 setFocusPolicy (Qt::StrongFocus);
103 xelection.setMapEditor (this);
104 xelection.unselect();
107 defXLinkColor=QColor (230,230,230);
115 fileName=tr("unnamed");
118 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
119 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
120 mainWindow->updateHistory (undoSet);
122 // Initialize find routine
129 blockReposition=false;
130 blockSaveState=false;
132 hidemode=BranchObj::HideNone;
134 // Create temporary files
141 setAcceptDrops (true);
143 mapCenter->reposition(); // for positioning heading
147 //timerId = startTimer(100);
150 autosaveTimer=new QTimer (this);
151 connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
157 MapEditor::~MapEditor()
159 //cout <<"Destructor MapEditor\n";
160 autosaveTimer->stop();
163 MapCenterObj* MapEditor::getMapCenter()
168 QGraphicsScene * MapEditor::getScene()
173 MapEditor::State MapEditor::getState()
178 void MapEditor::setStateEditHeading(bool s)
182 if (state==Idle) state=EditHeading;
188 bool MapEditor::isRepositionBlocked()
190 return blockReposition;
193 void MapEditor::setSaveStateBlocked(bool b)
198 bool MapEditor::isSelectBlocked()
200 if (state==EditHeading)
206 QString MapEditor::getName (const LinkableMapObj *lmo)
209 if (!lmo) return QString("Error: NULL has no name!");
211 if ((typeid(*lmo) == typeid(BranchObj) ||
212 typeid(*lmo) == typeid(MapCenterObj)))
215 s=(((BranchObj*)lmo)->getHeading());
216 if (s=="") s="unnamed";
217 return QString("branch (%1)").arg(s);
218 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
220 if ((typeid(*lmo) == typeid(FloatImageObj) ))
221 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
222 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
223 return QString("Unknown type has no name!");
226 void MapEditor::makeTmpDirs()
228 // Create unique temporary directories
229 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
230 histPath=QDir::convertSeparators (tmpMapDir+"/history");
235 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
237 // tmpdir temporary directory to which data will be written
238 // prefix mapname, which will be appended to images etc.
239 // writeflags Only write flags for "real" save of map, not undo
240 // offset offset of bbox of whole map in scene.
241 // Needed for XML export
247 case LinkableMapObj::Line:
250 case LinkableMapObj::Parabel:
253 case LinkableMapObj::PolyLine:
257 ls="StylePolyParabel";
261 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
263 if (linkcolorhint==LinkableMapObj::HeadingColor)
264 colhint=attribut("linkColorHint","HeadingColor");
266 QString mapAttr=attribut("version",vymVersion);
267 if (!saveSel || saveSel==mapCenter)
268 mapAttr+= attribut("author",mapCenter->getAuthor()) +
269 attribut("comment",mapCenter->getComment()) +
270 attribut("date",mapCenter->getDate()) +
271 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
272 attribut("selectionColor", xelection.getColor().name() ) +
273 attribut("linkStyle", ls ) +
274 attribut("linkColor", defLinkColor.name() ) +
275 attribut("defXLinkColor", defXLinkColor.name() ) +
276 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
278 s+=beginElement("vymmap",mapAttr);
281 // Find the used flags while traversing the tree
282 standardFlagsDefault->resetUsedCounter();
284 // Reset the counters before saving
285 // TODO constr. of FIO creates lots of objects, better do this in some other way...
286 FloatImageObj (mapScene).resetSaveCounter();
288 // Build xml recursivly
289 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
290 // Save complete map, if saveSel not set
291 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
294 if ( typeid(*saveSel) == typeid(BranchObj) )
296 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
297 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
299 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
302 // Save local settings
303 s+=settings.getXMLData (destPath);
306 if (!xelection.isEmpty() && !saveSel )
307 s+=valueElement("select",xelection.getSelectString());
310 s+=endElement("vymmap");
313 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
317 QString MapEditor::getHistoryDir()
319 QString histName=QDir::convertSeparators (QString("history-%1").arg(curStep));
320 return QDir::convertSeparators (tmpMapDir +"/"+histName);
323 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
325 sendData(redoCom); //FIXME testing
330 if (blockSaveState) return;
332 if (debug) cout << "ME::saveState() for "<<mapName.ascii()<<endl;
334 // Find out current undo directory
335 if (undosAvail<stepsTotal) undosAvail++;
337 if (curStep>stepsTotal) curStep=1;
339 QString backupXML="";
340 QString histDir=getHistoryDir();
341 QString bakMapPath=QDir::convertSeparators(histDir+"/map.xml");
343 // Create histDir if not available
346 makeSubDirs (histDir);
348 // Save depending on how much needs to be saved
350 backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
352 QString undoCommand="";
353 if (savemode==UndoCommand)
357 else if (savemode==PartOfMap )
360 undoCommand.replace ("PATH",bakMapPath);
363 if (!backupXML.isEmpty())
364 // Write XML Data to disk
365 saveStringToDisk (QString(bakMapPath),backupXML);
367 // We would have to save all actions in a tree, to keep track of
368 // possible redos after a action. Possible, but we are too lazy: forget about redos.
371 // Write the current state to disk
372 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
373 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
374 undoSet.setEntry ("/history/curStep",QString::number(curStep));
375 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
376 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
377 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
378 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
379 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
380 undoSet.setEntry (QString("/history/version"),vymVersion);
381 undoSet.writeSettings(histPath);
385 // TODO remove after testing
386 //cout << " into="<< histPath.toStdString()<<endl;
387 cout << " stepsTotal="<<stepsTotal<<
388 ", undosAvail="<<undosAvail<<
389 ", redosAvail="<<redosAvail<<
390 ", curStep="<<curStep<<endl;
391 cout << " ---------------------------"<<endl;
392 cout << " comment="<<comment.toStdString()<<endl;
393 cout << " undoCom="<<undoCommand.toStdString()<<endl;
394 cout << " undoSel="<<undoSelection.toStdString()<<endl;
395 cout << " redoCom="<<redoCom.toStdString()<<endl;
396 cout << " redoSel="<<redoSelection.toStdString()<<endl;
397 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
398 cout << " ---------------------------"<<endl;
401 mainWindow->updateHistory (undoSet);
407 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
409 // save the selected part of the map, Undo will replace part of map
410 QString undoSelection="";
412 undoSelection=undoSel->getSelectString();
414 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
415 QString redoSelection="";
417 redoSelection=undoSel->getSelectString();
419 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
422 saveState (PartOfMap,
423 undoSelection, "addMapReplace (\"PATH\")",
429 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
433 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
436 QString undoSelection=redoSel->getParObj()->getSelectString();
437 QString redoSelection=redoSel->getSelectString();
438 if (typeid(*redoSel) == typeid(BranchObj) )
440 // save the selected branch of the map, Undo will insert part of map
441 saveState (PartOfMap,
442 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
443 redoSelection, "delete ()",
450 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
452 // "Normal" savestate: save commands, selections and comment
453 // so just save commands for undo and redo
454 // and use current selection
456 QString redoSelection="";
457 if (redoSel) redoSelection=redoSel->getSelectString();
458 QString undoSelection="";
459 if (undoSel) undoSelection=undoSel->getSelectString();
461 saveState (UndoCommand,
468 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
470 // "Normal" savestate: save commands, selections and comment
471 // so just save commands for undo and redo
472 // and use current selection
473 saveState (UndoCommand,
481 void MapEditor::parseAtom(const QString &atom)
483 BranchObj *selb=xelection.getBranch();
489 // Split string s into command and parameters
490 parser.parseAtom (atom);
491 QString com=parser.getCommand();
494 /////////////////////////////////////////////////////////////////////
495 if (com=="addBranch")
497 if (xelection.isEmpty())
499 parser.setError (Aborted,"Nothing selected");
502 parser.setError (Aborted,"Type of selection is not a branch");
507 if (parser.checkParCount(pl))
509 if (parser.parCount()==0)
513 n=parser.parInt (ok,0);
514 if (ok ) addNewBranch (n);
518 /////////////////////////////////////////////////////////////////////
519 } else if (com=="addBranchBefore")
521 if (xelection.isEmpty())
523 parser.setError (Aborted,"Nothing selected");
526 parser.setError (Aborted,"Type of selection is not a branch");
529 if (parser.parCount()==0)
531 addNewBranchBefore ();
534 /////////////////////////////////////////////////////////////////////
535 } else if (com==QString("addMapReplace"))
537 if (xelection.isEmpty())
539 parser.setError (Aborted,"Nothing selected");
542 parser.setError (Aborted,"Type of selection is not a branch");
543 } else if (parser.checkParCount(1))
545 //s=parser.parString (ok,0); // selection
546 t=parser.parString (ok,0); // path to map
547 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
548 addMapReplaceInt(selb->getSelectString(),t);
550 /////////////////////////////////////////////////////////////////////
551 } else if (com==QString("addMapInsert"))
553 if (xelection.isEmpty())
555 parser.setError (Aborted,"Nothing selected");
558 parser.setError (Aborted,"Type of selection is not a branch");
561 if (parser.checkParCount(2))
563 t=parser.parString (ok,0); // path to map
564 n=parser.parInt(ok,1); // position
565 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
566 addMapInsertInt(t,n);
569 /////////////////////////////////////////////////////////////////////
570 } else if (com=="clearFlags")
572 if (xelection.isEmpty() )
574 parser.setError (Aborted,"Nothing selected");
577 parser.setError (Aborted,"Type of selection is not a branch");
578 } else if (parser.checkParCount(0))
580 selb->clearStandardFlags();
581 selb->updateFlagsToolbar();
583 /////////////////////////////////////////////////////////////////////
584 } else if (com=="colorBranch")
586 if (xelection.isEmpty())
588 parser.setError (Aborted,"Nothing selected");
591 parser.setError (Aborted,"Type of selection is not a branch");
592 } else if (parser.checkParCount(1))
594 QColor c=parser.parColor (ok,0);
595 if (ok) colorBranch (c);
597 /////////////////////////////////////////////////////////////////////
598 } else if (com=="colorSubtree")
600 if (xelection.isEmpty())
602 parser.setError (Aborted,"Nothing selected");
605 parser.setError (Aborted,"Type of selection is not a branch");
606 } else if (parser.checkParCount(1))
608 QColor c=parser.parColor (ok,0);
609 if (ok) colorSubtree (c);
611 /////////////////////////////////////////////////////////////////////
612 } else if (com=="copy")
614 if (xelection.isEmpty())
616 parser.setError (Aborted,"Nothing selected");
619 parser.setError (Aborted,"Type of selection is not a branch");
620 } else if (parser.checkParCount(0))
622 //FIXME missing action for copy
624 /////////////////////////////////////////////////////////////////////
625 } else if (com=="cut")
627 if (xelection.isEmpty())
629 parser.setError (Aborted,"Nothing selected");
630 } else if ( xelection.type()!=Selection::Branch &&
631 xelection.type()!=Selection::MapCenter &&
632 xelection.type()!=Selection::FloatImage )
634 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
635 } else if (parser.checkParCount(0))
639 /////////////////////////////////////////////////////////////////////
640 } else if (com=="delete")
642 if (xelection.isEmpty())
644 parser.setError (Aborted,"Nothing selected");
645 } else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage )
647 parser.setError (Aborted,"Type of selection is wrong.");
648 } else if (parser.checkParCount(0))
652 /////////////////////////////////////////////////////////////////////
653 } else if (com=="deleteKeepChilds")
655 if (xelection.isEmpty())
657 parser.setError (Aborted,"Nothing selected");
660 parser.setError (Aborted,"Type of selection is not a branch");
661 } else if (parser.checkParCount(0))
665 /////////////////////////////////////////////////////////////////////
666 } else if (com=="deleteChilds")
668 if (xelection.isEmpty())
670 parser.setError (Aborted,"Nothing selected");
673 parser.setError (Aborted,"Type of selection is not a branch");
674 } else if (parser.checkParCount(0))
678 /////////////////////////////////////////////////////////////////////
679 } else if (com=="exportASCII")
683 if (parser.parCount()>=2)
684 // Hey, we even have a filename
685 fname=parser.parString(ok,1);
688 parser.setError (Aborted,"Could not read filename");
691 exportASCII (fname,false);
693 /////////////////////////////////////////////////////////////////////
694 } else if (com=="exportImage")
698 if (parser.parCount()>=2)
699 // Hey, we even have a filename
700 fname=parser.parString(ok,1);
703 parser.setError (Aborted,"Could not read filename");
706 QString format="PNG";
707 if (parser.parCount()>2)
709 format=parser.parString(ok,2);
711 exportImage (fname,false,format);
713 /////////////////////////////////////////////////////////////////////
714 } else if (com=="exportXHTML")
718 if (parser.parCount()>=2)
719 // Hey, we even have a filename
720 fname=parser.parString(ok,1);
723 parser.setError (Aborted,"Could not read filename");
726 exportXHTML (fname,false);
728 /////////////////////////////////////////////////////////////////////
729 } else if (com=="exportXML")
733 if (parser.parCount()>=2)
734 // Hey, we even have a filename
735 fname=parser.parString(ok,1);
738 parser.setError (Aborted,"Could not read filename");
741 exportXML (fname,false);
743 /////////////////////////////////////////////////////////////////////
744 } else if (com=="importDir")
746 if (xelection.isEmpty())
748 parser.setError (Aborted,"Nothing selected");
751 parser.setError (Aborted,"Type of selection is not a branch");
752 } else if (parser.checkParCount(1))
754 s=parser.parString(ok,0);
755 if (ok) importDirInt(s);
757 /////////////////////////////////////////////////////////////////////
758 } else if (com=="linkTo")
760 if (xelection.isEmpty())
762 parser.setError (Aborted,"Nothing selected");
765 if (parser.checkParCount(4))
767 // 0 selectstring of parent
768 // 1 num in parent (for branches)
769 // 2,3 x,y of mainbranch or mapcenter
770 s=parser.parString(ok,0);
771 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
774 if (typeid(*dst) == typeid(BranchObj) )
776 // Get number in parent
777 n=parser.parInt (ok,1);
780 selb->linkTo ((BranchObj*)(dst),n);
783 } else if (typeid(*dst) == typeid(MapCenterObj) )
785 selb->linkTo ((BranchObj*)(dst),-1);
786 // Get coordinates of mainbranch
787 x=parser.parDouble(ok,2);
790 y=parser.parDouble(ok,3);
800 } else if ( xelection.type() == Selection::FloatImage)
802 if (parser.checkParCount(1))
804 // 0 selectstring of parent
805 s=parser.parString(ok,0);
806 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
809 if (typeid(*dst) == typeid(BranchObj) ||
810 typeid(*dst) == typeid(MapCenterObj))
811 linkTo (dst->getSelectString());
813 parser.setError (Aborted,"Destination is not a branch");
816 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
817 /////////////////////////////////////////////////////////////////////
818 } else if (com=="loadImage")
820 if (xelection.isEmpty())
822 parser.setError (Aborted,"Nothing selected");
825 parser.setError (Aborted,"Type of selection is not a branch");
826 } else if (parser.checkParCount(1))
828 s=parser.parString(ok,0);
829 if (ok) loadFloatImageInt (s);
831 /////////////////////////////////////////////////////////////////////
832 } else if (com=="moveBranchUp")
834 if (xelection.isEmpty() )
836 parser.setError (Aborted,"Nothing selected");
839 parser.setError (Aborted,"Type of selection is not a branch");
840 } else if (parser.checkParCount(0))
844 /////////////////////////////////////////////////////////////////////
845 } else if (com=="moveBranchDown")
847 if (xelection.isEmpty() )
849 parser.setError (Aborted,"Nothing selected");
852 parser.setError (Aborted,"Type of selection is not a branch");
853 } else if (parser.checkParCount(0))
857 /////////////////////////////////////////////////////////////////////
858 } else if (com=="move")
860 if (xelection.isEmpty() )
862 parser.setError (Aborted,"Nothing selected");
863 } else if ( xelection.type()!=Selection::Branch &&
864 xelection.type()!=Selection::MapCenter &&
865 xelection.type()!=Selection::FloatImage )
867 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
868 } else if (parser.checkParCount(2))
870 x=parser.parDouble (ok,0);
873 y=parser.parDouble (ok,1);
877 /////////////////////////////////////////////////////////////////////
878 } else if (com=="moveRel")
880 if (xelection.isEmpty() )
882 parser.setError (Aborted,"Nothing selected");
883 } else if ( xelection.type()!=Selection::Selection::Branch &&
884 xelection.type()!=Selection::Selection::MapCenter &&
885 xelection.type()!=Selection::Selection::FloatImage )
887 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
888 } else if (parser.checkParCount(2))
890 x=parser.parDouble (ok,0);
893 y=parser.parDouble (ok,1);
894 if (ok) moveRel (x,y);
897 /////////////////////////////////////////////////////////////////////
898 } else if (com=="nop")
900 /////////////////////////////////////////////////////////////////////
901 } else if (com=="paste")
903 if (xelection.isEmpty() )
905 parser.setError (Aborted,"Nothing selected");
908 parser.setError (Aborted,"Type of selection is not a branch");
909 } else if (parser.checkParCount(1))
911 n=parser.parInt (ok,0);
912 if (ok) pasteNoSave(n);
914 /////////////////////////////////////////////////////////////////////
915 } else if (com=="qa")
917 if (xelection.isEmpty() )
919 parser.setError (Aborted,"Nothing selected");
922 parser.setError (Aborted,"Type of selection is not a branch");
923 } else if (parser.checkParCount(4))
926 c=parser.parString (ok,0);
929 parser.setError (Aborted,"No comment given");
932 s=parser.parString (ok,1);
935 parser.setError (Aborted,"First parameter is not a string");
938 t=parser.parString (ok,2);
941 parser.setError (Aborted,"Condition is not a string");
944 u=parser.parString (ok,3);
947 parser.setError (Aborted,"Third parameter is not a string");
952 parser.setError (Aborted,"Unknown type: "+s);
957 parser.setError (Aborted,"Unknown operator: "+t);
962 parser.setError (Aborted,"Type of selection is not a branch");
965 if (selb->getHeading() == u)
967 cout << "PASSED: " << c.ascii() << endl;
970 cout << "FAILED: " << c.ascii() << endl;
980 /////////////////////////////////////////////////////////////////////
981 } else if (com=="saveImage")
983 FloatImageObj *fio=xelection.getFloatImage();
986 parser.setError (Aborted,"Type of selection is not an image");
987 } else if (parser.checkParCount(2))
989 s=parser.parString(ok,0);
992 t=parser.parString(ok,1);
993 if (ok) saveFloatImageInt (fio,t,s);
996 /////////////////////////////////////////////////////////////////////
997 } else if (com=="scroll")
999 if (xelection.isEmpty() )
1001 parser.setError (Aborted,"Nothing selected");
1004 parser.setError (Aborted,"Type of selection is not a branch");
1005 } else if (parser.checkParCount(0))
1007 if (!scrollBranch (selb))
1008 parser.setError (Aborted,"Could not scroll branch");
1010 /////////////////////////////////////////////////////////////////////
1011 } else if (com=="select")
1013 if (parser.checkParCount(1))
1015 s=parser.parString(ok,0);
1018 /////////////////////////////////////////////////////////////////////
1019 } else if (com=="selectLastBranch")
1021 if (xelection.isEmpty() )
1023 parser.setError (Aborted,"Nothing selected");
1026 parser.setError (Aborted,"Type of selection is not a branch");
1027 } else if (parser.checkParCount(0))
1029 BranchObj *bo=selb->getLastBranch();
1031 parser.setError (Aborted,"Could not select last branch");
1035 /////////////////////////////////////////////////////////////////////
1036 } else if (com=="selectLastImage")
1038 if (xelection.isEmpty() )
1040 parser.setError (Aborted,"Nothing selected");
1043 parser.setError (Aborted,"Type of selection is not a branch");
1044 } else if (parser.checkParCount(0))
1046 FloatImageObj *fio=selb->getLastFloatImage();
1048 parser.setError (Aborted,"Could not select last image");
1052 /////////////////////////////////////////////////////////////////////
1053 } else if (com=="selectLatestAdded")
1055 if (latestSelection.isEmpty() )
1057 parser.setError (Aborted,"No latest added object");
1060 if (!select (latestSelection))
1061 parser.setError (Aborted,"Could not select latest added object "+latestSelection);
1063 /////////////////////////////////////////////////////////////////////
1064 } else if (com=="setFrameType")
1066 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1068 parser.setError (Aborted,"Type of selection does not allow setting frame type");
1070 else if (parser.checkParCount(1))
1072 s=parser.parString(ok,0);
1073 if (ok) setFrameType (s);
1075 /////////////////////////////////////////////////////////////////////
1076 } else if (com=="setFramePenColor")
1078 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1080 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
1082 else if (parser.checkParCount(1))
1084 QColor c=parser.parColor(ok,0);
1085 if (ok) setFramePenColor (c);
1087 /////////////////////////////////////////////////////////////////////
1088 } else if (com=="setFrameBrushColor")
1090 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1092 parser.setError (Aborted,"Type of selection does not allow setting brush color");
1094 else if (parser.checkParCount(1))
1096 QColor c=parser.parColor(ok,0);
1097 if (ok) setFrameBrushColor (c);
1099 /////////////////////////////////////////////////////////////////////
1100 } else if (com=="setFramePadding")
1102 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1104 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
1106 else if (parser.checkParCount(1))
1108 n=parser.parInt(ok,0);
1109 if (ok) setFramePadding(n);
1111 /////////////////////////////////////////////////////////////////////
1112 } else if (com=="setFrameBorderWidth")
1114 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1116 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
1118 else if (parser.checkParCount(1))
1120 n=parser.parInt(ok,0);
1121 if (ok) setFrameBorderWidth (n);
1123 /////////////////////////////////////////////////////////////////////
1124 } else if (com=="setMapAuthor")
1126 if (parser.checkParCount(1))
1128 s=parser.parString(ok,0);
1129 if (ok) setMapAuthor (s);
1131 /////////////////////////////////////////////////////////////////////
1132 } else if (com=="setMapComment")
1134 if (parser.checkParCount(1))
1136 s=parser.parString(ok,0);
1137 if (ok) setMapComment(s);
1139 /////////////////////////////////////////////////////////////////////
1140 } else if (com=="setMapBackgroundColor")
1142 if (xelection.isEmpty() )
1144 parser.setError (Aborted,"Nothing selected");
1145 } else if (! xelection.getBranch() )
1147 parser.setError (Aborted,"Type of selection is not a branch");
1148 } else if (parser.checkParCount(1))
1150 QColor c=parser.parColor (ok,0);
1151 if (ok) setMapBackgroundColor (c);
1153 /////////////////////////////////////////////////////////////////////
1154 } else if (com=="setMapDefLinkColor")
1156 if (xelection.isEmpty() )
1158 parser.setError (Aborted,"Nothing selected");
1161 parser.setError (Aborted,"Type of selection is not a branch");
1162 } else if (parser.checkParCount(1))
1164 QColor c=parser.parColor (ok,0);
1165 if (ok) setMapDefLinkColor (c);
1167 /////////////////////////////////////////////////////////////////////
1168 } else if (com=="setMapLinkStyle")
1170 if (parser.checkParCount(1))
1172 s=parser.parString (ok,0);
1173 if (ok) setMapLinkStyle(s);
1175 /////////////////////////////////////////////////////////////////////
1176 } else if (com=="setHeading")
1178 if (xelection.isEmpty() )
1180 parser.setError (Aborted,"Nothing selected");
1183 parser.setError (Aborted,"Type of selection is not a branch");
1184 } else if (parser.checkParCount(1))
1186 s=parser.parString (ok,0);
1190 /////////////////////////////////////////////////////////////////////
1191 } else if (com=="setHideExport")
1193 if (xelection.isEmpty() )
1195 parser.setError (Aborted,"Nothing selected");
1196 } else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage)
1198 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1199 } else if (parser.checkParCount(1))
1201 b=parser.parBool(ok,0);
1202 if (ok) setHideExport (b);
1204 /////////////////////////////////////////////////////////////////////
1205 } else if (com=="setIncludeImagesHorizontally")
1207 if (xelection.isEmpty() )
1209 parser.setError (Aborted,"Nothing selected");
1212 parser.setError (Aborted,"Type of selection is not a branch");
1213 } else if (parser.checkParCount(1))
1215 b=parser.parBool(ok,0);
1216 if (ok) setIncludeImagesHor(b);
1218 /////////////////////////////////////////////////////////////////////
1219 } else if (com=="setIncludeImagesVertically")
1221 if (xelection.isEmpty() )
1223 parser.setError (Aborted,"Nothing selected");
1226 parser.setError (Aborted,"Type of selection is not a branch");
1227 } else if (parser.checkParCount(1))
1229 b=parser.parBool(ok,0);
1230 if (ok) setIncludeImagesVer(b);
1232 /////////////////////////////////////////////////////////////////////
1233 } else if (com=="setHideLinkUnselected")
1235 if (xelection.isEmpty() )
1237 parser.setError (Aborted,"Nothing selected");
1238 } else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1240 parser.setError (Aborted,"Type of selection does not allow hiding the link");
1241 } else if (parser.checkParCount(1))
1243 b=parser.parBool(ok,0);
1244 if (ok) setHideLinkUnselected(b);
1246 /////////////////////////////////////////////////////////////////////
1247 } else if (com=="setSelectionColor")
1249 if (parser.checkParCount(1))
1251 QColor c=parser.parColor (ok,0);
1252 if (ok) setSelectionColorInt (c);
1254 /////////////////////////////////////////////////////////////////////
1255 } else if (com=="setURL")
1257 if (xelection.isEmpty() )
1259 parser.setError (Aborted,"Nothing selected");
1262 parser.setError (Aborted,"Type of selection is not a branch");
1263 } else if (parser.checkParCount(1))
1265 s=parser.parString (ok,0);
1268 /////////////////////////////////////////////////////////////////////
1269 } else if (com=="setVymLink")
1271 if (xelection.isEmpty() )
1273 parser.setError (Aborted,"Nothing selected");
1276 parser.setError (Aborted,"Type of selection is not a branch");
1277 } else if (parser.checkParCount(1))
1279 s=parser.parString (ok,0);
1280 if (ok) setVymLinkInt(s);
1283 /////////////////////////////////////////////////////////////////////
1284 else if (com=="setFlag")
1286 if (xelection.isEmpty() )
1288 parser.setError (Aborted,"Nothing selected");
1291 parser.setError (Aborted,"Type of selection is not a branch");
1292 } else if (parser.checkParCount(1))
1294 s=parser.parString(ok,0);
1297 selb->activateStandardFlag(s);
1298 selb->updateFlagsToolbar();
1301 /////////////////////////////////////////////////////////////////////
1302 } else if (com=="setFrameType")
1304 if (xelection.isEmpty() )
1306 parser.setError (Aborted,"Nothing selected");
1309 parser.setError (Aborted,"Type of selection is not a branch");
1310 } else if (parser.checkParCount(1))
1312 s=parser.parString(ok,0);
1316 /////////////////////////////////////////////////////////////////////
1317 } else if (com=="toggleFlag")
1319 if (xelection.isEmpty() )
1321 parser.setError (Aborted,"Nothing selected");
1324 parser.setError (Aborted,"Type of selection is not a branch");
1325 } else if (parser.checkParCount(1))
1327 s=parser.parString(ok,0);
1330 selb->toggleStandardFlag(s);
1331 selb->updateFlagsToolbar();
1334 /////////////////////////////////////////////////////////////////////
1335 } else if (com=="unscroll")
1337 if (xelection.isEmpty() )
1339 parser.setError (Aborted,"Nothing selected");
1342 parser.setError (Aborted,"Type of selection is not a branch");
1343 } else if (parser.checkParCount(0))
1345 if (!unscrollBranch (selb))
1346 parser.setError (Aborted,"Could not unscroll branch");
1348 /////////////////////////////////////////////////////////////////////
1349 } else if (com=="unscrollChilds")
1351 if (xelection.isEmpty() )
1353 parser.setError (Aborted,"Nothing selected");
1356 parser.setError (Aborted,"Type of selection is not a branch");
1357 } else if (parser.checkParCount(0))
1361 /////////////////////////////////////////////////////////////////////
1362 } else if (com=="unsetFlag")
1364 if (xelection.isEmpty() )
1366 parser.setError (Aborted,"Nothing selected");
1369 parser.setError (Aborted,"Type of selection is not a branch");
1370 } else if (parser.checkParCount(1))
1372 s=parser.parString(ok,0);
1375 selb->deactivateStandardFlag(s);
1376 selb->updateFlagsToolbar();
1380 parser.setError (Aborted,"Unknown command");
1383 if (parser.errorLevel()==NoError)
1386 mapCenter->reposition();
1390 // TODO Error handling
1391 qWarning("MapEditor::parseAtom: Error!");
1392 qWarning(parser.errorMessage());
1396 void MapEditor::runScript (QString script)
1398 parser.setScript (script);
1400 while (parser.next() )
1401 parseAtom(parser.getAtom());
1404 bool MapEditor::isDefault()
1409 bool MapEditor::hasChanged()
1414 void MapEditor::setChanged()
1417 autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
1425 void MapEditor::closeMap()
1427 // Unselect before disabling the toolbar actions
1428 if (!xelection.isEmpty() ) xelection.unselect();
1436 void MapEditor::setFilePath(QString fpath, QString destname)
1438 if (fpath.isEmpty() || fpath=="")
1445 filePath=fpath; // becomes absolute path
1446 fileName=fpath; // gets stripped of path
1447 destPath=destname; // needed for vymlinks
1449 // If fpath is not an absolute path, complete it
1450 filePath=QDir(fpath).absPath();
1451 fileDir=filePath.left (1+filePath.findRev ("/"));
1453 // Set short name, too. Search from behind:
1454 int i=fileName.findRev("/");
1455 if (i>=0) fileName=fileName.remove (0,i+1);
1457 // Forget the .vym (or .xml) for name of map
1458 mapName=fileName.left(fileName.findRev(".",-1,true) );
1462 void MapEditor::setFilePath(QString fpath)
1464 setFilePath (fpath,fpath);
1467 QString MapEditor::getFilePath()
1472 QString MapEditor::getFileName()
1477 QString MapEditor::getMapName()
1482 QString MapEditor::getDestPath()
1487 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1489 ErrorCode err=success;
1493 if (xelection.isEmpty() ) xelection.unselect();
1496 mapCenter->setMapEditor(this);
1497 // (map state is set later at end of load...)
1500 BranchObj *bo=xelection.getBranch();
1501 if (!bo) return aborted;
1502 if (lmode==ImportAdd)
1503 saveStateChangingPart(
1506 QString("addMapInsert (%1)").arg(fname),
1507 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1509 saveStateChangingPart(
1512 QString("addMapReplace(%1)").arg(fname),
1513 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1517 mapBuilderHandler handler;
1518 QFile file( fname );
1520 // I am paranoid: file should exist anyway
1521 // according to check in mainwindow.
1522 if (!file.exists() )
1524 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1525 tr("Couldn't open map " +fname)+".");
1529 bool blockSaveStateOrg=blockSaveState;
1530 blockReposition=true;
1531 blockSaveState=true;
1532 QXmlInputSource source( file);
1533 QXmlSimpleReader reader;
1534 reader.setContentHandler( &handler );
1535 reader.setErrorHandler( &handler );
1536 handler.setMapEditor( this );
1539 // We need to set the tmpDir in order to load files with rel. path
1540 QString tmpdir= fname.left(fname.findRev("/",-1));
1541 handler.setTmpDir (tmpdir);
1542 handler.setInputFile (file.name());
1543 handler.setLoadMode (lmode);
1544 bool ok = reader.parse( source );
1545 blockReposition=false;
1546 blockSaveState=blockSaveStateOrg;
1550 mapCenter->reposition();
1557 autosaveTimer->stop();
1561 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1562 tr( handler.errorProtocol() ) );
1564 // Still return "success": the map maybe at least
1565 // partially read by the parser
1572 int MapEditor::save (const SaveMode &savemode)
1574 // Create mapName and fileDir
1575 makeSubDirs (fileDir);
1579 fname=mapName+".xml";
1581 // use name given by user, even if he chooses .doc
1586 if (savemode==CompleteMap || xelection.isEmpty())
1587 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1590 // TODO take care of multiselections
1591 if (xelection.type()==Selection::FloatImage)
1594 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());
1598 if (!saveStringToDisk(fileDir+fname,saveFile))
1603 autosaveTimer->stop();
1608 void MapEditor::setZipped (bool z)
1613 bool MapEditor::saveZipped ()
1618 void MapEditor::print()
1622 printer = new QPrinter;
1623 printer->setColorMode (QPrinter::Color);
1624 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1625 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1626 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1629 QRectF totalBBox=mapCenter->getTotalBBox();
1631 // Try to set orientation automagically
1632 // Note: Interpretation of generated postscript is amibiguous, if
1633 // there are problems with landscape mode, see
1634 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1636 if (totalBBox.width()>totalBBox.height())
1637 // recommend landscape
1638 printer->setOrientation (QPrinter::Landscape);
1640 // recommend portrait
1641 printer->setOrientation (QPrinter::Portrait);
1643 if ( printer->setup(this) )
1644 // returns false, if printing is canceled
1646 QPainter pp(printer);
1648 pp.setRenderHint(QPainter::Antialiasing,true);
1650 // Don't print the visualisation of selection
1651 xelection.unselect();
1653 QRectF mapRect=totalBBox;
1654 QGraphicsRectItem *frame=NULL;
1658 // Print frame around map
1659 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1660 totalBBox.width()+20, totalBBox.height()+20);
1661 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1662 frame->setZValue(0);
1667 double paperAspect = (double)printer->width() / (double)printer->height();
1668 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1670 if (mapAspect>=paperAspect)
1672 // Fit horizontally to paper width
1673 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1674 viewBottom=(int)(printer->width()/mapAspect);
1677 // Fit vertically to paper height
1678 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1679 viewBottom=printer->height();
1684 // Print footer below map
1686 font.setPointSize(10);
1688 QRectF footerBox(0,viewBottom,printer->width(),15);
1689 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1690 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1694 QRectF (0,0,printer->width(),printer->height()-15),
1695 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1698 // Viewport has paper dimension
1699 if (frame) delete (frame);
1701 // Restore selection
1702 xelection.reselect();
1704 // Save settings in vymrc
1705 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1706 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1707 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1711 void MapEditor::setAntiAlias (bool b)
1713 setRenderHint(QPainter::Antialiasing,b);
1716 void MapEditor::setSmoothPixmap(bool b)
1718 setRenderHint(QPainter::SmoothPixmapTransform,b);
1721 QPixmap MapEditor::getPixmap()
1723 QRectF mapRect=mapCenter->getTotalBBox();
1724 QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+2);
1727 pp.setRenderHints(renderHints());
1729 // Don't print the visualisation of selection
1730 xelection.unselect();
1732 mapScene->render ( &pp,
1733 QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1734 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1736 // Restore selection
1737 xelection.reselect();
1742 void MapEditor::setHideTmpMode (BranchObj::HideTmpMode mode)
1745 mapCenter->setHideTmp (hidemode);
1746 mapCenter->reposition();
1750 BranchObj::HideTmpMode MapEditor::getHideTmpMode()
1755 void MapEditor::setExportMode (bool b)
1757 // should be called before and after exports
1758 // depending on the settings
1759 if (b && settings.value("/export/useHideExport","yes")=="yes")
1760 setHideTmpMode (BranchObj::HideExport);
1762 setHideTmpMode (BranchObj::HideNone);
1765 void MapEditor::exportASCII(QString fname,bool askName)
1768 ex.setMapCenter(mapCenter);
1770 ex.setFile (mapName+".txt");
1776 //ex.addFilter ("TXT (*.txt)");
1777 ex.setDir(lastImageDir);
1778 //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
1783 setExportMode(true);
1785 setExportMode(false);
1789 void MapEditor::exportImage(QString fname, bool askName, QString format)
1793 fname=mapName+".png";
1800 QFileDialog *fd=new QFileDialog (this);
1801 fd->setCaption (tr("Export map as image"));
1802 fd->setDirectory (lastImageDir);
1803 fd->setFileMode(QFileDialog::AnyFile);
1804 fd->setFilters (imageIO.getFilters() );
1807 fl=fd->selectedFiles();
1809 format=imageIO.getType(fd->selectedFilter());
1813 setExportMode (true);
1814 QPixmap pix (getPixmap());
1815 pix.save(fname, format);
1816 setExportMode (false);
1819 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1823 ex.setMapCenter(mapCenter);
1824 if (ex.setConfigFile(cf))
1826 setExportMode (true);
1827 ex.exportPresentation();
1828 setExportMode (false);
1832 void MapEditor::exportXHTML (const QString &dir, bool askForName)
1834 ExportXHTMLDialog dia(this);
1835 dia.setFilePath (filePath );
1836 dia.setMapName (mapName );
1838 if (dir!="") dia.setDir (dir);
1844 if (dia.exec()!=QDialog::Accepted)
1848 QDir d (dia.getDir());
1849 // Check, if warnings should be used before overwriting
1850 // the output directory
1851 if (d.exists() && d.count()>0)
1854 warn.showCancelButton (true);
1855 warn.setText(QString(
1856 "The directory %1 is not empty.\n"
1857 "Do you risk to overwrite some of its contents?").arg(d.path() ));
1858 warn.setCaption("Warning: Directory not empty");
1859 warn.setShowAgainName("mainwindow/overwrite-dir-xhtml");
1861 if (warn.exec()!=QDialog::Accepted) ok=false;
1868 exportXML (dia.getDir(),false );
1869 dia.doExport(mapName );
1870 //if (dia.hasChanged()) setChanged();
1874 void MapEditor::exportXML(QString dir, bool askForName)
1878 dir=browseDirectory(this,tr("Export XML to directory"));
1879 if (dir =="" && !reallyWriteDirectory(dir) )
1883 // Hide stuff during export, if settings want this
1884 setExportMode (true);
1886 // Create subdirectories
1889 // write to directory
1890 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1893 file.setName ( dir + "/"+mapName+".xml");
1894 if ( !file.open( QIODevice::WriteOnly ) )
1896 // This should neverever happen
1897 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1901 // Write it finally, and write in UTF8, no matter what
1902 QTextStream ts( &file );
1903 ts.setEncoding (QTextStream::UnicodeUTF8);
1907 // Now write image, too
1908 exportImage (dir+"/images/"+mapName+".png",false,"PNG");
1910 setExportMode (false);
1913 void MapEditor::clear()
1915 xelection.unselect();
1919 void MapEditor::copy()
1921 LinkableMapObj *sel=xelection.single();
1924 if (redosAvail == 0)
1927 QString s=sel->getSelectString();
1928 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel );
1929 curClipboard=curStep;
1932 // Copy also to global clipboard, because we are at last step in history
1933 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
1934 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
1935 copyDir (bakMapDir,clipboardDir );
1937 clipboardEmpty=false;
1942 void MapEditor::redo()
1944 // Can we undo at all?
1945 if (redosAvail<1) return;
1947 bool blockSaveStateOrg=blockSaveState;
1948 blockSaveState=true;
1952 if (undosAvail<stepsTotal) undosAvail++;
1954 if (curStep>stepsTotal) curStep=1;
1955 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1956 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1957 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1958 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1959 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1960 QString version=undoSet.readEntry ("/history/version");
1962 if (!checkVersion(version))
1963 QMessageBox::warning(0,tr("Warning"),
1964 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1967 // Find out current undo directory
1968 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1972 cout << "ME::redo() begin\n";
1973 cout << " undosAvail="<<undosAvail<<endl;
1974 cout << " redosAvail="<<redosAvail<<endl;
1975 cout << " curStep="<<curStep<<endl;
1976 cout << " ---------------------------"<<endl;
1977 cout << " comment="<<comment.toStdString()<<endl;
1978 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1979 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1980 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1981 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1982 cout << " ---------------------------"<<endl<<endl;
1985 // select object before redo
1986 if (!redoSelection.isEmpty())
1987 select (redoSelection);
1990 parseAtom (redoCommand);
1991 mapCenter->reposition();
1993 blockSaveState=blockSaveStateOrg;
1995 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1996 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1997 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1998 undoSet.writeSettings(histPath);
2000 mainWindow->updateHistory (undoSet);
2003 /* TODO remove testing
2004 cout << "ME::redo() end\n";
2005 cout << " undosAvail="<<undosAvail<<endl;
2006 cout << " redosAvail="<<redosAvail<<endl;
2007 cout << " curStep="<<curStep<<endl;
2008 cout << " ---------------------------"<<endl<<endl;
2014 bool MapEditor::isRedoAvailable()
2016 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
2022 void MapEditor::undo()
2024 // Can we undo at all?
2025 if (undosAvail<1) return;
2027 mainWindow->statusMessage (tr("Autosave disabled during undo."));
2029 bool blockSaveStateOrg=blockSaveState;
2030 blockSaveState=true;
2032 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
2033 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2034 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2035 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2036 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2037 QString version=undoSet.readEntry ("/history/version");
2039 if (!checkVersion(version))
2040 QMessageBox::warning(0,tr("Warning"),
2041 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2043 // Find out current undo directory
2044 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
2046 // select object before undo
2047 if (!undoSelection.isEmpty())
2048 select (undoSelection);
2052 cout << "ME::undo() begin\n";
2053 cout << " undosAvail="<<undosAvail<<endl;
2054 cout << " redosAvail="<<redosAvail<<endl;
2055 cout << " curStep="<<curStep<<endl;
2056 cout << " ---------------------------"<<endl;
2057 cout << " comment="<<comment.toStdString()<<endl;
2058 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2059 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2060 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2061 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2062 cout << " ---------------------------"<<endl<<endl;
2064 parseAtom (undoCommand);
2065 mapCenter->reposition();
2069 if (curStep<1) curStep=stepsTotal;
2073 blockSaveState=blockSaveStateOrg;
2074 /* TODO remove testing
2075 cout << "ME::undo() end\n";
2076 cout << " undosAvail="<<undosAvail<<endl;
2077 cout << " redosAvail="<<redosAvail<<endl;
2078 cout << " curStep="<<curStep<<endl;
2079 cout << " ---------------------------"<<endl<<endl;
2082 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2083 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2084 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2085 undoSet.writeSettings(histPath);
2087 mainWindow->updateHistory (undoSet);
2090 ensureSelectionVisible();
2093 bool MapEditor::isUndoAvailable()
2095 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
2101 void MapEditor::gotoHistoryStep (int i)
2103 // Restore variables
2104 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
2105 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
2107 if (i<0) i=undosAvail+redosAvail;
2109 // Clicking above current step makes us undo things
2112 for (int j=0; j<undosAvail-i; j++) undo();
2115 // Clicking below current step makes us redo things
2117 for (int j=undosAvail; j<i; j++)
2119 cout << "redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
2123 // And ignore clicking the current row ;-)
2126 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
2128 QString pathDir=path.left(path.findRev("/"));
2134 // We need to parse saved XML data
2135 mapBuilderHandler handler;
2136 QXmlInputSource source( file);
2137 QXmlSimpleReader reader;
2138 reader.setContentHandler( &handler );
2139 reader.setErrorHandler( &handler );
2140 handler.setMapEditor( this );
2141 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2142 if (undoSel.isEmpty())
2146 handler.setLoadMode (NewMap);
2150 handler.setLoadMode (ImportReplace);
2152 blockReposition=true;
2153 bool ok = reader.parse( source );
2154 blockReposition=false;
2157 // This should never ever happen
2158 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2159 handler.errorProtocol());
2162 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2165 void MapEditor::addMapInsertInt (const QString &path, int pos)
2167 BranchObj *sel=xelection.getBranch();
2170 QString pathDir=path.left(path.findRev("/"));
2176 // We need to parse saved XML data
2177 mapBuilderHandler handler;
2178 QXmlInputSource source( file);
2179 QXmlSimpleReader reader;
2180 reader.setContentHandler( &handler );
2181 reader.setErrorHandler( &handler );
2182 handler.setMapEditor( this );
2183 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2184 handler.setLoadMode (ImportAdd);
2185 blockReposition=true;
2186 bool ok = reader.parse( source );
2187 blockReposition=false;
2190 // This should never ever happen
2191 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2192 handler.errorProtocol());
2195 sel->getLastBranch()->linkTo (sel,pos);
2197 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2201 void MapEditor::pasteNoSave(const int &n)
2203 bool old=blockSaveState;
2204 blockSaveState=true;
2205 if (redosAvail > 0 || n!=0)
2207 // Use the "historical" buffer
2208 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(n));
2209 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
2210 load (bakMapDir+"/"+clipboardFile,ImportAdd);
2212 // Use the global buffer
2213 load (clipboardDir+"/"+clipboardFile,ImportAdd);
2217 void MapEditor::paste()
2219 BranchObj *sel=xelection.getBranch();
2222 saveStateChangingPart(
2225 QString ("paste (%1)").arg(curClipboard),
2226 QString("Paste to %1").arg( getName(sel))
2229 mapCenter->reposition();
2233 void MapEditor::cut()
2235 LinkableMapObj *sel=xelection.single();
2236 if ( sel && (xelection.type() == Selection::Branch ||
2237 xelection.type()==Selection::MapCenter ||
2238 xelection.type()==Selection::FloatImage))
2240 /* No savestate! savestate is called in cutNoSave
2241 saveStateChangingPart(
2245 QString("Cut %1").arg(getName(sel ))
2250 mapCenter->reposition();
2254 void MapEditor::move(const double &x, const double &y)
2256 LinkableMapObj *sel=xelection.single();
2259 QString ps=qpointfToString (sel->getAbsPos());
2260 QString s=xelection.single()->getSelectString();
2263 s, "move "+qpointfToString (QPointF (x,y)),
2264 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
2266 mapCenter->reposition();
2272 void MapEditor::moveRel (const double &x, const double &y)
2274 LinkableMapObj *sel=xelection.single();
2277 QString ps=qpointfToString (sel->getRelPos());
2278 QString s=sel->getSelectString();
2281 s, "moveRel "+qpointfToString (QPointF (x,y)),
2282 QString("Move %1 to relativ position %2").arg(getName(sel)).arg(ps));
2283 ((OrnamentedObj*)sel)->move2RelPos (x,y);
2284 mapCenter->reposition();
2290 void MapEditor::moveBranchUp()
2292 BranchObj* bo=xelection.getBranch();
2296 if (!bo->canMoveBranchUp()) return;
2297 par=(BranchObj*)(bo->getParObj());
2298 BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
2299 saveState (bo->getSelectString(),"moveBranchDown ()",obo->getSelectString(),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
2300 mapCenter->reposition();
2303 ensureSelectionVisible();
2307 void MapEditor::moveBranchDown()
2309 BranchObj* bo=xelection.getBranch();
2313 if (!bo->canMoveBranchDown()) return;
2314 par=(BranchObj*)(bo->getParObj());
2315 BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
2316 saveState(bo->getSelectString(),"moveBranchUp ()",obo->getSelectString(),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
2317 mapCenter->reposition();
2320 ensureSelectionVisible();
2324 void MapEditor::linkTo(const QString &dstString)
2326 FloatImageObj *fio=xelection.getFloatImage();
2329 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
2330 if (dst && (typeid(*dst)==typeid (BranchObj) ||
2331 typeid(*dst)==typeid (MapCenterObj)))
2333 LinkableMapObj *dstPar=dst->getParObj();
2334 QString parString=dstPar->getSelectString();
2335 QString fioPreSelectString=fio->getSelectString();
2336 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
2337 ((BranchObj*)(dst))->addFloatImage (fio);
2338 xelection.unselect();
2339 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
2340 fio=((BranchObj*)(dst))->getLastFloatImage();
2343 xelection.select(fio);
2345 fio->getSelectString(),
2346 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
2348 QString ("linkTo (\"%1\")").arg(dstString),
2349 QString ("Link floatimage to %1").arg(getName(dst)));
2354 QString MapEditor::getHeading(bool &ok, QPoint &p)
2356 BranchObj *bo=xelection.getBranch();
2360 p=mapFromScene(bo->getAbsPos());
2361 return bo->getHeading();
2367 void MapEditor::setHeading(const QString &s)
2369 BranchObj *sel=xelection.getBranch();
2374 "setHeading (\""+sel->getHeading()+"\")",
2376 "setHeading (\""+s+"\")",
2377 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
2378 sel->setHeading(s );
2379 mapCenter->reposition();
2381 ensureSelectionVisible();
2385 void MapEditor::setHeadingInt(const QString &s)
2387 BranchObj *bo=xelection.getBranch();
2391 mapCenter->reposition();
2393 ensureSelectionVisible();
2397 void MapEditor::setVymLinkInt (const QString &s)
2399 // Internal function, no saveState needed
2400 BranchObj *bo=xelection.getBranch();
2404 mapCenter->reposition();
2407 ensureSelectionVisible();
2411 BranchObj* MapEditor::addNewBranchInt(int num)
2413 // Depending on pos:
2414 // -3 insert in childs of parent above selection
2415 // -2 add branch to selection
2416 // -1 insert in childs of parent below selection
2417 // 0..n insert in childs of parent at pos
2418 BranchObj *newbo=NULL;
2419 BranchObj *bo=xelection.getBranch();
2424 // save scroll state. If scrolled, automatically select
2425 // new branch in order to tmp unscroll parent...
2426 newbo=bo->addBranch();
2431 bo=(BranchObj*)bo->getParObj();
2432 if (bo) newbo=bo->insertBranch(num);
2436 bo=(BranchObj*)bo->getParObj();
2437 if (bo) newbo=bo->insertBranch(num);
2439 if (!newbo) return NULL;
2444 BranchObj* MapEditor::addNewBranch(int pos)
2446 // Different meaning than num in addNewBranchInt!
2450 BranchObj *bo = xelection.getBranch();
2451 BranchObj *newbo=NULL;
2455 setCursor (Qt::ArrowCursor);
2457 newbo=addNewBranchInt (pos-2);
2465 QString ("addBranch (%1)").arg(pos),
2466 QString ("Add new branch to %1").arg(getName(bo)));
2468 mapCenter->reposition();
2470 latestSelection=newbo->getSelectString();
2471 // In Network mode, the client needs to know where the new branch is,
2472 // so we have to pass on this information via saveState.
2473 // TODO: Get rid of this positioning workaround
2474 QString ps=qpointfToString (newbo->getAbsPos());
2475 sendData ("selectLatestAdded ()");
2476 sendData (QString("move %1").arg(ps));
2484 BranchObj* MapEditor::addNewBranchBefore()
2486 BranchObj *newbo=NULL;
2487 BranchObj *bo = xelection.getBranch();
2488 if (bo && xelection.type()==Selection::Branch)
2489 // We accept no MapCenterObj here, so we _have_ a parent
2491 QPointF p=bo->getRelPos();
2494 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2496 // add below selection
2497 newbo=parbo->insertBranch(bo->getNum()+1);
2500 newbo->move2RelPos (p);
2502 // Move selection to new branch
2503 bo->linkTo (newbo,-1);
2505 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2506 QString ("Add branch before %1").arg(getName(bo)));
2508 mapCenter->reposition();
2512 latestSelection=xelection.getSelectString();
2516 void MapEditor::deleteSelection()
2518 BranchObj *bo = xelection.getBranch();
2519 if (bo && xelection.type()==Selection::Branch)
2521 BranchObj* par=(BranchObj*)(bo->getParObj());
2522 xelection.unselect();
2523 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2524 par->removeBranch(bo);
2525 xelection.select (par);
2526 ensureSelectionVisible();
2527 mapCenter->reposition();
2532 FloatImageObj *fio=xelection.getFloatImage();
2535 BranchObj* par=(BranchObj*)(fio->getParObj());
2536 saveStateChangingPart(
2540 QString("Delete %1").arg(getName(fio))
2542 xelection.unselect();
2543 par->removeFloatImage(fio);
2544 xelection.select (par);
2545 mapCenter->reposition();
2547 ensureSelectionVisible();
2552 LinkableMapObj* MapEditor::getSelection()
2554 return xelection.single();
2557 BranchObj* MapEditor::getSelectedBranch()
2559 return xelection.getBranch();
2562 FloatImageObj* MapEditor::getSelectedFloatImage()
2564 return xelection.getFloatImage();
2567 void MapEditor::unselect()
2569 xelection.unselect();
2572 void MapEditor::reselect()
2574 xelection.reselect();
2577 bool MapEditor::select (const QString &s)
2579 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2581 // Finally select the found object
2584 xelection.unselect();
2585 xelection.select(lmo);
2587 ensureSelectionVisible();
2594 QString MapEditor::getSelectString()
2596 return xelection.getSelectString();
2599 void MapEditor::selectInt (LinkableMapObj *lmo)
2601 if (lmo && xelection.single()!= lmo && isSelectBlocked()==false )
2603 xelection.select(lmo);
2609 void MapEditor::selectNextBranchInt()
2611 // Increase number of branch
2612 LinkableMapObj *sel=xelection.single();
2615 QString s=sel->getSelectString();
2621 part=s.section(",",-1);
2623 num=part.right(part.length() - 3);
2625 s=s.left (s.length() -num.length());
2628 num=QString ("%1").arg(num.toUInt()+1);
2632 // Try to select this one
2633 if (select (s)) return;
2635 // We have no direct successor,
2636 // try to increase the parental number in order to
2637 // find a successor with same depth
2639 int d=xelection.single()->getDepth();
2644 while (!found && d>0)
2646 s=s.section (",",0,d-1);
2647 // replace substring of current depth in s with "1"
2648 part=s.section(",",-1);
2650 num=part.right(part.length() - 3);
2654 // increase number of parent
2655 num=QString ("%1").arg(num.toUInt()+1);
2656 s=s.section (",",0,d-2) + ","+ typ+num;
2659 // Special case, look at orientation
2660 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2661 num=QString ("%1").arg(num.toUInt()+1);
2663 num=QString ("%1").arg(num.toUInt()-1);
2668 // pad to oldDepth, select the first branch for each depth
2669 for (i=d;i<oldDepth;i++)
2674 if ( xelection.getBranch()->countBranches()>0)
2682 // try to select the freshly built string
2690 void MapEditor::selectPrevBranchInt()
2692 // Decrease number of branch
2693 BranchObj *bo=xelection.getBranch();
2696 QString s=bo->getSelectString();
2702 part=s.section(",",-1);
2704 num=part.right(part.length() - 3);
2706 s=s.left (s.length() -num.length());
2708 int n=num.toInt()-1;
2711 num=QString ("%1").arg(n);
2714 // Try to select this one
2715 if (n>=0 && select (s)) return;
2717 // We have no direct precessor,
2718 // try to decrease the parental number in order to
2719 // find a precessor with same depth
2721 int d=xelection.single()->getDepth();
2726 while (!found && d>0)
2728 s=s.section (",",0,d-1);
2729 // replace substring of current depth in s with "1"
2730 part=s.section(",",-1);
2732 num=part.right(part.length() - 3);
2736 // decrease number of parent
2737 num=QString ("%1").arg(num.toInt()-1);
2738 s=s.section (",",0,d-2) + ","+ typ+num;
2741 // Special case, look at orientation
2742 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2743 num=QString ("%1").arg(num.toInt()-1);
2745 num=QString ("%1").arg(num.toInt()+1);
2750 // pad to oldDepth, select the last branch for each depth
2751 for (i=d;i<oldDepth;i++)
2755 if ( xelection.getBranch()->countBranches()>0)
2756 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2763 // try to select the freshly built string
2771 void MapEditor::selectUpperBranch()
2773 if (isSelectBlocked() ) return;
2775 BranchObj *bo=xelection.getBranch();
2776 if (bo && xelection.type()==Selection::Branch)
2778 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2779 selectPrevBranchInt();
2781 if (bo->getDepth()==1)
2782 selectNextBranchInt();
2784 selectPrevBranchInt();
2788 void MapEditor::selectLowerBranch()
2790 if (isSelectBlocked() ) return;
2792 BranchObj *bo=xelection.getBranch();
2793 if (bo && xelection.type()==Selection::Branch)
2794 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2795 selectNextBranchInt();
2797 if (bo->getDepth()==1)
2798 selectPrevBranchInt();
2800 selectNextBranchInt();
2804 void MapEditor::selectLeftBranch()
2806 if (isSelectBlocked() ) return;
2810 LinkableMapObj *sel=xelection.single();
2813 if (xelection.type()== Selection::MapCenter)
2815 par=xelection.getBranch();
2816 bo=par->getLastSelectedBranch();
2819 // Workaround for reselecting on left and right side
2820 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2821 bo=par->getLastBranch();
2824 bo=par->getLastBranch();
2825 xelection.select(bo);
2827 ensureSelectionVisible();
2833 par=(BranchObj*)(sel->getParObj());
2834 if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
2836 if (xelection.type() == Selection::Branch ||
2837 xelection.type() == Selection::FloatImage)
2839 xelection.select(par);
2841 ensureSelectionVisible();
2846 if (xelection.type() == Selection::Branch )
2848 bo=xelection.getBranch()->getLastSelectedBranch();
2851 xelection.select(bo);
2853 ensureSelectionVisible();
2862 void MapEditor::selectRightBranch()
2864 if (isSelectBlocked() ) return;
2868 LinkableMapObj *sel=xelection.single();
2871 if (xelection.type()==Selection::MapCenter)
2873 par=xelection.getBranch();
2874 bo=par->getLastSelectedBranch();
2877 // Workaround for reselecting on left and right side
2878 if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
2879 bo=par->getFirstBranch();
2882 xelection.select(bo);
2884 ensureSelectionVisible();
2890 par=(BranchObj*)(xelection.single()->getParObj());
2891 if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
2893 if (xelection.type() == Selection::Branch ||
2894 xelection.type() == Selection::FloatImage)
2896 xelection.select(par);
2898 ensureSelectionVisible();
2903 if (xelection.type() == Selection::Branch)
2905 bo=xelection.getBranch()->getLastSelectedBranch();
2908 xelection.select(bo);
2910 ensureSelectionVisible();
2919 void MapEditor::selectFirstBranch()
2921 BranchObj *bo1=xelection.getBranch();
2926 par=(BranchObj*)(bo1->getParObj());
2927 bo2=par->getFirstBranch();
2929 xelection.select(bo2);
2931 ensureSelectionVisible();
2937 void MapEditor::selectLastBranch()
2939 BranchObj *bo1=xelection.getBranch();
2944 par=(BranchObj*)(bo1->getParObj());
2945 bo2=par->getLastBranch();
2948 xelection.select(bo2);
2950 ensureSelectionVisible();
2956 void MapEditor::selectMapBackgroundImage ()
2958 Q3FileDialog *fd=new Q3FileDialog( this);
2959 fd->setMode (Q3FileDialog::ExistingFile);
2960 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2961 ImagePreview *p =new ImagePreview (fd);
2962 fd->setContentsPreviewEnabled( TRUE );
2963 fd->setContentsPreview( p, p );
2964 fd->setPreviewMode( Q3FileDialog::Contents );
2965 fd->setCaption(vymName+" - " +tr("Load background image"));
2966 fd->setDir (lastImageDir);
2969 if ( fd->exec() == QDialog::Accepted )
2971 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2972 lastImageDir=QDir (fd->dirPath());
2973 setMapBackgroundImage (fd->selectedFile());
2977 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
2979 QColor oldcol=mapScene->backgroundBrush().color();
2983 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2985 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2986 QString("Set background color of map to %1").arg(col.name()));
2989 brush.setTextureImage (QPixmap (fn));
2990 mapScene->setBackgroundBrush(brush);
2993 void MapEditor::selectMapBackgroundColor()
2995 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2996 if ( !col.isValid() ) return;
2997 setMapBackgroundColor( col );
3001 void MapEditor::setMapBackgroundColor(QColor col)
3003 QColor oldcol=mapScene->backgroundBrush().color();
3006 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
3008 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
3009 QString("Set background color of map to %1").arg(col.name()));
3010 mapScene->setBackgroundBrush(col);
3013 QColor MapEditor::getMapBackgroundColor()
3015 return mapScene->backgroundBrush().color();
3018 QColor MapEditor::getCurrentHeadingColor()
3020 BranchObj *bo=xelection.getBranch();
3021 if (bo) return bo->getColor();
3023 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
3027 void MapEditor::colorBranch (QColor c)
3029 BranchObj *bo=xelection.getBranch();
3034 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
3036 QString ("colorBranch (\"%1\")").arg(c.name()),
3037 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
3039 bo->setColor(c); // color branch
3043 void MapEditor::colorSubtree (QColor c)
3045 BranchObj *bo=xelection.getBranch();
3048 saveStateChangingPart(
3051 QString ("colorSubtree (\"%1\")").arg(c.name()),
3052 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
3054 bo->setColorSubtree (c); // color links, color childs
3059 void MapEditor::toggleStandardFlag(QString f)
3061 BranchObj *bo=xelection.getBranch();
3065 if (bo->isSetStandardFlag(f))
3077 QString("%1 (\"%2\")").arg(u).arg(f),
3079 QString("%1 (\"%2\")").arg(r).arg(f),
3080 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
3081 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
3087 BranchObj* MapEditor::findText (QString s, bool cs)
3089 QTextDocument::FindFlags flags=0;
3090 if (cs) flags=QTextDocument::FindCaseSensitively;
3093 { // Nothing found or new find process
3095 // nothing found, start again
3097 itFind=mapCenter->first();
3099 bool searching=true;
3100 bool foundNote=false;
3101 while (searching && !EOFind)
3105 // Searching in Note
3106 if (itFind->getNote().contains(s,cs))
3108 if (xelection.single()!=itFind)
3110 xelection.select(itFind);
3111 ensureSelectionVisible();
3113 if (textEditor->findText(s,flags))
3119 // Searching in Heading
3120 if (searching && itFind->getHeading().contains (s,cs) )
3122 xelection.select(itFind);
3123 ensureSelectionVisible();
3129 itFind=itFind->next();
3130 if (!itFind) EOFind=true;
3134 return xelection.getBranch();
3139 void MapEditor::findReset()
3140 { // Necessary if text to find changes during a find process
3144 void MapEditor::setURL(const QString &url)
3146 BranchObj *bo=xelection.getBranch();
3149 QString oldurl=bo->getURL();
3153 QString ("setURL (\"%1\")").arg(oldurl),
3155 QString ("setURL (\"%1\")").arg(url),
3156 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
3159 mapCenter->reposition();
3161 ensureSelectionVisible();
3165 void MapEditor::editURL()
3167 BranchObj *bo=xelection.getBranch();
3171 QString text = QInputDialog::getText(
3172 "VYM", tr("Enter URL:"), QLineEdit::Normal,
3173 bo->getURL(), &ok, this );
3175 // user entered something and pressed OK
3180 void MapEditor::editLocalURL()
3182 BranchObj *bo=xelection.getBranch();
3185 QStringList filters;
3186 filters <<"All files (*)";
3187 filters << tr("Text","Filedialog") + " (*.txt)";
3188 filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
3189 filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
3190 filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
3191 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Set URL to a local file"));
3192 fd->setFilters (filters);
3193 fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
3194 fd->setDirectory (lastFileDir);
3195 if (! bo->getVymLink().isEmpty() )
3196 fd->selectFile( bo->getURL() );
3199 if ( fd->exec() == QDialog::Accepted )
3201 lastFileDir=QDir (fd->directory().path());
3202 setURL (fd->selectedFile() );
3207 QString MapEditor::getURL()
3209 BranchObj *bo=xelection.getBranch();
3211 return bo->getURL();
3216 QStringList MapEditor::getURLs()
3219 BranchObj *bo=xelection.getBranch();
3225 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
3233 void MapEditor::editHeading2URL()
3235 BranchObj *bo=xelection.getBranch();
3237 setURL (bo->getHeading());
3240 void MapEditor::editBugzilla2URL()
3242 BranchObj *bo=xelection.getBranch();
3245 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
3250 void MapEditor::editFATE2URL()
3252 BranchObj *bo=xelection.getBranch();
3255 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
3258 "setURL (\""+bo->getURL()+"\")",
3260 "setURL (\""+url+"\")",
3261 QString("Use heading of %1 as link to FATE").arg(getName(bo))
3268 void MapEditor::editVymLink()
3270 BranchObj *bo=xelection.getBranch();
3273 QStringList filters;
3274 filters <<"VYM map (*.vym)";
3275 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
3276 fd->setFilters (filters);
3277 fd->setCaption(vymName+" - " +tr("Link to another map"));
3278 fd->setDirectory (lastFileDir);
3279 if (! bo->getVymLink().isEmpty() )
3280 fd->selectFile( bo->getVymLink() );
3284 if ( fd->exec() == QDialog::Accepted )
3286 lastFileDir=QDir (fd->directory().path());
3289 "setVymLink (\""+bo->getVymLink()+"\")",
3291 "setVymLink (\""+fd->selectedFile()+"\")",
3292 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
3294 setVymLinkInt (fd->selectedFile() );
3299 void MapEditor::deleteVymLink()
3301 BranchObj *bo=xelection.getBranch();
3306 "setVymLink (\""+bo->getVymLink()+"\")",
3308 "setVymLink (\"\")",
3309 QString("Unset vymlink of %1").arg(getName(bo))
3311 bo->setVymLink ("" );
3313 mapCenter->reposition();
3318 void MapEditor::setHideExport(bool b)
3320 BranchObj *bo=xelection.getBranch();
3323 bo->setHideInExport (b);
3324 QString u= b ? "false" : "true";
3325 QString r=!b ? "false" : "true";
3329 QString ("setHideExport (%1)").arg(u),
3331 QString ("setHideExport (%1)").arg(r),
3332 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
3335 mapCenter->reposition();
3341 void MapEditor::toggleHideExport()
3343 BranchObj *bo=xelection.getBranch();
3345 setHideExport ( !bo->hideInExport() );
3348 QString MapEditor::getVymLink()
3350 BranchObj *bo=xelection.getBranch();
3352 return bo->getVymLink();
3358 QStringList MapEditor::getVymLinks()
3361 BranchObj *bo=xelection.getBranch();
3367 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
3375 void MapEditor::deleteKeepChilds()
3377 BranchObj *bo=xelection.getBranch();
3381 par=(BranchObj*)(bo->getParObj());
3382 QPointF p=bo->getRelPos();
3383 saveStateChangingPart(
3386 "deleteKeepChilds ()",
3387 QString("Remove %1 and keep its childs").arg(getName(bo))
3390 QString sel=bo->getSelectString();
3392 par->removeBranchHere(bo);
3393 mapCenter->reposition();
3395 xelection.getBranch()->move2RelPos (p);
3396 mapCenter->reposition();
3400 void MapEditor::deleteChilds()
3402 BranchObj *bo=xelection.getBranch();
3405 saveStateChangingPart(
3409 QString( "Remove childs of branch %1").arg(getName(bo))
3412 mapCenter->reposition();
3416 void MapEditor::editMapInfo()
3418 ExtraInfoDialog dia;
3419 dia.setMapName (getFileName() );
3420 dia.setAuthor (mapCenter->getAuthor() );
3421 dia.setComment(mapCenter->getComment() );
3425 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
3432 bo=mapCenter->first();
3435 if (!bo->getNote().isEmpty() ) n++;
3436 f+= bo->countFloatImages();
3438 xl+=bo->countXLinks();
3441 stats+=QString ("%1 branches\n").arg (b-1,6);
3442 stats+=QString ("%1 xLinks \n").arg (xl,6);
3443 stats+=QString ("%1 notes\n").arg (n,6);
3444 stats+=QString ("%1 images\n").arg (f,6);
3445 dia.setStats (stats);
3447 // Finally show dialog
3448 if (dia.exec() == QDialog::Accepted)
3450 setMapAuthor (dia.getAuthor() );
3451 setMapComment (dia.getComment() );
3455 void MapEditor::ensureSelectionVisible()
3457 LinkableMapObj *lmo=xelection.single();
3458 if (lmo) ensureVisible (lmo->getBBox() );
3462 void MapEditor::updateSelection()
3464 // Tell selection to update geometries
3468 void MapEditor::updateActions()
3470 // Tell mainwindow to update states of actions
3471 mainWindow->updateActions();
3472 // TODO maybe don't update if blockReposition is set
3475 void MapEditor::updateNoteFlag()
3478 BranchObj *bo=xelection.getBranch();
3481 bo->updateNoteFlag();
3482 mainWindow->updateActions();
3486 void MapEditor::setMapAuthor (const QString &s)
3490 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3492 QString ("setMapAuthor (\"%1\")").arg(s),
3493 QString ("Set author of map to \"%1\"").arg(s)
3495 mapCenter->setAuthor (s);
3498 void MapEditor::setMapComment (const QString &s)
3502 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3504 QString ("setMapComment (\"%1\")").arg(s),
3505 QString ("Set comment of map")
3507 mapCenter->setComment (s);
3510 void MapEditor::setMapLinkStyle (const QString & s)
3512 saveStateChangingPart (
3515 QString("setMapLinkStyle (\"%1\")").arg(s),
3516 QString("Set map link style (\"%1\")").arg(s)
3520 linkstyle=LinkableMapObj::Line;
3521 else if (s=="StyleParabel")
3522 linkstyle=LinkableMapObj::Parabel;
3523 else if (s=="StylePolyLine")
3524 linkstyle=LinkableMapObj::PolyLine;
3526 linkstyle=LinkableMapObj::PolyParabel;
3529 bo=mapCenter->first();
3533 bo->setLinkStyle(bo->getDefLinkStyle());
3536 mapCenter->reposition();
3539 LinkableMapObj::Style MapEditor::getMapLinkStyle ()
3544 void MapEditor::setMapDefLinkColor(QColor c)
3548 bo=mapCenter->first();
3557 void MapEditor::setMapLinkColorHintInt()
3559 // called from setMapLinkColorHint(lch) or at end of parse
3561 bo=mapCenter->first();
3569 void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
3572 setMapLinkColorHintInt();
3575 void MapEditor::toggleMapLinkColorHint()
3577 if (linkcolorhint==LinkableMapObj::HeadingColor)
3578 linkcolorhint=LinkableMapObj::DefaultColor;
3580 linkcolorhint=LinkableMapObj::HeadingColor;
3582 bo=mapCenter->first();
3590 LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
3592 return linkcolorhint;
3595 QColor MapEditor::getMapDefLinkColor()
3597 return defLinkColor;
3600 void MapEditor::setMapDefXLinkColor(QColor col)
3605 QColor MapEditor::getMapDefXLinkColor()
3607 return defXLinkColor;
3610 void MapEditor::setMapDefXLinkWidth (int w)
3615 int MapEditor::getMapDefXLinkWidth()
3617 return defXLinkWidth;
3620 void MapEditor::selectMapLinkColor()
3622 QColor col = QColorDialog::getColor( defLinkColor, this );
3623 if ( !col.isValid() ) return;
3626 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3628 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3629 QString("Set map link color to %1").arg(col.name())
3631 setMapDefLinkColor( col );
3634 void MapEditor::selectMapSelectionColor()
3636 QColor col = QColorDialog::getColor( defLinkColor, this );
3637 setSelectionColor (col);
3640 void MapEditor::setSelectionColorInt (QColor col)
3642 if ( !col.isValid() ) return;
3643 xelection.setColor (col);
3646 void MapEditor::setSelectionColor(QColor col)
3648 if ( !col.isValid() ) return;
3651 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3653 QString("setSelectionColor (%1)").arg(col.name()),
3654 QString("Set color of selection box to %1").arg(col.name())
3656 setSelectionColorInt (col);
3659 QColor MapEditor::getSelectionColor()
3661 return xelection.getColor();
3664 bool MapEditor::scrollBranch(BranchObj *bo)
3668 if (bo->isScrolled()) return false;
3669 if (bo->countBranches()==0) return false;
3670 if (bo->getDepth()==0) return false;
3676 QString ("%1 ()").arg(u),
3678 QString ("%1 ()").arg(r),
3679 QString ("%1 %2").arg(r).arg(getName(bo))
3689 bool MapEditor::unscrollBranch(BranchObj *bo)
3693 if (!bo->isScrolled()) return false;
3694 if (bo->countBranches()==0) return false;
3695 if (bo->getDepth()==0) return false;
3701 QString ("%1 ()").arg(u),
3703 QString ("%1 ()").arg(r),
3704 QString ("%1 %2").arg(r).arg(getName(bo))
3714 void MapEditor::toggleScroll()
3716 BranchObj *bo=xelection.getBranch();
3717 if (xelection.type()==Selection::Branch )
3719 if (bo->isScrolled())
3720 unscrollBranch (bo);
3726 void MapEditor::unscrollChilds()
3728 BranchObj *bo=xelection.getBranch();
3734 if (bo->isScrolled()) unscrollBranch (bo);
3740 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3742 BranchObj *bo=xelection.getBranch();
3746 bo->addFloatImage();
3747 fio=bo->getLastFloatImage();
3749 mapCenter->reposition();
3756 void MapEditor::loadFloatImage ()
3758 BranchObj *bo=xelection.getBranch();
3762 Q3FileDialog *fd=new Q3FileDialog( this);
3763 fd->setMode (Q3FileDialog::ExistingFiles);
3764 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3765 ImagePreview *p =new ImagePreview (fd);
3766 fd->setContentsPreviewEnabled( TRUE );
3767 fd->setContentsPreview( p, p );
3768 fd->setPreviewMode( Q3FileDialog::Contents );
3769 fd->setCaption(vymName+" - " +tr("Load image"));
3770 fd->setDir (lastImageDir);
3773 if ( fd->exec() == QDialog::Accepted )
3775 // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
3776 lastImageDir=QDir (fd->dirPath());
3779 for (int j=0; j<fd->selectedFiles().count(); j++)
3781 s=fd->selectedFiles().at(j);
3782 fio=loadFloatImageInt (s);
3785 (LinkableMapObj*)fio,
3788 QString ("loadImage (%1)").arg(s ),
3789 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3792 // TODO loadFIO error handling
3793 qWarning ("Failed to load "+s);
3801 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3803 fio->save (fn,type);
3806 void MapEditor::saveFloatImage ()
3808 FloatImageObj *fio=xelection.getFloatImage();
3811 QFileDialog *fd=new QFileDialog( this);
3812 fd->setFilters (imageIO.getFilters());
3813 fd->setCaption(vymName+" - " +tr("Save image"));
3814 fd->setFileMode( QFileDialog::AnyFile );
3815 fd->setDirectory (lastImageDir);
3816 // fd->setSelection (fio->getOriginalFilename());
3820 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3822 fn=fd->selectedFiles().at(0);
3823 if (QFile (fn).exists() )
3825 QMessageBox mb( vymName,
3826 tr("The file %1 exists already.\n"
3827 "Do you want to overwrite it?").arg(fn),
3828 QMessageBox::Warning,
3829 QMessageBox::Yes | QMessageBox::Default,
3830 QMessageBox::Cancel | QMessageBox::Escape,
3831 QMessageBox::QMessageBox::NoButton );
3833 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3834 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3837 case QMessageBox::Yes:
3840 case QMessageBox::Cancel:
3847 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3853 void MapEditor::setFrameType(const FrameObj::FrameType &t)
3855 BranchObj *bo=xelection.getBranch();
3858 QString s=bo->getFrameTypeName();
3859 bo->setFrameType (t);
3860 saveState (bo, QString("setFrameType (\"%1\")").arg(s),
3861 bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
3862 mapCenter->reposition();
3867 void MapEditor::setFrameType(const QString &s)
3869 BranchObj *bo=xelection.getBranch();
3872 saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
3873 bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
3874 bo->setFrameType (s);
3875 mapCenter->reposition();
3880 void MapEditor::setFramePenColor(const QColor &c)
3882 BranchObj *bo=xelection.getBranch();
3885 saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
3886 bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
3887 bo->setFramePenColor (c);
3891 void MapEditor::setFrameBrushColor(const QColor &c)
3893 BranchObj *bo=xelection.getBranch();
3896 saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
3897 bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
3898 bo->setFrameBrushColor (c);
3902 void MapEditor::setFramePadding (const int &i)
3904 BranchObj *bo=xelection.getBranch();
3907 saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
3908 bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
3909 bo->setFramePadding (i);
3910 mapCenter->reposition();
3915 void MapEditor::setFrameBorderWidth(const int &i)
3917 BranchObj *bo=xelection.getBranch();
3920 saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
3921 bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
3922 bo->setFrameBorderWidth (i);
3923 mapCenter->reposition();
3928 void MapEditor::setIncludeImagesVer(bool b)
3930 BranchObj *bo=xelection.getBranch();
3933 QString u= b ? "false" : "true";
3934 QString r=!b ? "false" : "true";
3938 QString("setIncludeImagesVertically (%1)").arg(u),
3940 QString("setIncludeImagesVertically (%1)").arg(r),
3941 QString("Include images vertically in %1").arg(getName(bo))
3943 bo->setIncludeImagesVer(b);
3944 mapCenter->reposition();
3948 void MapEditor::setIncludeImagesHor(bool b)
3950 BranchObj *bo=xelection.getBranch();
3953 QString u= b ? "false" : "true";
3954 QString r=!b ? "false" : "true";
3958 QString("setIncludeImagesHorizontally (%1)").arg(u),
3960 QString("setIncludeImagesHorizontally (%1)").arg(r),
3961 QString("Include images horizontally in %1").arg(getName(bo))
3963 bo->setIncludeImagesHor(b);
3964 mapCenter->reposition();
3968 void MapEditor::setHideLinkUnselected (bool b)
3970 LinkableMapObj *sel=xelection.single();
3972 (xelection.type() == Selection::Branch ||
3973 xelection.type() == Selection::MapCenter ||
3974 xelection.type() == Selection::FloatImage ))
3976 QString u= b ? "false" : "true";
3977 QString r=!b ? "false" : "true";
3981 QString("setHideLinkUnselected (%1)").arg(u),
3983 QString("setHideLinkUnselected (%1)").arg(r),
3984 QString("Hide link of %1 if unselected").arg(getName(sel))
3986 sel->setHideLinkUnselected(b);
3990 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3992 BranchObj *bo=xelection.getBranch();
3995 // Traverse directories
3996 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3997 QFileInfoList list = d.entryInfoList();
4000 for (int i = 0; i < list.size(); ++i)
4003 if (fi.fileName() != "." && fi.fileName() != ".." )
4006 bo=dst->getLastBranch();
4007 bo->setHeading (fi.fileName() );
4008 bo->setColor (QColor("blue"));
4010 if ( !d.cd(fi.fileName()) )
4011 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
4014 // Recursively add subdirs
4015 importDirInt (bo,d);
4021 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
4022 list = d.entryInfoList();
4024 for (int i = 0; i < list.size(); ++i)
4028 bo=dst->getLastBranch();
4029 bo->setHeading (fi.fileName() );
4030 bo->setColor (QColor("black"));
4031 if (fi.fileName().right(4) == ".vym" )
4032 bo->setVymLink (fi.filePath());
4037 void MapEditor::importDirInt (const QString &s)
4039 BranchObj *bo=xelection.getBranch();
4042 saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
4045 importDirInt (bo,d);
4049 void MapEditor::importDir()
4051 BranchObj *bo=xelection.getBranch();
4054 QStringList filters;
4055 filters <<"VYM map (*.vym)";
4056 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
4057 fd->setMode (QFileDialog::DirectoryOnly);
4058 fd->setFilters (filters);
4059 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
4063 if ( fd->exec() == QDialog::Accepted )
4065 importDirInt (fd->selectedFile() );
4066 mapCenter->reposition();
4072 void MapEditor::followXLink(int i)
4074 BranchObj *bo=xelection.getBranch();
4077 bo=bo->XLinkTargetAt(i);
4080 xelection.select(bo);
4081 ensureSelectionVisible();
4086 void MapEditor::editXLink(int i) // FIXME missing saveState
4088 BranchObj *bo=xelection.getBranch();
4091 XLinkObj *xlo=bo->XLinkAt(i);
4094 EditXLinkDialog dia;
4096 dia.setSelection(bo);
4097 if (dia.exec() == QDialog::Accepted)
4099 if (dia.useSettingsGlobal() )
4101 setMapDefXLinkColor (xlo->getColor() );
4102 setMapDefXLinkWidth (xlo->getWidth() );
4104 if (dia.deleteXLink())
4105 bo->deleteXLinkAt(i);
4111 void MapEditor::testFunction1()
4115 BranchObj *bo=xelection.getBranch();
4116 if (bo) animObjList.append( bo );
4121 dia.showCancelButton (true);
4122 dia.setText("This is a longer \nWarning");
4123 dia.setCaption("Warning: Flux problem");
4124 dia.setShowAgainName("mapeditor/testDialog");
4125 if (dia.exec()==QDialog::Accepted)
4126 cout << "accepted!\n";
4128 cout << "canceled!\n";
4132 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
4133 if (hidemode==HideNone)
4135 setHideTmpMode (HideExport);
4136 mapCenter->calcBBoxSizeWithChilds();
4137 QRectF totalBBox=mapCenter->getTotalBBox();
4138 QRectF mapRect=totalBBox;
4139 QCanvasRectangle *frame=NULL;
4141 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
4143 mapRect.setRect (totalBBox.x(), totalBBox.y(),
4144 totalBBox.width(), totalBBox.height());
4145 frame=new QCanvasRectangle (mapRect,mapScene);
4146 frame->setBrush (QColor(white));
4147 frame->setPen (QColor(black));
4148 frame->setZValue(0);
4153 setHideTmpMode (HideNone);
4155 cout <<" hidemode="<<hidemode<<endl;
4159 void MapEditor::testFunction2()
4163 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
4165 // Lineedits are already closed by preceding
4166 // mouseEvent, we don't need to close here.
4168 QPointF p = mapToScene(e->pos());
4169 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4172 { // MapObj was found
4173 if (xelection.single() != lmo)
4175 // select the MapObj
4176 xelection.select(lmo);
4179 if (xelection.getBranch() )
4181 // Context Menu on branch or mapcenter
4183 branchContextMenu->popup(e->globalPos() );
4186 if (xelection.getFloatImage() )
4188 // Context Menu on floatimage
4190 floatimageContextMenu->popup(e->globalPos() );
4194 { // No MapObj found, we are on the Canvas itself
4195 // Context Menu on scene
4197 canvasContextMenu->popup(e->globalPos() );
4202 void MapEditor::keyPressEvent(QKeyEvent* e)
4204 if (e->modifiers() & Qt::ControlModifier)
4206 switch (mainWindow->getModMode())
4208 case Main::ModModeColor:
4209 setCursor (PickColorCursor);
4211 case Main::ModModeCopy:
4212 setCursor (CopyCursor);
4214 case Main::ModModeXLink:
4215 setCursor (XLinkCursor);
4218 setCursor (Qt::ArrowCursor);
4224 void MapEditor::keyReleaseEvent(QKeyEvent* e)
4226 if (!(e->modifiers() & Qt::ControlModifier))
4227 setCursor (Qt::ArrowCursor);
4230 void MapEditor::mousePressEvent(QMouseEvent* e)
4232 // Ignore right clicks, these will go to context menus
4233 if (e->button() == Qt::RightButton )
4239 //Ignore clicks while editing heading
4240 if (isSelectBlocked() )
4246 QPointF p = mapToScene(e->pos());
4247 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4251 //Take care of system flags _or_ modifier modes
4253 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
4254 typeid(*lmo)==typeid(MapCenterObj) ))
4256 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
4257 if (!foname.isEmpty())
4259 // systemFlag clicked
4263 if (e->state() & Qt::ControlModifier)
4264 mainWindow->editOpenURLTab();
4266 mainWindow->editOpenURL();
4268 else if (foname=="vymLink")
4270 mainWindow->editOpenVymLink();
4271 // tabWidget may change, better return now
4272 // before segfaulting...
4273 } else if (foname=="note")
4274 mainWindow->windowToggleNoteEditor();
4275 else if (foname=="hideInExport")
4282 // No system flag clicked, take care of modmodes (CTRL-Click)
4283 if (e->state() & Qt::ControlModifier)
4285 if (mainWindow->getModMode()==Main::ModModeColor)
4288 setCursor (PickColorCursor);
4291 if (mainWindow->getModMode()==Main::ModModeXLink)
4293 BranchObj *bo_begin=NULL;
4295 bo_begin=(BranchObj*)(lmo);
4297 if (xelection.getBranch() )
4298 bo_begin=xelection.getBranch();
4302 linkingObj_src=bo_begin;
4303 tmpXLink=new XLinkObj (mapScene);
4304 tmpXLink->setBegin (bo_begin);
4305 tmpXLink->setEnd (p);
4306 tmpXLink->setColor(defXLinkColor);
4307 tmpXLink->setWidth(defXLinkWidth);
4308 tmpXLink->updateXLink();
4309 tmpXLink->setVisibility (true);
4313 } // End of modmodes
4317 // Select the clicked object
4320 // Left Button Move Branches
4321 if (e->button() == Qt::LeftButton )
4323 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
4324 //movingObj_start.setY( p.y() - selection->y() );
4325 movingObj_start.setX( p.x() - lmo->x() );
4326 movingObj_start.setY( p.y() - lmo->y() );
4327 movingObj_orgPos.setX (lmo->x() );
4328 movingObj_orgPos.setY (lmo->y() );
4329 movingObj_orgRelPos=lmo->getRelPos();
4331 // If modMode==copy, then we want to "move" the _new_ object around
4332 // then we need the offset from p to the _old_ selection, because of tmp
4333 if (mainWindow->getModMode()==Main::ModModeCopy &&
4334 e->state() & Qt::ControlModifier)
4336 if (xelection.type()==Selection::Branch)
4339 mapCenter->addBranch ((BranchObj*)xelection.single());
4341 xelection.select(mapCenter->getLastBranch());
4342 mapCenter->reposition();
4346 movingObj=xelection.single();
4348 // Middle Button Toggle Scroll
4349 // (On Mac OS X this won't work, but we still have
4350 // a button in the toolbar)
4351 if (e->button() == Qt::MidButton )
4356 { // No MapObj found, we are on the scene itself
4357 // Left Button move Pos of sceneView
4358 if (e->button() == Qt::LeftButton )
4360 movingObj=NULL; // move Content not Obj
4361 movingObj_start=e->globalPos();
4362 movingCont_start=QPointF (
4363 horizontalScrollBar()->value(),
4364 verticalScrollBar()->value());
4365 movingVec=QPointF(0,0);
4366 setCursor(HandOpenCursor);
4371 void MapEditor::mouseMoveEvent(QMouseEvent* e)
4373 QPointF p = mapToScene(e->pos());
4374 LinkableMapObj *lmosel=xelection.single();
4376 // Move the selected MapObj
4377 if ( lmosel && movingObj)
4379 // reset cursor if we are moving and don't copy
4380 if (mainWindow->getModMode()!=Main::ModModeCopy)
4381 setCursor (Qt::ArrowCursor);
4383 // To avoid jumping of the sceneView, only
4384 // ensureSelectionVisible, if not tmp linked
4385 if (!lmosel->hasParObjTmp())
4386 ensureSelectionVisible ();
4388 // Now move the selection, but add relative position
4389 // (movingObj_start) where selection was chosen with
4390 // mousepointer. (This avoids flickering resp. jumping
4391 // of selection back to absPos)
4393 // Check if we could link
4394 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
4397 FloatObj *fio=xelection.getFloatImage();
4400 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4402 fio->updateLink(); //no need for reposition, if we update link here
4405 // Relink float to new mapcenter or branch, if shift is pressed
4406 // Only relink, if selection really has a new parent
4407 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
4408 ( (typeid(*lmo)==typeid(BranchObj)) ||
4409 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
4410 ( lmo != fio->getParObj())
4413 if (typeid(*fio) == typeid(FloatImageObj) &&
4414 ( (typeid(*lmo)==typeid(BranchObj) ||
4415 typeid(*lmo)==typeid(MapCenterObj)) ))
4418 // Also save the move which was done so far
4419 QString pold=qpointfToString(movingObj_orgRelPos);
4420 QString pnow=qpointfToString(fio->getRelPos());
4426 QString("Move %1 to relativ position %2").arg(getName(fio)).arg(pnow));
4427 fio->getParObj()->requestReposition();
4428 mapCenter->reposition();
4430 linkTo (lmo->getSelectString());
4432 //movingObj_orgRelPos=lmosel->getRelPos();
4434 mapCenter->reposition();
4438 { // selection != a FloatObj
4439 if (lmosel->getDepth()==0)
4442 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
4443 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4445 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4446 mapCenter->updateRelPositions();
4449 if (lmosel->getDepth()==1)
4452 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4453 lmosel->setRelPos();
4456 // Move ordinary branch
4457 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
4458 // Add width of bbox here, otherwise alignRelTo will cause jumping around
4459 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
4460 p.y()-movingObj_start.y() +lmosel->getTopPad() );
4462 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
4465 // Maybe we can relink temporary?
4466 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
4467 (typeid(*lmo)==typeid(BranchObj) ||
4468 typeid(*lmo)==typeid(MapCenterObj)) )
4471 if (e->modifiers()==Qt::ControlModifier)
4473 // Special case: CTRL to link below lmo
4474 lmosel->setParObjTmp (lmo,p,+1);
4476 else if (e->modifiers()==Qt::ShiftModifier)
4477 lmosel->setParObjTmp (lmo,p,-1);
4479 lmosel->setParObjTmp (lmo,p,0);
4482 lmosel->unsetParObjTmp();
4484 // reposition subbranch
4485 lmosel->reposition();
4489 } // no FloatImageObj
4493 } // selection && moving_obj
4495 // Draw a link from one branch to another
4498 tmpXLink->setEnd (p);
4499 tmpXLink->updateXLink();
4503 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
4505 QPointF p=e->globalPos();
4506 movingVec.setX(-p.x() + movingObj_start.x() );
4507 movingVec.setY(-p.y() + movingObj_start.y() );
4508 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
4509 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
4514 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
4516 QPointF p = mapToScene(e->pos());
4517 LinkableMapObj *dst;
4518 LinkableMapObj *lmosel=xelection.single();
4519 // Have we been picking color?
4523 setCursor (Qt::ArrowCursor);
4524 // Check if we are over another branch
4525 dst=mapCenter->findMapObj(p, NULL);
4528 if (e->state() & Qt::ShiftModifier)
4529 colorBranch (((BranchObj*)(dst))->getColor());
4531 colorSubtree (((BranchObj*)(dst))->getColor());
4536 // Have we been drawing a link?
4540 // Check if we are over another branch
4541 dst=mapCenter->findMapObj(p, NULL);
4544 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
4545 tmpXLink->updateXLink();
4546 tmpXLink->activate(); //FIXME savestate missing
4547 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );
4556 // Have we been moving something?
4557 if ( lmosel && movingObj )
4559 FloatImageObj *fo=xelection.getFloatImage();
4562 // Moved FloatObj. Maybe we need to reposition
4563 QString pold=qpointfToString(movingObj_orgRelPos);
4564 QString pnow=qpointfToString(fo->getRelPos());
4570 QString("Move %1 to relativ position %2").arg(getName(fo)).arg(pnow));
4572 fo->getParObj()->requestReposition();
4573 mapCenter->reposition();
4576 // Check if we are over another branch, but ignore
4577 // any found LMOs, which are FloatObjs
4578 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
4580 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4583 if (xelection.type() == Selection::MapCenter )
4585 // TODO: Check for problems if graphicsview is resized for
4587 QString pold=qpointfToString(movingObj_orgPos);
4588 QString pnow=qpointfToString(mapCenter->getAbsPos());
4594 QString("Move mapcenter %1 to position %2").arg(getName(mapCenter)).arg(pnow));
4597 if (xelection.type() == Selection::Branch )
4598 { // A branch was moved
4600 // save the position in case we link to mapcenter
4601 QPointF savePos=QPointF (lmosel->getAbsPos() );
4603 // Reset the temporary drawn link to the original one
4604 lmosel->unsetParObjTmp();
4606 // For Redo we may need to save original selection
4607 QString preSelStr=lmosel->getSelectString();
4612 BranchObj* bsel=xelection.getBranch();
4613 BranchObj* bdst=(BranchObj*)dst;
4615 QString preParStr=(bsel->getParObj())->getSelectString();
4616 QString preNum=QString::number (bsel->getNum(),10);
4617 QString preDstParStr;
4619 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4621 preDstParStr=dst->getParObj()->getSelectString();
4622 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4624 if (e->state() & Qt::ControlModifier && dst->getParObj())
4627 preDstParStr=dst->getParObj()->getSelectString();
4628 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4631 preDstParStr=dst->getSelectString();
4632 bsel->linkTo (bdst,-1);
4633 if (dst->getDepth()==0) bsel->move (savePos);
4635 QString postSelStr=lmosel->getSelectString();
4636 QString postNum=QString::number (bsel->getNum(),10);
4638 QString undoCom="linkTo (\""+
4639 preParStr+ "\"," + preNum +"," +
4640 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4642 QString redoCom="linkTo (\""+
4643 preDstParStr + "\"," + postNum + "," +
4644 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4649 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4651 if (lmosel->getDepth()==1)
4653 // The select string might be different _after_ moving around.
4654 // Therefor reposition and then use string of old selection, too
4655 mapCenter->reposition();
4657 QString ps=qpointfToString ( lmosel->getRelPos() );
4659 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4660 preSelStr, "moveRel "+ps,
4661 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4664 // Draw the original link, before selection was moved around
4665 mapCenter->reposition();
4668 // Finally resize scene, if needed
4672 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4675 // maybe we moved View: set old cursor
4676 setCursor (Qt::ArrowCursor);
4680 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4682 if (isSelectBlocked() )
4688 if (e->button() == Qt::LeftButton )
4690 QPointF p = mapToScene(e->pos());
4691 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4692 if (lmo) { // MapObj was found
4693 // First select the MapObj than edit heading
4694 xelection.select(lmo);
4695 mainWindow->editHeading();
4700 void MapEditor::resizeEvent (QResizeEvent* e)
4702 QGraphicsView::resizeEvent( e );
4705 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4707 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4708 // cerr << event->format(i) << endl;
4710 if (event->mimeData()->hasImage())
4711 event->acceptProposedAction();
4713 if (event->mimeData()->hasUrls())
4714 event->acceptProposedAction();
4717 void MapEditor::dragMoveEvent(QDragMoveEvent *)
4721 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4726 void MapEditor::dropEvent(QDropEvent *event)
4728 BranchObj *sel=xelection.getBranch();
4732 foreach (QString format,event->mimeData()->formats())
4733 cout << "MapEditor: Dropped format: "<<format.ascii()<<endl;
4737 if (event->mimeData()->hasImage())
4739 QVariant imageData = event->mimeData()->imageData();
4740 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4742 if (event->mimeData()->hasUrls())
4743 uris=event->mimeData()->urls();
4751 for (int i=0; i<uris.count();i++)
4753 // Workaround to avoid adding empty branches
4754 if (!uris.at(i).toString().isEmpty())
4756 bo=sel->addBranch();
4759 s=uris.at(i).toLocalFile();
4762 QString file = QDir::convertSeparators(s);
4763 heading = QFileInfo(file).baseName();
4765 if (file.endsWith(".vym", false))
4766 bo->setVymLink(file);
4768 bo->setURL(uris.at(i).toString());
4771 bo->setURL(uris.at(i).toString());
4774 if (!heading.isEmpty())
4775 bo->setHeading(heading);
4777 bo->setHeading(uris.at(i).toString());
4781 mapCenter->reposition();
4784 event->acceptProposedAction();
4787 void MapEditor::timerEvent(QTimerEvent *event) //TODO animation
4791 cout << "ME::timerEvent\n";
4793 for (int i=0; i<animObjList.size(); ++i)
4795 animObjList.at(i)->animate();
4796 ((BranchObj*)animObjList.at(i))->move2RelPos (((BranchObj*)animObjList.at(i))->getRelPos() );
4798 mapCenter->reposition();
4802 void MapEditor::sendSelection()
4804 if (netstate!=Server) return;
4805 sendData (QString("select (\"%1\")").arg(xelection.getSelectString()) );
4808 void MapEditor::newServer()
4812 tcpServer = new QTcpServer(this);
4813 if (!tcpServer->listen(QHostAddress::Any,port)) {
4814 QMessageBox::critical(this, "vym server",
4815 QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
4819 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
4821 cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
4824 void MapEditor::connectToServer()
4827 server="salam.suse.de";
4829 clientSocket = new QTcpSocket (this);
4830 clientSocket->abort();
4831 clientSocket->connectToHost(server ,port);
4832 connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
4833 connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
4834 this, SLOT(displayNetworkError(QAbstractSocket::SocketError)));
4836 cout<<"connected to "<<server.ascii()<<" port "<<port<<endl;
4841 void MapEditor::newClient()
4843 QTcpSocket *newClient = tcpServer->nextPendingConnection();
4844 connect(newClient, SIGNAL(disconnected()),
4845 newClient, SLOT(deleteLater()));
4847 cout <<"ME::newClient at "<<newClient->peerAddress().toString().ascii()<<endl;
4849 clientList.append (newClient);
4853 void MapEditor::sendData(const QString &s)
4855 if (clientList.size()==0) return;
4857 // Create bytearray to send
4859 QDataStream out(&block, QIODevice::WriteOnly);
4860 out.setVersion(QDataStream::Qt_4_0);
4862 // Reserve some space for blocksize
4865 // Write sendCounter
4866 out << sendCounter++;
4871 // Go back and write blocksize so far
4872 out.device()->seek(0);
4873 quint16 bs=(quint16)(block.size() - 2*sizeof(quint16));
4877 cout << "ME::sendData bs="<<bs<<" counter="<<sendCounter<<" s="<<s.ascii()<<endl;
4879 for (int i=0; i<clientList.size(); ++i)
4881 //cout << "Sending \""<<s.ascii()<<"\" to "<<clientList.at(i)->peerAddress().toString().ascii()<<endl;
4882 clientList.at(i)->write (block);
4886 void MapEditor::readData ()
4888 while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) )
4891 cout <<"readData bytesAvail="<<clientSocket->bytesAvailable();
4895 QDataStream in(clientSocket);
4896 in.setVersion(QDataStream::Qt_4_0);
4904 cout << " t="<<t.ascii()<<endl;
4910 void MapEditor::displayNetworkError(QAbstractSocket::SocketError socketError)
4912 switch (socketError) {
4913 case QAbstractSocket::RemoteHostClosedError:
4915 case QAbstractSocket::HostNotFoundError:
4916 QMessageBox::information(this, __VYM_NAME " Network client",
4917 "The host was not found. Please check the "
4918 "host name and port settings.");
4920 case QAbstractSocket::ConnectionRefusedError:
4921 QMessageBox::information(this, __VYM_NAME " Network client",
4922 "The connection was refused by the peer. "
4923 "Make sure the fortune server is running, "
4924 "and check that the host name and port "
4925 "settings are correct.");
4928 QMessageBox::information(this, __VYM_NAME " Network client",
4929 QString("The following error occurred: %1.")
4930 .arg(clientSocket->errorString()));
4934 void MapEditor::autosave()
4936 // Disable autosave, while we have gone back in history
4937 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
4938 if (redosAvail>0) return;
4941 if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() )
4942 mainWindow->fileSave (this);
4946 /*TODO not needed? void MapEditor::contentsDropEvent(QDropEvent *event)
4949 } else if (event->provides("application/x-moz-file-promise-url") &&
4950 event->provides("application/x-moz-nativeimage"))
4952 // Contains url to the img src in unicode16
4953 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4954 QString url = QString((const QChar*)d.data(),d.size()/2);
4958 } else if (event->provides ("text/uri-list"))
4959 { // Uris provided e.g. by konqueror
4960 Q3UriDrag::decode (event,uris);
4961 } else if (event->provides ("_NETSCAPE_URL"))
4962 { // Uris provided by Mozilla
4963 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4966 } else if (event->provides("text/html")) {
4968 // Handels text mime types
4969 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4970 QByteArray d = event->encodedData("text/html");
4973 text = QString((const QChar*)d.data(),d.size()/2);
4977 textEditor->setText(text);
4981 } else if (event->provides("text/plain")) {
4982 QByteArray d = event->encodedData("text/plain");
4985 text = QString((const QChar*)d.data(),d.size()/2);
4989 textEditor->setText(text);
4999 bool isUnicode16(const QByteArray &d)
5001 // TODO: make more precise check for unicode 16.
5002 // Guess unicode16 if any of second bytes are zero
5003 unsigned int length = max(0,d.size()-2)/2;
5004 for (unsigned int i = 0; i<length ; i++)
5005 if (d.at(i*2+1)==0) return true;
5009 void MapEditor::addFloatImageInt (const QPixmap &img)
5011 BranchObj *bo=xelection.getBranch();
5014 FloatImageObj *fio=bo->addFloatImage();
5016 fio->setOriginalFilename("No original filename (image added by dropevent)");
5017 QString s=bo->getSelectString();
5018 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio );
5019 saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image");
5020 mapCenter->reposition();
5027 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
5029 if (!imageBuffer) imageBuffer = new QBuffer();
5030 if (!imageBuffer->isOpen()) {
5031 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
5033 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
5037 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
5039 if (nop->state()==Q3NetworkProtocol::StDone) {
5040 QPixmap img(imageBuffer->buffer());
5041 addFloatImageInt (img);
5045 imageBuffer->close();
5047 imageBuffer->close();
5054 void MapEditor::fetchImage(const QString &url)
5057 urlOperator->stop();
5058 disconnect(urlOperator);
5062 urlOperator = new Q3UrlOperator(url);
5063 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
5064 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
5066 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
5067 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));