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"
22 #include "xml-freemind.h"
26 extern TextEditor *textEditor;
27 extern int statusbarTime;
28 extern Main *mainWindow;
29 extern QString tmpVymDir;
30 extern QString clipboardDir;
31 extern QString clipboardFile;
32 extern bool clipboardEmpty;
34 extern FlagRowObj *standardFlagsDefault;
36 extern QMenu* branchContextMenu;
37 extern QMenu* branchAddContextMenu;
38 extern QMenu* branchRemoveContextMenu;
39 extern QMenu* branchLinksContextMenu;
40 extern QMenu* branchXLinksContextMenuEdit;
41 extern QMenu* branchXLinksContextMenuFollow;
42 extern QMenu* floatimageContextMenu;
43 extern QMenu* canvasContextMenu;
46 extern Settings settings;
47 extern ImageIO imageIO;
49 extern QString vymName;
50 extern QString vymVersion;
52 extern QString iconPath;
53 extern QDir vymBaseDir;
54 extern QDir lastImageDir;
55 extern QDir lastFileDir;
57 int MapEditor::mapNum=0; // make instance
59 ///////////////////////////////////////////////////////////////////////
60 ///////////////////////////////////////////////////////////////////////
61 MapEditor::MapEditor( QWidget* parent) :
64 //cout << "Constructor ME "<<this<<endl;
68 mapScene= new QGraphicsScene(parent);
69 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
70 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
75 mapCenter = new MapCenterObj(mapScene);
76 mapCenter->setVisibility (true);
77 mapCenter->setMapEditor (this);
78 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
79 //mapCenter->move(mapScene->width()/2-mapCenter->width()/2,mapScene->height()/2-mapCenter->height()/2);
84 defLinkColor=QColor (0,0,255);
85 defXLinkColor=QColor (180,180,180);
86 linkcolorhint=LinkableMapObj::DefaultColor;
87 linkstyle=LinkableMapObj::PolyParabel;
89 // Create bitmap cursors, platform dependant
90 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
91 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
92 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
93 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
95 setFocusPolicy (Qt::StrongFocus);
104 xelection.setMapEditor (this);
105 xelection.unselect();
108 defXLinkColor=QColor (230,230,230);
116 fileName=tr("unnamed");
119 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
120 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
121 mainWindow->updateHistory (undoSet);
123 // Initialize find routine
130 blockReposition=false;
131 blockSaveState=false;
135 // Create temporary files
142 setAcceptDrops (true);
144 mapCenter->reposition(); // for positioning heading
148 //timerId = startTimer(100);
151 autosaveTimer=new QTimer (this);
152 connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
157 // Attributes //FIXME testing only...
160 attrTable= new AttributeTable();
162 ad=attrTable->addKey (k,StringList);
166 sl <<"val 1"<<"val 2"<< "val 3";
167 ad->setValue (QVariant (sl));
169 //attrTable->addValue ("Key A","P 1");
170 //attrTable->addValue ("Key A","P 2");
171 //attrTable->addValue ("Key A","P 3");
172 //attrTable->addValue ("Key A","P 4");
174 ad=attrTable->addKey (k,FreeString);
177 //attrTable->addValue ("Key B","w1");
178 //attrTable->addValue ("Key B","w2");
180 k="C - UniqueString";
181 ad=attrTable->addKey (k,UniqueString);
184 //attrTable->addKey ("Key Prio");
185 //attrTable->addValue ("Key Prio","Prio 1");
186 //attrTable->addValue ("Key Prio","Prio 2");
190 MapEditor::~MapEditor()
192 //cout <<"Destructor MapEditor\n";
193 autosaveTimer->stop();
195 // tmpMapDir is in tmpVymDir, so it gets removed automagically when vym closes
197 //removeDir(QDir(tmpMapDir));
200 MapCenterObj* MapEditor::getMapCenter()
205 QGraphicsScene * MapEditor::getScene()
210 MapEditor::State MapEditor::getState()
215 void MapEditor::setStateEditHeading(bool s)
219 if (state==Idle) state=EditHeading;
225 bool MapEditor::isRepositionBlocked()
227 return blockReposition;
230 void MapEditor::setSaveStateBlocked(bool b)
235 bool MapEditor::isSelectBlocked()
237 if (state==EditHeading)
243 QString MapEditor::getName (const LinkableMapObj *lmo)
246 if (!lmo) return QString("Error: NULL has no name!");
248 if ((typeid(*lmo) == typeid(BranchObj) ||
249 typeid(*lmo) == typeid(MapCenterObj)))
252 s=(((BranchObj*)lmo)->getHeading());
253 if (s=="") s="unnamed";
254 return QString("branch (%1)").arg(s);
256 if ((typeid(*lmo) == typeid(FloatImageObj) ))
257 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
258 return QString("Unknown type has no name!");
261 void MapEditor::makeTmpDirs()
263 // Create unique temporary directories
264 tmpMapDir = tmpVymDir+QString("/mapeditor-%1").arg(mapNum);
265 histPath = tmpMapDir+"/history";
270 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
272 // tmpdir temporary directory to which data will be written
273 // prefix mapname, which will be appended to images etc.
274 // writeflags Only write flags for "real" save of map, not undo
275 // offset offset of bbox of whole map in scene.
276 // Needed for XML export
282 case LinkableMapObj::Line:
285 case LinkableMapObj::Parabel:
288 case LinkableMapObj::PolyLine:
292 ls="StylePolyParabel";
296 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
298 if (linkcolorhint==LinkableMapObj::HeadingColor)
299 colhint=attribut("linkColorHint","HeadingColor");
301 QString mapAttr=attribut("version",vymVersion);
302 if (!saveSel || saveSel==mapCenter)
303 mapAttr+= attribut("author",mapCenter->getAuthor()) +
304 attribut("comment",mapCenter->getComment()) +
305 attribut("date",mapCenter->getDate()) +
306 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
307 attribut("selectionColor", xelection.getColor().name() ) +
308 attribut("linkStyle", ls ) +
309 attribut("linkColor", defLinkColor.name() ) +
310 attribut("defXLinkColor", defXLinkColor.name() ) +
311 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
313 s+=beginElement("vymmap",mapAttr);
316 // Find the used flags while traversing the tree
317 standardFlagsDefault->resetUsedCounter();
319 // Reset the counters before saving
320 // TODO constr. of FIO creates lots of objects, better do this in some other way...
321 FloatImageObj (mapScene).resetSaveCounter();
323 // Build xml recursivly
324 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
325 // Save complete map, if saveSel not set
326 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
329 if ( typeid(*saveSel) == typeid(BranchObj) )
331 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
332 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
334 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
337 // Save local settings
338 s+=settings.getDataXML (destPath);
341 if (!xelection.isEmpty() && !saveSel )
342 s+=valueElement("select",xelection.getSelectString());
345 s+=endElement("vymmap");
348 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
352 QString MapEditor::getHistoryDir()
354 QString histName(QString("history-%1").arg(curStep));
355 return (tmpMapDir+"/"+histName);
358 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
360 sendData(redoCom); //FIXME testing
365 if (blockSaveState) return;
367 if (debug) cout << "ME::saveState() for "<<mapName.ascii()<<endl;
369 // Find out current undo directory
370 if (undosAvail<stepsTotal) undosAvail++;
372 if (curStep>stepsTotal) curStep=1;
374 QString backupXML="";
375 QString histDir=getHistoryDir();
376 QString bakMapPath=histDir+"/map.xml";
378 // Create histDir if not available
381 makeSubDirs (histDir);
383 // Save depending on how much needs to be saved
385 backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
387 QString undoCommand="";
388 if (savemode==UndoCommand)
392 else if (savemode==PartOfMap )
395 undoCommand.replace ("PATH",bakMapPath);
398 if (!backupXML.isEmpty())
399 // Write XML Data to disk
400 saveStringToDisk (bakMapPath,backupXML);
402 // We would have to save all actions in a tree, to keep track of
403 // possible redos after a action. Possible, but we are too lazy: forget about redos.
406 // Write the current state to disk
407 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
408 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
409 undoSet.setEntry ("/history/curStep",QString::number(curStep));
410 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
411 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
412 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
413 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
414 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
415 undoSet.setEntry (QString("/history/version"),vymVersion);
416 undoSet.writeSettings(histPath);
420 // TODO remove after testing
421 //cout << " into="<< histPath.toStdString()<<endl;
422 cout << " stepsTotal="<<stepsTotal<<
423 ", undosAvail="<<undosAvail<<
424 ", redosAvail="<<redosAvail<<
425 ", curStep="<<curStep<<endl;
426 cout << " ---------------------------"<<endl;
427 cout << " comment="<<comment.toStdString()<<endl;
428 cout << " undoCom="<<undoCommand.toStdString()<<endl;
429 cout << " undoSel="<<undoSelection.toStdString()<<endl;
430 cout << " redoCom="<<redoCom.toStdString()<<endl;
431 cout << " redoSel="<<redoSelection.toStdString()<<endl;
432 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
433 cout << " ---------------------------"<<endl;
436 mainWindow->updateHistory (undoSet);
442 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
444 // save the selected part of the map, Undo will replace part of map
445 QString undoSelection="";
447 undoSelection=undoSel->getSelectString();
449 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
450 QString redoSelection="";
452 redoSelection=undoSel->getSelectString();
454 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
457 saveState (PartOfMap,
458 undoSelection, "addMapReplace (\"PATH\")",
464 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
468 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
471 QString undoSelection=redoSel->getParObj()->getSelectString();
472 QString redoSelection=redoSel->getSelectString();
473 if (typeid(*redoSel) == typeid(BranchObj) )
475 // save the selected branch of the map, Undo will insert part of map
476 saveState (PartOfMap,
477 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
478 redoSelection, "delete ()",
485 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
487 // "Normal" savestate: save commands, selections and comment
488 // so just save commands for undo and redo
489 // and use current selection
491 QString redoSelection="";
492 if (redoSel) redoSelection=redoSel->getSelectString();
493 QString undoSelection="";
494 if (undoSel) undoSelection=undoSel->getSelectString();
496 saveState (UndoCommand,
503 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
505 // "Normal" savestate: save commands, selections and comment
506 // so just save commands for undo and redo
507 // and use current selection
508 saveState (UndoCommand,
516 void MapEditor::parseAtom(const QString &atom)
518 BranchObj *selb=xelection.getBranch();
524 // Split string s into command and parameters
525 parser.parseAtom (atom);
526 QString com=parser.getCommand();
529 /////////////////////////////////////////////////////////////////////
530 if (com=="addBranch")
532 if (xelection.isEmpty())
534 parser.setError (Aborted,"Nothing selected");
537 parser.setError (Aborted,"Type of selection is not a branch");
542 if (parser.checkParCount(pl))
544 if (parser.parCount()==0)
548 n=parser.parInt (ok,0);
549 if (ok ) addNewBranch (n);
553 /////////////////////////////////////////////////////////////////////
554 } else if (com=="addBranchBefore")
556 if (xelection.isEmpty())
558 parser.setError (Aborted,"Nothing selected");
561 parser.setError (Aborted,"Type of selection is not a branch");
564 if (parser.parCount()==0)
566 addNewBranchBefore ();
569 /////////////////////////////////////////////////////////////////////
570 } else if (com==QString("addMapReplace"))
572 if (xelection.isEmpty())
574 parser.setError (Aborted,"Nothing selected");
577 parser.setError (Aborted,"Type of selection is not a branch");
578 } else if (parser.checkParCount(1))
580 //s=parser.parString (ok,0); // selection
581 t=parser.parString (ok,0); // path to map
582 if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
583 addMapReplaceInt(selb->getSelectString(),t);
585 /////////////////////////////////////////////////////////////////////
586 } else if (com==QString("addMapInsert"))
588 if (xelection.isEmpty())
590 parser.setError (Aborted,"Nothing selected");
593 parser.setError (Aborted,"Type of selection is not a branch");
596 if (parser.checkParCount(2))
598 t=parser.parString (ok,0); // path to map
599 n=parser.parInt(ok,1); // position
600 if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
601 addMapInsertInt(t,n);
604 /////////////////////////////////////////////////////////////////////
605 } else if (com=="clearFlags")
607 if (xelection.isEmpty() )
609 parser.setError (Aborted,"Nothing selected");
612 parser.setError (Aborted,"Type of selection is not a branch");
613 } else if (parser.checkParCount(0))
615 selb->clearStandardFlags();
616 selb->updateFlagsToolbar();
618 /////////////////////////////////////////////////////////////////////
619 } else if (com=="colorBranch")
621 if (xelection.isEmpty())
623 parser.setError (Aborted,"Nothing selected");
626 parser.setError (Aborted,"Type of selection is not a branch");
627 } else if (parser.checkParCount(1))
629 QColor c=parser.parColor (ok,0);
630 if (ok) colorBranch (c);
632 /////////////////////////////////////////////////////////////////////
633 } else if (com=="colorSubtree")
635 if (xelection.isEmpty())
637 parser.setError (Aborted,"Nothing selected");
640 parser.setError (Aborted,"Type of selection is not a branch");
641 } else if (parser.checkParCount(1))
643 QColor c=parser.parColor (ok,0);
644 if (ok) colorSubtree (c);
646 /////////////////////////////////////////////////////////////////////
647 } else if (com=="copy")
649 if (xelection.isEmpty())
651 parser.setError (Aborted,"Nothing selected");
654 parser.setError (Aborted,"Type of selection is not a branch");
655 } else if (parser.checkParCount(0))
657 //FIXME missing action for copy
659 /////////////////////////////////////////////////////////////////////
660 } else if (com=="cut")
662 if (xelection.isEmpty())
664 parser.setError (Aborted,"Nothing selected");
665 } else if ( xelection.type()!=Selection::Branch &&
666 xelection.type()!=Selection::MapCenter &&
667 xelection.type()!=Selection::FloatImage )
669 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
670 } else if (parser.checkParCount(0))
674 /////////////////////////////////////////////////////////////////////
675 } else if (com=="delete")
677 if (xelection.isEmpty())
679 parser.setError (Aborted,"Nothing selected");
680 } else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage )
682 parser.setError (Aborted,"Type of selection is wrong.");
683 } else if (parser.checkParCount(0))
687 /////////////////////////////////////////////////////////////////////
688 } else if (com=="deleteKeepChilds")
690 if (xelection.isEmpty())
692 parser.setError (Aborted,"Nothing selected");
695 parser.setError (Aborted,"Type of selection is not a branch");
696 } else if (parser.checkParCount(0))
700 /////////////////////////////////////////////////////////////////////
701 } else if (com=="deleteChilds")
703 if (xelection.isEmpty())
705 parser.setError (Aborted,"Nothing selected");
708 parser.setError (Aborted,"Type of selection is not a branch");
709 } else if (parser.checkParCount(0))
713 /////////////////////////////////////////////////////////////////////
714 } else if (com=="exportASCII")
718 if (parser.parCount()>=1)
719 // Hey, we even have a filename
720 fname=parser.parString(ok,0);
723 parser.setError (Aborted,"Could not read filename");
726 exportASCII (fname,false);
728 /////////////////////////////////////////////////////////////////////
729 } else if (com=="exportImage")
733 if (parser.parCount()>=2)
734 // Hey, we even have a filename
735 fname=parser.parString(ok,0);
738 parser.setError (Aborted,"Could not read filename");
741 QString format="PNG";
742 if (parser.parCount()>=2)
744 format=parser.parString(ok,1);
746 exportImage (fname,false,format);
748 /////////////////////////////////////////////////////////////////////
749 } else if (com=="exportXHTML")
753 if (parser.parCount()>=2)
754 // Hey, we even have a filename
755 fname=parser.parString(ok,1);
758 parser.setError (Aborted,"Could not read filename");
761 exportXHTML (fname,false);
763 /////////////////////////////////////////////////////////////////////
764 } else if (com=="exportXML")
768 if (parser.parCount()>=2)
769 // Hey, we even have a filename
770 fname=parser.parString(ok,1);
773 parser.setError (Aborted,"Could not read filename");
776 exportXML (fname,false);
778 /////////////////////////////////////////////////////////////////////
779 } else if (com=="importDir")
781 if (xelection.isEmpty())
783 parser.setError (Aborted,"Nothing selected");
786 parser.setError (Aborted,"Type of selection is not a branch");
787 } else if (parser.checkParCount(1))
789 s=parser.parString(ok,0);
790 if (ok) importDirInt(s);
792 /////////////////////////////////////////////////////////////////////
793 } else if (com=="linkTo")
795 if (xelection.isEmpty())
797 parser.setError (Aborted,"Nothing selected");
800 if (parser.checkParCount(4))
802 // 0 selectstring of parent
803 // 1 num in parent (for branches)
804 // 2,3 x,y of mainbranch or mapcenter
805 s=parser.parString(ok,0);
806 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
809 if (typeid(*dst) == typeid(BranchObj) )
811 // Get number in parent
812 n=parser.parInt (ok,1);
815 selb->linkTo ((BranchObj*)(dst),n);
818 } else if (typeid(*dst) == typeid(MapCenterObj) )
820 selb->linkTo ((BranchObj*)(dst),-1);
821 // Get coordinates of mainbranch
822 x=parser.parDouble(ok,2);
825 y=parser.parDouble(ok,3);
835 } else if ( xelection.type() == Selection::FloatImage)
837 if (parser.checkParCount(1))
839 // 0 selectstring of parent
840 s=parser.parString(ok,0);
841 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
844 if (typeid(*dst) == typeid(BranchObj) ||
845 typeid(*dst) == typeid(MapCenterObj))
846 linkTo (dst->getSelectString());
848 parser.setError (Aborted,"Destination is not a branch");
851 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
852 /////////////////////////////////////////////////////////////////////
853 } else if (com=="loadImage")
855 if (xelection.isEmpty())
857 parser.setError (Aborted,"Nothing selected");
860 parser.setError (Aborted,"Type of selection is not a branch");
861 } else if (parser.checkParCount(1))
863 s=parser.parString(ok,0);
864 if (ok) loadFloatImageInt (s);
866 /////////////////////////////////////////////////////////////////////
867 } else if (com=="moveBranchUp")
869 if (xelection.isEmpty() )
871 parser.setError (Aborted,"Nothing selected");
874 parser.setError (Aborted,"Type of selection is not a branch");
875 } else if (parser.checkParCount(0))
879 /////////////////////////////////////////////////////////////////////
880 } else if (com=="moveBranchDown")
882 if (xelection.isEmpty() )
884 parser.setError (Aborted,"Nothing selected");
887 parser.setError (Aborted,"Type of selection is not a branch");
888 } else if (parser.checkParCount(0))
892 /////////////////////////////////////////////////////////////////////
893 } else if (com=="move")
895 if (xelection.isEmpty() )
897 parser.setError (Aborted,"Nothing selected");
898 } else if ( xelection.type()!=Selection::Branch &&
899 xelection.type()!=Selection::MapCenter &&
900 xelection.type()!=Selection::FloatImage )
902 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
903 } else if (parser.checkParCount(2))
905 x=parser.parDouble (ok,0);
908 y=parser.parDouble (ok,1);
912 /////////////////////////////////////////////////////////////////////
913 } else if (com=="moveRel")
915 if (xelection.isEmpty() )
917 parser.setError (Aborted,"Nothing selected");
918 } else if ( xelection.type()!=Selection::Selection::Branch &&
919 xelection.type()!=Selection::Selection::MapCenter &&
920 xelection.type()!=Selection::Selection::FloatImage )
922 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
923 } else if (parser.checkParCount(2))
925 x=parser.parDouble (ok,0);
928 y=parser.parDouble (ok,1);
929 if (ok) moveRel (x,y);
932 /////////////////////////////////////////////////////////////////////
933 } else if (com=="nop")
935 /////////////////////////////////////////////////////////////////////
936 } else if (com=="paste")
938 if (xelection.isEmpty() )
940 parser.setError (Aborted,"Nothing selected");
943 parser.setError (Aborted,"Type of selection is not a branch");
944 } else if (parser.checkParCount(1))
946 n=parser.parInt (ok,0);
947 if (ok) pasteNoSave(n);
949 /////////////////////////////////////////////////////////////////////
950 } else if (com=="qa")
952 if (xelection.isEmpty() )
954 parser.setError (Aborted,"Nothing selected");
957 parser.setError (Aborted,"Type of selection is not a branch");
958 } else if (parser.checkParCount(4))
961 c=parser.parString (ok,0);
964 parser.setError (Aborted,"No comment given");
967 s=parser.parString (ok,1);
970 parser.setError (Aborted,"First parameter is not a string");
973 t=parser.parString (ok,2);
976 parser.setError (Aborted,"Condition is not a string");
979 u=parser.parString (ok,3);
982 parser.setError (Aborted,"Third parameter is not a string");
987 parser.setError (Aborted,"Unknown type: "+s);
992 parser.setError (Aborted,"Unknown operator: "+t);
997 parser.setError (Aborted,"Type of selection is not a branch");
1000 if (selb->getHeading() == u)
1002 cout << "PASSED: " << c.ascii() << endl;
1005 cout << "FAILED: " << c.ascii() << endl;
1015 /////////////////////////////////////////////////////////////////////
1016 } else if (com=="saveImage")
1018 FloatImageObj *fio=xelection.getFloatImage();
1021 parser.setError (Aborted,"Type of selection is not an image");
1022 } else if (parser.checkParCount(2))
1024 s=parser.parString(ok,0);
1027 t=parser.parString(ok,1);
1028 if (ok) saveFloatImageInt (fio,t,s);
1031 /////////////////////////////////////////////////////////////////////
1032 } else if (com=="scroll")
1034 if (xelection.isEmpty() )
1036 parser.setError (Aborted,"Nothing selected");
1039 parser.setError (Aborted,"Type of selection is not a branch");
1040 } else if (parser.checkParCount(0))
1042 if (!scrollBranch (selb))
1043 parser.setError (Aborted,"Could not scroll branch");
1045 /////////////////////////////////////////////////////////////////////
1046 } else if (com=="select")
1048 if (parser.checkParCount(1))
1050 s=parser.parString(ok,0);
1053 /////////////////////////////////////////////////////////////////////
1054 } else if (com=="selectLastBranch")
1056 if (xelection.isEmpty() )
1058 parser.setError (Aborted,"Nothing selected");
1061 parser.setError (Aborted,"Type of selection is not a branch");
1062 } else if (parser.checkParCount(0))
1064 BranchObj *bo=selb->getLastBranch();
1066 parser.setError (Aborted,"Could not select last branch");
1070 /////////////////////////////////////////////////////////////////////
1071 } else if (com=="selectLastImage")
1073 if (xelection.isEmpty() )
1075 parser.setError (Aborted,"Nothing selected");
1078 parser.setError (Aborted,"Type of selection is not a branch");
1079 } else if (parser.checkParCount(0))
1081 FloatImageObj *fio=selb->getLastFloatImage();
1083 parser.setError (Aborted,"Could not select last image");
1087 /////////////////////////////////////////////////////////////////////
1088 } else if (com=="selectLatestAdded")
1090 if (latestSelection.isEmpty() )
1092 parser.setError (Aborted,"No latest added object");
1095 if (!select (latestSelection))
1096 parser.setError (Aborted,"Could not select latest added object "+latestSelection);
1098 /////////////////////////////////////////////////////////////////////
1099 } else if (com=="setFrameType")
1101 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1103 parser.setError (Aborted,"Type of selection does not allow setting frame type");
1105 else if (parser.checkParCount(1))
1107 s=parser.parString(ok,0);
1108 if (ok) setFrameType (s);
1110 /////////////////////////////////////////////////////////////////////
1111 } else if (com=="setFramePenColor")
1113 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1115 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
1117 else if (parser.checkParCount(1))
1119 QColor c=parser.parColor(ok,0);
1120 if (ok) setFramePenColor (c);
1122 /////////////////////////////////////////////////////////////////////
1123 } else if (com=="setFrameBrushColor")
1125 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1127 parser.setError (Aborted,"Type of selection does not allow setting brush color");
1129 else if (parser.checkParCount(1))
1131 QColor c=parser.parColor(ok,0);
1132 if (ok) setFrameBrushColor (c);
1134 /////////////////////////////////////////////////////////////////////
1135 } else if (com=="setFramePadding")
1137 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1139 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
1141 else if (parser.checkParCount(1))
1143 n=parser.parInt(ok,0);
1144 if (ok) setFramePadding(n);
1146 /////////////////////////////////////////////////////////////////////
1147 } else if (com=="setFrameBorderWidth")
1149 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1151 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
1153 else if (parser.checkParCount(1))
1155 n=parser.parInt(ok,0);
1156 if (ok) setFrameBorderWidth (n);
1158 /////////////////////////////////////////////////////////////////////
1159 } else if (com=="setMapAuthor")
1161 if (parser.checkParCount(1))
1163 s=parser.parString(ok,0);
1164 if (ok) setMapAuthor (s);
1166 /////////////////////////////////////////////////////////////////////
1167 } else if (com=="setMapComment")
1169 if (parser.checkParCount(1))
1171 s=parser.parString(ok,0);
1172 if (ok) setMapComment(s);
1174 /////////////////////////////////////////////////////////////////////
1175 } else if (com=="setMapBackgroundColor")
1177 if (xelection.isEmpty() )
1179 parser.setError (Aborted,"Nothing selected");
1180 } else if (! xelection.getBranch() )
1182 parser.setError (Aborted,"Type of selection is not a branch");
1183 } else if (parser.checkParCount(1))
1185 QColor c=parser.parColor (ok,0);
1186 if (ok) setMapBackgroundColor (c);
1188 /////////////////////////////////////////////////////////////////////
1189 } else if (com=="setMapDefLinkColor")
1191 if (xelection.isEmpty() )
1193 parser.setError (Aborted,"Nothing selected");
1196 parser.setError (Aborted,"Type of selection is not a branch");
1197 } else if (parser.checkParCount(1))
1199 QColor c=parser.parColor (ok,0);
1200 if (ok) setMapDefLinkColor (c);
1202 /////////////////////////////////////////////////////////////////////
1203 } else if (com=="setMapLinkStyle")
1205 if (parser.checkParCount(1))
1207 s=parser.parString (ok,0);
1208 if (ok) setMapLinkStyle(s);
1210 /////////////////////////////////////////////////////////////////////
1211 } else if (com=="setHeading")
1213 if (xelection.isEmpty() )
1215 parser.setError (Aborted,"Nothing selected");
1218 parser.setError (Aborted,"Type of selection is not a branch");
1219 } else if (parser.checkParCount(1))
1221 s=parser.parString (ok,0);
1225 /////////////////////////////////////////////////////////////////////
1226 } else if (com=="setHideExport")
1228 if (xelection.isEmpty() )
1230 parser.setError (Aborted,"Nothing selected");
1231 } else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage)
1233 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1234 } else if (parser.checkParCount(1))
1236 b=parser.parBool(ok,0);
1237 if (ok) setHideExport (b);
1239 /////////////////////////////////////////////////////////////////////
1240 } else if (com=="setIncludeImagesHorizontally")
1242 if (xelection.isEmpty() )
1244 parser.setError (Aborted,"Nothing selected");
1247 parser.setError (Aborted,"Type of selection is not a branch");
1248 } else if (parser.checkParCount(1))
1250 b=parser.parBool(ok,0);
1251 if (ok) setIncludeImagesHor(b);
1253 /////////////////////////////////////////////////////////////////////
1254 } else if (com=="setIncludeImagesVertically")
1256 if (xelection.isEmpty() )
1258 parser.setError (Aborted,"Nothing selected");
1261 parser.setError (Aborted,"Type of selection is not a branch");
1262 } else if (parser.checkParCount(1))
1264 b=parser.parBool(ok,0);
1265 if (ok) setIncludeImagesVer(b);
1267 /////////////////////////////////////////////////////////////////////
1268 } else if (com=="setHideLinkUnselected")
1270 if (xelection.isEmpty() )
1272 parser.setError (Aborted,"Nothing selected");
1273 } else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1275 parser.setError (Aborted,"Type of selection does not allow hiding the link");
1276 } else if (parser.checkParCount(1))
1278 b=parser.parBool(ok,0);
1279 if (ok) setHideLinkUnselected(b);
1281 /////////////////////////////////////////////////////////////////////
1282 } else if (com=="setSelectionColor")
1284 if (parser.checkParCount(1))
1286 QColor c=parser.parColor (ok,0);
1287 if (ok) setSelectionColorInt (c);
1289 /////////////////////////////////////////////////////////////////////
1290 } else if (com=="setURL")
1292 if (xelection.isEmpty() )
1294 parser.setError (Aborted,"Nothing selected");
1297 parser.setError (Aborted,"Type of selection is not a branch");
1298 } else if (parser.checkParCount(1))
1300 s=parser.parString (ok,0);
1303 /////////////////////////////////////////////////////////////////////
1304 } else if (com=="setVymLink")
1306 if (xelection.isEmpty() )
1308 parser.setError (Aborted,"Nothing selected");
1311 parser.setError (Aborted,"Type of selection is not a branch");
1312 } else if (parser.checkParCount(1))
1314 s=parser.parString (ok,0);
1315 if (ok) setVymLinkInt(s);
1318 /////////////////////////////////////////////////////////////////////
1319 else if (com=="setFlag")
1321 if (xelection.isEmpty() )
1323 parser.setError (Aborted,"Nothing selected");
1326 parser.setError (Aborted,"Type of selection is not a branch");
1327 } else if (parser.checkParCount(1))
1329 s=parser.parString(ok,0);
1332 selb->activateStandardFlag(s);
1333 selb->updateFlagsToolbar();
1336 /////////////////////////////////////////////////////////////////////
1337 } else if (com=="setFrameType")
1339 if (xelection.isEmpty() )
1341 parser.setError (Aborted,"Nothing selected");
1344 parser.setError (Aborted,"Type of selection is not a branch");
1345 } else if (parser.checkParCount(1))
1347 s=parser.parString(ok,0);
1351 /////////////////////////////////////////////////////////////////////
1352 } else if (com=="sortChildren")
1354 if (xelection.isEmpty() )
1356 parser.setError (Aborted,"Nothing selected");
1359 parser.setError (Aborted,"Type of selection is not a branch");
1360 } else if (parser.checkParCount(0))
1364 /////////////////////////////////////////////////////////////////////
1365 } else if (com=="toggleFlag")
1367 if (xelection.isEmpty() )
1369 parser.setError (Aborted,"Nothing selected");
1372 parser.setError (Aborted,"Type of selection is not a branch");
1373 } else if (parser.checkParCount(1))
1375 s=parser.parString(ok,0);
1378 selb->toggleStandardFlag(s);
1379 selb->updateFlagsToolbar();
1382 /////////////////////////////////////////////////////////////////////
1383 } else if (com=="unscroll")
1385 if (xelection.isEmpty() )
1387 parser.setError (Aborted,"Nothing selected");
1390 parser.setError (Aborted,"Type of selection is not a branch");
1391 } else if (parser.checkParCount(0))
1393 if (!unscrollBranch (selb))
1394 parser.setError (Aborted,"Could not unscroll branch");
1396 /////////////////////////////////////////////////////////////////////
1397 } else if (com=="unscrollChilds")
1399 if (xelection.isEmpty() )
1401 parser.setError (Aborted,"Nothing selected");
1404 parser.setError (Aborted,"Type of selection is not a branch");
1405 } else if (parser.checkParCount(0))
1409 /////////////////////////////////////////////////////////////////////
1410 } else if (com=="unsetFlag")
1412 if (xelection.isEmpty() )
1414 parser.setError (Aborted,"Nothing selected");
1417 parser.setError (Aborted,"Type of selection is not a branch");
1418 } else if (parser.checkParCount(1))
1420 s=parser.parString(ok,0);
1423 selb->deactivateStandardFlag(s);
1424 selb->updateFlagsToolbar();
1428 parser.setError (Aborted,"Unknown command");
1431 if (parser.errorLevel()==NoError)
1433 // setChanged(); FIXME should not be called e.g. for export?!
1434 mapCenter->reposition();
1438 // TODO Error handling
1439 qWarning("MapEditor::parseAtom: Error!");
1440 qWarning(parser.errorMessage());
1444 void MapEditor::runScript (QString script)
1446 parser.setScript (script);
1448 while (parser.next() )
1449 parseAtom(parser.getAtom());
1452 bool MapEditor::isDefault()
1457 bool MapEditor::hasChanged()
1462 void MapEditor::setChanged()
1465 autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
1473 void MapEditor::closeMap()
1475 // Unselect before disabling the toolbar actions
1476 if (!xelection.isEmpty() ) xelection.unselect();
1484 void MapEditor::setFilePath(QString fpath, QString destname)
1486 if (fpath.isEmpty() || fpath=="")
1493 filePath=fpath; // becomes absolute path
1494 fileName=fpath; // gets stripped of path
1495 destPath=destname; // needed for vymlinks
1497 // If fpath is not an absolute path, complete it
1498 filePath=QDir(fpath).absPath();
1499 fileDir=filePath.left (1+filePath.findRev ("/"));
1501 // Set short name, too. Search from behind:
1502 int i=fileName.findRev("/");
1503 if (i>=0) fileName=fileName.remove (0,i+1);
1505 // Forget the .vym (or .xml) for name of map
1506 mapName=fileName.left(fileName.findRev(".",-1,true) );
1510 void MapEditor::setFilePath(QString fpath)
1512 setFilePath (fpath,fpath);
1515 QString MapEditor::getFilePath()
1520 QString MapEditor::getFileName()
1525 QString MapEditor::getMapName()
1530 QString MapEditor::getDestPath()
1535 ErrorCode MapEditor::load (QString fname, const LoadMode &lmode, const FileType &ftype)
1537 ErrorCode err=success;
1539 parseBaseHandler *handler;
1542 case VymMap: handler=new parseVYMHandler; break;
1543 case FreemindMap : handler=new parseFreemindHandler; break;
1545 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1546 "Unknown FileType in MapEditor::load()");
1551 if (xelection.isEmpty() ) xelection.unselect();
1554 mapCenter->setMapEditor(this);
1555 // (map state is set later at end of load...)
1558 BranchObj *bo=xelection.getBranch();
1559 if (!bo) return aborted;
1560 if (lmode==ImportAdd)
1561 saveStateChangingPart(
1564 QString("addMapInsert (%1)").arg(fname),
1565 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1567 saveStateChangingPart(
1570 QString("addMapReplace(%1)").arg(fname),
1571 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1574 QFile file( fname );
1576 // I am paranoid: file should exist anyway
1577 // according to check in mainwindow.
1578 if (!file.exists() )
1580 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1581 tr("Couldn't open map " +fname)+".");
1585 bool blockSaveStateOrg=blockSaveState;
1586 blockReposition=true;
1587 blockSaveState=true;
1588 QXmlInputSource source( file);
1589 QXmlSimpleReader reader;
1590 reader.setContentHandler( handler );
1591 reader.setErrorHandler( handler );
1592 handler->setMapEditor( this );
1595 // We need to set the tmpDir in order to load files with rel. path
1596 QString tmpdir= fname.left(fname.findRev("/",-1));
1597 handler->setTmpDir (tmpdir);
1598 handler->setInputFile (file.name());
1599 handler->setLoadMode (lmode);
1600 bool ok = reader.parse( source );
1601 blockReposition=false;
1602 blockSaveState=blockSaveStateOrg;
1606 mapCenter->reposition();
1613 autosaveTimer->stop();
1617 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1618 tr( handler->errorProtocol() ) );
1620 // Still return "success": the map maybe at least
1621 // partially read by the parser
1628 int MapEditor::save (const SaveMode &savemode)
1630 // Create mapName and fileDir
1631 makeSubDirs (fileDir);
1635 fname=mapName+".xml";
1637 // use name given by user, even if he chooses .doc
1642 if (savemode==CompleteMap || xelection.isEmpty())
1644 // Save complete map
1645 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1648 autosaveTimer->stop();
1653 if (xelection.type()==Selection::FloatImage)
1656 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());
1657 // TODO take care of multiselections
1660 if (!saveStringToDisk(fileDir+fname,saveFile))
1667 void MapEditor::setZipped (bool z)
1672 bool MapEditor::saveZipped ()
1677 void MapEditor::print()
1681 printer = new QPrinter;
1682 printer->setColorMode (QPrinter::Color);
1683 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1684 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1685 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1688 QRectF totalBBox=mapCenter->getTotalBBox();
1690 // Try to set orientation automagically
1691 // Note: Interpretation of generated postscript is amibiguous, if
1692 // there are problems with landscape mode, see
1693 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1695 if (totalBBox.width()>totalBBox.height())
1696 // recommend landscape
1697 printer->setOrientation (QPrinter::Landscape);
1699 // recommend portrait
1700 printer->setOrientation (QPrinter::Portrait);
1702 if ( printer->setup(this) )
1703 // returns false, if printing is canceled
1705 QPainter pp(printer);
1707 pp.setRenderHint(QPainter::Antialiasing,true);
1709 // Don't print the visualisation of selection
1710 xelection.unselect();
1712 QRectF mapRect=totalBBox;
1713 QGraphicsRectItem *frame=NULL;
1717 // Print frame around map
1718 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1719 totalBBox.width()+20, totalBBox.height()+20);
1720 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1721 frame->setZValue(0);
1726 double paperAspect = (double)printer->width() / (double)printer->height();
1727 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1729 if (mapAspect>=paperAspect)
1731 // Fit horizontally to paper width
1732 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1733 viewBottom=(int)(printer->width()/mapAspect);
1736 // Fit vertically to paper height
1737 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1738 viewBottom=printer->height();
1743 // Print footer below map
1745 font.setPointSize(10);
1747 QRectF footerBox(0,viewBottom,printer->width(),15);
1748 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1749 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1753 QRectF (0,0,printer->width(),printer->height()-15),
1754 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1757 // Viewport has paper dimension
1758 if (frame) delete (frame);
1760 // Restore selection
1761 xelection.reselect();
1763 // Save settings in vymrc
1764 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1765 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1766 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1770 void MapEditor::setAntiAlias (bool b)
1772 setRenderHint(QPainter::Antialiasing,b);
1775 void MapEditor::setSmoothPixmap(bool b)
1777 setRenderHint(QPainter::SmoothPixmapTransform,b);
1780 QPixmap MapEditor::getPixmap()
1782 QRectF mapRect=mapCenter->getTotalBBox();
1783 QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+1);
1786 pp.setRenderHints(renderHints());
1788 // Don't print the visualisation of selection
1789 xelection.unselect();
1791 mapScene->render ( &pp,
1792 QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1793 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1795 // Restore selection
1796 xelection.reselect();
1801 void MapEditor::setHideTmpMode (HideTmpMode mode)
1804 mapCenter->setHideTmp (hidemode);
1805 mapCenter->reposition();
1809 HideTmpMode MapEditor::getHideTmpMode()
1814 void MapEditor::setExportMode (bool b)
1816 // should be called before and after exports
1817 // depending on the settings
1818 if (b && settings.value("/export/useHideExport","true")=="true")
1819 setHideTmpMode (HideExport);
1821 setHideTmpMode (HideNone);
1824 void MapEditor::exportASCII(QString fname,bool askName)
1827 ex.setMapCenter(mapCenter);
1829 ex.setFile (mapName+".txt");
1835 //ex.addFilter ("TXT (*.txt)");
1836 ex.setDir(lastImageDir);
1837 //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
1842 setExportMode(true);
1844 setExportMode(false);
1848 void MapEditor::exportImage(QString fname, bool askName, QString format)
1852 fname=mapName+".png";
1859 QFileDialog *fd=new QFileDialog (this);
1860 fd->setCaption (tr("Export map as image"));
1861 fd->setDirectory (lastImageDir);
1862 fd->setFileMode(QFileDialog::AnyFile);
1863 fd->setFilters (imageIO.getFilters() );
1866 fl=fd->selectedFiles();
1868 format=imageIO.getType(fd->selectedFilter());
1872 setExportMode (true);
1873 QPixmap pix (getPixmap());
1874 pix.save(fname, format);
1875 setExportMode (false);
1878 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1882 ex.setMapCenter(mapCenter);
1883 if (ex.setConfigFile(cf))
1885 setExportMode (true);
1886 ex.exportPresentation();
1887 setExportMode (false);
1891 void MapEditor::exportXHTML (const QString &dir, bool askForName)
1893 ExportXHTMLDialog dia(this);
1894 dia.setFilePath (filePath );
1895 dia.setMapName (mapName );
1897 if (dir!="") dia.setDir (dir);
1903 if (dia.exec()!=QDialog::Accepted)
1907 QDir d (dia.getDir());
1908 // Check, if warnings should be used before overwriting
1909 // the output directory
1910 if (d.exists() && d.count()>0)
1913 warn.showCancelButton (true);
1914 warn.setText(QString(
1915 "The directory %1 is not empty.\n"
1916 "Do you risk to overwrite some of its contents?").arg(d.path() ));
1917 warn.setCaption("Warning: Directory not empty");
1918 warn.setShowAgainName("mainwindow/overwrite-dir-xhtml");
1920 if (warn.exec()!=QDialog::Accepted) ok=false;
1927 exportXML (dia.getDir(),false );
1928 dia.doExport(mapName );
1929 //if (dia.hasChanged()) setChanged();
1933 void MapEditor::exportXML(QString dir, bool askForName)
1937 dir=browseDirectory(this,tr("Export XML to directory"));
1938 if (dir =="" && !reallyWriteDirectory(dir) )
1942 // Hide stuff during export, if settings want this
1943 setExportMode (true);
1945 // Create subdirectories
1948 // write to directory
1949 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1952 file.setName ( dir + "/"+mapName+".xml");
1953 if ( !file.open( QIODevice::WriteOnly ) )
1955 // This should neverever happen
1956 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1960 // Write it finally, and write in UTF8, no matter what
1961 QTextStream ts( &file );
1962 ts.setEncoding (QTextStream::UnicodeUTF8);
1966 // Now write image, too
1967 exportImage (dir+"/images/"+mapName+".png",false,"PNG");
1969 setExportMode (false);
1972 void MapEditor::clear()
1974 xelection.unselect();
1978 void MapEditor::copy()
1980 LinkableMapObj *sel=xelection.single();
1983 if (redosAvail == 0)
1986 QString s=sel->getSelectString();
1987 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel );
1988 curClipboard=curStep;
1991 // Copy also to global clipboard, because we are at last step in history
1992 QString bakMapName(QString("history-%1").arg(curStep));
1993 QString bakMapDir(tmpMapDir +"/"+bakMapName);
1994 copyDir (bakMapDir,clipboardDir );
1996 clipboardEmpty=false;
2001 void MapEditor::redo()
2003 // Can we undo at all?
2004 if (redosAvail<1) return;
2006 bool blockSaveStateOrg=blockSaveState;
2007 blockSaveState=true;
2011 if (undosAvail<stepsTotal) undosAvail++;
2013 if (curStep>stepsTotal) curStep=1;
2014 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
2015 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2016 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2017 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2018 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2019 QString version=undoSet.readEntry ("/history/version");
2021 if (!checkVersion(version))
2022 QMessageBox::warning(0,tr("Warning"),
2023 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2026 // Find out current undo directory
2027 QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
2031 cout << "ME::redo() begin\n";
2032 cout << " undosAvail="<<undosAvail<<endl;
2033 cout << " redosAvail="<<redosAvail<<endl;
2034 cout << " curStep="<<curStep<<endl;
2035 cout << " ---------------------------"<<endl;
2036 cout << " comment="<<comment.toStdString()<<endl;
2037 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2038 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2039 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2040 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2041 cout << " ---------------------------"<<endl<<endl;
2044 // select object before redo
2045 if (!redoSelection.isEmpty())
2046 select (redoSelection);
2049 parseAtom (redoCommand);
2050 mapCenter->reposition();
2052 blockSaveState=blockSaveStateOrg;
2054 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2055 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2056 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2057 undoSet.writeSettings(histPath);
2059 mainWindow->updateHistory (undoSet);
2062 /* TODO remove testing
2063 cout << "ME::redo() end\n";
2064 cout << " undosAvail="<<undosAvail<<endl;
2065 cout << " redosAvail="<<redosAvail<<endl;
2066 cout << " curStep="<<curStep<<endl;
2067 cout << " ---------------------------"<<endl<<endl;
2073 bool MapEditor::isRedoAvailable()
2075 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
2081 void MapEditor::undo()
2083 // Can we undo at all?
2084 if (undosAvail<1) return;
2086 mainWindow->statusMessage (tr("Autosave disabled during undo."));
2088 bool blockSaveStateOrg=blockSaveState;
2089 blockSaveState=true;
2091 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
2092 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2093 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2094 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2095 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2096 QString version=undoSet.readEntry ("/history/version");
2098 if (!checkVersion(version))
2099 QMessageBox::warning(0,tr("Warning"),
2100 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2102 // Find out current undo directory
2103 QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
2105 // select object before undo
2106 if (!undoSelection.isEmpty())
2107 select (undoSelection);
2111 cout << "ME::undo() begin\n";
2112 cout << " undosAvail="<<undosAvail<<endl;
2113 cout << " redosAvail="<<redosAvail<<endl;
2114 cout << " curStep="<<curStep<<endl;
2115 cout << " ---------------------------"<<endl;
2116 cout << " comment="<<comment.toStdString()<<endl;
2117 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2118 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2119 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2120 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2121 cout << " ---------------------------"<<endl<<endl;
2123 parseAtom (undoCommand);
2124 mapCenter->reposition();
2128 if (curStep<1) curStep=stepsTotal;
2132 blockSaveState=blockSaveStateOrg;
2133 /* TODO remove testing
2134 cout << "ME::undo() end\n";
2135 cout << " undosAvail="<<undosAvail<<endl;
2136 cout << " redosAvail="<<redosAvail<<endl;
2137 cout << " curStep="<<curStep<<endl;
2138 cout << " ---------------------------"<<endl<<endl;
2141 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2142 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2143 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2144 undoSet.writeSettings(histPath);
2146 mainWindow->updateHistory (undoSet);
2149 ensureSelectionVisible();
2152 bool MapEditor::isUndoAvailable()
2154 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
2160 void MapEditor::gotoHistoryStep (int i)
2162 // Restore variables
2163 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
2164 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
2166 if (i<0) i=undosAvail+redosAvail;
2168 // Clicking above current step makes us undo things
2171 for (int j=0; j<undosAvail-i; j++) undo();
2174 // Clicking below current step makes us redo things
2176 for (int j=undosAvail; j<i; j++)
2178 cout << "redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
2182 // And ignore clicking the current row ;-)
2185 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
2187 QString pathDir=path.left(path.findRev("/"));
2193 // We need to parse saved XML data
2194 parseVYMHandler handler;
2195 QXmlInputSource source( file);
2196 QXmlSimpleReader reader;
2197 reader.setContentHandler( &handler );
2198 reader.setErrorHandler( &handler );
2199 handler.setMapEditor( this );
2200 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2201 if (undoSel.isEmpty())
2205 handler.setLoadMode (NewMap);
2209 handler.setLoadMode (ImportReplace);
2211 blockReposition=true;
2212 bool ok = reader.parse( source );
2213 blockReposition=false;
2216 // This should never ever happen
2217 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2218 handler.errorProtocol());
2221 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2224 void MapEditor::addMapInsertInt (const QString &path, int pos)
2226 BranchObj *sel=xelection.getBranch();
2229 QString pathDir=path.left(path.findRev("/"));
2235 // We need to parse saved XML data
2236 parseVYMHandler handler;
2237 QXmlInputSource source( file);
2238 QXmlSimpleReader reader;
2239 reader.setContentHandler( &handler );
2240 reader.setErrorHandler( &handler );
2241 handler.setMapEditor( this );
2242 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2243 handler.setLoadMode (ImportAdd);
2244 blockReposition=true;
2245 bool ok = reader.parse( source );
2246 blockReposition=false;
2249 // This should never ever happen
2250 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2251 handler.errorProtocol());
2254 sel->getLastBranch()->linkTo (sel,pos);
2256 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2260 void MapEditor::pasteNoSave(const int &n)
2262 bool old=blockSaveState;
2263 blockSaveState=true;
2264 if (redosAvail > 0 || n!=0)
2266 // Use the "historical" buffer
2267 QString bakMapName(QString("history-%1").arg(n));
2268 QString bakMapDir(tmpMapDir +"/"+bakMapName);
2269 load (bakMapDir+"/"+clipboardFile,ImportAdd, VymMap);
2271 // Use the global buffer
2272 load (clipboardDir+"/"+clipboardFile,ImportAdd, VymMap);
2276 void MapEditor::paste()
2278 BranchObj *sel=xelection.getBranch();
2281 saveStateChangingPart(
2284 QString ("paste (%1)").arg(curClipboard),
2285 QString("Paste to %1").arg( getName(sel))
2288 mapCenter->reposition();
2292 void MapEditor::cut()
2294 LinkableMapObj *sel=xelection.single();
2295 if ( sel && (xelection.type() == Selection::Branch ||
2296 xelection.type()==Selection::MapCenter ||
2297 xelection.type()==Selection::FloatImage))
2299 /* No savestate! savestate is called in cutNoSave
2300 saveStateChangingPart(
2304 QString("Cut %1").arg(getName(sel ))
2309 mapCenter->reposition();
2313 void MapEditor::move(const double &x, const double &y)
2315 LinkableMapObj *sel=xelection.single();
2318 QPointF ap(sel->getAbsPos());
2322 QString ps=qpointfToString(ap);
2323 QString s=xelection.single()->getSelectString();
2326 s, "move "+qpointfToString(to),
2327 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
2329 mapCenter->reposition();
2335 void MapEditor::moveRel (const double &x, const double &y)
2337 LinkableMapObj *sel=xelection.single();
2340 QPointF rp(sel->getRelPos());
2344 QString ps=qpointfToString (sel->getRelPos());
2345 QString s=sel->getSelectString();
2348 s, "moveRel "+qpointfToString(to),
2349 QString("Move %1 to relative position %2").arg(getName(sel)).arg(ps));
2350 ((OrnamentedObj*)sel)->move2RelPos (x,y);
2351 mapCenter->reposition();
2358 void MapEditor::moveBranchUp()
2360 BranchObj* bo=xelection.getBranch();
2364 if (!bo->canMoveBranchUp()) return;
2365 par=(BranchObj*)(bo->getParObj());
2366 BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
2367 saveState (bo->getSelectString(),"moveBranchDown ()",obo->getSelectString(),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
2368 mapCenter->reposition();
2371 ensureSelectionVisible();
2375 void MapEditor::moveBranchDown()
2377 BranchObj* bo=xelection.getBranch();
2381 if (!bo->canMoveBranchDown()) return;
2382 par=(BranchObj*)(bo->getParObj());
2383 BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
2384 saveState(bo->getSelectString(),"moveBranchUp ()",obo->getSelectString(),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
2385 mapCenter->reposition();
2388 ensureSelectionVisible();
2392 void MapEditor::sortChildren()
2394 BranchObj* bo=xelection.getBranch();
2397 if(bo->countBranches()>1)
2399 saveStateChangingPart(bo,bo, "sortChildren ()",QString("Sort children of %1").arg(getName(bo)));
2401 mapCenter->reposition();
2402 ensureSelectionVisible();
2407 void MapEditor::linkTo(const QString &dstString)
2409 FloatImageObj *fio=xelection.getFloatImage();
2412 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
2413 if (dst && (typeid(*dst)==typeid (BranchObj) ||
2414 typeid(*dst)==typeid (MapCenterObj)))
2416 LinkableMapObj *dstPar=dst->getParObj();
2417 QString parString=dstPar->getSelectString();
2418 QString fioPreSelectString=fio->getSelectString();
2419 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
2420 ((BranchObj*)(dst))->addFloatImage (fio);
2421 xelection.unselect();
2422 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
2423 fio=((BranchObj*)(dst))->getLastFloatImage();
2426 xelection.select(fio);
2428 fio->getSelectString(),
2429 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
2431 QString ("linkTo (\"%1\")").arg(dstString),
2432 QString ("Link floatimage to %1").arg(getName(dst)));
2437 QString MapEditor::getHeading(bool &ok, QPoint &p)
2439 BranchObj *bo=xelection.getBranch();
2443 p=mapFromScene(bo->getAbsPos());
2444 return bo->getHeading();
2450 void MapEditor::setHeading(const QString &s)
2452 BranchObj *sel=xelection.getBranch();
2457 "setHeading (\""+sel->getHeading()+"\")",
2459 "setHeading (\""+s+"\")",
2460 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
2461 sel->setHeading(s );
2462 mapCenter->reposition();
2464 ensureSelectionVisible();
2468 void MapEditor::setHeadingInt(const QString &s)
2470 BranchObj *bo=xelection.getBranch();
2474 mapCenter->reposition();
2476 ensureSelectionVisible();
2480 void MapEditor::setVymLinkInt (const QString &s)
2482 // Internal function, no saveState needed
2483 BranchObj *bo=xelection.getBranch();
2487 mapCenter->reposition();
2490 ensureSelectionVisible();
2494 BranchObj* MapEditor::addNewBranchInt(int num)
2496 // Depending on pos:
2497 // -3 insert in childs of parent above selection
2498 // -2 add branch to selection
2499 // -1 insert in childs of parent below selection
2500 // 0..n insert in childs of parent at pos
2501 BranchObj *newbo=NULL;
2502 BranchObj *bo=xelection.getBranch();
2507 // save scroll state. If scrolled, automatically select
2508 // new branch in order to tmp unscroll parent...
2509 newbo=bo->addBranch();
2514 bo=(BranchObj*)bo->getParObj();
2515 if (bo) newbo=bo->insertBranch(num);
2519 bo=(BranchObj*)bo->getParObj();
2520 if (bo) newbo=bo->insertBranch(num);
2522 if (!newbo) return NULL;
2527 BranchObj* MapEditor::addNewBranch(int pos)
2529 // Different meaning than num in addNewBranchInt!
2533 BranchObj *bo = xelection.getBranch();
2534 BranchObj *newbo=NULL;
2538 setCursor (Qt::ArrowCursor);
2540 newbo=addNewBranchInt (pos-2);
2548 QString ("addBranch (%1)").arg(pos),
2549 QString ("Add new branch to %1").arg(getName(bo)));
2551 mapCenter->reposition();
2553 latestSelection=newbo->getSelectString();
2554 // In Network mode, the client needs to know where the new branch is,
2555 // so we have to pass on this information via saveState.
2556 // TODO: Get rid of this positioning workaround
2557 QString ps=qpointfToString (newbo->getAbsPos());
2558 sendData ("selectLatestAdded ()");
2559 sendData (QString("move %1").arg(ps));
2567 BranchObj* MapEditor::addNewBranchBefore()
2569 BranchObj *newbo=NULL;
2570 BranchObj *bo = xelection.getBranch();
2571 if (bo && xelection.type()==Selection::Branch)
2572 // We accept no MapCenterObj here, so we _have_ a parent
2574 QPointF p=bo->getRelPos();
2577 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2579 // add below selection
2580 newbo=parbo->insertBranch(bo->getNum()+1);
2583 newbo->move2RelPos (p);
2585 // Move selection to new branch
2586 bo->linkTo (newbo,-1);
2588 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2589 QString ("Add branch before %1").arg(getName(bo)));
2591 mapCenter->reposition();
2595 latestSelection=xelection.getSelectString();
2599 void MapEditor::deleteSelection()
2601 BranchObj *bo = xelection.getBranch();
2602 if (bo && xelection.type()==Selection::Branch)
2604 BranchObj* par=(BranchObj*)(bo->getParObj());
2605 xelection.unselect();
2606 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2607 par->removeBranch(bo);
2608 xelection.select (par);
2609 ensureSelectionVisible();
2610 mapCenter->reposition();
2615 FloatImageObj *fio=xelection.getFloatImage();
2618 BranchObj* par=(BranchObj*)(fio->getParObj());
2619 saveStateChangingPart(
2623 QString("Delete %1").arg(getName(fio))
2625 xelection.unselect();
2626 par->removeFloatImage(fio);
2627 xelection.select (par);
2628 mapCenter->reposition();
2630 ensureSelectionVisible();
2635 LinkableMapObj* MapEditor::getSelection()
2637 return xelection.single();
2640 BranchObj* MapEditor::getSelectedBranch()
2642 return xelection.getBranch();
2645 FloatImageObj* MapEditor::getSelectedFloatImage()
2647 return xelection.getFloatImage();
2650 void MapEditor::unselect()
2652 xelection.unselect();
2655 void MapEditor::reselect()
2657 xelection.reselect();
2660 bool MapEditor::select (const QString &s)
2662 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2664 // Finally select the found object
2667 xelection.unselect();
2668 xelection.select(lmo);
2670 ensureSelectionVisible();
2677 QString MapEditor::getSelectString()
2679 return xelection.getSelectString();
2682 void MapEditor::selectInt (LinkableMapObj *lmo)
2684 if (lmo && xelection.single()!= lmo && isSelectBlocked()==false )
2686 xelection.select(lmo);
2692 void MapEditor::selectNextBranchInt()
2694 // Increase number of branch
2695 LinkableMapObj *sel=xelection.single();
2698 QString s=sel->getSelectString();
2704 part=s.section(",",-1);
2706 num=part.right(part.length() - 3);
2708 s=s.left (s.length() -num.length());
2711 num=QString ("%1").arg(num.toUInt()+1);
2715 // Try to select this one
2716 if (select (s)) return;
2718 // We have no direct successor,
2719 // try to increase the parental number in order to
2720 // find a successor with same depth
2722 int d=xelection.single()->getDepth();
2727 while (!found && d>0)
2729 s=s.section (",",0,d-1);
2730 // replace substring of current depth in s with "1"
2731 part=s.section(",",-1);
2733 num=part.right(part.length() - 3);
2737 // increase number of parent
2738 num=QString ("%1").arg(num.toUInt()+1);
2739 s=s.section (",",0,d-2) + ","+ typ+num;
2742 // Special case, look at orientation
2743 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2744 num=QString ("%1").arg(num.toUInt()+1);
2746 num=QString ("%1").arg(num.toUInt()-1);
2751 // pad to oldDepth, select the first branch for each depth
2752 for (i=d;i<oldDepth;i++)
2757 if ( xelection.getBranch()->countBranches()>0)
2765 // try to select the freshly built string
2773 void MapEditor::selectPrevBranchInt()
2775 // Decrease number of branch
2776 BranchObj *bo=xelection.getBranch();
2779 QString s=bo->getSelectString();
2785 part=s.section(",",-1);
2787 num=part.right(part.length() - 3);
2789 s=s.left (s.length() -num.length());
2791 int n=num.toInt()-1;
2794 num=QString ("%1").arg(n);
2797 // Try to select this one
2798 if (n>=0 && select (s)) return;
2800 // We have no direct precessor,
2801 // try to decrease the parental number in order to
2802 // find a precessor with same depth
2804 int d=xelection.single()->getDepth();
2809 while (!found && d>0)
2811 s=s.section (",",0,d-1);
2812 // replace substring of current depth in s with "1"
2813 part=s.section(",",-1);
2815 num=part.right(part.length() - 3);
2819 // decrease number of parent
2820 num=QString ("%1").arg(num.toInt()-1);
2821 s=s.section (",",0,d-2) + ","+ typ+num;
2824 // Special case, look at orientation
2825 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2826 num=QString ("%1").arg(num.toInt()-1);
2828 num=QString ("%1").arg(num.toInt()+1);
2833 // pad to oldDepth, select the last branch for each depth
2834 for (i=d;i<oldDepth;i++)
2838 if ( xelection.getBranch()->countBranches()>0)
2839 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2846 // try to select the freshly built string
2854 void MapEditor::selectUpperBranch()
2856 if (isSelectBlocked() ) return;
2858 BranchObj *bo=xelection.getBranch();
2859 if (bo && xelection.type()==Selection::Branch)
2861 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2862 selectPrevBranchInt();
2864 if (bo->getDepth()==1)
2865 selectNextBranchInt();
2867 selectPrevBranchInt();
2871 void MapEditor::selectLowerBranch()
2873 if (isSelectBlocked() ) return;
2875 BranchObj *bo=xelection.getBranch();
2876 if (bo && xelection.type()==Selection::Branch)
2877 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2878 selectNextBranchInt();
2880 if (bo->getDepth()==1)
2881 selectPrevBranchInt();
2883 selectNextBranchInt();
2887 void MapEditor::selectLeftBranch()
2889 if (isSelectBlocked() ) return;
2893 LinkableMapObj *sel=xelection.single();
2896 if (xelection.type()== Selection::MapCenter)
2898 par=xelection.getBranch();
2899 bo=par->getLastSelectedBranch();
2902 // Workaround for reselecting on left and right side
2903 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2904 bo=par->getLastBranch();
2907 bo=par->getLastBranch();
2908 xelection.select(bo);
2910 ensureSelectionVisible();
2916 par=(BranchObj*)(sel->getParObj());
2917 if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
2919 if (xelection.type() == Selection::Branch ||
2920 xelection.type() == Selection::FloatImage)
2922 xelection.select(par);
2924 ensureSelectionVisible();
2929 if (xelection.type() == Selection::Branch )
2931 bo=xelection.getBranch()->getLastSelectedBranch();
2934 xelection.select(bo);
2936 ensureSelectionVisible();
2945 void MapEditor::selectRightBranch()
2947 if (isSelectBlocked() ) return;
2951 LinkableMapObj *sel=xelection.single();
2954 if (xelection.type()==Selection::MapCenter)
2956 par=xelection.getBranch();
2957 bo=par->getLastSelectedBranch();
2960 // Workaround for reselecting on left and right side
2961 if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
2962 bo=par->getFirstBranch();
2965 xelection.select(bo);
2967 ensureSelectionVisible();
2973 par=(BranchObj*)(xelection.single()->getParObj());
2974 if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
2976 if (xelection.type() == Selection::Branch ||
2977 xelection.type() == Selection::FloatImage)
2979 xelection.select(par);
2981 ensureSelectionVisible();
2986 if (xelection.type() == Selection::Branch)
2988 bo=xelection.getBranch()->getLastSelectedBranch();
2991 xelection.select(bo);
2993 ensureSelectionVisible();
3002 void MapEditor::selectFirstBranch()
3004 BranchObj *bo1=xelection.getBranch();
3009 par=(BranchObj*)(bo1->getParObj());
3010 bo2=par->getFirstBranch();
3012 xelection.select(bo2);
3014 ensureSelectionVisible();
3020 void MapEditor::selectLastBranch()
3022 BranchObj *bo1=xelection.getBranch();
3027 par=(BranchObj*)(bo1->getParObj());
3028 bo2=par->getLastBranch();
3031 xelection.select(bo2);
3033 ensureSelectionVisible();
3039 void MapEditor::selectMapBackgroundImage ()
3041 Q3FileDialog *fd=new Q3FileDialog( this);
3042 fd->setMode (Q3FileDialog::ExistingFile);
3043 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3044 ImagePreview *p =new ImagePreview (fd);
3045 fd->setContentsPreviewEnabled( TRUE );
3046 fd->setContentsPreview( p, p );
3047 fd->setPreviewMode( Q3FileDialog::Contents );
3048 fd->setCaption(vymName+" - " +tr("Load background image"));
3049 fd->setDir (lastImageDir);
3052 if ( fd->exec() == QDialog::Accepted )
3054 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
3055 lastImageDir=QDir (fd->dirPath());
3056 setMapBackgroundImage (fd->selectedFile());
3060 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
3062 QColor oldcol=mapScene->backgroundBrush().color();
3066 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
3068 QString ("setMapBackgroundImage (%1)").arg(col.name()),
3069 QString("Set background color of map to %1").arg(col.name()));
3072 brush.setTextureImage (QPixmap (fn));
3073 mapScene->setBackgroundBrush(brush);
3076 void MapEditor::selectMapBackgroundColor()
3078 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
3079 if ( !col.isValid() ) return;
3080 setMapBackgroundColor( col );
3084 void MapEditor::setMapBackgroundColor(QColor col)
3086 QColor oldcol=mapScene->backgroundBrush().color();
3089 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
3091 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
3092 QString("Set background color of map to %1").arg(col.name()));
3093 mapScene->setBackgroundBrush(col);
3096 QColor MapEditor::getMapBackgroundColor()
3098 return mapScene->backgroundBrush().color();
3101 QColor MapEditor::getCurrentHeadingColor()
3103 BranchObj *bo=xelection.getBranch();
3104 if (bo) return bo->getColor();
3106 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
3110 void MapEditor::colorBranch (QColor c)
3112 BranchObj *bo=xelection.getBranch();
3117 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
3119 QString ("colorBranch (\"%1\")").arg(c.name()),
3120 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
3122 bo->setColor(c); // color branch
3126 void MapEditor::colorSubtree (QColor c)
3128 BranchObj *bo=xelection.getBranch();
3131 saveStateChangingPart(
3134 QString ("colorSubtree (\"%1\")").arg(c.name()),
3135 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
3137 bo->setColorSubtree (c); // color links, color childs
3142 void MapEditor::toggleStandardFlag(QString f)
3144 BranchObj *bo=xelection.getBranch();
3148 if (bo->isSetStandardFlag(f))
3160 QString("%1 (\"%2\")").arg(u).arg(f),
3162 QString("%1 (\"%2\")").arg(r).arg(f),
3163 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
3164 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
3170 BranchObj* MapEditor::findText (QString s, bool cs)
3172 QTextDocument::FindFlags flags=0;
3173 if (cs) flags=QTextDocument::FindCaseSensitively;
3176 { // Nothing found or new find process
3178 // nothing found, start again
3180 itFind=mapCenter->first();
3182 bool searching=true;
3183 bool foundNote=false;
3184 while (searching && !EOFind)
3188 // Searching in Note
3189 if (itFind->getNote().contains(s,cs))
3191 if (xelection.single()!=itFind)
3193 xelection.select(itFind);
3194 ensureSelectionVisible();
3196 if (textEditor->findText(s,flags))
3202 // Searching in Heading
3203 if (searching && itFind->getHeading().contains (s,cs) )
3205 xelection.select(itFind);
3206 ensureSelectionVisible();
3212 itFind=itFind->next();
3213 if (!itFind) EOFind=true;
3217 return xelection.getBranch();
3222 void MapEditor::findReset()
3223 { // Necessary if text to find changes during a find process
3227 void MapEditor::setURL(const QString &url)
3229 BranchObj *bo=xelection.getBranch();
3232 QString oldurl=bo->getURL();
3236 QString ("setURL (\"%1\")").arg(oldurl),
3238 QString ("setURL (\"%1\")").arg(url),
3239 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
3242 mapCenter->reposition();
3244 ensureSelectionVisible();
3248 void MapEditor::editURL()
3250 BranchObj *bo=xelection.getBranch();
3254 QString text = QInputDialog::getText(
3255 "VYM", tr("Enter URL:"), QLineEdit::Normal,
3256 bo->getURL(), &ok, this );
3258 // user entered something and pressed OK
3263 void MapEditor::editLocalURL()
3265 BranchObj *bo=xelection.getBranch();
3268 QStringList filters;
3269 filters <<"All files (*)";
3270 filters << tr("Text","Filedialog") + " (*.txt)";
3271 filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
3272 filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
3273 filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
3274 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Set URL to a local file"));
3275 fd->setFilters (filters);
3276 fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
3277 fd->setDirectory (lastFileDir);
3278 if (! bo->getVymLink().isEmpty() )
3279 fd->selectFile( bo->getURL() );
3282 if ( fd->exec() == QDialog::Accepted )
3284 lastFileDir=QDir (fd->directory().path());
3285 setURL (fd->selectedFile() );
3290 QString MapEditor::getURL()
3292 BranchObj *bo=xelection.getBranch();
3294 return bo->getURL();
3299 QStringList MapEditor::getURLs()
3302 BranchObj *bo=xelection.getBranch();
3308 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
3316 void MapEditor::editHeading2URL()
3318 BranchObj *bo=xelection.getBranch();
3320 setURL (bo->getHeading());
3323 void MapEditor::editBugzilla2URL()
3325 BranchObj *bo=xelection.getBranch();
3328 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
3333 void MapEditor::editFATE2URL()
3335 BranchObj *bo=xelection.getBranch();
3338 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
3341 "setURL (\""+bo->getURL()+"\")",
3343 "setURL (\""+url+"\")",
3344 QString("Use heading of %1 as link to FATE").arg(getName(bo))
3351 void MapEditor::editVymLink()
3353 BranchObj *bo=xelection.getBranch();
3356 QStringList filters;
3357 filters <<"VYM map (*.vym)";
3358 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
3359 fd->setFilters (filters);
3360 fd->setCaption(vymName+" - " +tr("Link to another map"));
3361 fd->setDirectory (lastFileDir);
3362 if (! bo->getVymLink().isEmpty() )
3363 fd->selectFile( bo->getVymLink() );
3367 if ( fd->exec() == QDialog::Accepted )
3369 lastFileDir=QDir (fd->directory().path());
3372 "setVymLink (\""+bo->getVymLink()+"\")",
3374 "setVymLink (\""+fd->selectedFile()+"\")",
3375 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
3377 setVymLinkInt (fd->selectedFile() );
3382 void MapEditor::deleteVymLink()
3384 BranchObj *bo=xelection.getBranch();
3389 "setVymLink (\""+bo->getVymLink()+"\")",
3391 "setVymLink (\"\")",
3392 QString("Unset vymlink of %1").arg(getName(bo))
3394 bo->setVymLink ("" );
3396 mapCenter->reposition();
3401 void MapEditor::setHideExport(bool b)
3403 BranchObj *bo=xelection.getBranch();
3406 bo->setHideInExport (b);
3407 QString u= b ? "false" : "true";
3408 QString r=!b ? "false" : "true";
3412 QString ("setHideExport (%1)").arg(u),
3414 QString ("setHideExport (%1)").arg(r),
3415 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
3418 mapCenter->reposition();
3424 void MapEditor::toggleHideExport()
3426 BranchObj *bo=xelection.getBranch();
3428 setHideExport ( !bo->hideInExport() );
3431 QString MapEditor::getVymLink()
3433 BranchObj *bo=xelection.getBranch();
3435 return bo->getVymLink();
3441 QStringList MapEditor::getVymLinks()
3444 BranchObj *bo=xelection.getBranch();
3450 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
3458 void MapEditor::deleteKeepChilds()
3460 BranchObj *bo=xelection.getBranch();
3464 par=(BranchObj*)(bo->getParObj());
3465 QPointF p=bo->getRelPos();
3466 saveStateChangingPart(
3469 "deleteKeepChilds ()",
3470 QString("Remove %1 and keep its childs").arg(getName(bo))
3473 QString sel=bo->getSelectString();
3475 par->removeBranchHere(bo);
3476 mapCenter->reposition();
3478 xelection.getBranch()->move2RelPos (p);
3479 mapCenter->reposition();
3483 void MapEditor::deleteChilds()
3485 BranchObj *bo=xelection.getBranch();
3488 saveStateChangingPart(
3492 QString( "Remove childs of branch %1").arg(getName(bo))
3495 mapCenter->reposition();
3499 void MapEditor::editMapInfo()
3501 ExtraInfoDialog dia;
3502 dia.setMapName (getFileName() );
3503 dia.setAuthor (mapCenter->getAuthor() );
3504 dia.setComment(mapCenter->getComment() );
3508 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
3515 bo=mapCenter->first();
3518 if (!bo->getNote().isEmpty() ) n++;
3519 f+= bo->countFloatImages();
3521 xl+=bo->countXLinks();
3524 stats+=QString ("%1 branches\n").arg (b-1,6);
3525 stats+=QString ("%1 xLinks \n").arg (xl,6);
3526 stats+=QString ("%1 notes\n").arg (n,6);
3527 stats+=QString ("%1 images\n").arg (f,6);
3528 dia.setStats (stats);
3530 // Finally show dialog
3531 if (dia.exec() == QDialog::Accepted)
3533 setMapAuthor (dia.getAuthor() );
3534 setMapComment (dia.getComment() );
3538 void MapEditor::ensureSelectionVisible()
3540 LinkableMapObj *lmo=xelection.single();
3541 if (lmo) ensureVisible (lmo->getBBox() );
3545 void MapEditor::updateSelection()
3547 // Tell selection to update geometries
3551 void MapEditor::updateActions()
3553 // Tell mainwindow to update states of actions
3554 mainWindow->updateActions();
3555 // TODO maybe don't update if blockReposition is set
3558 void MapEditor::updateNoteFlag()
3561 BranchObj *bo=xelection.getBranch();
3564 bo->updateNoteFlag();
3565 mainWindow->updateActions();
3569 void MapEditor::setMapAuthor (const QString &s)
3573 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3575 QString ("setMapAuthor (\"%1\")").arg(s),
3576 QString ("Set author of map to \"%1\"").arg(s)
3578 mapCenter->setAuthor (s);
3581 void MapEditor::setMapComment (const QString &s)
3585 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3587 QString ("setMapComment (\"%1\")").arg(s),
3588 QString ("Set comment of map")
3590 mapCenter->setComment (s);
3593 void MapEditor::setMapLinkStyle (const QString & s)
3595 saveStateChangingPart (
3598 QString("setMapLinkStyle (\"%1\")").arg(s),
3599 QString("Set map link style (\"%1\")").arg(s)
3603 linkstyle=LinkableMapObj::Line;
3604 else if (s=="StyleParabel")
3605 linkstyle=LinkableMapObj::Parabel;
3606 else if (s=="StylePolyLine")
3607 linkstyle=LinkableMapObj::PolyLine;
3609 linkstyle=LinkableMapObj::PolyParabel;
3612 bo=mapCenter->first();
3616 bo->setLinkStyle(bo->getDefLinkStyle());
3619 mapCenter->reposition();
3622 LinkableMapObj::Style MapEditor::getMapLinkStyle ()
3627 void MapEditor::setMapDefLinkColor(QColor c)
3631 bo=mapCenter->first();
3640 void MapEditor::setMapLinkColorHintInt()
3642 // called from setMapLinkColorHint(lch) or at end of parse
3644 bo=mapCenter->first();
3652 void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
3655 setMapLinkColorHintInt();
3658 void MapEditor::toggleMapLinkColorHint()
3660 if (linkcolorhint==LinkableMapObj::HeadingColor)
3661 linkcolorhint=LinkableMapObj::DefaultColor;
3663 linkcolorhint=LinkableMapObj::HeadingColor;
3665 bo=mapCenter->first();
3673 LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
3675 return linkcolorhint;
3678 QColor MapEditor::getMapDefLinkColor()
3680 return defLinkColor;
3683 void MapEditor::setMapDefXLinkColor(QColor col)
3688 QColor MapEditor::getMapDefXLinkColor()
3690 return defXLinkColor;
3693 void MapEditor::setMapDefXLinkWidth (int w)
3698 int MapEditor::getMapDefXLinkWidth()
3700 return defXLinkWidth;
3703 void MapEditor::selectMapLinkColor()
3705 QColor col = QColorDialog::getColor( defLinkColor, this );
3706 if ( !col.isValid() ) return;
3709 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3711 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3712 QString("Set map link color to %1").arg(col.name())
3714 setMapDefLinkColor( col );
3717 void MapEditor::selectMapSelectionColor()
3719 QColor col = QColorDialog::getColor( defLinkColor, this );
3720 setSelectionColor (col);
3723 void MapEditor::setSelectionColorInt (QColor col)
3725 if ( !col.isValid() ) return;
3726 xelection.setColor (col);
3729 void MapEditor::setSelectionColor(QColor col)
3731 if ( !col.isValid() ) return;
3734 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3736 QString("setSelectionColor (%1)").arg(col.name()),
3737 QString("Set color of selection box to %1").arg(col.name())
3739 setSelectionColorInt (col);
3742 QColor MapEditor::getSelectionColor()
3744 return xelection.getColor();
3747 bool MapEditor::scrollBranch(BranchObj *bo)
3751 if (bo->isScrolled()) return false;
3752 if (bo->countBranches()==0) return false;
3753 if (bo->getDepth()==0) return false;
3759 QString ("%1 ()").arg(u),
3761 QString ("%1 ()").arg(r),
3762 QString ("%1 %2").arg(r).arg(getName(bo))
3772 bool MapEditor::unscrollBranch(BranchObj *bo)
3776 if (!bo->isScrolled()) return false;
3777 if (bo->countBranches()==0) return false;
3778 if (bo->getDepth()==0) return false;
3784 QString ("%1 ()").arg(u),
3786 QString ("%1 ()").arg(r),
3787 QString ("%1 %2").arg(r).arg(getName(bo))
3797 void MapEditor::toggleScroll()
3799 BranchObj *bo=xelection.getBranch();
3800 if (xelection.type()==Selection::Branch )
3802 if (bo->isScrolled())
3803 unscrollBranch (bo);
3809 void MapEditor::unscrollChilds()
3811 BranchObj *bo=xelection.getBranch();
3817 if (bo->isScrolled()) unscrollBranch (bo);
3823 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3825 BranchObj *bo=xelection.getBranch();
3829 bo->addFloatImage();
3830 fio=bo->getLastFloatImage();
3832 mapCenter->reposition();
3839 void MapEditor::loadFloatImage ()
3841 BranchObj *bo=xelection.getBranch();
3845 Q3FileDialog *fd=new Q3FileDialog( this);
3846 fd->setMode (Q3FileDialog::ExistingFiles);
3847 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3848 ImagePreview *p =new ImagePreview (fd);
3849 fd->setContentsPreviewEnabled( TRUE );
3850 fd->setContentsPreview( p, p );
3851 fd->setPreviewMode( Q3FileDialog::Contents );
3852 fd->setCaption(vymName+" - " +tr("Load image"));
3853 fd->setDir (lastImageDir);
3856 if ( fd->exec() == QDialog::Accepted )
3858 // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
3859 lastImageDir=QDir (fd->dirPath());
3862 for (int j=0; j<fd->selectedFiles().count(); j++)
3864 s=fd->selectedFiles().at(j);
3865 fio=loadFloatImageInt (s);
3868 (LinkableMapObj*)fio,
3871 QString ("loadImage (%1)").arg(s ),
3872 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3875 // TODO loadFIO error handling
3876 qWarning ("Failed to load "+s);
3884 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3886 fio->save (fn,type);
3889 void MapEditor::saveFloatImage ()
3891 FloatImageObj *fio=xelection.getFloatImage();
3894 QFileDialog *fd=new QFileDialog( this);
3895 fd->setFilters (imageIO.getFilters());
3896 fd->setCaption(vymName+" - " +tr("Save image"));
3897 fd->setFileMode( QFileDialog::AnyFile );
3898 fd->setDirectory (lastImageDir);
3899 // fd->setSelection (fio->getOriginalFilename());
3903 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3905 fn=fd->selectedFiles().at(0);
3906 if (QFile (fn).exists() )
3908 QMessageBox mb( vymName,
3909 tr("The file %1 exists already.\n"
3910 "Do you want to overwrite it?").arg(fn),
3911 QMessageBox::Warning,
3912 QMessageBox::Yes | QMessageBox::Default,
3913 QMessageBox::Cancel | QMessageBox::Escape,
3914 QMessageBox::QMessageBox::NoButton );
3916 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3917 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3920 case QMessageBox::Yes:
3923 case QMessageBox::Cancel:
3930 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3936 void MapEditor::setFrameType(const FrameObj::FrameType &t)
3938 BranchObj *bo=xelection.getBranch();
3941 QString s=bo->getFrameTypeName();
3942 bo->setFrameType (t);
3943 saveState (bo, QString("setFrameType (\"%1\")").arg(s),
3944 bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
3945 mapCenter->reposition();
3950 void MapEditor::setFrameType(const QString &s)
3952 BranchObj *bo=xelection.getBranch();
3955 saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
3956 bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
3957 bo->setFrameType (s);
3958 mapCenter->reposition();
3963 void MapEditor::setFramePenColor(const QColor &c)
3965 BranchObj *bo=xelection.getBranch();
3968 saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
3969 bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
3970 bo->setFramePenColor (c);
3974 void MapEditor::setFrameBrushColor(const QColor &c)
3976 BranchObj *bo=xelection.getBranch();
3979 saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
3980 bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
3981 bo->setFrameBrushColor (c);
3985 void MapEditor::setFramePadding (const int &i)
3987 BranchObj *bo=xelection.getBranch();
3990 saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
3991 bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
3992 bo->setFramePadding (i);
3993 mapCenter->reposition();
3998 void MapEditor::setFrameBorderWidth(const int &i)
4000 BranchObj *bo=xelection.getBranch();
4003 saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
4004 bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
4005 bo->setFrameBorderWidth (i);
4006 mapCenter->reposition();
4011 void MapEditor::setIncludeImagesVer(bool b)
4013 BranchObj *bo=xelection.getBranch();
4016 QString u= b ? "false" : "true";
4017 QString r=!b ? "false" : "true";
4021 QString("setIncludeImagesVertically (%1)").arg(u),
4023 QString("setIncludeImagesVertically (%1)").arg(r),
4024 QString("Include images vertically in %1").arg(getName(bo))
4026 bo->setIncludeImagesVer(b);
4027 mapCenter->reposition();
4031 void MapEditor::setIncludeImagesHor(bool b)
4033 BranchObj *bo=xelection.getBranch();
4036 QString u= b ? "false" : "true";
4037 QString r=!b ? "false" : "true";
4041 QString("setIncludeImagesHorizontally (%1)").arg(u),
4043 QString("setIncludeImagesHorizontally (%1)").arg(r),
4044 QString("Include images horizontally in %1").arg(getName(bo))
4046 bo->setIncludeImagesHor(b);
4047 mapCenter->reposition();
4051 void MapEditor::setHideLinkUnselected (bool b)
4053 LinkableMapObj *sel=xelection.single();
4055 (xelection.type() == Selection::Branch ||
4056 xelection.type() == Selection::MapCenter ||
4057 xelection.type() == Selection::FloatImage ))
4059 QString u= b ? "false" : "true";
4060 QString r=!b ? "false" : "true";
4064 QString("setHideLinkUnselected (%1)").arg(u),
4066 QString("setHideLinkUnselected (%1)").arg(r),
4067 QString("Hide link of %1 if unselected").arg(getName(sel))
4069 sel->setHideLinkUnselected(b);
4073 void MapEditor::importDirInt(BranchObj *dst, QDir d)
4075 BranchObj *bo=xelection.getBranch();
4078 // Traverse directories
4079 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
4080 QFileInfoList list = d.entryInfoList();
4083 for (int i = 0; i < list.size(); ++i)
4086 if (fi.fileName() != "." && fi.fileName() != ".." )
4089 bo=dst->getLastBranch();
4090 bo->setHeading (fi.fileName() );
4091 bo->setColor (QColor("blue"));
4093 if ( !d.cd(fi.fileName()) )
4094 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
4097 // Recursively add subdirs
4098 importDirInt (bo,d);
4104 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
4105 list = d.entryInfoList();
4107 for (int i = 0; i < list.size(); ++i)
4111 bo=dst->getLastBranch();
4112 bo->setHeading (fi.fileName() );
4113 bo->setColor (QColor("black"));
4114 if (fi.fileName().right(4) == ".vym" )
4115 bo->setVymLink (fi.filePath());
4120 void MapEditor::importDirInt (const QString &s)
4122 BranchObj *bo=xelection.getBranch();
4125 saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
4128 importDirInt (bo,d);
4132 void MapEditor::importDir()
4134 BranchObj *bo=xelection.getBranch();
4137 QStringList filters;
4138 filters <<"VYM map (*.vym)";
4139 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
4140 fd->setMode (QFileDialog::DirectoryOnly);
4141 fd->setFilters (filters);
4142 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
4146 if ( fd->exec() == QDialog::Accepted )
4148 importDirInt (fd->selectedFile() );
4149 mapCenter->reposition();
4155 void MapEditor::followXLink(int i)
4157 BranchObj *bo=xelection.getBranch();
4160 bo=bo->XLinkTargetAt(i);
4163 xelection.select(bo);
4164 ensureSelectionVisible();
4169 void MapEditor::editXLink(int i) // FIXME missing saveState
4171 BranchObj *bo=xelection.getBranch();
4174 XLinkObj *xlo=bo->XLinkAt(i);
4177 EditXLinkDialog dia;
4179 dia.setSelection(bo);
4180 if (dia.exec() == QDialog::Accepted)
4182 if (dia.useSettingsGlobal() )
4184 setMapDefXLinkColor (xlo->getColor() );
4185 setMapDefXLinkWidth (xlo->getWidth() );
4187 if (dia.deleteXLink())
4188 bo->deleteXLinkAt(i);
4194 AttributeTable* MapEditor::attributeTable()
4199 void MapEditor::testFunction1()
4202 BranchObj *bo=xelection.getBranch();
4203 if (bo) animObjList.append( bo );
4206 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
4207 if (hidemode==HideNone)
4209 setHideTmpMode (HideExport);
4210 mapCenter->calcBBoxSizeWithChilds();
4211 QRectF totalBBox=mapCenter->getTotalBBox();
4212 QRectF mapRect=totalBBox;
4213 QCanvasRectangle *frame=NULL;
4215 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
4217 mapRect.setRect (totalBBox.x(), totalBBox.y(),
4218 totalBBox.width(), totalBBox.height());
4219 frame=new QCanvasRectangle (mapRect,mapScene);
4220 frame->setBrush (QColor(white));
4221 frame->setPen (QColor(black));
4222 frame->setZValue(0);
4227 setHideTmpMode (HideNone);
4229 cout <<" hidemode="<<hidemode<<endl;
4233 void MapEditor::testFunction2()
4235 mapCenter->reposition();
4240 if (hidemode==HideExport)
4241 setHideTmpMode (HideNone);
4243 setHideTmpMode (HideExport);
4246 LinkableMapObj *lmo=xelection.getBranch();
4249 cout << "LMO::id="<<lmo->getID().ascii()<<endl;
4250 cout << " BO::id="<<((BranchObj*)lmo)->getID().ascii()<<endl;
4255 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
4257 // Lineedits are already closed by preceding
4258 // mouseEvent, we don't need to close here.
4260 QPointF p = mapToScene(e->pos());
4261 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4264 { // MapObj was found
4265 if (xelection.single() != lmo)
4267 // select the MapObj
4268 xelection.select(lmo);
4271 if (xelection.getBranch() )
4273 // Context Menu on branch or mapcenter
4275 branchContextMenu->popup(e->globalPos() );
4278 if (xelection.getFloatImage() )
4280 // Context Menu on floatimage
4282 floatimageContextMenu->popup(e->globalPos() );
4286 { // No MapObj found, we are on the Canvas itself
4287 // Context Menu on scene
4289 canvasContextMenu->popup(e->globalPos() );
4294 void MapEditor::keyPressEvent(QKeyEvent* e)
4296 if (e->modifiers() & Qt::ControlModifier)
4298 switch (mainWindow->getModMode())
4300 case Main::ModModeColor:
4301 setCursor (PickColorCursor);
4303 case Main::ModModeCopy:
4304 setCursor (CopyCursor);
4306 case Main::ModModeXLink:
4307 setCursor (XLinkCursor);
4310 setCursor (Qt::ArrowCursor);
4316 void MapEditor::keyReleaseEvent(QKeyEvent* e)
4318 if (!(e->modifiers() & Qt::ControlModifier))
4319 setCursor (Qt::ArrowCursor);
4322 void MapEditor::mousePressEvent(QMouseEvent* e)
4324 // Ignore right clicks, these will go to context menus
4325 if (e->button() == Qt::RightButton )
4331 //Ignore clicks while editing heading
4332 if (isSelectBlocked() )
4338 QPointF p = mapToScene(e->pos());
4339 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4343 //Take care of system flags _or_ modifier modes
4345 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
4346 typeid(*lmo)==typeid(MapCenterObj) ))
4348 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
4349 if (!foname.isEmpty())
4351 // systemFlag clicked
4355 if (e->state() & Qt::ControlModifier)
4356 mainWindow->editOpenURLTab();
4358 mainWindow->editOpenURL();
4360 else if (foname=="vymLink")
4362 mainWindow->editOpenVymLink();
4363 // tabWidget may change, better return now
4364 // before segfaulting...
4365 } else if (foname=="note")
4366 mainWindow->windowToggleNoteEditor();
4367 else if (foname=="hideInExport")
4374 // No system flag clicked, take care of modmodes (CTRL-Click)
4375 if (e->state() & Qt::ControlModifier)
4377 if (mainWindow->getModMode()==Main::ModModeColor)
4380 setCursor (PickColorCursor);
4383 if (mainWindow->getModMode()==Main::ModModeXLink)
4385 BranchObj *bo_begin=NULL;
4387 bo_begin=(BranchObj*)(lmo);
4389 if (xelection.getBranch() )
4390 bo_begin=xelection.getBranch();
4394 linkingObj_src=bo_begin;
4395 tmpXLink=new XLinkObj (mapScene);
4396 tmpXLink->setBegin (bo_begin);
4397 tmpXLink->setEnd (p);
4398 tmpXLink->setColor(defXLinkColor);
4399 tmpXLink->setWidth(defXLinkWidth);
4400 tmpXLink->updateXLink();
4401 tmpXLink->setVisibility (true);
4405 } // End of modmodes
4409 // Select the clicked object
4412 // Left Button Move Branches
4413 if (e->button() == Qt::LeftButton )
4415 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
4416 //movingObj_start.setY( p.y() - selection->y() );
4417 movingObj_start.setX( p.x() - lmo->x() );
4418 movingObj_start.setY( p.y() - lmo->y() );
4419 movingObj_orgPos.setX (lmo->x() );
4420 movingObj_orgPos.setY (lmo->y() );
4421 movingObj_orgRelPos=lmo->getRelPos();
4423 // If modMode==copy, then we want to "move" the _new_ object around
4424 // then we need the offset from p to the _old_ selection, because of tmp
4425 if (mainWindow->getModMode()==Main::ModModeCopy &&
4426 e->state() & Qt::ControlModifier)
4428 if (xelection.type()==Selection::Branch)
4431 mapCenter->addBranch ((BranchObj*)xelection.single());
4433 xelection.select(mapCenter->getLastBranch());
4434 mapCenter->reposition();
4438 movingObj=xelection.single();
4440 // Middle Button Toggle Scroll
4441 // (On Mac OS X this won't work, but we still have
4442 // a button in the toolbar)
4443 if (e->button() == Qt::MidButton )
4448 { // No MapObj found, we are on the scene itself
4449 // Left Button move Pos of sceneView
4450 if (e->button() == Qt::LeftButton )
4452 movingObj=NULL; // move Content not Obj
4453 movingObj_start=e->globalPos();
4454 movingCont_start=QPointF (
4455 horizontalScrollBar()->value(),
4456 verticalScrollBar()->value());
4457 movingVec=QPointF(0,0);
4458 setCursor(HandOpenCursor);
4463 void MapEditor::mouseMoveEvent(QMouseEvent* e)
4465 QPointF p = mapToScene(e->pos());
4466 LinkableMapObj *lmosel=xelection.single();
4468 // Move the selected MapObj
4469 if ( lmosel && movingObj)
4471 // reset cursor if we are moving and don't copy
4472 if (mainWindow->getModMode()!=Main::ModModeCopy)
4473 setCursor (Qt::ArrowCursor);
4475 // To avoid jumping of the sceneView, only
4476 // ensureSelectionVisible, if not tmp linked
4477 if (!lmosel->hasParObjTmp())
4478 ensureSelectionVisible ();
4480 // Now move the selection, but add relative position
4481 // (movingObj_start) where selection was chosen with
4482 // mousepointer. (This avoids flickering resp. jumping
4483 // of selection back to absPos)
4485 // Check if we could link
4486 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
4489 FloatObj *fio=xelection.getFloatImage();
4492 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4494 fio->updateLink(); //no need for reposition, if we update link here
4497 // Relink float to new mapcenter or branch, if shift is pressed
4498 // Only relink, if selection really has a new parent
4499 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
4500 ( (typeid(*lmo)==typeid(BranchObj)) ||
4501 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
4502 ( lmo != fio->getParObj())
4505 if (typeid(*fio) == typeid(FloatImageObj) &&
4506 ( (typeid(*lmo)==typeid(BranchObj) ||
4507 typeid(*lmo)==typeid(MapCenterObj)) ))
4510 // Also save the move which was done so far
4511 QString pold=qpointfToString(movingObj_orgRelPos);
4512 QString pnow=qpointfToString(fio->getRelPos());
4518 QString("Move %1 to relative position %2").arg(getName(fio)).arg(pnow));
4519 fio->getParObj()->requestReposition();
4520 mapCenter->reposition();
4522 linkTo (lmo->getSelectString());
4524 //movingObj_orgRelPos=lmosel->getRelPos();
4526 mapCenter->reposition();
4530 { // selection != a FloatObj
4531 if (lmosel->getDepth()==0)
4534 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
4535 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4537 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4538 mapCenter->updateRelPositions();
4541 if (lmosel->getDepth()==1)
4544 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4545 lmosel->setRelPos();
4548 // Move ordinary branch
4549 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
4550 // Add width of bbox here, otherwise alignRelTo will cause jumping around
4551 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
4552 p.y()-movingObj_start.y() +lmosel->getTopPad() );
4554 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
4557 // Maybe we can relink temporary?
4558 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
4559 (typeid(*lmo)==typeid(BranchObj) ||
4560 typeid(*lmo)==typeid(MapCenterObj)) )
4563 if (e->modifiers()==Qt::ControlModifier)
4565 // Special case: CTRL to link below lmo
4566 lmosel->setParObjTmp (lmo,p,+1);
4568 else if (e->modifiers()==Qt::ShiftModifier)
4569 lmosel->setParObjTmp (lmo,p,-1);
4571 lmosel->setParObjTmp (lmo,p,0);
4574 lmosel->unsetParObjTmp();
4576 // reposition subbranch
4577 lmosel->reposition();
4581 } // no FloatImageObj
4585 } // selection && moving_obj
4587 // Draw a link from one branch to another
4590 tmpXLink->setEnd (p);
4591 tmpXLink->updateXLink();
4595 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
4597 QPointF p=e->globalPos();
4598 movingVec.setX(-p.x() + movingObj_start.x() );
4599 movingVec.setY(-p.y() + movingObj_start.y() );
4600 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
4601 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
4606 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
4608 QPointF p = mapToScene(e->pos());
4609 LinkableMapObj *dst;
4610 LinkableMapObj *lmosel=xelection.single();
4611 // Have we been picking color?
4615 setCursor (Qt::ArrowCursor);
4616 // Check if we are over another branch
4617 dst=mapCenter->findMapObj(p, NULL);
4620 if (e->state() & Qt::ShiftModifier)
4621 colorBranch (((BranchObj*)dst)->getColor());
4623 colorSubtree (((BranchObj*)dst)->getColor());
4628 // Have we been drawing a link?
4632 // Check if we are over another branch
4633 dst=mapCenter->findMapObj(p, NULL);
4636 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
4637 tmpXLink->updateXLink();
4638 tmpXLink->activate(); //FIXME savestate missing
4639 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );
4648 // Have we been moving something?
4649 if ( lmosel && movingObj )
4651 FloatImageObj *fo=xelection.getFloatImage();
4654 // Moved FloatObj. Maybe we need to reposition
4655 QString pold=qpointfToString(movingObj_orgRelPos);
4656 QString pnow=qpointfToString(fo->getRelPos());
4662 QString("Move %1 to relative position %2").arg(getName(fo)).arg(pnow));
4664 fo->getParObj()->requestReposition();
4665 mapCenter->reposition();
4668 // Check if we are over another branch, but ignore
4669 // any found LMOs, which are FloatObjs
4670 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
4672 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4675 if (xelection.type() == Selection::MapCenter )
4677 // TODO: Check for problems if graphicsview is resized for
4679 if (movingObj_orgPos != mapCenter->getAbsPos())
4681 QString pold=qpointfToString(movingObj_orgPos);
4682 QString pnow=qpointfToString(mapCenter->getAbsPos());
4688 QString("Move mapcenter %1 to position %2").arg(getName(mapCenter)).arg(pnow));
4692 if (xelection.type() == Selection::Branch )
4693 { // A branch was moved
4695 // save the position in case we link to mapcenter
4696 QPointF savePos=QPointF (lmosel->getAbsPos() );
4698 // Reset the temporary drawn link to the original one
4699 lmosel->unsetParObjTmp();
4701 // For Redo we may need to save original selection
4702 QString preSelStr=lmosel->getSelectString();
4707 BranchObj* bsel=xelection.getBranch();
4708 BranchObj* bdst=(BranchObj*)dst;
4710 QString preParStr=(bsel->getParObj())->getSelectString();
4711 QString preNum=QString::number (bsel->getNum(),10);
4712 QString preDstParStr;
4714 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4716 preDstParStr=dst->getParObj()->getSelectString();
4717 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4719 if (e->state() & Qt::ControlModifier && dst->getParObj())
4722 preDstParStr=dst->getParObj()->getSelectString();
4723 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4726 preDstParStr=dst->getSelectString();
4727 bsel->linkTo (bdst,-1);
4728 if (dst->getDepth()==0) bsel->move (savePos);
4730 QString postSelStr=lmosel->getSelectString();
4731 QString postNum=QString::number (bsel->getNum(),10);
4733 QString undoCom="linkTo (\""+
4734 preParStr+ "\"," + preNum +"," +
4735 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4737 QString redoCom="linkTo (\""+
4738 preDstParStr + "\"," + postNum + "," +
4739 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4744 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4746 if (lmosel->getDepth()==1)
4748 // The select string might be different _after_ moving around.
4749 // Therefor reposition and then use string of old selection, too
4750 mapCenter->reposition();
4752 QPointF rp(lmosel->getRelPos());
4753 if (rp != movingObj_orgRelPos)
4755 QString ps=qpointfToString(rp);
4757 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4758 preSelStr, "moveRel "+ps,
4759 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4762 // Draw the original link, before selection was moved around
4763 mapCenter->reposition();
4766 // Finally resize scene, if needed
4770 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4773 // maybe we moved View: set old cursor
4774 setCursor (Qt::ArrowCursor);
4778 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4780 if (isSelectBlocked() )
4786 if (e->button() == Qt::LeftButton )
4788 QPointF p = mapToScene(e->pos());
4789 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4790 if (lmo) { // MapObj was found
4791 // First select the MapObj than edit heading
4792 xelection.select(lmo);
4793 mainWindow->editHeading();
4798 void MapEditor::resizeEvent (QResizeEvent* e)
4800 QGraphicsView::resizeEvent( e );
4803 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4805 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4806 // cerr << event->format(i) << endl;
4808 if (event->mimeData()->hasImage())
4809 event->acceptProposedAction();
4811 if (event->mimeData()->hasUrls())
4812 event->acceptProposedAction();
4815 void MapEditor::dragMoveEvent(QDragMoveEvent *)
4819 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4824 void MapEditor::dropEvent(QDropEvent *event)
4826 BranchObj *sel=xelection.getBranch();
4830 foreach (QString format,event->mimeData()->formats())
4831 cout << "MapEditor: Dropped format: "<<format.ascii()<<endl;
4835 if (event->mimeData()->hasImage())
4837 QVariant imageData = event->mimeData()->imageData();
4838 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4840 if (event->mimeData()->hasUrls())
4841 uris=event->mimeData()->urls();
4849 for (int i=0; i<uris.count();i++)
4851 // Workaround to avoid adding empty branches
4852 if (!uris.at(i).toString().isEmpty())
4854 bo=sel->addBranch();
4857 s=uris.at(i).toLocalFile();
4860 QString file = QDir::fromNativeSeparators(s);
4861 heading = QFileInfo(file).baseName();
4863 if (file.endsWith(".vym", false))
4864 bo->setVymLink(file);
4866 bo->setURL(uris.at(i).toString());
4869 bo->setURL(uris.at(i).toString());
4872 if (!heading.isEmpty())
4873 bo->setHeading(heading);
4875 bo->setHeading(uris.at(i).toString());
4879 mapCenter->reposition();
4882 event->acceptProposedAction();
4885 void MapEditor::timerEvent(QTimerEvent *event) //TODO animation
4889 cout << "ME::timerEvent\n";
4891 for (int i=0; i<animObjList.size(); ++i)
4893 animObjList.at(i)->animate();
4894 ((BranchObj*)animObjList.at(i))->move2RelPos (((BranchObj*)animObjList.at(i))->getRelPos() );
4896 mapCenter->reposition();
4900 void MapEditor::sendSelection()
4902 if (netstate!=Server) return;
4903 sendData (QString("select (\"%1\")").arg(xelection.getSelectString()) );
4906 void MapEditor::newServer()
4910 tcpServer = new QTcpServer(this);
4911 if (!tcpServer->listen(QHostAddress::Any,port)) {
4912 QMessageBox::critical(this, "vym server",
4913 QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
4917 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
4919 cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
4922 void MapEditor::connectToServer()
4925 server="salam.suse.de";
4927 clientSocket = new QTcpSocket (this);
4928 clientSocket->abort();
4929 clientSocket->connectToHost(server ,port);
4930 connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
4931 connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
4932 this, SLOT(displayNetworkError(QAbstractSocket::SocketError)));
4934 cout<<"connected to "<<server.ascii()<<" port "<<port<<endl;
4939 void MapEditor::newClient()
4941 QTcpSocket *newClient = tcpServer->nextPendingConnection();
4942 connect(newClient, SIGNAL(disconnected()),
4943 newClient, SLOT(deleteLater()));
4945 cout <<"ME::newClient at "<<newClient->peerAddress().toString().ascii()<<endl;
4947 clientList.append (newClient);
4951 void MapEditor::sendData(const QString &s)
4953 if (clientList.size()==0) return;
4955 // Create bytearray to send
4957 QDataStream out(&block, QIODevice::WriteOnly);
4958 out.setVersion(QDataStream::Qt_4_0);
4960 // Reserve some space for blocksize
4963 // Write sendCounter
4964 out << sendCounter++;
4969 // Go back and write blocksize so far
4970 out.device()->seek(0);
4971 quint16 bs=(quint16)(block.size() - 2*sizeof(quint16));
4975 cout << "ME::sendData bs="<<bs<<" counter="<<sendCounter<<" s="<<s.ascii()<<endl;
4977 for (int i=0; i<clientList.size(); ++i)
4979 //cout << "Sending \""<<s.ascii()<<"\" to "<<clientList.at(i)->peerAddress().toString().ascii()<<endl;
4980 clientList.at(i)->write (block);
4984 void MapEditor::readData ()
4986 while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) )
4989 cout <<"readData bytesAvail="<<clientSocket->bytesAvailable();
4993 QDataStream in(clientSocket);
4994 in.setVersion(QDataStream::Qt_4_0);
5002 cout << " t="<<t.ascii()<<endl;
5008 void MapEditor::displayNetworkError(QAbstractSocket::SocketError socketError)
5010 switch (socketError) {
5011 case QAbstractSocket::RemoteHostClosedError:
5013 case QAbstractSocket::HostNotFoundError:
5014 QMessageBox::information(this, __VYM_NAME " Network client",
5015 "The host was not found. Please check the "
5016 "host name and port settings.");
5018 case QAbstractSocket::ConnectionRefusedError:
5019 QMessageBox::information(this, __VYM_NAME " Network client",
5020 "The connection was refused by the peer. "
5021 "Make sure the fortune server is running, "
5022 "and check that the host name and port "
5023 "settings are correct.");
5026 QMessageBox::information(this, __VYM_NAME " Network client",
5027 QString("The following error occurred: %1.")
5028 .arg(clientSocket->errorString()));
5032 void MapEditor::autosave()
5034 // Disable autosave, while we have gone back in history
5035 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
5036 if (redosAvail>0) return;
5039 if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() )
5040 mainWindow->fileSave (this);
5044 /*TODO not needed? void MapEditor::contentsDropEvent(QDropEvent *event)
5047 } else if (event->provides("application/x-moz-file-promise-url") &&
5048 event->provides("application/x-moz-nativeimage"))
5050 // Contains url to the img src in unicode16
5051 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
5052 QString url = QString((const QChar*)d.data(),d.size()/2);
5056 } else if (event->provides ("text/uri-list"))
5057 { // Uris provided e.g. by konqueror
5058 Q3UriDrag::decode (event,uris);
5059 } else if (event->provides ("_NETSCAPE_URL"))
5060 { // Uris provided by Mozilla
5061 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
5064 } else if (event->provides("text/html")) {
5066 // Handels text mime types
5067 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
5068 QByteArray d = event->encodedData("text/html");
5071 text = QString((const QChar*)d.data(),d.size()/2);
5075 textEditor->setText(text);
5079 } else if (event->provides("text/plain")) {
5080 QByteArray d = event->encodedData("text/plain");
5083 text = QString((const QChar*)d.data(),d.size()/2);
5087 textEditor->setText(text);
5097 bool isUnicode16(const QByteArray &d)
5099 // TODO: make more precise check for unicode 16.
5100 // Guess unicode16 if any of second bytes are zero
5101 unsigned int length = max(0,d.size()-2)/2;
5102 for (unsigned int i = 0; i<length ; i++)
5103 if (d.at(i*2+1)==0) return true;
5107 void MapEditor::addFloatImageInt (const QPixmap &img)
5109 BranchObj *bo=xelection.getBranch();
5112 FloatImageObj *fio=bo->addFloatImage();
5114 fio->setOriginalFilename("No original filename (image added by dropevent)");
5115 QString s=bo->getSelectString();
5116 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio );
5117 saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image");
5118 mapCenter->reposition();
5125 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
5127 if (!imageBuffer) imageBuffer = new QBuffer();
5128 if (!imageBuffer->isOpen()) {
5129 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
5131 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
5135 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
5137 if (nop->state()==Q3NetworkProtocol::StDone) {
5138 QPixmap img(imageBuffer->buffer());
5139 addFloatImageInt (img);
5143 imageBuffer->close();
5145 imageBuffer->close();
5152 void MapEditor::fetchImage(const QString &url)
5155 urlOperator->stop();
5156 disconnect(urlOperator);
5160 urlOperator = new Q3UrlOperator(url);
5161 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
5162 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
5164 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
5165 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));