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()));
158 attrTable= new AttributeTable();
159 attrTable->addKey ("Key A - Priority");
160 attrTable->addValue ("Key A","P 1");
161 attrTable->addValue ("Key A","P 2");
162 attrTable->addValue ("Key A","P 3");
163 attrTable->addValue ("Key A","P 4");
164 attrTable->addKey ("Key B");
165 attrTable->addValue ("Key B","w1");
166 attrTable->addValue ("Key B","w2");
167 attrTable->addKey ("Key Prio");
168 attrTable->addValue ("Key Prio","Prio 1");
169 attrTable->addValue ("Key Prio","Prio 2");
172 MapEditor::~MapEditor()
174 //cout <<"Destructor MapEditor\n";
175 autosaveTimer->stop();
177 // tmpMapDir is in tmpVymDir, so it gets removed automagically when vym closes
179 //removeDir(QDir(tmpMapDir));
182 MapCenterObj* MapEditor::getMapCenter()
187 QGraphicsScene * MapEditor::getScene()
192 MapEditor::State MapEditor::getState()
197 void MapEditor::setStateEditHeading(bool s)
201 if (state==Idle) state=EditHeading;
207 bool MapEditor::isRepositionBlocked()
209 return blockReposition;
212 void MapEditor::setSaveStateBlocked(bool b)
217 bool MapEditor::isSelectBlocked()
219 if (state==EditHeading)
225 QString MapEditor::getName (const LinkableMapObj *lmo)
228 if (!lmo) return QString("Error: NULL has no name!");
230 if ((typeid(*lmo) == typeid(BranchObj) ||
231 typeid(*lmo) == typeid(MapCenterObj)))
234 s=(((BranchObj*)lmo)->getHeading());
235 if (s=="") s="unnamed";
236 return QString("branch (%1)").arg(s);
237 //return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
239 if ((typeid(*lmo) == typeid(FloatImageObj) ))
240 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
241 //return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
242 return QString("Unknown type has no name!");
245 void MapEditor::makeTmpDirs()
247 // Create unique temporary directories
248 tmpMapDir = tmpVymDir+QString("/mapeditor-%1").arg(mapNum);
249 histPath = tmpMapDir+"/history";
254 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
256 // tmpdir temporary directory to which data will be written
257 // prefix mapname, which will be appended to images etc.
258 // writeflags Only write flags for "real" save of map, not undo
259 // offset offset of bbox of whole map in scene.
260 // Needed for XML export
266 case LinkableMapObj::Line:
269 case LinkableMapObj::Parabel:
272 case LinkableMapObj::PolyLine:
276 ls="StylePolyParabel";
280 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
282 if (linkcolorhint==LinkableMapObj::HeadingColor)
283 colhint=attribut("linkColorHint","HeadingColor");
285 QString mapAttr=attribut("version",vymVersion);
286 if (!saveSel || saveSel==mapCenter)
287 mapAttr+= attribut("author",mapCenter->getAuthor()) +
288 attribut("comment",mapCenter->getComment()) +
289 attribut("date",mapCenter->getDate()) +
290 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
291 attribut("selectionColor", xelection.getColor().name() ) +
292 attribut("linkStyle", ls ) +
293 attribut("linkColor", defLinkColor.name() ) +
294 attribut("defXLinkColor", defXLinkColor.name() ) +
295 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
297 s+=beginElement("vymmap",mapAttr);
300 // Find the used flags while traversing the tree
301 standardFlagsDefault->resetUsedCounter();
303 // Reset the counters before saving
304 // TODO constr. of FIO creates lots of objects, better do this in some other way...
305 FloatImageObj (mapScene).resetSaveCounter();
307 // Build xml recursivly
308 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
309 // Save complete map, if saveSel not set
310 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
313 if ( typeid(*saveSel) == typeid(BranchObj) )
315 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
316 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
318 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
321 // Save local settings
322 s+=settings.getDataXML (destPath);
325 if (!xelection.isEmpty() && !saveSel )
326 s+=valueElement("select",xelection.getSelectString());
329 s+=endElement("vymmap");
332 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
336 QString MapEditor::getHistoryDir()
338 QString histName(QString("history-%1").arg(curStep));
339 return (tmpMapDir+"/"+histName);
342 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
344 sendData(redoCom); //FIXME testing
349 if (blockSaveState) return;
351 if (debug) cout << "ME::saveState() for "<<mapName.ascii()<<endl;
353 // Find out current undo directory
354 if (undosAvail<stepsTotal) undosAvail++;
356 if (curStep>stepsTotal) curStep=1;
358 QString backupXML="";
359 QString histDir=getHistoryDir();
360 QString bakMapPath=histDir+"/map.xml";
362 // Create histDir if not available
365 makeSubDirs (histDir);
367 // Save depending on how much needs to be saved
369 backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
371 QString undoCommand="";
372 if (savemode==UndoCommand)
376 else if (savemode==PartOfMap )
379 undoCommand.replace ("PATH",bakMapPath);
382 if (!backupXML.isEmpty())
383 // Write XML Data to disk
384 saveStringToDisk (bakMapPath,backupXML);
386 // We would have to save all actions in a tree, to keep track of
387 // possible redos after a action. Possible, but we are too lazy: forget about redos.
390 // Write the current state to disk
391 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
392 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
393 undoSet.setEntry ("/history/curStep",QString::number(curStep));
394 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
395 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
396 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
397 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
398 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
399 undoSet.setEntry (QString("/history/version"),vymVersion);
400 undoSet.writeSettings(histPath);
404 // TODO remove after testing
405 //cout << " into="<< histPath.toStdString()<<endl;
406 cout << " stepsTotal="<<stepsTotal<<
407 ", undosAvail="<<undosAvail<<
408 ", redosAvail="<<redosAvail<<
409 ", curStep="<<curStep<<endl;
410 cout << " ---------------------------"<<endl;
411 cout << " comment="<<comment.toStdString()<<endl;
412 cout << " undoCom="<<undoCommand.toStdString()<<endl;
413 cout << " undoSel="<<undoSelection.toStdString()<<endl;
414 cout << " redoCom="<<redoCom.toStdString()<<endl;
415 cout << " redoSel="<<redoSelection.toStdString()<<endl;
416 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
417 cout << " ---------------------------"<<endl;
420 mainWindow->updateHistory (undoSet);
426 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
428 // save the selected part of the map, Undo will replace part of map
429 QString undoSelection="";
431 undoSelection=undoSel->getSelectString();
433 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
434 QString redoSelection="";
436 redoSelection=undoSel->getSelectString();
438 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
441 saveState (PartOfMap,
442 undoSelection, "addMapReplace (\"PATH\")",
448 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
452 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
455 QString undoSelection=redoSel->getParObj()->getSelectString();
456 QString redoSelection=redoSel->getSelectString();
457 if (typeid(*redoSel) == typeid(BranchObj) )
459 // save the selected branch of the map, Undo will insert part of map
460 saveState (PartOfMap,
461 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
462 redoSelection, "delete ()",
469 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
471 // "Normal" savestate: save commands, selections and comment
472 // so just save commands for undo and redo
473 // and use current selection
475 QString redoSelection="";
476 if (redoSel) redoSelection=redoSel->getSelectString();
477 QString undoSelection="";
478 if (undoSel) undoSelection=undoSel->getSelectString();
480 saveState (UndoCommand,
487 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
489 // "Normal" savestate: save commands, selections and comment
490 // so just save commands for undo and redo
491 // and use current selection
492 saveState (UndoCommand,
500 void MapEditor::parseAtom(const QString &atom)
502 BranchObj *selb=xelection.getBranch();
508 // Split string s into command and parameters
509 parser.parseAtom (atom);
510 QString com=parser.getCommand();
513 /////////////////////////////////////////////////////////////////////
514 if (com=="addBranch")
516 if (xelection.isEmpty())
518 parser.setError (Aborted,"Nothing selected");
521 parser.setError (Aborted,"Type of selection is not a branch");
526 if (parser.checkParCount(pl))
528 if (parser.parCount()==0)
532 n=parser.parInt (ok,0);
533 if (ok ) addNewBranch (n);
537 /////////////////////////////////////////////////////////////////////
538 } else if (com=="addBranchBefore")
540 if (xelection.isEmpty())
542 parser.setError (Aborted,"Nothing selected");
545 parser.setError (Aborted,"Type of selection is not a branch");
548 if (parser.parCount()==0)
550 addNewBranchBefore ();
553 /////////////////////////////////////////////////////////////////////
554 } else if (com==QString("addMapReplace"))
556 if (xelection.isEmpty())
558 parser.setError (Aborted,"Nothing selected");
561 parser.setError (Aborted,"Type of selection is not a branch");
562 } else if (parser.checkParCount(1))
564 //s=parser.parString (ok,0); // selection
565 t=parser.parString (ok,0); // path to map
566 if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
567 addMapReplaceInt(selb->getSelectString(),t);
569 /////////////////////////////////////////////////////////////////////
570 } else if (com==QString("addMapInsert"))
572 if (xelection.isEmpty())
574 parser.setError (Aborted,"Nothing selected");
577 parser.setError (Aborted,"Type of selection is not a branch");
580 if (parser.checkParCount(2))
582 t=parser.parString (ok,0); // path to map
583 n=parser.parInt(ok,1); // position
584 if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
585 addMapInsertInt(t,n);
588 /////////////////////////////////////////////////////////////////////
589 } else if (com=="clearFlags")
591 if (xelection.isEmpty() )
593 parser.setError (Aborted,"Nothing selected");
596 parser.setError (Aborted,"Type of selection is not a branch");
597 } else if (parser.checkParCount(0))
599 selb->clearStandardFlags();
600 selb->updateFlagsToolbar();
602 /////////////////////////////////////////////////////////////////////
603 } else if (com=="colorBranch")
605 if (xelection.isEmpty())
607 parser.setError (Aborted,"Nothing selected");
610 parser.setError (Aborted,"Type of selection is not a branch");
611 } else if (parser.checkParCount(1))
613 QColor c=parser.parColor (ok,0);
614 if (ok) colorBranch (c);
616 /////////////////////////////////////////////////////////////////////
617 } else if (com=="colorSubtree")
619 if (xelection.isEmpty())
621 parser.setError (Aborted,"Nothing selected");
624 parser.setError (Aborted,"Type of selection is not a branch");
625 } else if (parser.checkParCount(1))
627 QColor c=parser.parColor (ok,0);
628 if (ok) colorSubtree (c);
630 /////////////////////////////////////////////////////////////////////
631 } else if (com=="copy")
633 if (xelection.isEmpty())
635 parser.setError (Aborted,"Nothing selected");
638 parser.setError (Aborted,"Type of selection is not a branch");
639 } else if (parser.checkParCount(0))
641 //FIXME missing action for copy
643 /////////////////////////////////////////////////////////////////////
644 } else if (com=="cut")
646 if (xelection.isEmpty())
648 parser.setError (Aborted,"Nothing selected");
649 } else if ( xelection.type()!=Selection::Branch &&
650 xelection.type()!=Selection::MapCenter &&
651 xelection.type()!=Selection::FloatImage )
653 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
654 } else if (parser.checkParCount(0))
658 /////////////////////////////////////////////////////////////////////
659 } else if (com=="delete")
661 if (xelection.isEmpty())
663 parser.setError (Aborted,"Nothing selected");
664 } else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage )
666 parser.setError (Aborted,"Type of selection is wrong.");
667 } else if (parser.checkParCount(0))
671 /////////////////////////////////////////////////////////////////////
672 } else if (com=="deleteKeepChilds")
674 if (xelection.isEmpty())
676 parser.setError (Aborted,"Nothing selected");
679 parser.setError (Aborted,"Type of selection is not a branch");
680 } else if (parser.checkParCount(0))
684 /////////////////////////////////////////////////////////////////////
685 } else if (com=="deleteChilds")
687 if (xelection.isEmpty())
689 parser.setError (Aborted,"Nothing selected");
692 parser.setError (Aborted,"Type of selection is not a branch");
693 } else if (parser.checkParCount(0))
697 /////////////////////////////////////////////////////////////////////
698 } else if (com=="exportASCII")
702 if (parser.parCount()>=1)
703 // Hey, we even have a filename
704 fname=parser.parString(ok,0);
707 parser.setError (Aborted,"Could not read filename");
710 exportASCII (fname,false);
712 /////////////////////////////////////////////////////////////////////
713 } else if (com=="exportImage")
717 if (parser.parCount()>=2)
718 // Hey, we even have a filename
719 fname=parser.parString(ok,0);
722 parser.setError (Aborted,"Could not read filename");
725 QString format="PNG";
726 if (parser.parCount()>=2)
728 format=parser.parString(ok,1);
730 exportImage (fname,false,format);
732 /////////////////////////////////////////////////////////////////////
733 } else if (com=="exportXHTML")
737 if (parser.parCount()>=2)
738 // Hey, we even have a filename
739 fname=parser.parString(ok,1);
742 parser.setError (Aborted,"Could not read filename");
745 exportXHTML (fname,false);
747 /////////////////////////////////////////////////////////////////////
748 } else if (com=="exportXML")
752 if (parser.parCount()>=2)
753 // Hey, we even have a filename
754 fname=parser.parString(ok,1);
757 parser.setError (Aborted,"Could not read filename");
760 exportXML (fname,false);
762 /////////////////////////////////////////////////////////////////////
763 } else if (com=="importDir")
765 if (xelection.isEmpty())
767 parser.setError (Aborted,"Nothing selected");
770 parser.setError (Aborted,"Type of selection is not a branch");
771 } else if (parser.checkParCount(1))
773 s=parser.parString(ok,0);
774 if (ok) importDirInt(s);
776 /////////////////////////////////////////////////////////////////////
777 } else if (com=="linkTo")
779 if (xelection.isEmpty())
781 parser.setError (Aborted,"Nothing selected");
784 if (parser.checkParCount(4))
786 // 0 selectstring of parent
787 // 1 num in parent (for branches)
788 // 2,3 x,y of mainbranch or mapcenter
789 s=parser.parString(ok,0);
790 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
793 if (typeid(*dst) == typeid(BranchObj) )
795 // Get number in parent
796 n=parser.parInt (ok,1);
799 selb->linkTo ((BranchObj*)(dst),n);
802 } else if (typeid(*dst) == typeid(MapCenterObj) )
804 selb->linkTo ((BranchObj*)(dst),-1);
805 // Get coordinates of mainbranch
806 x=parser.parDouble(ok,2);
809 y=parser.parDouble(ok,3);
819 } else if ( xelection.type() == Selection::FloatImage)
821 if (parser.checkParCount(1))
823 // 0 selectstring of parent
824 s=parser.parString(ok,0);
825 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
828 if (typeid(*dst) == typeid(BranchObj) ||
829 typeid(*dst) == typeid(MapCenterObj))
830 linkTo (dst->getSelectString());
832 parser.setError (Aborted,"Destination is not a branch");
835 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
836 /////////////////////////////////////////////////////////////////////
837 } else if (com=="loadImage")
839 if (xelection.isEmpty())
841 parser.setError (Aborted,"Nothing selected");
844 parser.setError (Aborted,"Type of selection is not a branch");
845 } else if (parser.checkParCount(1))
847 s=parser.parString(ok,0);
848 if (ok) loadFloatImageInt (s);
850 /////////////////////////////////////////////////////////////////////
851 } else if (com=="moveBranchUp")
853 if (xelection.isEmpty() )
855 parser.setError (Aborted,"Nothing selected");
858 parser.setError (Aborted,"Type of selection is not a branch");
859 } else if (parser.checkParCount(0))
863 /////////////////////////////////////////////////////////////////////
864 } else if (com=="moveBranchDown")
866 if (xelection.isEmpty() )
868 parser.setError (Aborted,"Nothing selected");
871 parser.setError (Aborted,"Type of selection is not a branch");
872 } else if (parser.checkParCount(0))
876 /////////////////////////////////////////////////////////////////////
877 } else if (com=="move")
879 if (xelection.isEmpty() )
881 parser.setError (Aborted,"Nothing selected");
882 } else if ( xelection.type()!=Selection::Branch &&
883 xelection.type()!=Selection::MapCenter &&
884 xelection.type()!=Selection::FloatImage )
886 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
887 } else if (parser.checkParCount(2))
889 x=parser.parDouble (ok,0);
892 y=parser.parDouble (ok,1);
896 /////////////////////////////////////////////////////////////////////
897 } else if (com=="moveRel")
899 if (xelection.isEmpty() )
901 parser.setError (Aborted,"Nothing selected");
902 } else if ( xelection.type()!=Selection::Selection::Branch &&
903 xelection.type()!=Selection::Selection::MapCenter &&
904 xelection.type()!=Selection::Selection::FloatImage )
906 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
907 } else if (parser.checkParCount(2))
909 x=parser.parDouble (ok,0);
912 y=parser.parDouble (ok,1);
913 if (ok) moveRel (x,y);
916 /////////////////////////////////////////////////////////////////////
917 } else if (com=="nop")
919 /////////////////////////////////////////////////////////////////////
920 } else if (com=="paste")
922 if (xelection.isEmpty() )
924 parser.setError (Aborted,"Nothing selected");
927 parser.setError (Aborted,"Type of selection is not a branch");
928 } else if (parser.checkParCount(1))
930 n=parser.parInt (ok,0);
931 if (ok) pasteNoSave(n);
933 /////////////////////////////////////////////////////////////////////
934 } else if (com=="qa")
936 if (xelection.isEmpty() )
938 parser.setError (Aborted,"Nothing selected");
941 parser.setError (Aborted,"Type of selection is not a branch");
942 } else if (parser.checkParCount(4))
945 c=parser.parString (ok,0);
948 parser.setError (Aborted,"No comment given");
951 s=parser.parString (ok,1);
954 parser.setError (Aborted,"First parameter is not a string");
957 t=parser.parString (ok,2);
960 parser.setError (Aborted,"Condition is not a string");
963 u=parser.parString (ok,3);
966 parser.setError (Aborted,"Third parameter is not a string");
971 parser.setError (Aborted,"Unknown type: "+s);
976 parser.setError (Aborted,"Unknown operator: "+t);
981 parser.setError (Aborted,"Type of selection is not a branch");
984 if (selb->getHeading() == u)
986 cout << "PASSED: " << c.ascii() << endl;
989 cout << "FAILED: " << c.ascii() << endl;
999 /////////////////////////////////////////////////////////////////////
1000 } else if (com=="saveImage")
1002 FloatImageObj *fio=xelection.getFloatImage();
1005 parser.setError (Aborted,"Type of selection is not an image");
1006 } else if (parser.checkParCount(2))
1008 s=parser.parString(ok,0);
1011 t=parser.parString(ok,1);
1012 if (ok) saveFloatImageInt (fio,t,s);
1015 /////////////////////////////////////////////////////////////////////
1016 } else if (com=="scroll")
1018 if (xelection.isEmpty() )
1020 parser.setError (Aborted,"Nothing selected");
1023 parser.setError (Aborted,"Type of selection is not a branch");
1024 } else if (parser.checkParCount(0))
1026 if (!scrollBranch (selb))
1027 parser.setError (Aborted,"Could not scroll branch");
1029 /////////////////////////////////////////////////////////////////////
1030 } else if (com=="select")
1032 if (parser.checkParCount(1))
1034 s=parser.parString(ok,0);
1037 /////////////////////////////////////////////////////////////////////
1038 } else if (com=="selectLastBranch")
1040 if (xelection.isEmpty() )
1042 parser.setError (Aborted,"Nothing selected");
1045 parser.setError (Aborted,"Type of selection is not a branch");
1046 } else if (parser.checkParCount(0))
1048 BranchObj *bo=selb->getLastBranch();
1050 parser.setError (Aborted,"Could not select last branch");
1054 /////////////////////////////////////////////////////////////////////
1055 } else if (com=="selectLastImage")
1057 if (xelection.isEmpty() )
1059 parser.setError (Aborted,"Nothing selected");
1062 parser.setError (Aborted,"Type of selection is not a branch");
1063 } else if (parser.checkParCount(0))
1065 FloatImageObj *fio=selb->getLastFloatImage();
1067 parser.setError (Aborted,"Could not select last image");
1071 /////////////////////////////////////////////////////////////////////
1072 } else if (com=="selectLatestAdded")
1074 if (latestSelection.isEmpty() )
1076 parser.setError (Aborted,"No latest added object");
1079 if (!select (latestSelection))
1080 parser.setError (Aborted,"Could not select latest added object "+latestSelection);
1082 /////////////////////////////////////////////////////////////////////
1083 } else if (com=="setFrameType")
1085 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1087 parser.setError (Aborted,"Type of selection does not allow setting frame type");
1089 else if (parser.checkParCount(1))
1091 s=parser.parString(ok,0);
1092 if (ok) setFrameType (s);
1094 /////////////////////////////////////////////////////////////////////
1095 } else if (com=="setFramePenColor")
1097 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1099 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
1101 else if (parser.checkParCount(1))
1103 QColor c=parser.parColor(ok,0);
1104 if (ok) setFramePenColor (c);
1106 /////////////////////////////////////////////////////////////////////
1107 } else if (com=="setFrameBrushColor")
1109 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1111 parser.setError (Aborted,"Type of selection does not allow setting brush color");
1113 else if (parser.checkParCount(1))
1115 QColor c=parser.parColor(ok,0);
1116 if (ok) setFrameBrushColor (c);
1118 /////////////////////////////////////////////////////////////////////
1119 } else if (com=="setFramePadding")
1121 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1123 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
1125 else if (parser.checkParCount(1))
1127 n=parser.parInt(ok,0);
1128 if (ok) setFramePadding(n);
1130 /////////////////////////////////////////////////////////////////////
1131 } else if (com=="setFrameBorderWidth")
1133 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1135 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
1137 else if (parser.checkParCount(1))
1139 n=parser.parInt(ok,0);
1140 if (ok) setFrameBorderWidth (n);
1142 /////////////////////////////////////////////////////////////////////
1143 } else if (com=="setMapAuthor")
1145 if (parser.checkParCount(1))
1147 s=parser.parString(ok,0);
1148 if (ok) setMapAuthor (s);
1150 /////////////////////////////////////////////////////////////////////
1151 } else if (com=="setMapComment")
1153 if (parser.checkParCount(1))
1155 s=parser.parString(ok,0);
1156 if (ok) setMapComment(s);
1158 /////////////////////////////////////////////////////////////////////
1159 } else if (com=="setMapBackgroundColor")
1161 if (xelection.isEmpty() )
1163 parser.setError (Aborted,"Nothing selected");
1164 } else if (! xelection.getBranch() )
1166 parser.setError (Aborted,"Type of selection is not a branch");
1167 } else if (parser.checkParCount(1))
1169 QColor c=parser.parColor (ok,0);
1170 if (ok) setMapBackgroundColor (c);
1172 /////////////////////////////////////////////////////////////////////
1173 } else if (com=="setMapDefLinkColor")
1175 if (xelection.isEmpty() )
1177 parser.setError (Aborted,"Nothing selected");
1180 parser.setError (Aborted,"Type of selection is not a branch");
1181 } else if (parser.checkParCount(1))
1183 QColor c=parser.parColor (ok,0);
1184 if (ok) setMapDefLinkColor (c);
1186 /////////////////////////////////////////////////////////////////////
1187 } else if (com=="setMapLinkStyle")
1189 if (parser.checkParCount(1))
1191 s=parser.parString (ok,0);
1192 if (ok) setMapLinkStyle(s);
1194 /////////////////////////////////////////////////////////////////////
1195 } else if (com=="setHeading")
1197 if (xelection.isEmpty() )
1199 parser.setError (Aborted,"Nothing selected");
1202 parser.setError (Aborted,"Type of selection is not a branch");
1203 } else if (parser.checkParCount(1))
1205 s=parser.parString (ok,0);
1209 /////////////////////////////////////////////////////////////////////
1210 } else if (com=="setHideExport")
1212 if (xelection.isEmpty() )
1214 parser.setError (Aborted,"Nothing selected");
1215 } else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage)
1217 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1218 } else if (parser.checkParCount(1))
1220 b=parser.parBool(ok,0);
1221 if (ok) setHideExport (b);
1223 /////////////////////////////////////////////////////////////////////
1224 } else if (com=="setIncludeImagesHorizontally")
1226 if (xelection.isEmpty() )
1228 parser.setError (Aborted,"Nothing selected");
1231 parser.setError (Aborted,"Type of selection is not a branch");
1232 } else if (parser.checkParCount(1))
1234 b=parser.parBool(ok,0);
1235 if (ok) setIncludeImagesHor(b);
1237 /////////////////////////////////////////////////////////////////////
1238 } else if (com=="setIncludeImagesVertically")
1240 if (xelection.isEmpty() )
1242 parser.setError (Aborted,"Nothing selected");
1245 parser.setError (Aborted,"Type of selection is not a branch");
1246 } else if (parser.checkParCount(1))
1248 b=parser.parBool(ok,0);
1249 if (ok) setIncludeImagesVer(b);
1251 /////////////////////////////////////////////////////////////////////
1252 } else if (com=="setHideLinkUnselected")
1254 if (xelection.isEmpty() )
1256 parser.setError (Aborted,"Nothing selected");
1257 } else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1259 parser.setError (Aborted,"Type of selection does not allow hiding the link");
1260 } else if (parser.checkParCount(1))
1262 b=parser.parBool(ok,0);
1263 if (ok) setHideLinkUnselected(b);
1265 /////////////////////////////////////////////////////////////////////
1266 } else if (com=="setSelectionColor")
1268 if (parser.checkParCount(1))
1270 QColor c=parser.parColor (ok,0);
1271 if (ok) setSelectionColorInt (c);
1273 /////////////////////////////////////////////////////////////////////
1274 } else if (com=="setURL")
1276 if (xelection.isEmpty() )
1278 parser.setError (Aborted,"Nothing selected");
1281 parser.setError (Aborted,"Type of selection is not a branch");
1282 } else if (parser.checkParCount(1))
1284 s=parser.parString (ok,0);
1287 /////////////////////////////////////////////////////////////////////
1288 } else if (com=="setVymLink")
1290 if (xelection.isEmpty() )
1292 parser.setError (Aborted,"Nothing selected");
1295 parser.setError (Aborted,"Type of selection is not a branch");
1296 } else if (parser.checkParCount(1))
1298 s=parser.parString (ok,0);
1299 if (ok) setVymLinkInt(s);
1302 /////////////////////////////////////////////////////////////////////
1303 else if (com=="setFlag")
1305 if (xelection.isEmpty() )
1307 parser.setError (Aborted,"Nothing selected");
1310 parser.setError (Aborted,"Type of selection is not a branch");
1311 } else if (parser.checkParCount(1))
1313 s=parser.parString(ok,0);
1316 selb->activateStandardFlag(s);
1317 selb->updateFlagsToolbar();
1320 /////////////////////////////////////////////////////////////////////
1321 } else if (com=="setFrameType")
1323 if (xelection.isEmpty() )
1325 parser.setError (Aborted,"Nothing selected");
1328 parser.setError (Aborted,"Type of selection is not a branch");
1329 } else if (parser.checkParCount(1))
1331 s=parser.parString(ok,0);
1335 /////////////////////////////////////////////////////////////////////
1336 } else if (com=="sortChildren")
1338 if (xelection.isEmpty() )
1340 parser.setError (Aborted,"Nothing selected");
1343 parser.setError (Aborted,"Type of selection is not a branch");
1344 } else if (parser.checkParCount(0))
1348 /////////////////////////////////////////////////////////////////////
1349 } else if (com=="toggleFlag")
1351 if (xelection.isEmpty() )
1353 parser.setError (Aborted,"Nothing selected");
1356 parser.setError (Aborted,"Type of selection is not a branch");
1357 } else if (parser.checkParCount(1))
1359 s=parser.parString(ok,0);
1362 selb->toggleStandardFlag(s);
1363 selb->updateFlagsToolbar();
1366 /////////////////////////////////////////////////////////////////////
1367 } else if (com=="unscroll")
1369 if (xelection.isEmpty() )
1371 parser.setError (Aborted,"Nothing selected");
1374 parser.setError (Aborted,"Type of selection is not a branch");
1375 } else if (parser.checkParCount(0))
1377 if (!unscrollBranch (selb))
1378 parser.setError (Aborted,"Could not unscroll branch");
1380 /////////////////////////////////////////////////////////////////////
1381 } else if (com=="unscrollChilds")
1383 if (xelection.isEmpty() )
1385 parser.setError (Aborted,"Nothing selected");
1388 parser.setError (Aborted,"Type of selection is not a branch");
1389 } else if (parser.checkParCount(0))
1393 /////////////////////////////////////////////////////////////////////
1394 } else if (com=="unsetFlag")
1396 if (xelection.isEmpty() )
1398 parser.setError (Aborted,"Nothing selected");
1401 parser.setError (Aborted,"Type of selection is not a branch");
1402 } else if (parser.checkParCount(1))
1404 s=parser.parString(ok,0);
1407 selb->deactivateStandardFlag(s);
1408 selb->updateFlagsToolbar();
1412 parser.setError (Aborted,"Unknown command");
1415 if (parser.errorLevel()==NoError)
1417 // setChanged(); FIXME should not be called e.g. for export?!
1418 mapCenter->reposition();
1422 // TODO Error handling
1423 qWarning("MapEditor::parseAtom: Error!");
1424 qWarning(parser.errorMessage());
1428 void MapEditor::runScript (QString script)
1430 parser.setScript (script);
1432 while (parser.next() )
1433 parseAtom(parser.getAtom());
1436 bool MapEditor::isDefault()
1441 bool MapEditor::hasChanged()
1446 void MapEditor::setChanged()
1449 autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
1457 void MapEditor::closeMap()
1459 // Unselect before disabling the toolbar actions
1460 if (!xelection.isEmpty() ) xelection.unselect();
1468 void MapEditor::setFilePath(QString fpath, QString destname)
1470 if (fpath.isEmpty() || fpath=="")
1477 filePath=fpath; // becomes absolute path
1478 fileName=fpath; // gets stripped of path
1479 destPath=destname; // needed for vymlinks
1481 // If fpath is not an absolute path, complete it
1482 filePath=QDir(fpath).absPath();
1483 fileDir=filePath.left (1+filePath.findRev ("/"));
1485 // Set short name, too. Search from behind:
1486 int i=fileName.findRev("/");
1487 if (i>=0) fileName=fileName.remove (0,i+1);
1489 // Forget the .vym (or .xml) for name of map
1490 mapName=fileName.left(fileName.findRev(".",-1,true) );
1494 void MapEditor::setFilePath(QString fpath)
1496 setFilePath (fpath,fpath);
1499 QString MapEditor::getFilePath()
1504 QString MapEditor::getFileName()
1509 QString MapEditor::getMapName()
1514 QString MapEditor::getDestPath()
1519 ErrorCode MapEditor::load (QString fname, const LoadMode &lmode, const FileType &ftype)
1521 ErrorCode err=success;
1523 parseBaseHandler *handler;
1526 case VymMap: handler=new parseVYMHandler; break;
1527 case FreemindMap : handler=new parseFreemindHandler; break;
1529 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1530 "Unknown FileType in MapEditor::load()");
1535 if (xelection.isEmpty() ) xelection.unselect();
1538 mapCenter->setMapEditor(this);
1539 // (map state is set later at end of load...)
1542 BranchObj *bo=xelection.getBranch();
1543 if (!bo) return aborted;
1544 if (lmode==ImportAdd)
1545 saveStateChangingPart(
1548 QString("addMapInsert (%1)").arg(fname),
1549 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1551 saveStateChangingPart(
1554 QString("addMapReplace(%1)").arg(fname),
1555 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1558 QFile file( fname );
1560 // I am paranoid: file should exist anyway
1561 // according to check in mainwindow.
1562 if (!file.exists() )
1564 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1565 tr("Couldn't open map " +fname)+".");
1569 bool blockSaveStateOrg=blockSaveState;
1570 blockReposition=true;
1571 blockSaveState=true;
1572 QXmlInputSource source( file);
1573 QXmlSimpleReader reader;
1574 reader.setContentHandler( handler );
1575 reader.setErrorHandler( handler );
1576 handler->setMapEditor( this );
1579 // We need to set the tmpDir in order to load files with rel. path
1580 QString tmpdir= fname.left(fname.findRev("/",-1));
1581 handler->setTmpDir (tmpdir);
1582 handler->setInputFile (file.name());
1583 handler->setLoadMode (lmode);
1584 bool ok = reader.parse( source );
1585 blockReposition=false;
1586 blockSaveState=blockSaveStateOrg;
1590 mapCenter->reposition();
1597 autosaveTimer->stop();
1601 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1602 tr( handler->errorProtocol() ) );
1604 // Still return "success": the map maybe at least
1605 // partially read by the parser
1612 int MapEditor::save (const SaveMode &savemode)
1614 // Create mapName and fileDir
1615 makeSubDirs (fileDir);
1619 fname=mapName+".xml";
1621 // use name given by user, even if he chooses .doc
1626 if (savemode==CompleteMap || xelection.isEmpty())
1628 // Save complete map
1629 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1632 autosaveTimer->stop();
1637 if (xelection.type()==Selection::FloatImage)
1640 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());
1641 // TODO take care of multiselections
1644 if (!saveStringToDisk(fileDir+fname,saveFile))
1651 void MapEditor::setZipped (bool z)
1656 bool MapEditor::saveZipped ()
1661 void MapEditor::print()
1665 printer = new QPrinter;
1666 printer->setColorMode (QPrinter::Color);
1667 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1668 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1669 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1672 QRectF totalBBox=mapCenter->getTotalBBox();
1674 // Try to set orientation automagically
1675 // Note: Interpretation of generated postscript is amibiguous, if
1676 // there are problems with landscape mode, see
1677 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1679 if (totalBBox.width()>totalBBox.height())
1680 // recommend landscape
1681 printer->setOrientation (QPrinter::Landscape);
1683 // recommend portrait
1684 printer->setOrientation (QPrinter::Portrait);
1686 if ( printer->setup(this) )
1687 // returns false, if printing is canceled
1689 QPainter pp(printer);
1691 pp.setRenderHint(QPainter::Antialiasing,true);
1693 // Don't print the visualisation of selection
1694 xelection.unselect();
1696 QRectF mapRect=totalBBox;
1697 QGraphicsRectItem *frame=NULL;
1701 // Print frame around map
1702 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1703 totalBBox.width()+20, totalBBox.height()+20);
1704 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1705 frame->setZValue(0);
1710 double paperAspect = (double)printer->width() / (double)printer->height();
1711 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1713 if (mapAspect>=paperAspect)
1715 // Fit horizontally to paper width
1716 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1717 viewBottom=(int)(printer->width()/mapAspect);
1720 // Fit vertically to paper height
1721 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1722 viewBottom=printer->height();
1727 // Print footer below map
1729 font.setPointSize(10);
1731 QRectF footerBox(0,viewBottom,printer->width(),15);
1732 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1733 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1737 QRectF (0,0,printer->width(),printer->height()-15),
1738 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1741 // Viewport has paper dimension
1742 if (frame) delete (frame);
1744 // Restore selection
1745 xelection.reselect();
1747 // Save settings in vymrc
1748 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1749 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1750 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1754 void MapEditor::setAntiAlias (bool b)
1756 setRenderHint(QPainter::Antialiasing,b);
1759 void MapEditor::setSmoothPixmap(bool b)
1761 setRenderHint(QPainter::SmoothPixmapTransform,b);
1764 QPixmap MapEditor::getPixmap()
1766 QRectF mapRect=mapCenter->getTotalBBox();
1767 QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+1);
1770 pp.setRenderHints(renderHints());
1772 // Don't print the visualisation of selection
1773 xelection.unselect();
1775 mapScene->render ( &pp,
1776 QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1777 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1779 // Restore selection
1780 xelection.reselect();
1785 void MapEditor::setHideTmpMode (HideTmpMode mode)
1788 mapCenter->setHideTmp (hidemode);
1789 mapCenter->reposition();
1793 HideTmpMode MapEditor::getHideTmpMode()
1798 void MapEditor::setExportMode (bool b)
1800 // should be called before and after exports
1801 // depending on the settings
1802 if (b && settings.value("/export/useHideExport","true")=="true")
1803 setHideTmpMode (HideExport);
1805 setHideTmpMode (HideNone);
1808 void MapEditor::exportASCII(QString fname,bool askName)
1811 ex.setMapCenter(mapCenter);
1813 ex.setFile (mapName+".txt");
1819 //ex.addFilter ("TXT (*.txt)");
1820 ex.setDir(lastImageDir);
1821 //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
1826 setExportMode(true);
1828 setExportMode(false);
1832 void MapEditor::exportImage(QString fname, bool askName, QString format)
1836 fname=mapName+".png";
1843 QFileDialog *fd=new QFileDialog (this);
1844 fd->setCaption (tr("Export map as image"));
1845 fd->setDirectory (lastImageDir);
1846 fd->setFileMode(QFileDialog::AnyFile);
1847 fd->setFilters (imageIO.getFilters() );
1850 fl=fd->selectedFiles();
1852 format=imageIO.getType(fd->selectedFilter());
1856 setExportMode (true);
1857 QPixmap pix (getPixmap());
1858 pix.save(fname, format);
1859 setExportMode (false);
1862 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1866 ex.setMapCenter(mapCenter);
1867 if (ex.setConfigFile(cf))
1869 setExportMode (true);
1870 ex.exportPresentation();
1871 setExportMode (false);
1875 void MapEditor::exportXHTML (const QString &dir, bool askForName)
1877 ExportXHTMLDialog dia(this);
1878 dia.setFilePath (filePath );
1879 dia.setMapName (mapName );
1881 if (dir!="") dia.setDir (dir);
1887 if (dia.exec()!=QDialog::Accepted)
1891 QDir d (dia.getDir());
1892 // Check, if warnings should be used before overwriting
1893 // the output directory
1894 if (d.exists() && d.count()>0)
1897 warn.showCancelButton (true);
1898 warn.setText(QString(
1899 "The directory %1 is not empty.\n"
1900 "Do you risk to overwrite some of its contents?").arg(d.path() ));
1901 warn.setCaption("Warning: Directory not empty");
1902 warn.setShowAgainName("mainwindow/overwrite-dir-xhtml");
1904 if (warn.exec()!=QDialog::Accepted) ok=false;
1911 exportXML (dia.getDir(),false );
1912 dia.doExport(mapName );
1913 //if (dia.hasChanged()) setChanged();
1917 void MapEditor::exportXML(QString dir, bool askForName)
1921 dir=browseDirectory(this,tr("Export XML to directory"));
1922 if (dir =="" && !reallyWriteDirectory(dir) )
1926 // Hide stuff during export, if settings want this
1927 setExportMode (true);
1929 // Create subdirectories
1932 // write to directory
1933 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1936 file.setName ( dir + "/"+mapName+".xml");
1937 if ( !file.open( QIODevice::WriteOnly ) )
1939 // This should neverever happen
1940 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1944 // Write it finally, and write in UTF8, no matter what
1945 QTextStream ts( &file );
1946 ts.setEncoding (QTextStream::UnicodeUTF8);
1950 // Now write image, too
1951 exportImage (dir+"/images/"+mapName+".png",false,"PNG");
1953 setExportMode (false);
1956 void MapEditor::clear()
1958 xelection.unselect();
1962 void MapEditor::copy()
1964 LinkableMapObj *sel=xelection.single();
1967 if (redosAvail == 0)
1970 QString s=sel->getSelectString();
1971 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel );
1972 curClipboard=curStep;
1975 // Copy also to global clipboard, because we are at last step in history
1976 QString bakMapName(QString("history-%1").arg(curStep));
1977 QString bakMapDir(tmpMapDir +"/"+bakMapName);
1978 copyDir (bakMapDir,clipboardDir );
1980 clipboardEmpty=false;
1985 void MapEditor::redo()
1987 // Can we undo at all?
1988 if (redosAvail<1) return;
1990 bool blockSaveStateOrg=blockSaveState;
1991 blockSaveState=true;
1995 if (undosAvail<stepsTotal) undosAvail++;
1997 if (curStep>stepsTotal) curStep=1;
1998 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1999 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2000 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2001 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2002 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2003 QString version=undoSet.readEntry ("/history/version");
2005 if (!checkVersion(version))
2006 QMessageBox::warning(0,tr("Warning"),
2007 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2010 // Find out current undo directory
2011 QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
2015 cout << "ME::redo() begin\n";
2016 cout << " undosAvail="<<undosAvail<<endl;
2017 cout << " redosAvail="<<redosAvail<<endl;
2018 cout << " curStep="<<curStep<<endl;
2019 cout << " ---------------------------"<<endl;
2020 cout << " comment="<<comment.toStdString()<<endl;
2021 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2022 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2023 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2024 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2025 cout << " ---------------------------"<<endl<<endl;
2028 // select object before redo
2029 if (!redoSelection.isEmpty())
2030 select (redoSelection);
2033 parseAtom (redoCommand);
2034 mapCenter->reposition();
2036 blockSaveState=blockSaveStateOrg;
2038 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2039 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2040 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2041 undoSet.writeSettings(histPath);
2043 mainWindow->updateHistory (undoSet);
2046 /* TODO remove testing
2047 cout << "ME::redo() end\n";
2048 cout << " undosAvail="<<undosAvail<<endl;
2049 cout << " redosAvail="<<redosAvail<<endl;
2050 cout << " curStep="<<curStep<<endl;
2051 cout << " ---------------------------"<<endl<<endl;
2057 bool MapEditor::isRedoAvailable()
2059 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
2065 void MapEditor::undo()
2067 // Can we undo at all?
2068 if (undosAvail<1) return;
2070 mainWindow->statusMessage (tr("Autosave disabled during undo."));
2072 bool blockSaveStateOrg=blockSaveState;
2073 blockSaveState=true;
2075 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
2076 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2077 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2078 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2079 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2080 QString version=undoSet.readEntry ("/history/version");
2082 if (!checkVersion(version))
2083 QMessageBox::warning(0,tr("Warning"),
2084 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2086 // Find out current undo directory
2087 QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
2089 // select object before undo
2090 if (!undoSelection.isEmpty())
2091 select (undoSelection);
2095 cout << "ME::undo() begin\n";
2096 cout << " undosAvail="<<undosAvail<<endl;
2097 cout << " redosAvail="<<redosAvail<<endl;
2098 cout << " curStep="<<curStep<<endl;
2099 cout << " ---------------------------"<<endl;
2100 cout << " comment="<<comment.toStdString()<<endl;
2101 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2102 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2103 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2104 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2105 cout << " ---------------------------"<<endl<<endl;
2107 parseAtom (undoCommand);
2108 mapCenter->reposition();
2112 if (curStep<1) curStep=stepsTotal;
2116 blockSaveState=blockSaveStateOrg;
2117 /* TODO remove testing
2118 cout << "ME::undo() end\n";
2119 cout << " undosAvail="<<undosAvail<<endl;
2120 cout << " redosAvail="<<redosAvail<<endl;
2121 cout << " curStep="<<curStep<<endl;
2122 cout << " ---------------------------"<<endl<<endl;
2125 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2126 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2127 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2128 undoSet.writeSettings(histPath);
2130 mainWindow->updateHistory (undoSet);
2133 ensureSelectionVisible();
2136 bool MapEditor::isUndoAvailable()
2138 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
2144 void MapEditor::gotoHistoryStep (int i)
2146 // Restore variables
2147 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
2148 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
2150 if (i<0) i=undosAvail+redosAvail;
2152 // Clicking above current step makes us undo things
2155 for (int j=0; j<undosAvail-i; j++) undo();
2158 // Clicking below current step makes us redo things
2160 for (int j=undosAvail; j<i; j++)
2162 cout << "redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
2166 // And ignore clicking the current row ;-)
2169 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
2171 QString pathDir=path.left(path.findRev("/"));
2177 // We need to parse saved XML data
2178 parseVYMHandler handler;
2179 QXmlInputSource source( file);
2180 QXmlSimpleReader reader;
2181 reader.setContentHandler( &handler );
2182 reader.setErrorHandler( &handler );
2183 handler.setMapEditor( this );
2184 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2185 if (undoSel.isEmpty())
2189 handler.setLoadMode (NewMap);
2193 handler.setLoadMode (ImportReplace);
2195 blockReposition=true;
2196 bool ok = reader.parse( source );
2197 blockReposition=false;
2200 // This should never ever happen
2201 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2202 handler.errorProtocol());
2205 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2208 void MapEditor::addMapInsertInt (const QString &path, int pos)
2210 BranchObj *sel=xelection.getBranch();
2213 QString pathDir=path.left(path.findRev("/"));
2219 // We need to parse saved XML data
2220 parseVYMHandler handler;
2221 QXmlInputSource source( file);
2222 QXmlSimpleReader reader;
2223 reader.setContentHandler( &handler );
2224 reader.setErrorHandler( &handler );
2225 handler.setMapEditor( this );
2226 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2227 handler.setLoadMode (ImportAdd);
2228 blockReposition=true;
2229 bool ok = reader.parse( source );
2230 blockReposition=false;
2233 // This should never ever happen
2234 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2235 handler.errorProtocol());
2238 sel->getLastBranch()->linkTo (sel,pos);
2240 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2244 void MapEditor::pasteNoSave(const int &n)
2246 bool old=blockSaveState;
2247 blockSaveState=true;
2248 if (redosAvail > 0 || n!=0)
2250 // Use the "historical" buffer
2251 QString bakMapName(QString("history-%1").arg(n));
2252 QString bakMapDir(tmpMapDir +"/"+bakMapName);
2253 load (bakMapDir+"/"+clipboardFile,ImportAdd, VymMap);
2255 // Use the global buffer
2256 load (clipboardDir+"/"+clipboardFile,ImportAdd, VymMap);
2260 void MapEditor::paste()
2262 BranchObj *sel=xelection.getBranch();
2265 saveStateChangingPart(
2268 QString ("paste (%1)").arg(curClipboard),
2269 QString("Paste to %1").arg( getName(sel))
2272 mapCenter->reposition();
2276 void MapEditor::cut()
2278 LinkableMapObj *sel=xelection.single();
2279 if ( sel && (xelection.type() == Selection::Branch ||
2280 xelection.type()==Selection::MapCenter ||
2281 xelection.type()==Selection::FloatImage))
2283 /* No savestate! savestate is called in cutNoSave
2284 saveStateChangingPart(
2288 QString("Cut %1").arg(getName(sel ))
2293 mapCenter->reposition();
2297 void MapEditor::move(const double &x, const double &y)
2299 LinkableMapObj *sel=xelection.single();
2302 QPointF ap(sel->getAbsPos());
2306 QString ps=qpointfToString(ap);
2307 QString s=xelection.single()->getSelectString();
2310 s, "move "+qpointfToString(to),
2311 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
2313 mapCenter->reposition();
2319 void MapEditor::moveRel (const double &x, const double &y)
2321 LinkableMapObj *sel=xelection.single();
2324 QPointF rp(sel->getRelPos());
2328 QString ps=qpointfToString (sel->getRelPos());
2329 QString s=sel->getSelectString();
2332 s, "moveRel "+qpointfToString(to),
2333 QString("Move %1 to relative position %2").arg(getName(sel)).arg(ps));
2334 ((OrnamentedObj*)sel)->move2RelPos (x,y);
2335 mapCenter->reposition();
2342 void MapEditor::moveBranchUp()
2344 BranchObj* bo=xelection.getBranch();
2348 if (!bo->canMoveBranchUp()) return;
2349 par=(BranchObj*)(bo->getParObj());
2350 BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
2351 saveState (bo->getSelectString(),"moveBranchDown ()",obo->getSelectString(),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
2352 mapCenter->reposition();
2355 ensureSelectionVisible();
2359 void MapEditor::moveBranchDown()
2361 BranchObj* bo=xelection.getBranch();
2365 if (!bo->canMoveBranchDown()) return;
2366 par=(BranchObj*)(bo->getParObj());
2367 BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
2368 saveState(bo->getSelectString(),"moveBranchUp ()",obo->getSelectString(),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
2369 mapCenter->reposition();
2372 ensureSelectionVisible();
2376 void MapEditor::sortChildren()
2378 BranchObj* bo=xelection.getBranch();
2381 if(bo->countBranches()>1)
2383 saveStateChangingPart(bo,bo, "sortChildren ()",QString("Sort children of %1").arg(getName(bo)));
2385 mapCenter->reposition();
2386 ensureSelectionVisible();
2391 void MapEditor::linkTo(const QString &dstString)
2393 FloatImageObj *fio=xelection.getFloatImage();
2396 BranchObj *dst=(BranchObj*)(mapCenter->findObjBySelect(dstString));
2397 if (dst && (typeid(*dst)==typeid (BranchObj) ||
2398 typeid(*dst)==typeid (MapCenterObj)))
2400 LinkableMapObj *dstPar=dst->getParObj();
2401 QString parString=dstPar->getSelectString();
2402 QString fioPreSelectString=fio->getSelectString();
2403 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
2404 ((BranchObj*)(dst))->addFloatImage (fio);
2405 xelection.unselect();
2406 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
2407 fio=((BranchObj*)(dst))->getLastFloatImage();
2410 xelection.select(fio);
2412 fio->getSelectString(),
2413 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
2415 QString ("linkTo (\"%1\")").arg(dstString),
2416 QString ("Link floatimage to %1").arg(getName(dst)));
2421 QString MapEditor::getHeading(bool &ok, QPoint &p)
2423 BranchObj *bo=xelection.getBranch();
2427 p=mapFromScene(bo->getAbsPos());
2428 return bo->getHeading();
2434 void MapEditor::setHeading(const QString &s)
2436 BranchObj *sel=xelection.getBranch();
2441 "setHeading (\""+sel->getHeading()+"\")",
2443 "setHeading (\""+s+"\")",
2444 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
2445 sel->setHeading(s );
2446 mapCenter->reposition();
2448 ensureSelectionVisible();
2452 void MapEditor::setHeadingInt(const QString &s)
2454 BranchObj *bo=xelection.getBranch();
2458 mapCenter->reposition();
2460 ensureSelectionVisible();
2464 void MapEditor::setVymLinkInt (const QString &s)
2466 // Internal function, no saveState needed
2467 BranchObj *bo=xelection.getBranch();
2471 mapCenter->reposition();
2474 ensureSelectionVisible();
2478 BranchObj* MapEditor::addNewBranchInt(int num)
2480 // Depending on pos:
2481 // -3 insert in childs of parent above selection
2482 // -2 add branch to selection
2483 // -1 insert in childs of parent below selection
2484 // 0..n insert in childs of parent at pos
2485 BranchObj *newbo=NULL;
2486 BranchObj *bo=xelection.getBranch();
2491 // save scroll state. If scrolled, automatically select
2492 // new branch in order to tmp unscroll parent...
2493 newbo=bo->addBranch();
2498 bo=(BranchObj*)bo->getParObj();
2499 if (bo) newbo=bo->insertBranch(num);
2503 bo=(BranchObj*)bo->getParObj();
2504 if (bo) newbo=bo->insertBranch(num);
2506 if (!newbo) return NULL;
2511 BranchObj* MapEditor::addNewBranch(int pos)
2513 // Different meaning than num in addNewBranchInt!
2517 BranchObj *bo = xelection.getBranch();
2518 BranchObj *newbo=NULL;
2522 setCursor (Qt::ArrowCursor);
2524 newbo=addNewBranchInt (pos-2);
2532 QString ("addBranch (%1)").arg(pos),
2533 QString ("Add new branch to %1").arg(getName(bo)));
2535 mapCenter->reposition();
2537 latestSelection=newbo->getSelectString();
2538 // In Network mode, the client needs to know where the new branch is,
2539 // so we have to pass on this information via saveState.
2540 // TODO: Get rid of this positioning workaround
2541 QString ps=qpointfToString (newbo->getAbsPos());
2542 sendData ("selectLatestAdded ()");
2543 sendData (QString("move %1").arg(ps));
2551 BranchObj* MapEditor::addNewBranchBefore()
2553 BranchObj *newbo=NULL;
2554 BranchObj *bo = xelection.getBranch();
2555 if (bo && xelection.type()==Selection::Branch)
2556 // We accept no MapCenterObj here, so we _have_ a parent
2558 QPointF p=bo->getRelPos();
2561 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2563 // add below selection
2564 newbo=parbo->insertBranch(bo->getNum()+1);
2567 newbo->move2RelPos (p);
2569 // Move selection to new branch
2570 bo->linkTo (newbo,-1);
2572 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2573 QString ("Add branch before %1").arg(getName(bo)));
2575 mapCenter->reposition();
2579 latestSelection=xelection.getSelectString();
2583 void MapEditor::deleteSelection()
2585 BranchObj *bo = xelection.getBranch();
2586 if (bo && xelection.type()==Selection::Branch)
2588 BranchObj* par=(BranchObj*)(bo->getParObj());
2589 xelection.unselect();
2590 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2591 par->removeBranch(bo);
2592 xelection.select (par);
2593 ensureSelectionVisible();
2594 mapCenter->reposition();
2599 FloatImageObj *fio=xelection.getFloatImage();
2602 BranchObj* par=(BranchObj*)(fio->getParObj());
2603 saveStateChangingPart(
2607 QString("Delete %1").arg(getName(fio))
2609 xelection.unselect();
2610 par->removeFloatImage(fio);
2611 xelection.select (par);
2612 mapCenter->reposition();
2614 ensureSelectionVisible();
2619 LinkableMapObj* MapEditor::getSelection()
2621 return xelection.single();
2624 BranchObj* MapEditor::getSelectedBranch()
2626 return xelection.getBranch();
2629 FloatImageObj* MapEditor::getSelectedFloatImage()
2631 return xelection.getFloatImage();
2634 void MapEditor::unselect()
2636 xelection.unselect();
2639 void MapEditor::reselect()
2641 xelection.reselect();
2644 bool MapEditor::select (const QString &s)
2646 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
2648 // Finally select the found object
2651 xelection.unselect();
2652 xelection.select(lmo);
2654 ensureSelectionVisible();
2661 QString MapEditor::getSelectString()
2663 return xelection.getSelectString();
2666 void MapEditor::selectInt (LinkableMapObj *lmo)
2668 if (lmo && xelection.single()!= lmo && isSelectBlocked()==false )
2670 xelection.select(lmo);
2676 void MapEditor::selectNextBranchInt()
2678 // Increase number of branch
2679 LinkableMapObj *sel=xelection.single();
2682 QString s=sel->getSelectString();
2688 part=s.section(",",-1);
2690 num=part.right(part.length() - 3);
2692 s=s.left (s.length() -num.length());
2695 num=QString ("%1").arg(num.toUInt()+1);
2699 // Try to select this one
2700 if (select (s)) return;
2702 // We have no direct successor,
2703 // try to increase the parental number in order to
2704 // find a successor with same depth
2706 int d=xelection.single()->getDepth();
2711 while (!found && d>0)
2713 s=s.section (",",0,d-1);
2714 // replace substring of current depth in s with "1"
2715 part=s.section(",",-1);
2717 num=part.right(part.length() - 3);
2721 // increase number of parent
2722 num=QString ("%1").arg(num.toUInt()+1);
2723 s=s.section (",",0,d-2) + ","+ typ+num;
2726 // Special case, look at orientation
2727 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2728 num=QString ("%1").arg(num.toUInt()+1);
2730 num=QString ("%1").arg(num.toUInt()-1);
2735 // pad to oldDepth, select the first branch for each depth
2736 for (i=d;i<oldDepth;i++)
2741 if ( xelection.getBranch()->countBranches()>0)
2749 // try to select the freshly built string
2757 void MapEditor::selectPrevBranchInt()
2759 // Decrease number of branch
2760 BranchObj *bo=xelection.getBranch();
2763 QString s=bo->getSelectString();
2769 part=s.section(",",-1);
2771 num=part.right(part.length() - 3);
2773 s=s.left (s.length() -num.length());
2775 int n=num.toInt()-1;
2778 num=QString ("%1").arg(n);
2781 // Try to select this one
2782 if (n>=0 && select (s)) return;
2784 // We have no direct precessor,
2785 // try to decrease the parental number in order to
2786 // find a precessor with same depth
2788 int d=xelection.single()->getDepth();
2793 while (!found && d>0)
2795 s=s.section (",",0,d-1);
2796 // replace substring of current depth in s with "1"
2797 part=s.section(",",-1);
2799 num=part.right(part.length() - 3);
2803 // decrease number of parent
2804 num=QString ("%1").arg(num.toInt()-1);
2805 s=s.section (",",0,d-2) + ","+ typ+num;
2808 // Special case, look at orientation
2809 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2810 num=QString ("%1").arg(num.toInt()-1);
2812 num=QString ("%1").arg(num.toInt()+1);
2817 // pad to oldDepth, select the last branch for each depth
2818 for (i=d;i<oldDepth;i++)
2822 if ( xelection.getBranch()->countBranches()>0)
2823 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2830 // try to select the freshly built string
2838 void MapEditor::selectUpperBranch()
2840 if (isSelectBlocked() ) return;
2842 BranchObj *bo=xelection.getBranch();
2843 if (bo && xelection.type()==Selection::Branch)
2845 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2846 selectPrevBranchInt();
2848 if (bo->getDepth()==1)
2849 selectNextBranchInt();
2851 selectPrevBranchInt();
2855 void MapEditor::selectLowerBranch()
2857 if (isSelectBlocked() ) return;
2859 BranchObj *bo=xelection.getBranch();
2860 if (bo && xelection.type()==Selection::Branch)
2861 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2862 selectNextBranchInt();
2864 if (bo->getDepth()==1)
2865 selectPrevBranchInt();
2867 selectNextBranchInt();
2871 void MapEditor::selectLeftBranch()
2873 if (isSelectBlocked() ) return;
2877 LinkableMapObj *sel=xelection.single();
2880 if (xelection.type()== Selection::MapCenter)
2882 par=xelection.getBranch();
2883 bo=par->getLastSelectedBranch();
2886 // Workaround for reselecting on left and right side
2887 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2888 bo=par->getLastBranch();
2891 bo=par->getLastBranch();
2892 xelection.select(bo);
2894 ensureSelectionVisible();
2900 par=(BranchObj*)(sel->getParObj());
2901 if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
2903 if (xelection.type() == Selection::Branch ||
2904 xelection.type() == Selection::FloatImage)
2906 xelection.select(par);
2908 ensureSelectionVisible();
2913 if (xelection.type() == Selection::Branch )
2915 bo=xelection.getBranch()->getLastSelectedBranch();
2918 xelection.select(bo);
2920 ensureSelectionVisible();
2929 void MapEditor::selectRightBranch()
2931 if (isSelectBlocked() ) return;
2935 LinkableMapObj *sel=xelection.single();
2938 if (xelection.type()==Selection::MapCenter)
2940 par=xelection.getBranch();
2941 bo=par->getLastSelectedBranch();
2944 // Workaround for reselecting on left and right side
2945 if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
2946 bo=par->getFirstBranch();
2949 xelection.select(bo);
2951 ensureSelectionVisible();
2957 par=(BranchObj*)(xelection.single()->getParObj());
2958 if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
2960 if (xelection.type() == Selection::Branch ||
2961 xelection.type() == Selection::FloatImage)
2963 xelection.select(par);
2965 ensureSelectionVisible();
2970 if (xelection.type() == Selection::Branch)
2972 bo=xelection.getBranch()->getLastSelectedBranch();
2975 xelection.select(bo);
2977 ensureSelectionVisible();
2986 void MapEditor::selectFirstBranch()
2988 BranchObj *bo1=xelection.getBranch();
2993 par=(BranchObj*)(bo1->getParObj());
2994 bo2=par->getFirstBranch();
2996 xelection.select(bo2);
2998 ensureSelectionVisible();
3004 void MapEditor::selectLastBranch()
3006 BranchObj *bo1=xelection.getBranch();
3011 par=(BranchObj*)(bo1->getParObj());
3012 bo2=par->getLastBranch();
3015 xelection.select(bo2);
3017 ensureSelectionVisible();
3023 void MapEditor::selectMapBackgroundImage ()
3025 Q3FileDialog *fd=new Q3FileDialog( this);
3026 fd->setMode (Q3FileDialog::ExistingFile);
3027 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3028 ImagePreview *p =new ImagePreview (fd);
3029 fd->setContentsPreviewEnabled( TRUE );
3030 fd->setContentsPreview( p, p );
3031 fd->setPreviewMode( Q3FileDialog::Contents );
3032 fd->setCaption(vymName+" - " +tr("Load background image"));
3033 fd->setDir (lastImageDir);
3036 if ( fd->exec() == QDialog::Accepted )
3038 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
3039 lastImageDir=QDir (fd->dirPath());
3040 setMapBackgroundImage (fd->selectedFile());
3044 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
3046 QColor oldcol=mapScene->backgroundBrush().color();
3050 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
3052 QString ("setMapBackgroundImage (%1)").arg(col.name()),
3053 QString("Set background color of map to %1").arg(col.name()));
3056 brush.setTextureImage (QPixmap (fn));
3057 mapScene->setBackgroundBrush(brush);
3060 void MapEditor::selectMapBackgroundColor()
3062 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
3063 if ( !col.isValid() ) return;
3064 setMapBackgroundColor( col );
3068 void MapEditor::setMapBackgroundColor(QColor col)
3070 QColor oldcol=mapScene->backgroundBrush().color();
3073 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
3075 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
3076 QString("Set background color of map to %1").arg(col.name()));
3077 mapScene->setBackgroundBrush(col);
3080 QColor MapEditor::getMapBackgroundColor()
3082 return mapScene->backgroundBrush().color();
3085 QColor MapEditor::getCurrentHeadingColor()
3087 BranchObj *bo=xelection.getBranch();
3088 if (bo) return bo->getColor();
3090 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
3094 void MapEditor::colorBranch (QColor c)
3096 BranchObj *bo=xelection.getBranch();
3101 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
3103 QString ("colorBranch (\"%1\")").arg(c.name()),
3104 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
3106 bo->setColor(c); // color branch
3110 void MapEditor::colorSubtree (QColor c)
3112 BranchObj *bo=xelection.getBranch();
3115 saveStateChangingPart(
3118 QString ("colorSubtree (\"%1\")").arg(c.name()),
3119 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
3121 bo->setColorSubtree (c); // color links, color childs
3126 void MapEditor::toggleStandardFlag(QString f)
3128 BranchObj *bo=xelection.getBranch();
3132 if (bo->isSetStandardFlag(f))
3144 QString("%1 (\"%2\")").arg(u).arg(f),
3146 QString("%1 (\"%2\")").arg(r).arg(f),
3147 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
3148 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
3154 BranchObj* MapEditor::findText (QString s, bool cs)
3156 QTextDocument::FindFlags flags=0;
3157 if (cs) flags=QTextDocument::FindCaseSensitively;
3160 { // Nothing found or new find process
3162 // nothing found, start again
3164 itFind=mapCenter->first();
3166 bool searching=true;
3167 bool foundNote=false;
3168 while (searching && !EOFind)
3172 // Searching in Note
3173 if (itFind->getNote().contains(s,cs))
3175 if (xelection.single()!=itFind)
3177 xelection.select(itFind);
3178 ensureSelectionVisible();
3180 if (textEditor->findText(s,flags))
3186 // Searching in Heading
3187 if (searching && itFind->getHeading().contains (s,cs) )
3189 xelection.select(itFind);
3190 ensureSelectionVisible();
3196 itFind=itFind->next();
3197 if (!itFind) EOFind=true;
3201 return xelection.getBranch();
3206 void MapEditor::findReset()
3207 { // Necessary if text to find changes during a find process
3211 void MapEditor::setURL(const QString &url)
3213 BranchObj *bo=xelection.getBranch();
3216 QString oldurl=bo->getURL();
3220 QString ("setURL (\"%1\")").arg(oldurl),
3222 QString ("setURL (\"%1\")").arg(url),
3223 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
3226 mapCenter->reposition();
3228 ensureSelectionVisible();
3232 void MapEditor::editURL()
3234 BranchObj *bo=xelection.getBranch();
3238 QString text = QInputDialog::getText(
3239 "VYM", tr("Enter URL:"), QLineEdit::Normal,
3240 bo->getURL(), &ok, this );
3242 // user entered something and pressed OK
3247 void MapEditor::editLocalURL()
3249 BranchObj *bo=xelection.getBranch();
3252 QStringList filters;
3253 filters <<"All files (*)";
3254 filters << tr("Text","Filedialog") + " (*.txt)";
3255 filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
3256 filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
3257 filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
3258 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Set URL to a local file"));
3259 fd->setFilters (filters);
3260 fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
3261 fd->setDirectory (lastFileDir);
3262 if (! bo->getVymLink().isEmpty() )
3263 fd->selectFile( bo->getURL() );
3266 if ( fd->exec() == QDialog::Accepted )
3268 lastFileDir=QDir (fd->directory().path());
3269 setURL (fd->selectedFile() );
3274 QString MapEditor::getURL()
3276 BranchObj *bo=xelection.getBranch();
3278 return bo->getURL();
3283 QStringList MapEditor::getURLs()
3286 BranchObj *bo=xelection.getBranch();
3292 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
3300 void MapEditor::editHeading2URL()
3302 BranchObj *bo=xelection.getBranch();
3304 setURL (bo->getHeading());
3307 void MapEditor::editBugzilla2URL()
3309 BranchObj *bo=xelection.getBranch();
3312 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
3317 void MapEditor::editFATE2URL()
3319 BranchObj *bo=xelection.getBranch();
3322 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
3325 "setURL (\""+bo->getURL()+"\")",
3327 "setURL (\""+url+"\")",
3328 QString("Use heading of %1 as link to FATE").arg(getName(bo))
3335 void MapEditor::editVymLink()
3337 BranchObj *bo=xelection.getBranch();
3340 QStringList filters;
3341 filters <<"VYM map (*.vym)";
3342 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
3343 fd->setFilters (filters);
3344 fd->setCaption(vymName+" - " +tr("Link to another map"));
3345 fd->setDirectory (lastFileDir);
3346 if (! bo->getVymLink().isEmpty() )
3347 fd->selectFile( bo->getVymLink() );
3351 if ( fd->exec() == QDialog::Accepted )
3353 lastFileDir=QDir (fd->directory().path());
3356 "setVymLink (\""+bo->getVymLink()+"\")",
3358 "setVymLink (\""+fd->selectedFile()+"\")",
3359 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
3361 setVymLinkInt (fd->selectedFile() );
3366 void MapEditor::deleteVymLink()
3368 BranchObj *bo=xelection.getBranch();
3373 "setVymLink (\""+bo->getVymLink()+"\")",
3375 "setVymLink (\"\")",
3376 QString("Unset vymlink of %1").arg(getName(bo))
3378 bo->setVymLink ("" );
3380 mapCenter->reposition();
3385 void MapEditor::setHideExport(bool b)
3387 BranchObj *bo=xelection.getBranch();
3390 bo->setHideInExport (b);
3391 QString u= b ? "false" : "true";
3392 QString r=!b ? "false" : "true";
3396 QString ("setHideExport (%1)").arg(u),
3398 QString ("setHideExport (%1)").arg(r),
3399 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
3402 mapCenter->reposition();
3408 void MapEditor::toggleHideExport()
3410 BranchObj *bo=xelection.getBranch();
3412 setHideExport ( !bo->hideInExport() );
3415 QString MapEditor::getVymLink()
3417 BranchObj *bo=xelection.getBranch();
3419 return bo->getVymLink();
3425 QStringList MapEditor::getVymLinks()
3428 BranchObj *bo=xelection.getBranch();
3434 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
3442 void MapEditor::deleteKeepChilds()
3444 BranchObj *bo=xelection.getBranch();
3448 par=(BranchObj*)(bo->getParObj());
3449 QPointF p=bo->getRelPos();
3450 saveStateChangingPart(
3453 "deleteKeepChilds ()",
3454 QString("Remove %1 and keep its childs").arg(getName(bo))
3457 QString sel=bo->getSelectString();
3459 par->removeBranchHere(bo);
3460 mapCenter->reposition();
3462 xelection.getBranch()->move2RelPos (p);
3463 mapCenter->reposition();
3467 void MapEditor::deleteChilds()
3469 BranchObj *bo=xelection.getBranch();
3472 saveStateChangingPart(
3476 QString( "Remove childs of branch %1").arg(getName(bo))
3479 mapCenter->reposition();
3483 void MapEditor::editMapInfo()
3485 ExtraInfoDialog dia;
3486 dia.setMapName (getFileName() );
3487 dia.setAuthor (mapCenter->getAuthor() );
3488 dia.setComment(mapCenter->getComment() );
3492 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
3499 bo=mapCenter->first();
3502 if (!bo->getNote().isEmpty() ) n++;
3503 f+= bo->countFloatImages();
3505 xl+=bo->countXLinks();
3508 stats+=QString ("%1 branches\n").arg (b-1,6);
3509 stats+=QString ("%1 xLinks \n").arg (xl,6);
3510 stats+=QString ("%1 notes\n").arg (n,6);
3511 stats+=QString ("%1 images\n").arg (f,6);
3512 dia.setStats (stats);
3514 // Finally show dialog
3515 if (dia.exec() == QDialog::Accepted)
3517 setMapAuthor (dia.getAuthor() );
3518 setMapComment (dia.getComment() );
3522 void MapEditor::ensureSelectionVisible()
3524 LinkableMapObj *lmo=xelection.single();
3525 if (lmo) ensureVisible (lmo->getBBox() );
3529 void MapEditor::updateSelection()
3531 // Tell selection to update geometries
3535 void MapEditor::updateActions()
3537 // Tell mainwindow to update states of actions
3538 mainWindow->updateActions();
3539 // TODO maybe don't update if blockReposition is set
3542 void MapEditor::updateNoteFlag()
3545 BranchObj *bo=xelection.getBranch();
3548 bo->updateNoteFlag();
3549 mainWindow->updateActions();
3553 void MapEditor::setMapAuthor (const QString &s)
3557 QString ("setMapAuthor (\"%1\")").arg(mapCenter->getAuthor()),
3559 QString ("setMapAuthor (\"%1\")").arg(s),
3560 QString ("Set author of map to \"%1\"").arg(s)
3562 mapCenter->setAuthor (s);
3565 void MapEditor::setMapComment (const QString &s)
3569 QString ("setMapComment (\"%1\")").arg(mapCenter->getComment()),
3571 QString ("setMapComment (\"%1\")").arg(s),
3572 QString ("Set comment of map")
3574 mapCenter->setComment (s);
3577 void MapEditor::setMapLinkStyle (const QString & s)
3579 saveStateChangingPart (
3582 QString("setMapLinkStyle (\"%1\")").arg(s),
3583 QString("Set map link style (\"%1\")").arg(s)
3587 linkstyle=LinkableMapObj::Line;
3588 else if (s=="StyleParabel")
3589 linkstyle=LinkableMapObj::Parabel;
3590 else if (s=="StylePolyLine")
3591 linkstyle=LinkableMapObj::PolyLine;
3593 linkstyle=LinkableMapObj::PolyParabel;
3596 bo=mapCenter->first();
3600 bo->setLinkStyle(bo->getDefLinkStyle());
3603 mapCenter->reposition();
3606 LinkableMapObj::Style MapEditor::getMapLinkStyle ()
3611 void MapEditor::setMapDefLinkColor(QColor c)
3615 bo=mapCenter->first();
3624 void MapEditor::setMapLinkColorHintInt()
3626 // called from setMapLinkColorHint(lch) or at end of parse
3628 bo=mapCenter->first();
3636 void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
3639 setMapLinkColorHintInt();
3642 void MapEditor::toggleMapLinkColorHint()
3644 if (linkcolorhint==LinkableMapObj::HeadingColor)
3645 linkcolorhint=LinkableMapObj::DefaultColor;
3647 linkcolorhint=LinkableMapObj::HeadingColor;
3649 bo=mapCenter->first();
3657 LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
3659 return linkcolorhint;
3662 QColor MapEditor::getMapDefLinkColor()
3664 return defLinkColor;
3667 void MapEditor::setMapDefXLinkColor(QColor col)
3672 QColor MapEditor::getMapDefXLinkColor()
3674 return defXLinkColor;
3677 void MapEditor::setMapDefXLinkWidth (int w)
3682 int MapEditor::getMapDefXLinkWidth()
3684 return defXLinkWidth;
3687 void MapEditor::selectMapLinkColor()
3689 QColor col = QColorDialog::getColor( defLinkColor, this );
3690 if ( !col.isValid() ) return;
3693 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3695 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3696 QString("Set map link color to %1").arg(col.name())
3698 setMapDefLinkColor( col );
3701 void MapEditor::selectMapSelectionColor()
3703 QColor col = QColorDialog::getColor( defLinkColor, this );
3704 setSelectionColor (col);
3707 void MapEditor::setSelectionColorInt (QColor col)
3709 if ( !col.isValid() ) return;
3710 xelection.setColor (col);
3713 void MapEditor::setSelectionColor(QColor col)
3715 if ( !col.isValid() ) return;
3718 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3720 QString("setSelectionColor (%1)").arg(col.name()),
3721 QString("Set color of selection box to %1").arg(col.name())
3723 setSelectionColorInt (col);
3726 QColor MapEditor::getSelectionColor()
3728 return xelection.getColor();
3731 bool MapEditor::scrollBranch(BranchObj *bo)
3735 if (bo->isScrolled()) return false;
3736 if (bo->countBranches()==0) return false;
3737 if (bo->getDepth()==0) return false;
3743 QString ("%1 ()").arg(u),
3745 QString ("%1 ()").arg(r),
3746 QString ("%1 %2").arg(r).arg(getName(bo))
3756 bool MapEditor::unscrollBranch(BranchObj *bo)
3760 if (!bo->isScrolled()) return false;
3761 if (bo->countBranches()==0) return false;
3762 if (bo->getDepth()==0) return false;
3768 QString ("%1 ()").arg(u),
3770 QString ("%1 ()").arg(r),
3771 QString ("%1 %2").arg(r).arg(getName(bo))
3781 void MapEditor::toggleScroll()
3783 BranchObj *bo=xelection.getBranch();
3784 if (xelection.type()==Selection::Branch )
3786 if (bo->isScrolled())
3787 unscrollBranch (bo);
3793 void MapEditor::unscrollChilds()
3795 BranchObj *bo=xelection.getBranch();
3801 if (bo->isScrolled()) unscrollBranch (bo);
3807 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3809 BranchObj *bo=xelection.getBranch();
3813 bo->addFloatImage();
3814 fio=bo->getLastFloatImage();
3816 mapCenter->reposition();
3823 void MapEditor::loadFloatImage ()
3825 BranchObj *bo=xelection.getBranch();
3829 Q3FileDialog *fd=new Q3FileDialog( this);
3830 fd->setMode (Q3FileDialog::ExistingFiles);
3831 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3832 ImagePreview *p =new ImagePreview (fd);
3833 fd->setContentsPreviewEnabled( TRUE );
3834 fd->setContentsPreview( p, p );
3835 fd->setPreviewMode( Q3FileDialog::Contents );
3836 fd->setCaption(vymName+" - " +tr("Load image"));
3837 fd->setDir (lastImageDir);
3840 if ( fd->exec() == QDialog::Accepted )
3842 // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
3843 lastImageDir=QDir (fd->dirPath());
3846 for (int j=0; j<fd->selectedFiles().count(); j++)
3848 s=fd->selectedFiles().at(j);
3849 fio=loadFloatImageInt (s);
3852 (LinkableMapObj*)fio,
3855 QString ("loadImage (%1)").arg(s ),
3856 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3859 // TODO loadFIO error handling
3860 qWarning ("Failed to load "+s);
3868 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3870 fio->save (fn,type);
3873 void MapEditor::saveFloatImage ()
3875 FloatImageObj *fio=xelection.getFloatImage();
3878 QFileDialog *fd=new QFileDialog( this);
3879 fd->setFilters (imageIO.getFilters());
3880 fd->setCaption(vymName+" - " +tr("Save image"));
3881 fd->setFileMode( QFileDialog::AnyFile );
3882 fd->setDirectory (lastImageDir);
3883 // fd->setSelection (fio->getOriginalFilename());
3887 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3889 fn=fd->selectedFiles().at(0);
3890 if (QFile (fn).exists() )
3892 QMessageBox mb( vymName,
3893 tr("The file %1 exists already.\n"
3894 "Do you want to overwrite it?").arg(fn),
3895 QMessageBox::Warning,
3896 QMessageBox::Yes | QMessageBox::Default,
3897 QMessageBox::Cancel | QMessageBox::Escape,
3898 QMessageBox::QMessageBox::NoButton );
3900 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3901 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3904 case QMessageBox::Yes:
3907 case QMessageBox::Cancel:
3914 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3920 void MapEditor::setFrameType(const FrameObj::FrameType &t)
3922 BranchObj *bo=xelection.getBranch();
3925 QString s=bo->getFrameTypeName();
3926 bo->setFrameType (t);
3927 saveState (bo, QString("setFrameType (\"%1\")").arg(s),
3928 bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
3929 mapCenter->reposition();
3934 void MapEditor::setFrameType(const QString &s)
3936 BranchObj *bo=xelection.getBranch();
3939 saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
3940 bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
3941 bo->setFrameType (s);
3942 mapCenter->reposition();
3947 void MapEditor::setFramePenColor(const QColor &c)
3949 BranchObj *bo=xelection.getBranch();
3952 saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
3953 bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
3954 bo->setFramePenColor (c);
3958 void MapEditor::setFrameBrushColor(const QColor &c)
3960 BranchObj *bo=xelection.getBranch();
3963 saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
3964 bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
3965 bo->setFrameBrushColor (c);
3969 void MapEditor::setFramePadding (const int &i)
3971 BranchObj *bo=xelection.getBranch();
3974 saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
3975 bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
3976 bo->setFramePadding (i);
3977 mapCenter->reposition();
3982 void MapEditor::setFrameBorderWidth(const int &i)
3984 BranchObj *bo=xelection.getBranch();
3987 saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
3988 bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
3989 bo->setFrameBorderWidth (i);
3990 mapCenter->reposition();
3995 void MapEditor::setIncludeImagesVer(bool b)
3997 BranchObj *bo=xelection.getBranch();
4000 QString u= b ? "false" : "true";
4001 QString r=!b ? "false" : "true";
4005 QString("setIncludeImagesVertically (%1)").arg(u),
4007 QString("setIncludeImagesVertically (%1)").arg(r),
4008 QString("Include images vertically in %1").arg(getName(bo))
4010 bo->setIncludeImagesVer(b);
4011 mapCenter->reposition();
4015 void MapEditor::setIncludeImagesHor(bool b)
4017 BranchObj *bo=xelection.getBranch();
4020 QString u= b ? "false" : "true";
4021 QString r=!b ? "false" : "true";
4025 QString("setIncludeImagesHorizontally (%1)").arg(u),
4027 QString("setIncludeImagesHorizontally (%1)").arg(r),
4028 QString("Include images horizontally in %1").arg(getName(bo))
4030 bo->setIncludeImagesHor(b);
4031 mapCenter->reposition();
4035 void MapEditor::setHideLinkUnselected (bool b)
4037 LinkableMapObj *sel=xelection.single();
4039 (xelection.type() == Selection::Branch ||
4040 xelection.type() == Selection::MapCenter ||
4041 xelection.type() == Selection::FloatImage ))
4043 QString u= b ? "false" : "true";
4044 QString r=!b ? "false" : "true";
4048 QString("setHideLinkUnselected (%1)").arg(u),
4050 QString("setHideLinkUnselected (%1)").arg(r),
4051 QString("Hide link of %1 if unselected").arg(getName(sel))
4053 sel->setHideLinkUnselected(b);
4057 void MapEditor::importDirInt(BranchObj *dst, QDir d)
4059 BranchObj *bo=xelection.getBranch();
4062 // Traverse directories
4063 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
4064 QFileInfoList list = d.entryInfoList();
4067 for (int i = 0; i < list.size(); ++i)
4070 if (fi.fileName() != "." && fi.fileName() != ".." )
4073 bo=dst->getLastBranch();
4074 bo->setHeading (fi.fileName() );
4075 bo->setColor (QColor("blue"));
4077 if ( !d.cd(fi.fileName()) )
4078 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
4081 // Recursively add subdirs
4082 importDirInt (bo,d);
4088 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
4089 list = d.entryInfoList();
4091 for (int i = 0; i < list.size(); ++i)
4095 bo=dst->getLastBranch();
4096 bo->setHeading (fi.fileName() );
4097 bo->setColor (QColor("black"));
4098 if (fi.fileName().right(4) == ".vym" )
4099 bo->setVymLink (fi.filePath());
4104 void MapEditor::importDirInt (const QString &s)
4106 BranchObj *bo=xelection.getBranch();
4109 saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
4112 importDirInt (bo,d);
4116 void MapEditor::importDir()
4118 BranchObj *bo=xelection.getBranch();
4121 QStringList filters;
4122 filters <<"VYM map (*.vym)";
4123 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
4124 fd->setMode (QFileDialog::DirectoryOnly);
4125 fd->setFilters (filters);
4126 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
4130 if ( fd->exec() == QDialog::Accepted )
4132 importDirInt (fd->selectedFile() );
4133 mapCenter->reposition();
4139 void MapEditor::followXLink(int i)
4141 BranchObj *bo=xelection.getBranch();
4144 bo=bo->XLinkTargetAt(i);
4147 xelection.select(bo);
4148 ensureSelectionVisible();
4153 void MapEditor::editXLink(int i) // FIXME missing saveState
4155 BranchObj *bo=xelection.getBranch();
4158 XLinkObj *xlo=bo->XLinkAt(i);
4161 EditXLinkDialog dia;
4163 dia.setSelection(bo);
4164 if (dia.exec() == QDialog::Accepted)
4166 if (dia.useSettingsGlobal() )
4168 setMapDefXLinkColor (xlo->getColor() );
4169 setMapDefXLinkWidth (xlo->getWidth() );
4171 if (dia.deleteXLink())
4172 bo->deleteXLinkAt(i);
4178 AttributeTable* MapEditor::attributeTable()
4183 void MapEditor::testFunction1()
4186 BranchObj *bo=xelection.getBranch();
4187 if (bo) animObjList.append( bo );
4190 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
4191 if (hidemode==HideNone)
4193 setHideTmpMode (HideExport);
4194 mapCenter->calcBBoxSizeWithChilds();
4195 QRectF totalBBox=mapCenter->getTotalBBox();
4196 QRectF mapRect=totalBBox;
4197 QCanvasRectangle *frame=NULL;
4199 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
4201 mapRect.setRect (totalBBox.x(), totalBBox.y(),
4202 totalBBox.width(), totalBBox.height());
4203 frame=new QCanvasRectangle (mapRect,mapScene);
4204 frame->setBrush (QColor(white));
4205 frame->setPen (QColor(black));
4206 frame->setZValue(0);
4211 setHideTmpMode (HideNone);
4213 cout <<" hidemode="<<hidemode<<endl;
4217 void MapEditor::testFunction2()
4220 if (hidemode==HideExport)
4221 setHideTmpMode (HideNone);
4223 setHideTmpMode (HideExport);
4226 LinkableMapObj *lmo=xelection.getBranch();
4229 cout << "LMO::id="<<lmo->getID().ascii()<<endl;
4230 cout << " BO::id="<<((BranchObj*)lmo)->getID().ascii()<<endl;
4235 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
4237 // Lineedits are already closed by preceding
4238 // mouseEvent, we don't need to close here.
4240 QPointF p = mapToScene(e->pos());
4241 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4244 { // MapObj was found
4245 if (xelection.single() != lmo)
4247 // select the MapObj
4248 xelection.select(lmo);
4251 if (xelection.getBranch() )
4253 // Context Menu on branch or mapcenter
4255 branchContextMenu->popup(e->globalPos() );
4258 if (xelection.getFloatImage() )
4260 // Context Menu on floatimage
4262 floatimageContextMenu->popup(e->globalPos() );
4266 { // No MapObj found, we are on the Canvas itself
4267 // Context Menu on scene
4269 canvasContextMenu->popup(e->globalPos() );
4274 void MapEditor::keyPressEvent(QKeyEvent* e)
4276 if (e->modifiers() & Qt::ControlModifier)
4278 switch (mainWindow->getModMode())
4280 case Main::ModModeColor:
4281 setCursor (PickColorCursor);
4283 case Main::ModModeCopy:
4284 setCursor (CopyCursor);
4286 case Main::ModModeXLink:
4287 setCursor (XLinkCursor);
4290 setCursor (Qt::ArrowCursor);
4296 void MapEditor::keyReleaseEvent(QKeyEvent* e)
4298 if (!(e->modifiers() & Qt::ControlModifier))
4299 setCursor (Qt::ArrowCursor);
4302 void MapEditor::mousePressEvent(QMouseEvent* e)
4304 // Ignore right clicks, these will go to context menus
4305 if (e->button() == Qt::RightButton )
4311 //Ignore clicks while editing heading
4312 if (isSelectBlocked() )
4318 QPointF p = mapToScene(e->pos());
4319 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
4323 //Take care of system flags _or_ modifier modes
4325 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
4326 typeid(*lmo)==typeid(MapCenterObj) ))
4328 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
4329 if (!foname.isEmpty())
4331 // systemFlag clicked
4335 if (e->state() & Qt::ControlModifier)
4336 mainWindow->editOpenURLTab();
4338 mainWindow->editOpenURL();
4340 else if (foname=="vymLink")
4342 mainWindow->editOpenVymLink();
4343 // tabWidget may change, better return now
4344 // before segfaulting...
4345 } else if (foname=="note")
4346 mainWindow->windowToggleNoteEditor();
4347 else if (foname=="hideInExport")
4354 // No system flag clicked, take care of modmodes (CTRL-Click)
4355 if (e->state() & Qt::ControlModifier)
4357 if (mainWindow->getModMode()==Main::ModModeColor)
4360 setCursor (PickColorCursor);
4363 if (mainWindow->getModMode()==Main::ModModeXLink)
4365 BranchObj *bo_begin=NULL;
4367 bo_begin=(BranchObj*)(lmo);
4369 if (xelection.getBranch() )
4370 bo_begin=xelection.getBranch();
4374 linkingObj_src=bo_begin;
4375 tmpXLink=new XLinkObj (mapScene);
4376 tmpXLink->setBegin (bo_begin);
4377 tmpXLink->setEnd (p);
4378 tmpXLink->setColor(defXLinkColor);
4379 tmpXLink->setWidth(defXLinkWidth);
4380 tmpXLink->updateXLink();
4381 tmpXLink->setVisibility (true);
4385 } // End of modmodes
4389 // Select the clicked object
4392 // Left Button Move Branches
4393 if (e->button() == Qt::LeftButton )
4395 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
4396 //movingObj_start.setY( p.y() - selection->y() );
4397 movingObj_start.setX( p.x() - lmo->x() );
4398 movingObj_start.setY( p.y() - lmo->y() );
4399 movingObj_orgPos.setX (lmo->x() );
4400 movingObj_orgPos.setY (lmo->y() );
4401 movingObj_orgRelPos=lmo->getRelPos();
4403 // If modMode==copy, then we want to "move" the _new_ object around
4404 // then we need the offset from p to the _old_ selection, because of tmp
4405 if (mainWindow->getModMode()==Main::ModModeCopy &&
4406 e->state() & Qt::ControlModifier)
4408 if (xelection.type()==Selection::Branch)
4411 mapCenter->addBranch ((BranchObj*)xelection.single());
4413 xelection.select(mapCenter->getLastBranch());
4414 mapCenter->reposition();
4418 movingObj=xelection.single();
4420 // Middle Button Toggle Scroll
4421 // (On Mac OS X this won't work, but we still have
4422 // a button in the toolbar)
4423 if (e->button() == Qt::MidButton )
4428 { // No MapObj found, we are on the scene itself
4429 // Left Button move Pos of sceneView
4430 if (e->button() == Qt::LeftButton )
4432 movingObj=NULL; // move Content not Obj
4433 movingObj_start=e->globalPos();
4434 movingCont_start=QPointF (
4435 horizontalScrollBar()->value(),
4436 verticalScrollBar()->value());
4437 movingVec=QPointF(0,0);
4438 setCursor(HandOpenCursor);
4443 void MapEditor::mouseMoveEvent(QMouseEvent* e)
4445 QPointF p = mapToScene(e->pos());
4446 LinkableMapObj *lmosel=xelection.single();
4448 // Move the selected MapObj
4449 if ( lmosel && movingObj)
4451 // reset cursor if we are moving and don't copy
4452 if (mainWindow->getModMode()!=Main::ModModeCopy)
4453 setCursor (Qt::ArrowCursor);
4455 // To avoid jumping of the sceneView, only
4456 // ensureSelectionVisible, if not tmp linked
4457 if (!lmosel->hasParObjTmp())
4458 ensureSelectionVisible ();
4460 // Now move the selection, but add relative position
4461 // (movingObj_start) where selection was chosen with
4462 // mousepointer. (This avoids flickering resp. jumping
4463 // of selection back to absPos)
4465 // Check if we could link
4466 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
4469 FloatObj *fio=xelection.getFloatImage();
4472 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4474 fio->updateLink(); //no need for reposition, if we update link here
4477 // Relink float to new mapcenter or branch, if shift is pressed
4478 // Only relink, if selection really has a new parent
4479 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
4480 ( (typeid(*lmo)==typeid(BranchObj)) ||
4481 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
4482 ( lmo != fio->getParObj())
4485 if (typeid(*fio) == typeid(FloatImageObj) &&
4486 ( (typeid(*lmo)==typeid(BranchObj) ||
4487 typeid(*lmo)==typeid(MapCenterObj)) ))
4490 // Also save the move which was done so far
4491 QString pold=qpointfToString(movingObj_orgRelPos);
4492 QString pnow=qpointfToString(fio->getRelPos());
4498 QString("Move %1 to relative position %2").arg(getName(fio)).arg(pnow));
4499 fio->getParObj()->requestReposition();
4500 mapCenter->reposition();
4502 linkTo (lmo->getSelectString());
4504 //movingObj_orgRelPos=lmosel->getRelPos();
4506 mapCenter->reposition();
4510 { // selection != a FloatObj
4511 if (lmosel->getDepth()==0)
4514 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
4515 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4517 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4518 mapCenter->updateRelPositions();
4521 if (lmosel->getDepth()==1)
4524 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4525 lmosel->setRelPos();
4528 // Move ordinary branch
4529 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
4530 // Add width of bbox here, otherwise alignRelTo will cause jumping around
4531 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
4532 p.y()-movingObj_start.y() +lmosel->getTopPad() );
4534 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
4537 // Maybe we can relink temporary?
4538 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
4539 (typeid(*lmo)==typeid(BranchObj) ||
4540 typeid(*lmo)==typeid(MapCenterObj)) )
4543 if (e->modifiers()==Qt::ControlModifier)
4545 // Special case: CTRL to link below lmo
4546 lmosel->setParObjTmp (lmo,p,+1);
4548 else if (e->modifiers()==Qt::ShiftModifier)
4549 lmosel->setParObjTmp (lmo,p,-1);
4551 lmosel->setParObjTmp (lmo,p,0);
4554 lmosel->unsetParObjTmp();
4556 // reposition subbranch
4557 lmosel->reposition();
4561 } // no FloatImageObj
4565 } // selection && moving_obj
4567 // Draw a link from one branch to another
4570 tmpXLink->setEnd (p);
4571 tmpXLink->updateXLink();
4575 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
4577 QPointF p=e->globalPos();
4578 movingVec.setX(-p.x() + movingObj_start.x() );
4579 movingVec.setY(-p.y() + movingObj_start.y() );
4580 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
4581 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
4586 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
4588 QPointF p = mapToScene(e->pos());
4589 LinkableMapObj *dst;
4590 LinkableMapObj *lmosel=xelection.single();
4591 // Have we been picking color?
4595 setCursor (Qt::ArrowCursor);
4596 // Check if we are over another branch
4597 dst=mapCenter->findMapObj(p, NULL);
4600 if (e->state() & Qt::ShiftModifier)
4601 colorBranch (((BranchObj*)(dst))->getColor());
4603 colorSubtree (((BranchObj*)(dst))->getColor());
4608 // Have we been drawing a link?
4612 // Check if we are over another branch
4613 dst=mapCenter->findMapObj(p, NULL);
4616 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
4617 tmpXLink->updateXLink();
4618 tmpXLink->activate(); //FIXME savestate missing
4619 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );
4628 // Have we been moving something?
4629 if ( lmosel && movingObj )
4631 FloatImageObj *fo=xelection.getFloatImage();
4634 // Moved FloatObj. Maybe we need to reposition
4635 QString pold=qpointfToString(movingObj_orgRelPos);
4636 QString pnow=qpointfToString(fo->getRelPos());
4642 QString("Move %1 to relative position %2").arg(getName(fo)).arg(pnow));
4644 fo->getParObj()->requestReposition();
4645 mapCenter->reposition();
4648 // Check if we are over another branch, but ignore
4649 // any found LMOs, which are FloatObjs
4650 dst=mapCenter->findMapObj(mapToScene(e->pos() ), lmosel);
4652 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4655 if (xelection.type() == Selection::MapCenter )
4657 // TODO: Check for problems if graphicsview is resized for
4659 if (movingObj_orgPos != mapCenter->getAbsPos())
4661 QString pold=qpointfToString(movingObj_orgPos);
4662 QString pnow=qpointfToString(mapCenter->getAbsPos());
4668 QString("Move mapcenter %1 to position %2").arg(getName(mapCenter)).arg(pnow));
4672 if (xelection.type() == Selection::Branch )
4673 { // A branch was moved
4675 // save the position in case we link to mapcenter
4676 QPointF savePos=QPointF (lmosel->getAbsPos() );
4678 // Reset the temporary drawn link to the original one
4679 lmosel->unsetParObjTmp();
4681 // For Redo we may need to save original selection
4682 QString preSelStr=lmosel->getSelectString();
4687 BranchObj* bsel=xelection.getBranch();
4688 BranchObj* bdst=(BranchObj*)dst;
4690 QString preParStr=(bsel->getParObj())->getSelectString();
4691 QString preNum=QString::number (bsel->getNum(),10);
4692 QString preDstParStr;
4694 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4696 preDstParStr=dst->getParObj()->getSelectString();
4697 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4699 if (e->state() & Qt::ControlModifier && dst->getParObj())
4702 preDstParStr=dst->getParObj()->getSelectString();
4703 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4706 preDstParStr=dst->getSelectString();
4707 bsel->linkTo (bdst,-1);
4708 if (dst->getDepth()==0) bsel->move (savePos);
4710 QString postSelStr=lmosel->getSelectString();
4711 QString postNum=QString::number (bsel->getNum(),10);
4713 QString undoCom="linkTo (\""+
4714 preParStr+ "\"," + preNum +"," +
4715 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4717 QString redoCom="linkTo (\""+
4718 preDstParStr + "\"," + postNum + "," +
4719 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4724 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4726 if (lmosel->getDepth()==1)
4728 // The select string might be different _after_ moving around.
4729 // Therefor reposition and then use string of old selection, too
4730 mapCenter->reposition();
4732 QPointF rp(lmosel->getRelPos());
4733 if (rp != movingObj_orgRelPos)
4735 QString ps=qpointfToString(rp);
4737 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4738 preSelStr, "moveRel "+ps,
4739 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4742 // Draw the original link, before selection was moved around
4743 mapCenter->reposition();
4746 // Finally resize scene, if needed
4750 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4753 // maybe we moved View: set old cursor
4754 setCursor (Qt::ArrowCursor);
4758 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4760 if (isSelectBlocked() )
4766 if (e->button() == Qt::LeftButton )
4768 QPointF p = mapToScene(e->pos());
4769 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
4770 if (lmo) { // MapObj was found
4771 // First select the MapObj than edit heading
4772 xelection.select(lmo);
4773 mainWindow->editHeading();
4778 void MapEditor::resizeEvent (QResizeEvent* e)
4780 QGraphicsView::resizeEvent( e );
4783 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4785 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4786 // cerr << event->format(i) << endl;
4788 if (event->mimeData()->hasImage())
4789 event->acceptProposedAction();
4791 if (event->mimeData()->hasUrls())
4792 event->acceptProposedAction();
4795 void MapEditor::dragMoveEvent(QDragMoveEvent *)
4799 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4804 void MapEditor::dropEvent(QDropEvent *event)
4806 BranchObj *sel=xelection.getBranch();
4810 foreach (QString format,event->mimeData()->formats())
4811 cout << "MapEditor: Dropped format: "<<format.ascii()<<endl;
4815 if (event->mimeData()->hasImage())
4817 QVariant imageData = event->mimeData()->imageData();
4818 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4820 if (event->mimeData()->hasUrls())
4821 uris=event->mimeData()->urls();
4829 for (int i=0; i<uris.count();i++)
4831 // Workaround to avoid adding empty branches
4832 if (!uris.at(i).toString().isEmpty())
4834 bo=sel->addBranch();
4837 s=uris.at(i).toLocalFile();
4840 QString file = QDir::fromNativeSeparators(s);
4841 heading = QFileInfo(file).baseName();
4843 if (file.endsWith(".vym", false))
4844 bo->setVymLink(file);
4846 bo->setURL(uris.at(i).toString());
4849 bo->setURL(uris.at(i).toString());
4852 if (!heading.isEmpty())
4853 bo->setHeading(heading);
4855 bo->setHeading(uris.at(i).toString());
4859 mapCenter->reposition();
4862 event->acceptProposedAction();
4865 void MapEditor::timerEvent(QTimerEvent *event) //TODO animation
4869 cout << "ME::timerEvent\n";
4871 for (int i=0; i<animObjList.size(); ++i)
4873 animObjList.at(i)->animate();
4874 ((BranchObj*)animObjList.at(i))->move2RelPos (((BranchObj*)animObjList.at(i))->getRelPos() );
4876 mapCenter->reposition();
4880 void MapEditor::sendSelection()
4882 if (netstate!=Server) return;
4883 sendData (QString("select (\"%1\")").arg(xelection.getSelectString()) );
4886 void MapEditor::newServer()
4890 tcpServer = new QTcpServer(this);
4891 if (!tcpServer->listen(QHostAddress::Any,port)) {
4892 QMessageBox::critical(this, "vym server",
4893 QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
4897 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
4899 cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
4902 void MapEditor::connectToServer()
4905 server="salam.suse.de";
4907 clientSocket = new QTcpSocket (this);
4908 clientSocket->abort();
4909 clientSocket->connectToHost(server ,port);
4910 connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
4911 connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
4912 this, SLOT(displayNetworkError(QAbstractSocket::SocketError)));
4914 cout<<"connected to "<<server.ascii()<<" port "<<port<<endl;
4919 void MapEditor::newClient()
4921 QTcpSocket *newClient = tcpServer->nextPendingConnection();
4922 connect(newClient, SIGNAL(disconnected()),
4923 newClient, SLOT(deleteLater()));
4925 cout <<"ME::newClient at "<<newClient->peerAddress().toString().ascii()<<endl;
4927 clientList.append (newClient);
4931 void MapEditor::sendData(const QString &s)
4933 if (clientList.size()==0) return;
4935 // Create bytearray to send
4937 QDataStream out(&block, QIODevice::WriteOnly);
4938 out.setVersion(QDataStream::Qt_4_0);
4940 // Reserve some space for blocksize
4943 // Write sendCounter
4944 out << sendCounter++;
4949 // Go back and write blocksize so far
4950 out.device()->seek(0);
4951 quint16 bs=(quint16)(block.size() - 2*sizeof(quint16));
4955 cout << "ME::sendData bs="<<bs<<" counter="<<sendCounter<<" s="<<s.ascii()<<endl;
4957 for (int i=0; i<clientList.size(); ++i)
4959 //cout << "Sending \""<<s.ascii()<<"\" to "<<clientList.at(i)->peerAddress().toString().ascii()<<endl;
4960 clientList.at(i)->write (block);
4964 void MapEditor::readData ()
4966 while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) )
4969 cout <<"readData bytesAvail="<<clientSocket->bytesAvailable();
4973 QDataStream in(clientSocket);
4974 in.setVersion(QDataStream::Qt_4_0);
4982 cout << " t="<<t.ascii()<<endl;
4988 void MapEditor::displayNetworkError(QAbstractSocket::SocketError socketError)
4990 switch (socketError) {
4991 case QAbstractSocket::RemoteHostClosedError:
4993 case QAbstractSocket::HostNotFoundError:
4994 QMessageBox::information(this, __VYM_NAME " Network client",
4995 "The host was not found. Please check the "
4996 "host name and port settings.");
4998 case QAbstractSocket::ConnectionRefusedError:
4999 QMessageBox::information(this, __VYM_NAME " Network client",
5000 "The connection was refused by the peer. "
5001 "Make sure the fortune server is running, "
5002 "and check that the host name and port "
5003 "settings are correct.");
5006 QMessageBox::information(this, __VYM_NAME " Network client",
5007 QString("The following error occurred: %1.")
5008 .arg(clientSocket->errorString()));
5012 void MapEditor::autosave()
5014 // Disable autosave, while we have gone back in history
5015 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
5016 if (redosAvail>0) return;
5019 if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() )
5020 mainWindow->fileSave (this);
5024 /*TODO not needed? void MapEditor::contentsDropEvent(QDropEvent *event)
5027 } else if (event->provides("application/x-moz-file-promise-url") &&
5028 event->provides("application/x-moz-nativeimage"))
5030 // Contains url to the img src in unicode16
5031 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
5032 QString url = QString((const QChar*)d.data(),d.size()/2);
5036 } else if (event->provides ("text/uri-list"))
5037 { // Uris provided e.g. by konqueror
5038 Q3UriDrag::decode (event,uris);
5039 } else if (event->provides ("_NETSCAPE_URL"))
5040 { // Uris provided by Mozilla
5041 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
5044 } else if (event->provides("text/html")) {
5046 // Handels text mime types
5047 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
5048 QByteArray d = event->encodedData("text/html");
5051 text = QString((const QChar*)d.data(),d.size()/2);
5055 textEditor->setText(text);
5059 } else if (event->provides("text/plain")) {
5060 QByteArray d = event->encodedData("text/plain");
5063 text = QString((const QChar*)d.data(),d.size()/2);
5067 textEditor->setText(text);
5077 bool isUnicode16(const QByteArray &d)
5079 // TODO: make more precise check for unicode 16.
5080 // Guess unicode16 if any of second bytes are zero
5081 unsigned int length = max(0,d.size()-2)/2;
5082 for (unsigned int i = 0; i<length ; i++)
5083 if (d.at(i*2+1)==0) return true;
5087 void MapEditor::addFloatImageInt (const QPixmap &img)
5089 BranchObj *bo=xelection.getBranch();
5092 FloatImageObj *fio=bo->addFloatImage();
5094 fio->setOriginalFilename("No original filename (image added by dropevent)");
5095 QString s=bo->getSelectString();
5096 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio );
5097 saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image");
5098 mapCenter->reposition();
5105 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
5107 if (!imageBuffer) imageBuffer = new QBuffer();
5108 if (!imageBuffer->isOpen()) {
5109 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
5111 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
5115 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
5117 if (nop->state()==Q3NetworkProtocol::StDone) {
5118 QPixmap img(imageBuffer->buffer());
5119 addFloatImageInt (img);
5123 imageBuffer->close();
5125 imageBuffer->close();
5132 void MapEditor::fetchImage(const QString &url)
5135 urlOperator->stop();
5136 disconnect(urlOperator);
5140 urlOperator = new Q3UrlOperator(url);
5141 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
5142 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
5144 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
5145 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));