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();
488 // Split string s into command and parameters
489 parser.parseAtom (atom);
490 QString com=parser.getCommand();
493 /////////////////////////////////////////////////////////////////////
494 if (com=="addBranch")
496 if (xelection.isEmpty())
498 parser.setError (Aborted,"Nothing selected");
501 parser.setError (Aborted,"Type of selection is not a branch");
506 if (parser.checkParCount(pl))
508 if (parser.parCount()==0)
509 addNewBranchInt (-2);
512 y=parser.parInt (ok,0);
513 if (ok ) addNewBranchInt (y);
517 /////////////////////////////////////////////////////////////////////
518 } else if (com=="addBranchBefore")
520 if (xelection.isEmpty())
522 parser.setError (Aborted,"Nothing selected");
525 parser.setError (Aborted,"Type of selection is not a branch");
528 if (parser.parCount()==0)
530 addNewBranchBefore ();
533 /////////////////////////////////////////////////////////////////////
534 } else if (com==QString("addMapReplace"))
536 if (xelection.isEmpty())
538 parser.setError (Aborted,"Nothing selected");
541 parser.setError (Aborted,"Type of selection is not a branch");
542 } else if (parser.checkParCount(1))
544 //s=parser.parString (ok,0); // selection
545 t=parser.parString (ok,0); // path to map
546 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
547 addMapReplaceInt(selb->getSelectString(),t);
549 /////////////////////////////////////////////////////////////////////
550 } else if (com==QString("addMapInsert"))
552 if (xelection.isEmpty())
554 parser.setError (Aborted,"Nothing selected");
557 parser.setError (Aborted,"Type of selection is not a branch");
560 if (parser.checkParCount(2))
562 t=parser.parString (ok,0); // path to map
563 y=parser.parInt(ok,1); // position
564 if (QDir::isRelativePath(t)) t=QDir::convertSeparators (tmpMapDir + "/"+t);
565 addMapInsertInt(t,y);
568 /////////////////////////////////////////////////////////////////////
569 } else if (com=="clearFlags")
571 if (xelection.isEmpty() )
573 parser.setError (Aborted,"Nothing selected");
576 parser.setError (Aborted,"Type of selection is not a branch");
577 } else if (parser.checkParCount(0))
579 selb->clearStandardFlags();
580 selb->updateFlagsToolbar();
582 /////////////////////////////////////////////////////////////////////
583 } else if (com=="colorBranch")
585 if (xelection.isEmpty())
587 parser.setError (Aborted,"Nothing selected");
590 parser.setError (Aborted,"Type of selection is not a branch");
591 } else if (parser.checkParCount(1))
593 QColor c=parser.parColor (ok,0);
594 if (ok) colorBranch (c);
596 /////////////////////////////////////////////////////////////////////
597 } else if (com=="colorSubtree")
599 if (xelection.isEmpty())
601 parser.setError (Aborted,"Nothing selected");
604 parser.setError (Aborted,"Type of selection is not a branch");
605 } else if (parser.checkParCount(1))
607 QColor c=parser.parColor (ok,0);
608 if (ok) colorSubtree (c);
610 /////////////////////////////////////////////////////////////////////
611 } else if (com=="copy")
613 if (xelection.isEmpty())
615 parser.setError (Aborted,"Nothing selected");
618 parser.setError (Aborted,"Type of selection is not a branch");
619 } else if (parser.checkParCount(0))
621 //FIXME missing action for copy
623 /////////////////////////////////////////////////////////////////////
624 } else if (com=="cut")
626 if (xelection.isEmpty())
628 parser.setError (Aborted,"Nothing selected");
629 } else if ( xelection.type()!=Selection::Branch &&
630 xelection.type()!=Selection::MapCenter &&
631 xelection.type()!=Selection::FloatImage )
633 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
634 } else if (parser.checkParCount(0))
638 /////////////////////////////////////////////////////////////////////
639 } else if (com=="delete")
641 if (xelection.isEmpty())
643 parser.setError (Aborted,"Nothing selected");
644 } else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage )
646 parser.setError (Aborted,"Type of selection is wrong.");
647 } else if (parser.checkParCount(0))
651 /////////////////////////////////////////////////////////////////////
652 } else if (com=="deleteKeepChilds")
654 if (xelection.isEmpty())
656 parser.setError (Aborted,"Nothing selected");
659 parser.setError (Aborted,"Type of selection is not a branch");
660 } else if (parser.checkParCount(0))
664 /////////////////////////////////////////////////////////////////////
665 } else if (com=="deleteChilds")
667 if (xelection.isEmpty())
669 parser.setError (Aborted,"Nothing selected");
672 parser.setError (Aborted,"Type of selection is not a branch");
673 } else if (parser.checkParCount(0))
677 /////////////////////////////////////////////////////////////////////
678 } else if (com=="exportASCII")
682 if (parser.parCount()>=2)
683 // Hey, we even have a filename
684 fname=parser.parString(ok,1);
687 parser.setError (Aborted,"Could not read filename");
690 exportASCII (fname,false);
692 /////////////////////////////////////////////////////////////////////
693 } else if (com=="exportImage")
697 if (parser.parCount()>=2)
698 // Hey, we even have a filename
699 fname=parser.parString(ok,1);
702 parser.setError (Aborted,"Could not read filename");
705 QString format="PNG";
706 if (parser.parCount()>2)
708 format=parser.parString(ok,2);
710 exportImage (fname,false,format);
712 /////////////////////////////////////////////////////////////////////
713 } else if (com=="exportXHTML")
717 if (parser.parCount()>=2)
718 // Hey, we even have a filename
719 fname=parser.parString(ok,1);
722 parser.setError (Aborted,"Could not read filename");
725 exportXHTML (fname,false);
727 /////////////////////////////////////////////////////////////////////
728 } else if (com=="exportXML")
732 if (parser.parCount()>=2)
733 // Hey, we even have a filename
734 fname=parser.parString(ok,1);
737 parser.setError (Aborted,"Could not read filename");
740 exportXML (fname,false);
742 /////////////////////////////////////////////////////////////////////
743 } else if (com=="importDir")
745 if (xelection.isEmpty())
747 parser.setError (Aborted,"Nothing selected");
750 parser.setError (Aborted,"Type of selection is not a branch");
751 } else if (parser.checkParCount(1))
753 s=parser.parString(ok,0);
754 if (ok) importDirInt(s);
756 /////////////////////////////////////////////////////////////////////
757 } else if (com=="linkTo")
759 if (xelection.isEmpty())
761 parser.setError (Aborted,"Nothing selected");
764 if (parser.checkParCount(4))
766 // 0 selectstring of parent
767 // 1 num in parent (for branches)
768 // 2,3 x,y of mainbranch or mapcenter
769 s=parser.parString(ok,0);
770 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
773 if (typeid(*dst) == typeid(BranchObj) )
775 // Get number in parent
776 x=parser.parInt (ok,1);
778 selb->linkTo ((BranchObj*)(dst),x);
779 } else if (typeid(*dst) == typeid(MapCenterObj) )
781 selb->linkTo ((BranchObj*)(dst),-1);
782 // Get coordinates of mainbranch
783 x=parser.parInt (ok,2);
786 y=parser.parInt (ok,3);
787 if (ok) selb->move (x,y);
792 } else if ( xelection.type() == Selection::FloatImage)
794 if (parser.checkParCount(1))
796 // 0 selectstring of parent
797 s=parser.parString(ok,0);
798 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
801 if (typeid(*dst) == typeid(BranchObj) ||
802 typeid(*dst) == typeid(MapCenterObj))
803 linkTo (dst->getSelectString());
805 parser.setError (Aborted,"Destination is not a branch");
808 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
809 /////////////////////////////////////////////////////////////////////
810 } else if (com=="loadImage")
812 if (xelection.isEmpty())
814 parser.setError (Aborted,"Nothing selected");
817 parser.setError (Aborted,"Type of selection is not a branch");
818 } else if (parser.checkParCount(1))
820 s=parser.parString(ok,0);
821 if (ok) loadFloatImageInt (s);
823 /////////////////////////////////////////////////////////////////////
824 } else if (com=="moveBranchUp")
826 if (xelection.isEmpty() )
828 parser.setError (Aborted,"Nothing selected");
831 parser.setError (Aborted,"Type of selection is not a branch");
832 } else if (parser.checkParCount(0))
836 /////////////////////////////////////////////////////////////////////
837 } else if (com=="moveBranchDown")
839 if (xelection.isEmpty() )
841 parser.setError (Aborted,"Nothing selected");
844 parser.setError (Aborted,"Type of selection is not a branch");
845 } else if (parser.checkParCount(0))
849 /////////////////////////////////////////////////////////////////////
850 } else if (com=="move")
852 if (xelection.isEmpty() )
854 parser.setError (Aborted,"Nothing selected");
855 } else if ( xelection.type()!=Selection::Branch &&
856 xelection.type()!=Selection::MapCenter &&
857 xelection.type()!=Selection::FloatImage )
859 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
860 } else if (parser.checkParCount(2))
862 x=parser.parInt (ok,0);
865 y=parser.parInt (ok,1);
869 /////////////////////////////////////////////////////////////////////
870 } else if (com=="moveRel")
872 if (xelection.isEmpty() )
874 parser.setError (Aborted,"Nothing selected");
875 } else if ( xelection.type()!=Selection::Selection::Branch &&
876 xelection.type()!=Selection::Selection::MapCenter &&
877 xelection.type()!=Selection::Selection::FloatImage )
879 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
880 } else if (parser.checkParCount(2))
882 x=parser.parInt (ok,0);
885 y=parser.parInt (ok,1);
886 if (ok) moveRel (x,y);
889 /////////////////////////////////////////////////////////////////////
890 } else if (com=="nop")
892 /////////////////////////////////////////////////////////////////////
893 } else if (com=="paste")
895 if (xelection.isEmpty() )
897 parser.setError (Aborted,"Nothing selected");
900 parser.setError (Aborted,"Type of selection is not a branch");
901 } else if (parser.checkParCount(1))
903 x=parser.parInt (ok,0);
904 if (ok) pasteNoSave(x);
906 /////////////////////////////////////////////////////////////////////
907 } else if (com=="qa")
909 if (xelection.isEmpty() )
911 parser.setError (Aborted,"Nothing selected");
914 parser.setError (Aborted,"Type of selection is not a branch");
915 } else if (parser.checkParCount(4))
918 c=parser.parString (ok,0);
921 parser.setError (Aborted,"No comment given");
924 s=parser.parString (ok,1);
927 parser.setError (Aborted,"First parameter is not a string");
930 t=parser.parString (ok,2);
933 parser.setError (Aborted,"Condition is not a string");
936 u=parser.parString (ok,3);
939 parser.setError (Aborted,"Third parameter is not a string");
944 parser.setError (Aborted,"Unknown type: "+s);
949 parser.setError (Aborted,"Unknown operator: "+t);
954 parser.setError (Aborted,"Type of selection is not a branch");
957 if (selb->getHeading() == u)
959 cout << "PASSED: " << c.ascii() << endl;
962 cout << "FAILED: " << c.ascii() << endl;
972 /////////////////////////////////////////////////////////////////////
973 } else if (com=="saveImage")
975 FloatImageObj *fio=xelection.getFloatImage();
978 parser.setError (Aborted,"Type of selection is not an image");
979 } else if (parser.checkParCount(2))
981 s=parser.parString(ok,0);
984 t=parser.parString(ok,1);
985 if (ok) saveFloatImageInt (fio,t,s);
988 /////////////////////////////////////////////////////////////////////
989 } else if (com=="scroll")
991 if (xelection.isEmpty() )
993 parser.setError (Aborted,"Nothing selected");
996 parser.setError (Aborted,"Type of selection is not a branch");
997 } else if (parser.checkParCount(0))
999 if (!scrollBranch (selb))
1000 parser.setError (Aborted,"Could not scroll branch");
1002 /////////////////////////////////////////////////////////////////////
1003 } else if (com=="select")
1005 if (parser.checkParCount(1))
1007 s=parser.parString(ok,0);
1010 /////////////////////////////////////////////////////////////////////
1011 } else if (com=="selectLastBranch")
1013 if (xelection.isEmpty() )
1015 parser.setError (Aborted,"Nothing selected");
1018 parser.setError (Aborted,"Type of selection is not a branch");
1019 } else if (parser.checkParCount(0))
1021 BranchObj *bo=selb->getLastBranch();
1023 parser.setError (Aborted,"Could not select last branch");
1027 /////////////////////////////////////////////////////////////////////
1028 } else if (com=="selectLastImage")
1030 if (xelection.isEmpty() )
1032 parser.setError (Aborted,"Nothing selected");
1035 parser.setError (Aborted,"Type of selection is not a branch");
1036 } else if (parser.checkParCount(0))
1038 FloatImageObj *fio=selb->getLastFloatImage();
1040 parser.setError (Aborted,"Could not select last image");
1044 /////////////////////////////////////////////////////////////////////
1045 } else if (com=="setFrameType")
1047 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1049 parser.setError (Aborted,"Type of selection does not allow setting frame type");
1051 else if (parser.checkParCount(1))
1053 s=parser.parString(ok,0);
1054 if (ok) setFrameType (s);
1056 /////////////////////////////////////////////////////////////////////
1057 } else if (com=="setFramePenColor")
1059 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1061 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
1063 else if (parser.checkParCount(1))
1065 QColor c=parser.parColor(ok,0);
1066 if (ok) setFramePenColor (c);
1068 /////////////////////////////////////////////////////////////////////
1069 } else if (com=="setFrameBrushColor")
1071 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1073 parser.setError (Aborted,"Type of selection does not allow setting brush color");
1075 else if (parser.checkParCount(1))
1077 QColor c=parser.parColor(ok,0);
1078 if (ok) setFrameBrushColor (c);
1080 /////////////////////////////////////////////////////////////////////
1081 } else if (com=="setFramePadding")
1083 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1085 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
1087 else if (parser.checkParCount(1))
1089 x=parser.parInt(ok,0);
1090 if (ok) setFramePadding(x);
1092 /////////////////////////////////////////////////////////////////////
1093 } else if (com=="setFrameBorderWidth")
1095 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1097 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
1099 else if (parser.checkParCount(1))
1101 x=parser.parInt(ok,0);
1102 if (ok) setFrameBorderWidth (x);
1104 /////////////////////////////////////////////////////////////////////
1105 } else if (com=="setMapAuthor")
1107 if (parser.checkParCount(1))
1109 s=parser.parString(ok,0);
1110 if (ok) setMapAuthor (s);
1112 /////////////////////////////////////////////////////////////////////
1113 } else if (com=="setMapComment")
1115 if (parser.checkParCount(1))
1117 s=parser.parString(ok,0);
1118 if (ok) setMapComment(s);
1120 /////////////////////////////////////////////////////////////////////
1121 } else if (com=="setMapBackgroundColor")
1123 if (xelection.isEmpty() )
1125 parser.setError (Aborted,"Nothing selected");
1126 } else if (! xelection.getBranch() )
1128 parser.setError (Aborted,"Type of selection is not a branch");
1129 } else if (parser.checkParCount(1))
1131 QColor c=parser.parColor (ok,0);
1132 if (ok) setMapBackgroundColor (c);
1134 /////////////////////////////////////////////////////////////////////
1135 } else if (com=="setMapDefLinkColor")
1137 if (xelection.isEmpty() )
1139 parser.setError (Aborted,"Nothing selected");
1142 parser.setError (Aborted,"Type of selection is not a branch");
1143 } else if (parser.checkParCount(1))
1145 QColor c=parser.parColor (ok,0);
1146 if (ok) setMapDefLinkColor (c);
1148 /////////////////////////////////////////////////////////////////////
1149 } else if (com=="setMapLinkStyle")
1151 if (parser.checkParCount(1))
1153 s=parser.parString (ok,0);
1154 if (ok) setMapLinkStyle(s);
1156 /////////////////////////////////////////////////////////////////////
1157 } else if (com=="setHeading")
1159 if (xelection.isEmpty() )
1161 parser.setError (Aborted,"Nothing selected");
1164 parser.setError (Aborted,"Type of selection is not a branch");
1165 } else if (parser.checkParCount(1))
1167 s=parser.parString (ok,0);
1171 /////////////////////////////////////////////////////////////////////
1172 } else if (com=="setHideExport")
1174 if (xelection.isEmpty() )
1176 parser.setError (Aborted,"Nothing selected");
1177 } else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage)
1179 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1180 } else if (parser.checkParCount(1))
1182 b=parser.parBool(ok,0);
1183 if (ok) setHideExport (b);
1185 /////////////////////////////////////////////////////////////////////
1186 } else if (com=="setIncludeImagesHorizontally")
1188 if (xelection.isEmpty() )
1190 parser.setError (Aborted,"Nothing selected");
1193 parser.setError (Aborted,"Type of selection is not a branch");
1194 } else if (parser.checkParCount(1))
1196 b=parser.parBool(ok,0);
1197 if (ok) setIncludeImagesHor(b);
1199 /////////////////////////////////////////////////////////////////////
1200 } else if (com=="setIncludeImagesVertically")
1202 if (xelection.isEmpty() )
1204 parser.setError (Aborted,"Nothing selected");
1207 parser.setError (Aborted,"Type of selection is not a branch");
1208 } else if (parser.checkParCount(1))
1210 b=parser.parBool(ok,0);
1211 if (ok) setIncludeImagesVer(b);
1213 /////////////////////////////////////////////////////////////////////
1214 } else if (com=="setHideLinkUnselected")
1216 if (xelection.isEmpty() )
1218 parser.setError (Aborted,"Nothing selected");
1219 } else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1221 parser.setError (Aborted,"Type of selection does not allow hiding the link");
1222 } else if (parser.checkParCount(1))
1224 b=parser.parBool(ok,0);
1225 if (ok) setHideLinkUnselected(b);
1227 /////////////////////////////////////////////////////////////////////
1228 } else if (com=="setSelectionColor")
1230 if (parser.checkParCount(1))
1232 QColor c=parser.parColor (ok,0);
1233 if (ok) setSelectionColorInt (c);
1235 /////////////////////////////////////////////////////////////////////
1236 } else if (com=="setURL")
1238 if (xelection.isEmpty() )
1240 parser.setError (Aborted,"Nothing selected");
1243 parser.setError (Aborted,"Type of selection is not a branch");
1244 } else if (parser.checkParCount(1))
1246 s=parser.parString (ok,0);
1249 /////////////////////////////////////////////////////////////////////
1250 } else if (com=="setVymLink")
1252 if (xelection.isEmpty() )
1254 parser.setError (Aborted,"Nothing selected");
1257 parser.setError (Aborted,"Type of selection is not a branch");
1258 } else if (parser.checkParCount(1))
1260 s=parser.parString (ok,0);
1261 if (ok) setVymLinkInt(s);
1264 /////////////////////////////////////////////////////////////////////
1265 else if (com=="setFlag")
1267 if (xelection.isEmpty() )
1269 parser.setError (Aborted,"Nothing selected");
1272 parser.setError (Aborted,"Type of selection is not a branch");
1273 } else if (parser.checkParCount(1))
1275 s=parser.parString(ok,0);
1278 selb->activateStandardFlag(s);
1279 selb->updateFlagsToolbar();
1282 /////////////////////////////////////////////////////////////////////
1283 } else if (com=="setFrameType")
1285 if (xelection.isEmpty() )
1287 parser.setError (Aborted,"Nothing selected");
1290 parser.setError (Aborted,"Type of selection is not a branch");
1291 } else if (parser.checkParCount(1))
1293 s=parser.parString(ok,0);
1297 /////////////////////////////////////////////////////////////////////
1298 } else if (com=="toggleFlag")
1300 if (xelection.isEmpty() )
1302 parser.setError (Aborted,"Nothing selected");
1305 parser.setError (Aborted,"Type of selection is not a branch");
1306 } else if (parser.checkParCount(1))
1308 s=parser.parString(ok,0);
1311 selb->toggleStandardFlag(s);
1312 selb->updateFlagsToolbar();
1315 /////////////////////////////////////////////////////////////////////
1316 } else if (com=="unscroll")
1318 if (xelection.isEmpty() )
1320 parser.setError (Aborted,"Nothing selected");
1323 parser.setError (Aborted,"Type of selection is not a branch");
1324 } else if (parser.checkParCount(0))
1326 if (!unscrollBranch (selb))
1327 parser.setError (Aborted,"Could not unscroll branch");
1329 /////////////////////////////////////////////////////////////////////
1330 } else if (com=="unscrollChilds")
1332 if (xelection.isEmpty() )
1334 parser.setError (Aborted,"Nothing selected");
1337 parser.setError (Aborted,"Type of selection is not a branch");
1338 } else if (parser.checkParCount(0))
1342 /////////////////////////////////////////////////////////////////////
1343 } else if (com=="unsetFlag")
1345 if (xelection.isEmpty() )
1347 parser.setError (Aborted,"Nothing selected");
1350 parser.setError (Aborted,"Type of selection is not a branch");
1351 } else if (parser.checkParCount(1))
1353 s=parser.parString(ok,0);
1356 selb->deactivateStandardFlag(s);
1357 selb->updateFlagsToolbar();
1361 parser.setError (Aborted,"Unknown command");
1364 if (parser.errorLevel()==NoError)
1367 mapCenter->reposition();
1371 // TODO Error handling
1372 qWarning("MapEditor::parseAtom: Error!");
1373 qWarning(parser.errorMessage());
1377 void MapEditor::runScript (QString script)
1379 parser.setScript (script);
1381 while (parser.next() )
1382 parseAtom(parser.getAtom());
1385 bool MapEditor::isDefault()
1390 bool MapEditor::hasChanged()
1395 void MapEditor::setChanged()
1398 autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
1406 void MapEditor::closeMap()
1408 // Unselect before disabling the toolbar actions
1409 if (!xelection.isEmpty() ) xelection.unselect();
1417 void MapEditor::setFilePath(QString fpath, QString destname)
1419 if (fpath.isEmpty() || fpath=="")
1426 filePath=fpath; // becomes absolute path
1427 fileName=fpath; // gets stripped of path
1428 destPath=destname; // needed for vymlinks
1430 // If fpath is not an absolute path, complete it
1431 filePath=QDir(fpath).absPath();
1432 fileDir=filePath.left (1+filePath.findRev ("/"));
1434 // Set short name, too. Search from behind:
1435 int i=fileName.findRev("/");
1436 if (i>=0) fileName=fileName.remove (0,i+1);
1438 // Forget the .vym (or .xml) for name of map
1439 mapName=fileName.left(fileName.findRev(".",-1,true) );
1443 void MapEditor::setFilePath(QString fpath)
1445 setFilePath (fpath,fpath);
1448 QString MapEditor::getFilePath()
1453 QString MapEditor::getFileName()
1458 QString MapEditor::getMapName()
1463 QString MapEditor::getDestPath()
1468 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
1470 ErrorCode err=success;
1474 if (xelection.isEmpty() ) xelection.unselect();
1477 mapCenter->setMapEditor(this);
1478 // (map state is set later at end of load...)
1481 BranchObj *bo=xelection.getBranch();
1482 if (!bo) return aborted;
1483 if (lmode==ImportAdd)
1484 saveStateChangingPart(
1487 QString("addMapInsert (%1)").arg(fname),
1488 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1490 saveStateChangingPart(
1493 QString("addMapReplace(%1)").arg(fname),
1494 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1498 mapBuilderHandler handler;
1499 QFile file( fname );
1501 // I am paranoid: file should exist anyway
1502 // according to check in mainwindow.
1503 if (!file.exists() )
1505 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1506 tr("Couldn't open map " +fname)+".");
1510 bool blockSaveStateOrg=blockSaveState;
1511 blockReposition=true;
1512 blockSaveState=true;
1513 QXmlInputSource source( file);
1514 QXmlSimpleReader reader;
1515 reader.setContentHandler( &handler );
1516 reader.setErrorHandler( &handler );
1517 handler.setMapEditor( this );
1520 // We need to set the tmpDir in order to load files with rel. path
1521 QString tmpdir= fname.left(fname.findRev("/",-1));
1522 handler.setTmpDir (tmpdir);
1523 handler.setInputFile (file.name());
1524 handler.setLoadMode (lmode);
1525 bool ok = reader.parse( source );
1526 blockReposition=false;
1527 blockSaveState=blockSaveStateOrg;
1531 mapCenter->reposition();
1538 autosaveTimer->stop();
1542 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1543 tr( handler.errorProtocol() ) );
1545 // Still return "success": the map maybe at least
1546 // partially read by the parser
1553 int MapEditor::save (const SaveMode &savemode)
1555 // Create mapName and fileDir
1556 makeSubDirs (fileDir);
1560 fname=mapName+".xml";
1562 // use name given by user, even if he chooses .doc
1567 if (savemode==CompleteMap || xelection.isEmpty())
1568 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1571 // TODO take care of multiselections
1572 if (xelection.type()==Selection::FloatImage)
1575 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());
1579 if (!saveStringToDisk(fileDir+fname,saveFile))
1584 autosaveTimer->stop();
1589 void MapEditor::setZipped (bool z)
1594 bool MapEditor::saveZipped ()
1599 void MapEditor::print()
1603 printer = new QPrinter;
1604 printer->setColorMode (QPrinter::Color);
1605 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1606 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1607 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1610 QRectF totalBBox=mapCenter->getTotalBBox();
1612 // Try to set orientation automagically
1613 // Note: Interpretation of generated postscript is amibiguous, if
1614 // there are problems with landscape mode, see
1615 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1617 if (totalBBox.width()>totalBBox.height())
1618 // recommend landscape
1619 printer->setOrientation (QPrinter::Landscape);
1621 // recommend portrait
1622 printer->setOrientation (QPrinter::Portrait);
1624 if ( printer->setup(this) )
1625 // returns false, if printing is canceled
1627 QPainter pp(printer);
1629 pp.setRenderHint(QPainter::Antialiasing,true);
1631 // Don't print the visualisation of selection
1632 xelection.unselect();
1634 QRectF mapRect=totalBBox;
1635 QGraphicsRectItem *frame=NULL;
1639 // Print frame around map
1640 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1641 totalBBox.width()+20, totalBBox.height()+20);
1642 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1643 frame->setZValue(0);
1648 double paperAspect = (double)printer->width() / (double)printer->height();
1649 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1651 if (mapAspect>=paperAspect)
1653 // Fit horizontally to paper width
1654 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1655 viewBottom=(int)(printer->width()/mapAspect);
1658 // Fit vertically to paper height
1659 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1660 viewBottom=printer->height();
1665 // Print footer below map
1667 font.setPointSize(10);
1669 QRectF footerBox(0,viewBottom,printer->width(),15);
1670 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1671 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1675 QRectF (0,0,printer->width(),printer->height()-15),
1676 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1679 // Viewport has paper dimension
1680 if (frame) delete (frame);
1682 // Restore selection
1683 xelection.reselect();
1685 // Save settings in vymrc
1686 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1687 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1688 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1692 void MapEditor::setAntiAlias (bool b)
1694 setRenderHint(QPainter::Antialiasing,b);
1697 void MapEditor::setSmoothPixmap(bool b)
1699 setRenderHint(QPainter::SmoothPixmapTransform,b);
1702 QPixmap MapEditor::getPixmap()
1704 QRectF mapRect=mapCenter->getTotalBBox();
1705 QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+2);
1708 pp.setRenderHints(renderHints());
1710 // Don't print the visualisation of selection
1711 xelection.unselect();
1713 mapScene->render ( &pp,
1714 QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1715 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1717 // Restore selection
1718 xelection.reselect();
1723 void MapEditor::setHideTmpMode (BranchObj::HideTmpMode mode)
1726 mapCenter->setHideTmp (hidemode);
1727 mapCenter->reposition();
1731 BranchObj::HideTmpMode MapEditor::getHideTmpMode()
1736 void MapEditor::setExportMode (bool b)
1738 // should be called before and after exports
1739 // depending on the settings
1740 if (b && settings.value("/export/useHideExport","yes")=="yes")
1741 setHideTmpMode (BranchObj::HideExport);
1743 setHideTmpMode (BranchObj::HideNone);
1746 void MapEditor::exportASCII(QString fname,bool askName)
1749 ex.setMapCenter(mapCenter);
1751 ex.setFile (mapName+".txt");
1757 //ex.addFilter ("TXT (*.txt)");
1758 ex.setDir(lastImageDir);
1759 //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
1764 setExportMode(true);
1766 setExportMode(false);
1770 void MapEditor::exportImage(QString fname, bool askName, QString format)
1774 fname=mapName+".png";
1781 QFileDialog *fd=new QFileDialog (this);
1782 fd->setCaption (tr("Export map as image"));
1783 fd->setDirectory (lastImageDir);
1784 fd->setFileMode(QFileDialog::AnyFile);
1785 fd->setFilters (imageIO.getFilters() );
1788 fl=fd->selectedFiles();
1790 format=imageIO.getType(fd->selectedFilter());
1794 setExportMode (true);
1795 QPixmap pix (getPixmap());
1796 pix.save(fname, format);
1797 setExportMode (false);
1800 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1804 ex.setMapCenter(mapCenter);
1805 if (ex.setConfigFile(cf))
1807 setExportMode (true);
1808 ex.exportPresentation();
1809 setExportMode (false);
1813 void MapEditor::exportXHTML (const QString &dir, bool askForName)
1815 ExportXHTMLDialog dia(this);
1816 dia.setFilePath (filePath );
1817 dia.setMapName (mapName );
1819 if (dir!="") dia.setDir (dir);
1825 if (dia.exec()!=QDialog::Accepted)
1829 QDir d (dia.getDir());
1830 // Check, if warnings should be used before overwriting
1831 // the output directory
1832 if (d.exists() && d.count()>0)
1835 warn.showCancelButton (true);
1836 warn.setText(QString(
1837 "The directory %1 is not empty.\n"
1838 "Do you risk to overwrite some of its contents?").arg(d.path() ));
1839 warn.setCaption("Warning: Directory not empty");
1840 warn.setShowAgainName("mainwindow/overwrite-dir-xhtml");
1842 if (warn.exec()!=QDialog::Accepted) ok=false;
1849 exportXML (dia.getDir(),false );
1850 dia.doExport(mapName );
1851 //if (dia.hasChanged()) setChanged();
1855 void MapEditor::exportXML(QString dir, bool askForName)
1859 dir=browseDirectory(this,tr("Export XML to directory"));
1860 if (dir =="" && !reallyWriteDirectory(dir) )
1864 // Hide stuff during export, if settings want this
1865 setExportMode (true);
1867 // Create subdirectories
1870 // write to directory
1871 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1874 file.setName ( dir + "/"+mapName+".xml");
1875 if ( !file.open( QIODevice::WriteOnly ) )
1877 // This should neverever happen
1878 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1882 // Write it finally, and write in UTF8, no matter what
1883 QTextStream ts( &file );
1884 ts.setEncoding (QTextStream::UnicodeUTF8);
1888 // Now write image, too
1889 exportImage (dir+"/images/"+mapName+".png",false,"PNG");
1891 setExportMode (false);
1894 void MapEditor::clear()
1896 xelection.unselect();
1900 void MapEditor::copy()
1902 LinkableMapObj *sel=xelection.single();
1905 if (redosAvail == 0)
1908 QString s=sel->getSelectString();
1909 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel );
1910 curClipboard=curStep;
1913 // Copy also to global clipboard, because we are at last step in history
1914 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(curStep));
1915 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
1916 copyDir (bakMapDir,clipboardDir );
1918 clipboardEmpty=false;
1923 void MapEditor::redo()
1925 // Can we undo at all?
1926 if (redosAvail<1) return;
1928 bool blockSaveStateOrg=blockSaveState;
1929 blockSaveState=true;
1933 if (undosAvail<stepsTotal) undosAvail++;
1935 if (curStep>stepsTotal) curStep=1;
1936 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1937 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1938 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1939 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1940 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1941 QString version=undoSet.readEntry ("/history/version");
1943 if (!checkVersion(version))
1944 QMessageBox::warning(0,tr("Warning"),
1945 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
1948 // Find out current undo directory
1949 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1953 cout << "ME::redo() begin\n";
1954 cout << " undosAvail="<<undosAvail<<endl;
1955 cout << " redosAvail="<<redosAvail<<endl;
1956 cout << " curStep="<<curStep<<endl;
1957 cout << " ---------------------------"<<endl;
1958 cout << " comment="<<comment.toStdString()<<endl;
1959 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1960 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1961 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1962 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1963 cout << " ---------------------------"<<endl<<endl;
1966 // select object before redo
1967 if (!redoSelection.isEmpty())
1968 select (redoSelection);
1971 parseAtom (redoCommand);
1972 mapCenter->reposition();
1974 blockSaveState=blockSaveStateOrg;
1976 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1977 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1978 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1979 undoSet.writeSettings(histPath);
1981 mainWindow->updateHistory (undoSet);
1984 /* TODO remove testing
1985 cout << "ME::redo() end\n";
1986 cout << " undosAvail="<<undosAvail<<endl;
1987 cout << " redosAvail="<<redosAvail<<endl;
1988 cout << " curStep="<<curStep<<endl;
1989 cout << " ---------------------------"<<endl<<endl;
1995 bool MapEditor::isRedoAvailable()
1997 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
2003 void MapEditor::undo()
2005 // Can we undo at all?
2006 if (undosAvail<1) return;
2008 mainWindow->statusMessage (tr("Autosave disabled during undo."));
2010 bool blockSaveStateOrg=blockSaveState;
2011 blockSaveState=true;
2013 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
2014 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2015 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2016 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2017 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2018 QString version=undoSet.readEntry ("/history/version");
2020 if (!checkVersion(version))
2021 QMessageBox::warning(0,tr("Warning"),
2022 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2024 // Find out current undo directory
2025 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
2027 // select object before undo
2028 if (!undoSelection.isEmpty())
2029 select (undoSelection);
2033 cout << "ME::undo() begin\n";
2034 cout << " undosAvail="<<undosAvail<<endl;
2035 cout << " redosAvail="<<redosAvail<<endl;
2036 cout << " curStep="<<curStep<<endl;
2037 cout << " ---------------------------"<<endl;
2038 cout << " comment="<<comment.toStdString()<<endl;
2039 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2040 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2041 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2042 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2043 cout << " ---------------------------"<<endl<<endl;
2045 parseAtom (undoCommand);
2046 mapCenter->reposition();
2050 if (curStep<1) curStep=stepsTotal;
2054 blockSaveState=blockSaveStateOrg;
2055 /* TODO remove testing
2056 cout << "ME::undo() end\n";
2057 cout << " undosAvail="<<undosAvail<<endl;
2058 cout << " redosAvail="<<redosAvail<<endl;
2059 cout << " curStep="<<curStep<<endl;
2060 cout << " ---------------------------"<<endl<<endl;
2063 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2064 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2065 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2066 undoSet.writeSettings(histPath);
2068 mainWindow->updateHistory (undoSet);
2071 ensureSelectionVisible();
2074 bool MapEditor::isUndoAvailable()
2076 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
2082 void MapEditor::gotoHistoryStep (int i)
2084 // Restore variables
2085 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
2086 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
2088 if (i<0) i=undosAvail+redosAvail;
2090 // Clicking above current step makes us undo things
2093 for (int j=0; j<undosAvail-i; j++) undo();
2096 // Clicking below current step makes us redo things
2098 for (int j=undosAvail; j<i; j++)
2100 cout << "redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
2104 // And ignore clicking the current row ;-)
2107 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
2109 QString pathDir=path.left(path.findRev("/"));
2115 // We need to parse saved XML data
2116 mapBuilderHandler handler;
2117 QXmlInputSource source( file);
2118 QXmlSimpleReader reader;
2119 reader.setContentHandler( &handler );
2120 reader.setErrorHandler( &handler );
2121 handler.setMapEditor( this );
2122 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2123 if (undoSel.isEmpty())
2127 handler.setLoadMode (NewMap);
2131 handler.setLoadMode (ImportReplace);
2133 blockReposition=true;
2134 bool ok = reader.parse( source );
2135 blockReposition=false;
2138 // This should never ever happen
2139 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2140 handler.errorProtocol());
2143 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2146 void MapEditor::addMapInsertInt (const QString &path, int pos)
2148 BranchObj *sel=xelection.getBranch();
2151 QString pathDir=path.left(path.findRev("/"));
2157 // We need to parse saved XML data
2158 mapBuilderHandler handler;
2159 QXmlInputSource source( file);
2160 QXmlSimpleReader reader;
2161 reader.setContentHandler( &handler );
2162 reader.setErrorHandler( &handler );
2163 handler.setMapEditor( this );
2164 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2165 handler.setLoadMode (ImportAdd);
2166 blockReposition=true;
2167 bool ok = reader.parse( source );
2168 blockReposition=false;
2171 // This should never ever happen
2172 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2173 handler.errorProtocol());
2176 sel->getLastBranch()->linkTo (sel,pos);
2178 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2182 void MapEditor::pasteNoSave(const int &n)
2184 bool old=blockSaveState;
2185 blockSaveState=true;
2186 if (redosAvail > 0 || n!=0)
2188 // Use the "historical" buffer
2189 QString bakMapName=QDir::convertSeparators (QString("history-%1").arg(n));
2190 QString bakMapDir=QDir::convertSeparators (tmpMapDir +"/"+bakMapName);
2191 load (bakMapDir+"/"+clipboardFile,ImportAdd);
2193 // Use the global buffer
2194 load (clipboardDir+"/"+clipboardFile,ImportAdd);
2198 void MapEditor::paste()
2200 BranchObj *sel=xelection.getBranch();
2203 saveStateChangingPart(
2206 QString ("paste (%1)").arg(curClipboard),
2207 QString("Paste to %1").arg( getName(sel))
2210 mapCenter->reposition();
2214 void MapEditor::cut()
2216 LinkableMapObj *sel=xelection.single();
2217 if ( sel && (xelection.type() == Selection::Branch ||
2218 xelection.type()==Selection::MapCenter ||
2219 xelection.type()==Selection::FloatImage))
2221 /* No savestate! savestate is called in cutNoSave
2222 saveStateChangingPart(
2226 QString("Cut %1").arg(getName(sel ))
2231 mapCenter->reposition();
2235 void MapEditor::move(const int &x, const int &y)
2237 LinkableMapObj *sel=xelection.single();
2240 QString ps=qpointfToString (sel->getAbsPos());
2241 QString s=xelection.single()->getSelectString();
2244 s, "move "+qpointfToString (QPointF (x,y)),
2245 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
2247 mapCenter->reposition();
2253 void MapEditor::moveRel (const int &x, const int &y)
2255 LinkableMapObj *sel=xelection.single();
2258 QString ps=qpointfToString (sel->getRelPos());
2259 QString s=sel->getSelectString();
2262 s, "moveRel "+qpointfToString (QPointF (x,y)),
2263 QString("Move %1 to relativ position %2").arg(getName(sel)).arg(ps));
2264 ((OrnamentedObj*)sel)->move2RelPos (x,y);
2265 mapCenter->reposition();
2271 void MapEditor::moveBranchUp()
2273 BranchObj* bo=xelection.getBranch();
2277 if (!bo->canMoveBranchUp()) return;
2278 par=(BranchObj*)(bo->getParObj());
2279 BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
2280 saveState (bo->getSelectString(),"moveBranchDown ()",obo->getSelectString(),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
2281 mapCenter->reposition();
2284 ensureSelectionVisible();
2288 void MapEditor::moveBranchDown()
2290 BranchObj* bo=xelection.getBranch();
2294 if (!bo->canMoveBranchDown()) return;
2295 par=(BranchObj*)(bo->getParObj());
2296 BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
2297 saveState(bo->getSelectString(),"moveBranchUp ()",obo->getSelectString(),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
2298 mapCenter->reposition();
2301 ensureSelectionVisible();
2305 void MapEditor::linkTo(const QString &dstString)
2307 FloatImageObj *fio=xelection.getFloatImage();
2310 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
2311 if (dst && (typeid(*dst)==typeid (BranchObj) ||
2312 typeid(*dst)==typeid (MapCenterObj)))
2314 LinkableMapObj *dstPar=dst->getParObj();
2315 QString parString=dstPar->getSelectString();
2316 QString fioPreSelectString=fio->getSelectString();
2317 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
2318 ((BranchObj*)(dst))->addFloatImage (fio);
2319 xelection.unselect();
2320 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
2321 fio=((BranchObj*)(dst))->getLastFloatImage();
2324 xelection.select(fio);
2326 fio->getSelectString(),
2327 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
2329 QString ("linkTo (\"%1\")").arg(dstString),
2330 QString ("Link floatimage to %1").arg(getName(dst)));
2335 QString MapEditor::getHeading(bool &ok, QPoint &p)
2337 BranchObj *bo=xelection.getBranch();
2341 p=mapFromScene(bo->getAbsPos());
2342 return bo->getHeading();
2348 void MapEditor::setHeading(const QString &s)
2350 BranchObj *sel=xelection.getBranch();
2355 "setHeading (\""+sel->getHeading()+"\")",
2357 "setHeading (\""+s+"\")",
2358 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
2359 sel->setHeading(s );
2360 mapCenter->reposition();
2362 ensureSelectionVisible();
2366 void MapEditor::setHeadingInt(const QString &s)
2368 BranchObj *bo=xelection.getBranch();
2372 mapCenter->reposition();
2374 ensureSelectionVisible();
2378 void MapEditor::setVymLinkInt (const QString &s)
2380 // Internal function, no saveState needed
2381 BranchObj *bo=xelection.getBranch();
2385 mapCenter->reposition();
2388 ensureSelectionVisible();
2392 BranchObj* MapEditor::addNewBranchInt(int num)
2394 // Depending on pos:
2395 // -3 insert in childs of parent above selection
2396 // -2 add branch to selection
2397 // -1 insert in childs of parent below selection
2398 // 0..n insert in childs of parent at pos
2399 BranchObj *newbo=NULL;
2400 BranchObj *bo=xelection.getBranch();
2405 // save scroll state. If scrolled, automatically select
2406 // new branch in order to tmp unscroll parent...
2407 return bo->addBranch();
2412 bo=(BranchObj*)bo->getParObj();
2416 bo=(BranchObj*)bo->getParObj();
2419 newbo=bo->insertBranch(num);
2424 BranchObj* MapEditor::addNewBranch(int pos)
2426 // Different meaning than num in addNewBranchInt!
2430 BranchObj *bo = xelection.getBranch();
2431 BranchObj *newbo=NULL;
2435 setCursor (Qt::ArrowCursor);
2437 newbo=addNewBranchInt (pos-2);
2445 QString ("addBranch (%1)").arg(pos-2),
2446 QString ("Add new branch to %1").arg(getName(bo)));
2448 mapCenter->reposition();
2449 // In Network mode, the client needs to know where the new branch is,
2450 // so we have to pass on this information via saveState.
2451 // TODO: Get rid of this positioning workaround
2452 QString ps=qpointfToString (newbo->getAbsPos());
2456 QString("Move %1 to %2").arg(getName(newbo)).arg(ps));
2465 BranchObj* MapEditor::addNewBranchBefore()
2467 BranchObj *newbo=NULL;
2468 BranchObj *bo = xelection.getBranch();
2469 if (bo && xelection.type()==Selection::Branch)
2470 // We accept no MapCenterObj here, so we _have_ a parent
2472 QPointF p=bo->getRelPos();
2475 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2477 // add below selection
2478 newbo=parbo->insertBranch(bo->getNum()+1);
2481 newbo->move2RelPos (p);
2483 // Move selection to new branch
2484 bo->linkTo (newbo,-1);
2486 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2487 QString ("Add branch before %1").arg(getName(bo)));
2489 mapCenter->reposition();
2496 void MapEditor::deleteSelection()
2498 BranchObj *bo = xelection.getBranch();
2499 if (bo && xelection.type()==Selection::Branch)
2501 BranchObj* par=(BranchObj*)(bo->getParObj());
2502 xelection.unselect();
2503 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2504 par->removeBranch(bo);
2505 xelection.select (par);
2506 ensureSelectionVisible();
2507 mapCenter->reposition();
2512 FloatImageObj *fio=xelection.getFloatImage();
2515 BranchObj* par=(BranchObj*)(fio->getParObj());
2516 saveStateChangingPart(
2520 QString("Delete %1").arg(getName(fio))
2522 xelection.unselect();
2523 par->removeFloatImage(fio);
2524 xelection.select (par);
2525 mapCenter->reposition();
2527 ensureSelectionVisible();
2532 LinkableMapObj* MapEditor::getSelection()
2534 return xelection.single();
2537 BranchObj* MapEditor::getSelectedBranch()
2539 return xelection.getBranch();
2542 FloatImageObj* MapEditor::getSelectedFloatImage()
2544 return xelection.getFloatImage();
2547 void MapEditor::unselect()
2549 xelection.unselect();
2552 void MapEditor::reselect()
2554 xelection.reselect();
2557 bool MapEditor::select (const QString &s)
2559 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2561 // Finally select the found object
2564 xelection.unselect();
2565 xelection.select(lmo);
2567 ensureSelectionVisible();
2574 QString MapEditor::getSelectString()
2576 return xelection.getSelectString();
2579 void MapEditor::selectInt (LinkableMapObj *lmo)
2581 if (lmo && xelection.single()!= lmo && isSelectBlocked()==false )
2583 xelection.select(lmo);
2589 void MapEditor::selectNextBranchInt()
2591 // Increase number of branch
2592 LinkableMapObj *sel=xelection.single();
2595 QString s=sel->getSelectString();
2601 part=s.section(",",-1);
2603 num=part.right(part.length() - 3);
2605 s=s.left (s.length() -num.length());
2608 num=QString ("%1").arg(num.toUInt()+1);
2612 // Try to select this one
2613 if (select (s)) return;
2615 // We have no direct successor,
2616 // try to increase the parental number in order to
2617 // find a successor with same depth
2619 int d=xelection.single()->getDepth();
2624 while (!found && d>0)
2626 s=s.section (",",0,d-1);
2627 // replace substring of current depth in s with "1"
2628 part=s.section(",",-1);
2630 num=part.right(part.length() - 3);
2634 // increase number of parent
2635 num=QString ("%1").arg(num.toUInt()+1);
2636 s=s.section (",",0,d-2) + ","+ typ+num;
2639 // Special case, look at orientation
2640 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2641 num=QString ("%1").arg(num.toUInt()+1);
2643 num=QString ("%1").arg(num.toUInt()-1);
2648 // pad to oldDepth, select the first branch for each depth
2649 for (i=d;i<oldDepth;i++)
2654 if ( xelection.getBranch()->countBranches()>0)
2662 // try to select the freshly built string
2670 void MapEditor::selectPrevBranchInt()
2672 // Decrease number of branch
2673 BranchObj *bo=xelection.getBranch();
2676 QString s=bo->getSelectString();
2682 part=s.section(",",-1);
2684 num=part.right(part.length() - 3);
2686 s=s.left (s.length() -num.length());
2688 int n=num.toInt()-1;
2691 num=QString ("%1").arg(n);
2694 // Try to select this one
2695 if (n>=0 && select (s)) return;
2697 // We have no direct precessor,
2698 // try to decrease the parental number in order to
2699 // find a precessor with same depth
2701 int d=xelection.single()->getDepth();
2706 while (!found && d>0)
2708 s=s.section (",",0,d-1);
2709 // replace substring of current depth in s with "1"
2710 part=s.section(",",-1);
2712 num=part.right(part.length() - 3);
2716 // decrease number of parent
2717 num=QString ("%1").arg(num.toInt()-1);
2718 s=s.section (",",0,d-2) + ","+ typ+num;
2721 // Special case, look at orientation
2722 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2723 num=QString ("%1").arg(num.toInt()-1);
2725 num=QString ("%1").arg(num.toInt()+1);
2730 // pad to oldDepth, select the last branch for each depth
2731 for (i=d;i<oldDepth;i++)
2735 if ( xelection.getBranch()->countBranches()>0)
2736 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2743 // try to select the freshly built string
2751 void MapEditor::selectUpperBranch()
2753 if (isSelectBlocked() ) return;
2755 BranchObj *bo=xelection.getBranch();
2756 if (bo && xelection.type()==Selection::Branch)
2758 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2759 selectPrevBranchInt();
2761 if (bo->getDepth()==1)
2762 selectNextBranchInt();
2764 selectPrevBranchInt();
2768 void MapEditor::selectLowerBranch()
2770 if (isSelectBlocked() ) return;
2772 BranchObj *bo=xelection.getBranch();
2773 if (bo && xelection.type()==Selection::Branch)
2774 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2775 selectNextBranchInt();
2777 if (bo->getDepth()==1)
2778 selectPrevBranchInt();
2780 selectNextBranchInt();
2784 void MapEditor::selectLeftBranch()
2786 if (isSelectBlocked() ) return;
2790 LinkableMapObj *sel=xelection.single();
2793 if (xelection.type()== Selection::MapCenter)
2795 par=xelection.getBranch();
2796 bo=par->getLastSelectedBranch();
2799 // Workaround for reselecting on left and right side
2800 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2801 bo=par->getLastBranch();
2804 bo=par->getLastBranch();
2805 xelection.select(bo);
2807 ensureSelectionVisible();
2813 par=(BranchObj*)(sel->getParObj());
2814 if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
2816 if (xelection.type() == Selection::Branch ||
2817 xelection.type() == Selection::FloatImage)
2819 xelection.select(par);
2821 ensureSelectionVisible();
2826 if (xelection.type() == Selection::Branch )
2828 bo=xelection.getBranch()->getLastSelectedBranch();
2831 xelection.select(bo);
2833 ensureSelectionVisible();
2842 void MapEditor::selectRightBranch()
2844 if (isSelectBlocked() ) return;
2848 LinkableMapObj *sel=xelection.single();
2851 if (xelection.type()==Selection::MapCenter)
2853 par=xelection.getBranch();
2854 bo=par->getLastSelectedBranch();
2857 // Workaround for reselecting on left and right side
2858 if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
2859 bo=par->getFirstBranch();
2862 xelection.select(bo);
2864 ensureSelectionVisible();
2870 par=(BranchObj*)(xelection.single()->getParObj());
2871 if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
2873 if (xelection.type() == Selection::Branch ||
2874 xelection.type() == Selection::FloatImage)
2876 xelection.select(par);
2878 ensureSelectionVisible();
2883 if (xelection.type() == Selection::Branch)
2885 bo=xelection.getBranch()->getLastSelectedBranch();
2888 xelection.select(bo);
2890 ensureSelectionVisible();
2899 void MapEditor::selectFirstBranch()
2901 BranchObj *bo1=xelection.getBranch();
2906 par=(BranchObj*)(bo1->getParObj());
2907 bo2=par->getFirstBranch();
2909 xelection.select(bo2);
2911 ensureSelectionVisible();
2917 void MapEditor::selectLastBranch()
2919 BranchObj *bo1=xelection.getBranch();
2924 par=(BranchObj*)(bo1->getParObj());
2925 bo2=par->getLastBranch();
2928 xelection.select(bo2);
2930 ensureSelectionVisible();
2936 void MapEditor::selectMapBackgroundImage ()
2938 Q3FileDialog *fd=new Q3FileDialog( this);
2939 fd->setMode (Q3FileDialog::ExistingFile);
2940 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2941 ImagePreview *p =new ImagePreview (fd);
2942 fd->setContentsPreviewEnabled( TRUE );
2943 fd->setContentsPreview( p, p );
2944 fd->setPreviewMode( Q3FileDialog::Contents );
2945 fd->setCaption(vymName+" - " +tr("Load background image"));
2946 fd->setDir (lastImageDir);
2949 if ( fd->exec() == QDialog::Accepted )
2951 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
2952 lastImageDir=QDir (fd->dirPath());
2953 setMapBackgroundImage (fd->selectedFile());
2957 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
2959 QColor oldcol=mapScene->backgroundBrush().color();
2963 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
2965 QString ("setMapBackgroundImage (%1)").arg(col.name()),
2966 QString("Set background color of map to %1").arg(col.name()));
2969 brush.setTextureImage (QPixmap (fn));
2970 mapScene->setBackgroundBrush(brush);
2973 void MapEditor::selectMapBackgroundColor()
2975 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
2976 if ( !col.isValid() ) return;
2977 setMapBackgroundColor( col );
2981 void MapEditor::setMapBackgroundColor(QColor col)
2983 QColor oldcol=mapScene->backgroundBrush().color();
2986 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
2988 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
2989 QString("Set background color of map to %1").arg(col.name()));
2990 mapScene->setBackgroundBrush(col);
2993 QColor MapEditor::getMapBackgroundColor()
2995 return mapScene->backgroundBrush().color();
2998 QColor MapEditor::getCurrentHeadingColor()
3000 BranchObj *bo=xelection.getBranch();
3001 if (bo) return bo->getColor();
3003 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
3007 void MapEditor::colorBranch (QColor c)
3009 BranchObj *bo=xelection.getBranch();
3014 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
3016 QString ("colorBranch (\"%1\")").arg(c.name()),
3017 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
3019 bo->setColor(c); // color branch
3023 void MapEditor::colorSubtree (QColor c)
3025 BranchObj *bo=xelection.getBranch();
3028 saveStateChangingPart(
3031 QString ("colorSubtree (\"%1\")").arg(c.name()),
3032 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
3034 bo->setColorSubtree (c); // color links, color childs
3039 void MapEditor::toggleStandardFlag(QString f)
3041 BranchObj *bo=xelection.getBranch();
3045 if (bo->isSetStandardFlag(f))
3057 QString("%1 (\"%2\")").arg(u).arg(f),
3059 QString("%1 (\"%2\")").arg(r).arg(f),
3060 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
3061 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
3067 BranchObj* MapEditor::findText (QString s, bool cs)
3069 QTextDocument::FindFlags flags=0;
3070 if (cs) flags=QTextDocument::FindCaseSensitively;
3073 { // Nothing found or new find process
3075 // nothing found, start again
3077 itFind=mapCenter->first();
3079 bool searching=true;
3080 bool foundNote=false;
3081 while (searching && !EOFind)
3085 // Searching in Note
3086 if (itFind->getNote().contains(s,cs))
3088 if (xelection.single()!=itFind)
3090 xelection.select(itFind);
3091 ensureSelectionVisible();
3093 if (textEditor->findText(s,flags))
3099 // Searching in Heading
3100 if (searching && itFind->getHeading().contains (s,cs) )
3102 xelection.select(itFind);
3103 ensureSelectionVisible();
3109 itFind=itFind->next();
3110 if (!itFind) EOFind=true;
3114 return xelection.getBranch();
3119 void MapEditor::findReset()
3120 { // Necessary if text to find changes during a find process
3124 void MapEditor::setURL(const QString &url)
3126 BranchObj *bo=xelection.getBranch();
3129 QString oldurl=bo->getURL();
3133 QString ("setURL (\"%1\")").arg(oldurl),
3135 QString ("setURL (\"%1\")").arg(url),
3136 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
3139 mapCenter->reposition();
3141 ensureSelectionVisible();
3145 void MapEditor::editURL()
3147 BranchObj *bo=xelection.getBranch();
3151 QString text = QInputDialog::getText(
3152 "VYM", tr("Enter URL:"), QLineEdit::Normal,
3153 bo->getURL(), &ok, this );
3155 // user entered something and pressed OK
3160 void MapEditor::editLocalURL()
3162 BranchObj *bo=xelection.getBranch();
3165 QStringList filters;
3166 filters <<"All files (*)";
3167 filters << tr("Text","Filedialog") + " (*.txt)";
3168 filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
3169 filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
3170 filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
3171 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Set URL to a local file"));
3172 fd->setFilters (filters);
3173 fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
3174 fd->setDirectory (lastFileDir);
3175 if (! bo->getVymLink().isEmpty() )
3176 fd->selectFile( bo->getURL() );
3179 if ( fd->exec() == QDialog::Accepted )
3181 lastFileDir=QDir (fd->directory().path());
3182 setURL (fd->selectedFile() );
3187 QString MapEditor::getURL()
3189 BranchObj *bo=xelection.getBranch();
3191 return bo->getURL();
3196 QStringList MapEditor::getURLs()
3199 BranchObj *bo=xelection.getBranch();
3205 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
3213 void MapEditor::editHeading2URL()
3215 BranchObj *bo=xelection.getBranch();
3217 setURL (bo->getHeading());
3220 void MapEditor::editBugzilla2URL()
3222 BranchObj *bo=xelection.getBranch();
3225 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
3230 void MapEditor::editFATE2URL()
3232 BranchObj *bo=xelection.getBranch();
3235 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
3238 "setURL (\""+bo->getURL()+"\")",
3240 "setURL (\""+url+"\")",
3241 QString("Use heading of %1 as link to FATE").arg(getName(bo))
3248 void MapEditor::editVymLink()
3250 BranchObj *bo=xelection.getBranch();
3253 QStringList filters;
3254 filters <<"VYM map (*.vym)";
3255 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
3256 fd->setFilters (filters);
3257 fd->setCaption(vymName+" - " +tr("Link to another map"));
3258 fd->setDirectory (lastFileDir);
3259 if (! bo->getVymLink().isEmpty() )
3260 fd->selectFile( bo->getVymLink() );
3264 if ( fd->exec() == QDialog::Accepted )
3266 lastFileDir=QDir (fd->directory().path());
3269 "setVymLink (\""+bo->getVymLink()+"\")",
3271 "setVymLink (\""+fd->selectedFile()+"\")",
3272 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
3274 setVymLinkInt (fd->selectedFile() );
3279 void MapEditor::deleteVymLink()
3281 BranchObj *bo=xelection.getBranch();
3286 "setVymLink (\""+bo->getVymLink()+"\")",
3288 "setVymLink (\"\")",
3289 QString("Unset vymlink of %1").arg(getName(bo))
3291 bo->setVymLink ("" );
3293 mapCenter->reposition();
3298 void MapEditor::setHideExport(bool b)
3300 BranchObj *bo=xelection.getBranch();
3303 bo->setHideInExport (b);
3304 QString u= b ? "false" : "true";
3305 QString r=!b ? "false" : "true";
3309 QString ("setHideExport (%1)").arg(u),
3311 QString ("setHideExport (%1)").arg(r),
3312 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
3315 mapCenter->reposition();
3321 void MapEditor::toggleHideExport()
3323 BranchObj *bo=xelection.getBranch();
3325 setHideExport ( !bo->hideInExport() );
3328 QString MapEditor::getVymLink()
3330 BranchObj *bo=xelection.getBranch();
3332 return bo->getVymLink();
3338 QStringList MapEditor::getVymLinks()
3341 BranchObj *bo=xelection.getBranch();
3347 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
3355 void MapEditor::deleteKeepChilds()
3357 BranchObj *bo=xelection.getBranch();
3361 par=(BranchObj*)(bo->getParObj());
3362 QPointF p=bo->getRelPos();
3363 saveStateChangingPart(
3366 "deleteKeepChilds ()",
3367 QString("Remove %1 and keep its childs").arg(getName(bo))
3370 QString sel=bo->getSelectString();
3372 par->removeBranchHere(bo);
3373 mapCenter->reposition();
3375 xelection.getBranch()->move2RelPos (p);
3376 mapCenter->reposition();
3380 void MapEditor::deleteChilds()
3382 BranchObj *bo=xelection.getBranch();
3385 saveStateChangingPart(
3389 QString( "Remove childs of branch %1").arg(getName(bo))
3392 mapCenter->reposition();
3396 void MapEditor::editMapInfo()
3398 ExtraInfoDialog dia;
3399 dia.setMapName (getFileName() );
3400 dia.setAuthor (mapCenter->getAuthor() );
3401 dia.setComment(mapCenter->getComment() );
3405 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
3412 bo=mapCenter->first();
3415 if (!bo->getNote().isEmpty() ) n++;
3416 f+= bo->countFloatImages();
3418 xl+=bo->countXLinks();
3421 stats+=QString ("%1 branches\n").arg (b-1,6);
3422 stats+=QString ("%1 xLinks \n").arg (xl,6);
3423 stats+=QString ("%1 notes\n").arg (n,6);
3424 stats+=QString ("%1 images\n").arg (f,6);
3425 dia.setStats (stats);
3427 // Finally show dialog
3428 if (dia.exec() == QDialog::Accepted)
3430 setMapAuthor (dia.getAuthor() );
3431 setMapComment (dia.getComment() );
3435 void MapEditor::ensureSelectionVisible()
3437 LinkableMapObj *lmo=xelection.single();
3438 if (lmo) ensureVisible (lmo->getBBox() );
3442 void MapEditor::updateSelection()
3444 // Tell selection to update geometries
3448 void MapEditor::updateActions()
3450 // Tell mainwindow to update states of actions
3451 mainWindow->updateActions();
3452 // TODO maybe don't update if blockReposition is set
3455 void MapEditor::updateNoteFlag()
3458 BranchObj *bo=xelection.getBranch();
3461 bo->updateNoteFlag();
3462 mainWindow->updateActions();
3466 void MapEditor::setMapAuthor (const QString &s)
3470 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3472 QString ("setMapAuthor (\"%1\")").arg(s),
3473 QString ("Set author of map to \"%1\"").arg(s)
3475 mapCenter->setAuthor (s);
3478 void MapEditor::setMapComment (const QString &s)
3482 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3484 QString ("setMapComment (\"%1\")").arg(s),
3485 QString ("Set comment of map")
3487 mapCenter->setComment (s);
3490 void MapEditor::setMapLinkStyle (const QString & s)
3492 saveStateChangingPart (
3495 QString("setMapLinkStyle (\"%1\")").arg(s),
3496 QString("Set map link style (\"%1\")").arg(s)
3500 linkstyle=LinkableMapObj::Line;
3501 else if (s=="StyleParabel")
3502 linkstyle=LinkableMapObj::Parabel;
3503 else if (s=="StylePolyLine")
3504 linkstyle=LinkableMapObj::PolyLine;
3506 linkstyle=LinkableMapObj::PolyParabel;
3509 bo=mapCenter->first();
3513 bo->setLinkStyle(bo->getDefLinkStyle());
3516 mapCenter->reposition();
3519 LinkableMapObj::Style MapEditor::getMapLinkStyle ()
3524 void MapEditor::setMapDefLinkColor(QColor c)
3528 bo=mapCenter->first();
3537 void MapEditor::setMapLinkColorHintInt()
3539 // called from setMapLinkColorHint(lch) or at end of parse
3541 bo=mapCenter->first();
3549 void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
3552 setMapLinkColorHintInt();
3555 void MapEditor::toggleMapLinkColorHint()
3557 if (linkcolorhint==LinkableMapObj::HeadingColor)
3558 linkcolorhint=LinkableMapObj::DefaultColor;
3560 linkcolorhint=LinkableMapObj::HeadingColor;
3562 bo=mapCenter->first();
3570 LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
3572 return linkcolorhint;
3575 QColor MapEditor::getMapDefLinkColor()
3577 return defLinkColor;
3580 void MapEditor::setMapDefXLinkColor(QColor col)
3585 QColor MapEditor::getMapDefXLinkColor()
3587 return defXLinkColor;
3590 void MapEditor::setMapDefXLinkWidth (int w)
3595 int MapEditor::getMapDefXLinkWidth()
3597 return defXLinkWidth;
3600 void MapEditor::selectMapLinkColor()
3602 QColor col = QColorDialog::getColor( defLinkColor, this );
3603 if ( !col.isValid() ) return;
3606 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3608 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3609 QString("Set map link color to %1").arg(col.name())
3611 setMapDefLinkColor( col );
3614 void MapEditor::selectMapSelectionColor()
3616 QColor col = QColorDialog::getColor( defLinkColor, this );
3617 setSelectionColor (col);
3620 void MapEditor::setSelectionColorInt (QColor col)
3622 if ( !col.isValid() ) return;
3623 xelection.setColor (col);
3626 void MapEditor::setSelectionColor(QColor col)
3628 if ( !col.isValid() ) return;
3631 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3633 QString("setSelectionColor (%1)").arg(col.name()),
3634 QString("Set color of selection box to %1").arg(col.name())
3636 setSelectionColorInt (col);
3639 QColor MapEditor::getSelectionColor()
3641 return xelection.getColor();
3644 bool MapEditor::scrollBranch(BranchObj *bo)
3648 if (bo->isScrolled()) return false;
3649 if (bo->countBranches()==0) return false;
3650 if (bo->getDepth()==0) return false;
3656 QString ("%1 ()").arg(u),
3658 QString ("%1 ()").arg(r),
3659 QString ("%1 %2").arg(r).arg(getName(bo))
3669 bool MapEditor::unscrollBranch(BranchObj *bo)
3673 if (!bo->isScrolled()) return false;
3674 if (bo->countBranches()==0) return false;
3675 if (bo->getDepth()==0) return false;
3681 QString ("%1 ()").arg(u),
3683 QString ("%1 ()").arg(r),
3684 QString ("%1 %2").arg(r).arg(getName(bo))
3694 void MapEditor::toggleScroll()
3696 BranchObj *bo=xelection.getBranch();
3697 if (xelection.type()==Selection::Branch )
3699 if (bo->isScrolled())
3700 unscrollBranch (bo);
3706 void MapEditor::unscrollChilds()
3708 BranchObj *bo=xelection.getBranch();
3714 if (bo->isScrolled()) unscrollBranch (bo);
3720 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3722 BranchObj *bo=xelection.getBranch();
3726 bo->addFloatImage();
3727 fio=bo->getLastFloatImage();
3729 mapCenter->reposition();
3736 void MapEditor::loadFloatImage ()
3738 BranchObj *bo=xelection.getBranch();
3742 Q3FileDialog *fd=new Q3FileDialog( this);
3743 fd->setMode (Q3FileDialog::ExistingFiles);
3744 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3745 ImagePreview *p =new ImagePreview (fd);
3746 fd->setContentsPreviewEnabled( TRUE );
3747 fd->setContentsPreview( p, p );
3748 fd->setPreviewMode( Q3FileDialog::Contents );
3749 fd->setCaption(vymName+" - " +tr("Load image"));
3750 fd->setDir (lastImageDir);
3753 if ( fd->exec() == QDialog::Accepted )
3755 // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
3756 lastImageDir=QDir (fd->dirPath());
3759 for (int j=0; j<fd->selectedFiles().count(); j++)
3761 s=fd->selectedFiles().at(j);
3762 fio=loadFloatImageInt (s);
3765 (LinkableMapObj*)fio,
3768 QString ("loadImage (%1)").arg(s ),
3769 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3772 // TODO loadFIO error handling
3773 qWarning ("Failed to load "+s);
3781 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3783 fio->save (fn,type);
3786 void MapEditor::saveFloatImage ()
3788 FloatImageObj *fio=xelection.getFloatImage();
3791 QFileDialog *fd=new QFileDialog( this);
3792 fd->setFilters (imageIO.getFilters());
3793 fd->setCaption(vymName+" - " +tr("Save image"));
3794 fd->setFileMode( QFileDialog::AnyFile );
3795 fd->setDirectory (lastImageDir);
3796 // fd->setSelection (fio->getOriginalFilename());
3800 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3802 fn=fd->selectedFiles().at(0);
3803 if (QFile (fn).exists() )
3805 QMessageBox mb( vymName,
3806 tr("The file %1 exists already.\n"
3807 "Do you want to overwrite it?").arg(fn),
3808 QMessageBox::Warning,
3809 QMessageBox::Yes | QMessageBox::Default,
3810 QMessageBox::Cancel | QMessageBox::Escape,
3811 QMessageBox::QMessageBox::NoButton );
3813 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3814 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3817 case QMessageBox::Yes:
3820 case QMessageBox::Cancel:
3827 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3833 void MapEditor::setFrameType(const FrameObj::FrameType &t)
3835 BranchObj *bo=xelection.getBranch();
3838 QString s=bo->getFrameTypeName();
3839 bo->setFrameType (t);
3840 saveState (bo, QString("setFrameType (\"%1\")").arg(s),
3841 bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
3842 mapCenter->reposition();
3847 void MapEditor::setFrameType(const QString &s)
3849 BranchObj *bo=xelection.getBranch();
3852 saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
3853 bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
3854 bo->setFrameType (s);
3855 mapCenter->reposition();
3860 void MapEditor::setFramePenColor(const QColor &c)
3862 BranchObj *bo=xelection.getBranch();
3865 saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
3866 bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
3867 bo->setFramePenColor (c);
3871 void MapEditor::setFrameBrushColor(const QColor &c)
3873 BranchObj *bo=xelection.getBranch();
3876 saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
3877 bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
3878 bo->setFrameBrushColor (c);
3882 void MapEditor::setFramePadding (const int &i)
3884 BranchObj *bo=xelection.getBranch();
3887 saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
3888 bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
3889 bo->setFramePadding (i);
3890 mapCenter->reposition();
3895 void MapEditor::setFrameBorderWidth(const int &i)
3897 BranchObj *bo=xelection.getBranch();
3900 saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
3901 bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
3902 bo->setFrameBorderWidth (i);
3903 mapCenter->reposition();
3908 void MapEditor::setIncludeImagesVer(bool b)
3910 BranchObj *bo=xelection.getBranch();
3913 QString u= b ? "false" : "true";
3914 QString r=!b ? "false" : "true";
3918 QString("setIncludeImagesVertically (%1)").arg(u),
3920 QString("setIncludeImagesVertically (%1)").arg(r),
3921 QString("Include images vertically in %1").arg(getName(bo))
3923 bo->setIncludeImagesVer(b);
3924 mapCenter->reposition();
3928 void MapEditor::setIncludeImagesHor(bool b)
3930 BranchObj *bo=xelection.getBranch();
3933 QString u= b ? "false" : "true";
3934 QString r=!b ? "false" : "true";
3938 QString("setIncludeImagesHorizontally (%1)").arg(u),
3940 QString("setIncludeImagesHorizontally (%1)").arg(r),
3941 QString("Include images horizontally in %1").arg(getName(bo))
3943 bo->setIncludeImagesHor(b);
3944 mapCenter->reposition();
3948 void MapEditor::setHideLinkUnselected (bool b)
3950 LinkableMapObj *sel=xelection.single();
3952 (xelection.type() == Selection::Branch ||
3953 xelection.type() == Selection::MapCenter ||
3954 xelection.type() == Selection::FloatImage ))
3956 QString u= b ? "false" : "true";
3957 QString r=!b ? "false" : "true";
3961 QString("setHideLinkUnselected (%1)").arg(u),
3963 QString("setHideLinkUnselected (%1)").arg(r),
3964 QString("Hide link of %1 if unselected").arg(getName(sel))
3966 sel->setHideLinkUnselected(b);
3970 void MapEditor::importDirInt(BranchObj *dst, QDir d)
3972 BranchObj *bo=xelection.getBranch();
3975 // Traverse directories
3976 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
3977 QFileInfoList list = d.entryInfoList();
3980 for (int i = 0; i < list.size(); ++i)
3983 if (fi.fileName() != "." && fi.fileName() != ".." )
3986 bo=dst->getLastBranch();
3987 bo->setHeading (fi.fileName() );
3988 bo->setColor (QColor("blue"));
3990 if ( !d.cd(fi.fileName()) )
3991 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3994 // Recursively add subdirs
3995 importDirInt (bo,d);
4001 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
4002 list = d.entryInfoList();
4004 for (int i = 0; i < list.size(); ++i)
4008 bo=dst->getLastBranch();
4009 bo->setHeading (fi.fileName() );
4010 bo->setColor (QColor("black"));
4011 if (fi.fileName().right(4) == ".vym" )
4012 bo->setVymLink (fi.filePath());
4017 void MapEditor::importDirInt (const QString &s)
4019 BranchObj *bo=xelection.getBranch();
4022 saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
4025 importDirInt (bo,d);
4029 void MapEditor::importDir()
4031 BranchObj *bo=xelection.getBranch();
4034 QStringList filters;
4035 filters <<"VYM map (*.vym)";
4036 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
4037 fd->setMode (QFileDialog::DirectoryOnly);
4038 fd->setFilters (filters);
4039 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
4043 if ( fd->exec() == QDialog::Accepted )
4045 importDirInt (fd->selectedFile() );
4046 mapCenter->reposition();
4052 void MapEditor::followXLink(int i)
4054 BranchObj *bo=xelection.getBranch();
4057 bo=bo->XLinkTargetAt(i);
4060 xelection.select(bo);
4061 ensureSelectionVisible();
4066 void MapEditor::editXLink(int i) // FIXME missing saveState
4068 BranchObj *bo=xelection.getBranch();
4071 XLinkObj *xlo=bo->XLinkAt(i);
4074 EditXLinkDialog dia;
4076 dia.setSelection(bo);
4077 if (dia.exec() == QDialog::Accepted)
4079 if (dia.useSettingsGlobal() )
4081 setMapDefXLinkColor (xlo->getColor() );
4082 setMapDefXLinkWidth (xlo->getWidth() );
4084 if (dia.deleteXLink())
4085 bo->deleteXLinkAt(i);
4091 void MapEditor::testFunction1()
4096 BranchObj *bo=xelection.getBranch();
4097 if (bo) animObjList.append( bo );
4102 dia.showCancelButton (true);
4103 dia.setText("This is a longer \nWarning");
4104 dia.setCaption("Warning: Flux problem");
4105 dia.setShowAgainName("mapeditor/testDialog");
4106 if (dia.exec()==QDialog::Accepted)
4107 cout << "accepted!\n";
4109 cout << "canceled!\n";
4113 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
4114 if (hidemode==HideNone)
4116 setHideTmpMode (HideExport);
4117 mapCenter->calcBBoxSizeWithChilds();
4118 QRectF totalBBox=mapCenter->getTotalBBox();
4119 QRectF mapRect=totalBBox;
4120 QCanvasRectangle *frame=NULL;
4122 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
4124 mapRect.setRect (totalBBox.x(), totalBBox.y(),
4125 totalBBox.width(), totalBBox.height());
4126 frame=new QCanvasRectangle (mapRect,mapScene);
4127 frame->setBrush (QColor(white));
4128 frame->setPen (QColor(black));
4129 frame->setZValue(0);
4134 setHideTmpMode (HideNone);
4136 cout <<" hidemode="<<hidemode<<endl;
4140 void MapEditor::testFunction2()
4145 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
4147 // Lineedits are already closed by preceding
4148 // mouseEvent, we don't need to close here.
4150 QPointF p = mapToScene(e->pos());
4151 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4154 { // MapObj was found
4155 if (xelection.single() != lmo)
4157 // select the MapObj
4158 xelection.select(lmo);
4161 if (xelection.getBranch() )
4163 // Context Menu on branch or mapcenter
4165 branchContextMenu->popup(e->globalPos() );
4168 if (xelection.getFloatImage() )
4170 // Context Menu on floatimage
4172 floatimageContextMenu->popup(e->globalPos() );
4176 { // No MapObj found, we are on the Canvas itself
4177 // Context Menu on scene
4179 canvasContextMenu->popup(e->globalPos() );
4184 void MapEditor::keyPressEvent(QKeyEvent* e)
4186 if (e->modifiers() & Qt::ControlModifier)
4188 switch (mainWindow->getModMode())
4190 case Main::ModModeColor:
4191 setCursor (PickColorCursor);
4193 case Main::ModModeCopy:
4194 setCursor (CopyCursor);
4196 case Main::ModModeXLink:
4197 setCursor (XLinkCursor);
4200 setCursor (Qt::ArrowCursor);
4206 void MapEditor::keyReleaseEvent(QKeyEvent* e)
4208 if (!(e->modifiers() & Qt::ControlModifier))
4209 setCursor (Qt::ArrowCursor);
4212 void MapEditor::mousePressEvent(QMouseEvent* e)
4214 // Ignore right clicks, these will go to context menus
4215 if (e->button() == Qt::RightButton )
4221 //Ignore clicks while editing heading
4222 if (isSelectBlocked() )
4228 QPointF p = mapToScene(e->pos());
4229 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4233 //Take care of system flags _or_ modifier modes
4235 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
4236 typeid(*lmo)==typeid(MapCenterObj) ))
4238 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
4239 if (!foname.isEmpty())
4241 // systemFlag clicked
4245 if (e->state() & Qt::ControlModifier)
4246 mainWindow->editOpenURLTab();
4248 mainWindow->editOpenURL();
4250 else if (foname=="vymLink")
4252 mainWindow->editOpenVymLink();
4253 // tabWidget may change, better return now
4254 // before segfaulting...
4255 } else if (foname=="note")
4256 mainWindow->windowToggleNoteEditor();
4257 else if (foname=="hideInExport")
4264 // No system flag clicked, take care of modmodes (CTRL-Click)
4265 if (e->state() & Qt::ControlModifier)
4267 if (mainWindow->getModMode()==Main::ModModeColor)
4270 setCursor (PickColorCursor);
4273 if (mainWindow->getModMode()==Main::ModModeXLink)
4275 BranchObj *bo_begin=NULL;
4277 bo_begin=(BranchObj*)(lmo);
4279 if (xelection.getBranch() )
4280 bo_begin=xelection.getBranch();
4284 linkingObj_src=bo_begin;
4285 tmpXLink=new XLinkObj (mapScene);
4286 tmpXLink->setBegin (bo_begin);
4287 tmpXLink->setEnd (p);
4288 tmpXLink->setColor(defXLinkColor);
4289 tmpXLink->setWidth(defXLinkWidth);
4290 tmpXLink->updateXLink();
4291 tmpXLink->setVisibility (true);
4295 } // End of modmodes
4299 // Select the clicked object
4302 // Left Button Move Branches
4303 if (e->button() == Qt::LeftButton )
4305 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
4306 //movingObj_start.setY( p.y() - selection->y() );
4307 movingObj_start.setX( p.x() - lmo->x() );
4308 movingObj_start.setY( p.y() - lmo->y() );
4309 movingObj_orgPos.setX (lmo->x() );
4310 movingObj_orgPos.setY (lmo->y() );
4311 movingObj_orgRelPos=lmo->getRelPos();
4313 // If modMode==copy, then we want to "move" the _new_ object around
4314 // then we need the offset from p to the _old_ selection, because of tmp
4315 if (mainWindow->getModMode()==Main::ModModeCopy &&
4316 e->state() & Qt::ControlModifier)
4318 if (xelection.type()==Selection::Branch)
4321 mapCenter->addBranch ((BranchObj*)xelection.single());
4323 xelection.select(mapCenter->getLastBranch());
4324 mapCenter->reposition();
4328 movingObj=xelection.single();
4330 // Middle Button Toggle Scroll
4331 // (On Mac OS X this won't work, but we still have
4332 // a button in the toolbar)
4333 if (e->button() == Qt::MidButton )
4338 { // No MapObj found, we are on the scene itself
4339 // Left Button move Pos of sceneView
4340 if (e->button() == Qt::LeftButton )
4342 movingObj=NULL; // move Content not Obj
4343 movingObj_start=e->globalPos();
4344 movingCont_start=QPointF (
4345 horizontalScrollBar()->value(),
4346 verticalScrollBar()->value());
4347 movingVec=QPointF(0,0);
4348 setCursor(HandOpenCursor);
4353 void MapEditor::mouseMoveEvent(QMouseEvent* e)
4355 QPointF p = mapToScene(e->pos());
4356 LinkableMapObj *lmosel=xelection.single();
4358 // Move the selected MapObj
4359 if ( lmosel && movingObj)
4361 // reset cursor if we are moving and don't copy
4362 if (mainWindow->getModMode()!=Main::ModModeCopy)
4363 setCursor (Qt::ArrowCursor);
4365 // To avoid jumping of the sceneView, only
4366 // ensureSelectionVisible, if not tmp linked
4367 if (!lmosel->hasParObjTmp())
4368 ensureSelectionVisible ();
4370 // Now move the selection, but add relative position
4371 // (movingObj_start) where selection was chosen with
4372 // mousepointer. (This avoids flickering resp. jumping
4373 // of selection back to absPos)
4375 // Check if we could link
4376 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
4379 FloatObj *fio=xelection.getFloatImage();
4382 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4384 fio->updateLink(); //no need for reposition, if we update link here
4387 // Relink float to new mapcenter or branch, if shift is pressed
4388 // Only relink, if selection really has a new parent
4389 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
4390 ( (typeid(*lmo)==typeid(BranchObj)) ||
4391 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
4392 ( lmo != fio->getParObj())
4395 if (typeid(*fio) == typeid(FloatImageObj) &&
4396 ( (typeid(*lmo)==typeid(BranchObj) ||
4397 typeid(*lmo)==typeid(MapCenterObj)) ))
4400 // Also save the move which was done so far
4401 QString pold=qpointfToString(movingObj_orgRelPos);
4402 QString pnow=qpointfToString(fio->getRelPos());
4408 QString("Move %1 to relativ position %2").arg(getName(fio)).arg(pnow));
4409 fio->getParObj()->requestReposition();
4410 mapCenter->reposition();
4412 linkTo (lmo->getSelectString());
4414 //movingObj_orgRelPos=lmosel->getRelPos();
4416 mapCenter->reposition();
4420 { // selection != a FloatObj
4421 if (lmosel->getDepth()==0)
4424 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
4425 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4427 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4428 mapCenter->updateRelPositions();
4431 if (lmosel->getDepth()==1)
4434 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4435 lmosel->setRelPos();
4438 // Move ordinary branch
4439 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
4440 // Add width of bbox here, otherwise alignRelTo will cause jumping around
4441 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
4442 p.y()-movingObj_start.y() +lmosel->getTopPad() );
4444 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
4447 // Maybe we can relink temporary?
4448 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
4449 (typeid(*lmo)==typeid(BranchObj) ||
4450 typeid(*lmo)==typeid(MapCenterObj)) )
4453 if (e->modifiers()==Qt::ControlModifier)
4455 // Special case: CTRL to link below lmo
4456 lmosel->setParObjTmp (lmo,p,+1);
4458 else if (e->modifiers()==Qt::ShiftModifier)
4459 lmosel->setParObjTmp (lmo,p,-1);
4461 lmosel->setParObjTmp (lmo,p,0);
4464 lmosel->unsetParObjTmp();
4466 // reposition subbranch
4467 lmosel->reposition();
4471 } // no FloatImageObj
4475 } // selection && moving_obj
4477 // Draw a link from one branch to another
4480 tmpXLink->setEnd (p);
4481 tmpXLink->updateXLink();
4485 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
4487 QPointF p=e->globalPos();
4488 movingVec.setX(-p.x() + movingObj_start.x() );
4489 movingVec.setY(-p.y() + movingObj_start.y() );
4490 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
4491 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
4496 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
4498 QPointF p = mapToScene(e->pos());
4499 LinkableMapObj *dst;
4500 LinkableMapObj *lmosel=xelection.single();
4501 // Have we been picking color?
4505 setCursor (Qt::ArrowCursor);
4506 // Check if we are over another branch
4507 dst=mapCenter->findMapObj(p, NULL);
4510 if (e->state() & Qt::ShiftModifier)
4511 colorBranch (((BranchObj*)(dst))->getColor());
4513 colorSubtree (((BranchObj*)(dst))->getColor());
4518 // Have we been drawing a link?
4522 // Check if we are over another branch
4523 dst=mapCenter->findMapObj(p, NULL);
4526 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
4527 tmpXLink->updateXLink();
4528 tmpXLink->activate(); //FIXME savestate missing
4529 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );
4538 // Have we been moving something?
4539 if ( lmosel && movingObj )
4541 FloatImageObj *fo=xelection.getFloatImage();
4544 // Moved FloatObj. Maybe we need to reposition
4545 QString pold=qpointfToString(movingObj_orgRelPos);
4546 QString pnow=qpointfToString(fo->getRelPos());
4552 QString("Move %1 to relativ position %2").arg(getName(fo)).arg(pnow));
4554 fo->getParObj()->requestReposition();
4555 mapCenter->reposition();
4558 // Check if we are over another branch, but ignore
4559 // any found LMOs, which are FloatObjs
4560 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
4562 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4565 if (xelection.type() == Selection::MapCenter )
4567 // TODO: Check for problems if graphicsview is resized for
4569 QString pold=qpointfToString(movingObj_orgPos);
4570 QString pnow=qpointfToString(mapCenter->getAbsPos());
4576 QString("Move mapcenter %1 to position %2").arg(getName(mapCenter)).arg(pnow));
4579 if (xelection.type() == Selection::Branch )
4580 { // A branch was moved
4582 // save the position in case we link to mapcenter
4583 QPointF savePos=QPointF (lmosel->getAbsPos() );
4585 // Reset the temporary drawn link to the original one
4586 lmosel->unsetParObjTmp();
4588 // For Redo we may need to save original selection
4589 QString preSelStr=lmosel->getSelectString();
4594 BranchObj* bsel=xelection.getBranch();
4595 BranchObj* bdst=(BranchObj*)dst;
4597 QString preParStr=(bsel->getParObj())->getSelectString();
4598 QString preNum=QString::number (bsel->getNum(),10);
4599 QString preDstParStr;
4601 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4603 preDstParStr=dst->getParObj()->getSelectString();
4604 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4606 if (e->state() & Qt::ControlModifier && dst->getParObj())
4609 preDstParStr=dst->getParObj()->getSelectString();
4610 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4613 preDstParStr=dst->getSelectString();
4614 bsel->linkTo (bdst,-1);
4615 if (dst->getDepth()==0) bsel->move (savePos);
4617 QString postSelStr=lmosel->getSelectString();
4618 QString postNum=QString::number (bsel->getNum(),10);
4620 QString undoCom="linkTo (\""+
4621 preParStr+ "\"," + preNum +"," +
4622 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4624 QString redoCom="linkTo (\""+
4625 preDstParStr + "\"," + postNum + "," +
4626 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4631 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4633 if (lmosel->getDepth()==1)
4635 // The select string might be different _after_ moving around.
4636 // Therefor reposition and then use string of old selection, too
4637 mapCenter->reposition();
4639 QString ps=qpointfToString ( lmosel->getRelPos() );
4641 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4642 preSelStr, "moveRel "+ps,
4643 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4646 // Draw the original link, before selection was moved around
4647 mapCenter->reposition();
4650 // Finally resize scene, if needed
4654 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4657 // maybe we moved View: set old cursor
4658 setCursor (Qt::ArrowCursor);
4662 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4664 if (isSelectBlocked() )
4670 if (e->button() == Qt::LeftButton )
4672 QPointF p = mapToScene(e->pos());
4673 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4674 if (lmo) { // MapObj was found
4675 // First select the MapObj than edit heading
4676 xelection.select(lmo);
4677 mainWindow->editHeading();
4682 void MapEditor::resizeEvent (QResizeEvent* e)
4684 QGraphicsView::resizeEvent( e );
4687 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4689 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4690 // cerr << event->format(i) << endl;
4692 if (event->mimeData()->hasImage())
4693 event->acceptProposedAction();
4695 if (event->mimeData()->hasUrls())
4696 event->acceptProposedAction();
4699 void MapEditor::dragMoveEvent(QDragMoveEvent *)
4703 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4708 void MapEditor::dropEvent(QDropEvent *event)
4710 BranchObj *sel=xelection.getBranch();
4714 foreach (QString format,event->mimeData()->formats())
4715 cout << "MapEditor: Dropped format: "<<format.ascii()<<endl;
4719 if (event->mimeData()->hasImage())
4721 QVariant imageData = event->mimeData()->imageData();
4722 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4724 if (event->mimeData()->hasUrls())
4725 uris=event->mimeData()->urls();
4733 for (int i=0; i<uris.count();i++)
4735 // Workaround to avoid adding empty branches
4736 if (!uris.at(i).toString().isEmpty())
4738 bo=sel->addBranch();
4741 s=uris.at(i).toLocalFile();
4744 QString file = QDir::convertSeparators(s);
4745 heading = QFileInfo(file).baseName();
4747 if (file.endsWith(".vym", false))
4748 bo->setVymLink(file);
4750 bo->setURL(uris.at(i).toString());
4753 bo->setURL(uris.at(i).toString());
4756 if (!heading.isEmpty())
4757 bo->setHeading(heading);
4759 bo->setHeading(uris.at(i).toString());
4763 mapCenter->reposition();
4766 event->acceptProposedAction();
4769 void MapEditor::timerEvent(QTimerEvent *event) //TODO animation
4773 cout << "ME::timerEvent\n";
4775 for (int i=0; i<animObjList.size(); ++i)
4777 animObjList.at(i)->animate();
4778 ((BranchObj*)animObjList.at(i))->move2RelPos (((BranchObj*)animObjList.at(i))->getRelPos() );
4780 mapCenter->reposition();
4784 void MapEditor::sendSelection()
4786 if (netstate!=Server) return;
4787 sendData (QString("select (\"%1\")").arg(xelection.getSelectString()) );
4790 void MapEditor::newServer()
4794 tcpServer = new QTcpServer(this);
4795 if (!tcpServer->listen(QHostAddress::Any,port)) {
4796 QMessageBox::critical(this, "vym server",
4797 QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
4801 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
4804 cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
4807 void MapEditor::connectToServer()
4810 server="salam.suse.de";
4812 clientSocket = new QTcpSocket (this);
4813 clientSocket->abort();
4814 clientSocket->connectToHost(server ,port);
4815 connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
4816 connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
4817 this, SLOT(displayNetworkError(QAbstractSocket::SocketError)));
4819 cout<<"connected to "<<server.ascii()<<" port "<<port<<endl;
4824 void MapEditor::newClient()
4826 QTcpSocket *newClient = tcpServer->nextPendingConnection();
4827 connect(newClient, SIGNAL(disconnected()),
4828 newClient, SLOT(deleteLater()));
4830 cout <<"ME::newClient at "<<newClient->peerAddress().toString().ascii()<<endl;
4832 clientList.append (newClient);
4836 void MapEditor::sendData(const QString &s)
4838 // Create bytearray to send
4840 QDataStream out(&block, QIODevice::WriteOnly);
4841 out.setVersion(QDataStream::Qt_4_0);
4843 // Reserve some space for blocksize
4846 // Write sendCounter
4847 out << sendCounter++;
4852 // Go back and write blocksize so far
4853 out.device()->seek(0);
4854 quint16 bs=(quint16)(block.size() - 2*sizeof(quint16));
4857 cout << "ME::sendData bs="<<bs<<" counter="<<sendCounter<<" s="<<s.ascii()<<endl;
4859 for (int i=0; i<clientList.size(); ++i)
4861 //cout << "Sending \""<<s.ascii()<<"\" to "<<clientList.at(i)->peerAddress().toString().ascii()<<endl;
4862 clientList.at(i)->write (block);
4866 void MapEditor::readData ()
4868 cout <<"readData bytesAvail="<<clientSocket->bytesAvailable()<<endl;
4872 QDataStream in(clientSocket);
4873 in.setVersion(QDataStream::Qt_4_0);
4880 in.readBytes (sp,l);
4881 cout << " sp="<<sp<<" l="<<l<<endl;
4884 cout << " t="<<t.ascii()<<endl;
4886 while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) )
4888 //cout <<"readData 1 bytesAvail="<<clientSocket->bytesAvailable()<<" readData bS="<<blockSize<<" rC="<<recCounter<<endl;
4891 //cout << "Received: "<< recCounter<< " "<<s.ascii() <<endl;
4892 cout <<" bytesAvail="<<clientSocket->bytesAvailable()<<" bS="<<blockSize<<" counter="<<recCounter<<" s="<<s.ascii()<<endl;
4897 void MapEditor::displayNetworkError(QAbstractSocket::SocketError socketError)
4899 switch (socketError) {
4900 case QAbstractSocket::RemoteHostClosedError:
4902 case QAbstractSocket::HostNotFoundError:
4903 QMessageBox::information(this, __VYM_NAME " Network client",
4904 "The host was not found. Please check the "
4905 "host name and port settings.");
4907 case QAbstractSocket::ConnectionRefusedError:
4908 QMessageBox::information(this, __VYM_NAME " Network client",
4909 "The connection was refused by the peer. "
4910 "Make sure the fortune server is running, "
4911 "and check that the host name and port "
4912 "settings are correct.");
4915 QMessageBox::information(this, __VYM_NAME " Network client",
4916 QString("The following error occurred: %1.")
4917 .arg(clientSocket->errorString()));
4921 void MapEditor::autosave()
4923 // Disable autosave, while we have gone back in history
4924 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
4925 if (redosAvail>0) return;
4928 if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() )
4929 mainWindow->fileSave (this);
4933 /*TODO not needed? void MapEditor::contentsDropEvent(QDropEvent *event)
4936 } else if (event->provides("application/x-moz-file-promise-url") &&
4937 event->provides("application/x-moz-nativeimage"))
4939 // Contains url to the img src in unicode16
4940 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
4941 QString url = QString((const QChar*)d.data(),d.size()/2);
4945 } else if (event->provides ("text/uri-list"))
4946 { // Uris provided e.g. by konqueror
4947 Q3UriDrag::decode (event,uris);
4948 } else if (event->provides ("_NETSCAPE_URL"))
4949 { // Uris provided by Mozilla
4950 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
4953 } else if (event->provides("text/html")) {
4955 // Handels text mime types
4956 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
4957 QByteArray d = event->encodedData("text/html");
4960 text = QString((const QChar*)d.data(),d.size()/2);
4964 textEditor->setText(text);
4968 } else if (event->provides("text/plain")) {
4969 QByteArray d = event->encodedData("text/plain");
4972 text = QString((const QChar*)d.data(),d.size()/2);
4976 textEditor->setText(text);
4986 bool isUnicode16(const QByteArray &d)
4988 // TODO: make more precise check for unicode 16.
4989 // Guess unicode16 if any of second bytes are zero
4990 unsigned int length = max(0,d.size()-2)/2;
4991 for (unsigned int i = 0; i<length ; i++)
4992 if (d.at(i*2+1)==0) return true;
4996 void MapEditor::addFloatImageInt (const QPixmap &img)
4998 BranchObj *bo=xelection.getBranch();
5001 FloatImageObj *fio=bo->addFloatImage();
5003 fio->setOriginalFilename("No original filename (image added by dropevent)");
5004 QString s=bo->getSelectString();
5005 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio );
5006 saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image");
5007 mapCenter->reposition();
5014 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
5016 if (!imageBuffer) imageBuffer = new QBuffer();
5017 if (!imageBuffer->isOpen()) {
5018 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
5020 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
5024 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
5026 if (nop->state()==Q3NetworkProtocol::StDone) {
5027 QPixmap img(imageBuffer->buffer());
5028 addFloatImageInt (img);
5032 imageBuffer->close();
5034 imageBuffer->close();
5041 void MapEditor::fetchImage(const QString &url)
5044 urlOperator->stop();
5045 disconnect(urlOperator);
5049 urlOperator = new Q3UrlOperator(url);
5050 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
5051 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
5053 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
5054 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));