3 #include <q3filedialog.h>
10 #include "editxlinkdialog.h"
12 #include "exportxhtmldialog.h"
13 #include "extrainfodialog.h"
15 #include "linkablemapobj.h"
16 #include "mainwindow.h"
18 #include "texteditor.h"
19 #include "warningdialog.h"
20 #include "xml-freemind.h"
24 extern TextEditor *textEditor;
25 extern int statusbarTime;
26 extern Main *mainWindow;
27 extern QString tmpVymDir;
28 extern QString clipboardDir;
29 extern QString clipboardFile;
30 extern bool clipboardEmpty;
32 extern FlagRowObj *standardFlagsDefault;
34 extern QMenu* branchContextMenu;
35 extern QMenu* branchAddContextMenu;
36 extern QMenu* branchRemoveContextMenu;
37 extern QMenu* branchLinksContextMenu;
38 extern QMenu* branchXLinksContextMenuEdit;
39 extern QMenu* branchXLinksContextMenuFollow;
40 extern QMenu* floatimageContextMenu;
41 extern QMenu* canvasContextMenu;
44 extern Settings settings;
45 extern ImageIO imageIO;
47 extern QString vymName;
48 extern QString vymVersion;
50 extern QString iconPath;
51 extern QDir vymBaseDir;
52 extern QDir lastImageDir;
53 extern QDir lastFileDir;
55 int MapEditor::mapNum=0; // make instance
57 ///////////////////////////////////////////////////////////////////////
58 ///////////////////////////////////////////////////////////////////////
59 MapEditor::MapEditor( QWidget* parent) :
62 //cout << "Constructor ME "<<this<<endl;
66 mapScene= new QGraphicsScene(parent);
67 //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent);
68 mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern));
71 model->setScene (mapScene);
72 model->setMapEditor (this);
78 defLinkColor=QColor (0,0,255);
79 defXLinkColor=QColor (180,180,180);
80 linkcolorhint=LinkableMapObj::DefaultColor;
81 linkstyle=LinkableMapObj::PolyParabel;
83 // Create bitmap cursors, platform dependant
84 HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1);
85 PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
86 CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 );
87 XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 );
89 setFocusPolicy (Qt::StrongFocus);
98 xelection.setModel (model);
102 defXLinkColor=QColor (230,230,230);
110 fileName=tr("unnamed");
113 stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100);
114 undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal));
115 mainWindow->updateHistory (undoSet);
117 // Initialize find routine
124 blockReposition=false;
125 blockSaveState=false;
129 // Create temporary files
136 setAcceptDrops (true);
142 //timerId = startTimer(100);
145 autosaveTimer=new QTimer (this);
146 connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave()));
151 // Attributes //FIXME testing only...
154 attrTable= new AttributeTable();
156 ad=attrTable->addKey (k,StringList);
160 sl <<"val 1"<<"val 2"<< "val 3";
161 ad->setValue (QVariant (sl));
163 //attrTable->addValue ("Key A","P 1");
164 //attrTable->addValue ("Key A","P 2");
165 //attrTable->addValue ("Key A","P 3");
166 //attrTable->addValue ("Key A","P 4");
168 ad=attrTable->addKey (k,FreeString);
171 //attrTable->addValue ("Key B","w1");
172 //attrTable->addValue ("Key B","w2");
174 k="C - UniqueString";
175 ad=attrTable->addKey (k,UniqueString);
178 //attrTable->addKey ("Key Prio");
179 //attrTable->addValue ("Key Prio","Prio 1");
180 //attrTable->addValue ("Key Prio","Prio 2");
184 MapEditor::~MapEditor()
186 //cout <<"Destructor MapEditor\n";
187 autosaveTimer->stop();
189 // tmpMapDir is in tmpVymDir, so it gets removed automagically when vym closes
191 //removeDir(QDir(tmpMapDir));
195 VymModel* MapEditor::getModel()
200 QGraphicsScene * MapEditor::getScene()
205 MapEditor::State MapEditor::getState()
210 void MapEditor::setStateEditHeading(bool s)
214 if (state==Idle) state=EditHeading;
220 bool MapEditor::isRepositionBlocked()
222 return blockReposition;
225 void MapEditor::setSaveStateBlocked(bool b)
230 bool MapEditor::isSelectBlocked()
232 if (state==EditHeading)
238 QString MapEditor::getName (const LinkableMapObj *lmo)
241 if (!lmo) return QString("Error: NULL has no name!");
243 if ((typeid(*lmo) == typeid(BranchObj) ||
244 typeid(*lmo) == typeid(MapCenterObj)))
247 s=(((BranchObj*)lmo)->getHeading());
248 if (s=="") s="unnamed";
249 return QString("branch (%1)").arg(s);
251 if ((typeid(*lmo) == typeid(FloatImageObj) ))
252 return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
253 return QString("Unknown type has no name!");
256 void MapEditor::makeTmpDirs()
258 // Create unique temporary directories
259 tmpMapDir = tmpVymDir+QString("/mapeditor-%1").arg(mapNum);
260 histPath = tmpMapDir+"/history";
265 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel)
267 // tmpdir temporary directory to which data will be written
268 // prefix mapname, which will be appended to images etc.
269 // writeflags Only write flags for "real" save of map, not undo
270 // offset offset of bbox of whole map in scene.
271 // Needed for XML export
277 case LinkableMapObj::Line:
280 case LinkableMapObj::Parabel:
283 case LinkableMapObj::PolyLine:
287 ls="StylePolyParabel";
291 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
293 if (linkcolorhint==LinkableMapObj::HeadingColor)
294 colhint=attribut("linkColorHint","HeadingColor");
296 QString mapAttr=attribut("version",vymVersion);
298 mapAttr+= attribut("author",model->getAuthor()) +
299 attribut("comment",model->getComment()) +
300 attribut("date",model->getDate()) +
301 attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) +
302 attribut("selectionColor", xelection.getColor().name() ) +
303 attribut("linkStyle", ls ) +
304 attribut("linkColor", defLinkColor.name() ) +
305 attribut("defXLinkColor", defXLinkColor.name() ) +
306 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
308 s+=beginElement("vymmap",mapAttr);
311 // Find the used flags while traversing the tree
312 standardFlagsDefault->resetUsedCounter();
314 // Reset the counters before saving
315 // TODO constr. of FIO creates lots of objects, better do this in some other way...
316 FloatImageObj (mapScene).resetSaveCounter();
318 // Build xml recursivly
319 if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj))
320 // Save complete map, if saveSel not set
321 s+=model->saveToDir(tmpdir,prefix,writeflags,offset);
324 if ( typeid(*saveSel) == typeid(BranchObj) )
326 s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset);
327 else if ( typeid(*saveSel) == typeid(FloatImageObj) )
329 s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix);
332 // Save local settings
333 s+=settings.getDataXML (destPath);
336 if (!xelection.isEmpty() && !saveSel )
337 s+=valueElement("select",xelection.getSelectString());
340 s+=endElement("vymmap");
343 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
347 QString MapEditor::getHistoryDir()
349 QString histName(QString("history-%1").arg(curStep));
350 return (tmpMapDir+"/"+histName);
353 void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel)
355 sendData(redoCom); //FIXME testing
360 if (blockSaveState) return;
362 if (debug) cout << "ME::saveState() for "<<mapName.ascii()<<endl;
364 // Find out current undo directory
365 if (undosAvail<stepsTotal) undosAvail++;
367 if (curStep>stepsTotal) curStep=1;
369 QString backupXML="";
370 QString histDir=getHistoryDir();
371 QString bakMapPath=histDir+"/map.xml";
373 // Create histDir if not available
376 makeSubDirs (histDir);
378 // Save depending on how much needs to be saved
380 backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel);
382 QString undoCommand="";
383 if (savemode==UndoCommand)
387 else if (savemode==PartOfMap )
390 undoCommand.replace ("PATH",bakMapPath);
393 if (!backupXML.isEmpty())
394 // Write XML Data to disk
395 saveStringToDisk (bakMapPath,backupXML);
397 // We would have to save all actions in a tree, to keep track of
398 // possible redos after a action. Possible, but we are too lazy: forget about redos.
401 // Write the current state to disk
402 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
403 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
404 undoSet.setEntry ("/history/curStep",QString::number(curStep));
405 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
406 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
407 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
408 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
409 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
410 undoSet.setEntry (QString("/history/version"),vymVersion);
411 undoSet.writeSettings(histPath);
415 // TODO remove after testing
416 //cout << " into="<< histPath.toStdString()<<endl;
417 cout << " stepsTotal="<<stepsTotal<<
418 ", undosAvail="<<undosAvail<<
419 ", redosAvail="<<redosAvail<<
420 ", curStep="<<curStep<<endl;
421 cout << " ---------------------------"<<endl;
422 cout << " comment="<<comment.toStdString()<<endl;
423 cout << " undoCom="<<undoCommand.toStdString()<<endl;
424 cout << " undoSel="<<undoSelection.toStdString()<<endl;
425 cout << " redoCom="<<redoCom.toStdString()<<endl;
426 cout << " redoSel="<<redoSelection.toStdString()<<endl;
427 if (saveSel) cout << " saveSel="<<saveSel->getSelectString().ascii()<<endl;
428 cout << " ---------------------------"<<endl;
431 mainWindow->updateHistory (undoSet);
437 void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment)
439 // save the selected part of the map, Undo will replace part of map
440 QString undoSelection="";
442 undoSelection=undoSel->getSelectString();
444 qWarning ("MapEditor::saveStateChangingPart no undoSel given!");
445 QString redoSelection="";
447 redoSelection=undoSel->getSelectString();
449 qWarning ("MapEditor::saveStateChangingPart no redoSel given!");
452 saveState (PartOfMap,
453 undoSelection, "addMapReplace (\"PATH\")",
459 void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment)
463 qWarning ("MapEditor::saveStateRemovingPart no redoSel given!");
466 QString undoSelection=redoSel->getParObj()->getSelectString();
467 QString redoSelection=redoSel->getSelectString();
468 if (typeid(*redoSel) == typeid(BranchObj) )
470 // save the selected branch of the map, Undo will insert part of map
471 saveState (PartOfMap,
472 undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()),
473 redoSelection, "delete ()",
480 void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment)
482 // "Normal" savestate: save commands, selections and comment
483 // so just save commands for undo and redo
484 // and use current selection
486 QString redoSelection="";
487 if (redoSel) redoSelection=redoSel->getSelectString();
488 QString undoSelection="";
489 if (undoSel) undoSelection=undoSel->getSelectString();
491 saveState (UndoCommand,
498 void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment)
500 // "Normal" savestate: save commands, selections and comment
501 // so just save commands for undo and redo
502 // and use current selection
503 saveState (UndoCommand,
510 void MapEditor::saveState(const QString &uc, const QString &rc, const QString &comment)
512 // "Normal" savestate applied to model (no selection needed):
513 // save commands and comment
514 saveState (UndoCommand,
522 void MapEditor::parseAtom(const QString &atom)
524 BranchObj *selb=xelection.getBranch();
530 // Split string s into command and parameters
531 parser.parseAtom (atom);
532 QString com=parser.getCommand();
535 /////////////////////////////////////////////////////////////////////
536 if (com=="addBranch")
538 if (xelection.isEmpty())
540 parser.setError (Aborted,"Nothing selected");
543 parser.setError (Aborted,"Type of selection is not a branch");
548 if (parser.checkParCount(pl))
550 if (parser.parCount()==0)
554 n=parser.parInt (ok,0);
555 if (ok ) addNewBranch (n);
559 /////////////////////////////////////////////////////////////////////
560 } else if (com=="addBranchBefore")
562 if (xelection.isEmpty())
564 parser.setError (Aborted,"Nothing selected");
567 parser.setError (Aborted,"Type of selection is not a branch");
570 if (parser.parCount()==0)
572 addNewBranchBefore ();
575 /////////////////////////////////////////////////////////////////////
576 } else if (com==QString("addMapReplace"))
578 if (xelection.isEmpty())
580 parser.setError (Aborted,"Nothing selected");
583 parser.setError (Aborted,"Type of selection is not a branch");
584 } else if (parser.checkParCount(1))
586 //s=parser.parString (ok,0); // selection
587 t=parser.parString (ok,0); // path to map
588 if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
589 addMapReplaceInt(selb->getSelectString(),t);
591 /////////////////////////////////////////////////////////////////////
592 } else if (com==QString("addMapInsert"))
594 if (xelection.isEmpty())
596 parser.setError (Aborted,"Nothing selected");
599 parser.setError (Aborted,"Type of selection is not a branch");
602 if (parser.checkParCount(2))
604 t=parser.parString (ok,0); // path to map
605 n=parser.parInt(ok,1); // position
606 if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t);
607 addMapInsertInt(t,n);
610 /////////////////////////////////////////////////////////////////////
611 } else if (com=="clearFlags")
613 if (xelection.isEmpty() )
615 parser.setError (Aborted,"Nothing selected");
618 parser.setError (Aborted,"Type of selection is not a branch");
619 } else if (parser.checkParCount(0))
621 selb->clearStandardFlags();
622 selb->updateFlagsToolbar();
624 /////////////////////////////////////////////////////////////////////
625 } else if (com=="colorBranch")
627 if (xelection.isEmpty())
629 parser.setError (Aborted,"Nothing selected");
632 parser.setError (Aborted,"Type of selection is not a branch");
633 } else if (parser.checkParCount(1))
635 QColor c=parser.parColor (ok,0);
636 if (ok) colorBranch (c);
638 /////////////////////////////////////////////////////////////////////
639 } else if (com=="colorSubtree")
641 if (xelection.isEmpty())
643 parser.setError (Aborted,"Nothing selected");
646 parser.setError (Aborted,"Type of selection is not a branch");
647 } else if (parser.checkParCount(1))
649 QColor c=parser.parColor (ok,0);
650 if (ok) colorSubtree (c);
652 /////////////////////////////////////////////////////////////////////
653 } else if (com=="copy")
655 if (xelection.isEmpty())
657 parser.setError (Aborted,"Nothing selected");
660 parser.setError (Aborted,"Type of selection is not a branch");
661 } else if (parser.checkParCount(0))
663 //FIXME missing action for copy
665 /////////////////////////////////////////////////////////////////////
666 } else if (com=="cut")
668 if (xelection.isEmpty())
670 parser.setError (Aborted,"Nothing selected");
671 } else if ( xelection.type()!=Selection::Branch &&
672 xelection.type()!=Selection::MapCenter &&
673 xelection.type()!=Selection::FloatImage )
675 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
676 } else if (parser.checkParCount(0))
680 /////////////////////////////////////////////////////////////////////
681 } else if (com=="delete")
683 if (xelection.isEmpty())
685 parser.setError (Aborted,"Nothing selected");
686 } else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage )
688 parser.setError (Aborted,"Type of selection is wrong.");
689 } else if (parser.checkParCount(0))
693 /////////////////////////////////////////////////////////////////////
694 } else if (com=="deleteKeepChilds")
696 if (xelection.isEmpty())
698 parser.setError (Aborted,"Nothing selected");
701 parser.setError (Aborted,"Type of selection is not a branch");
702 } else if (parser.checkParCount(0))
706 /////////////////////////////////////////////////////////////////////
707 } else if (com=="deleteChilds")
709 if (xelection.isEmpty())
711 parser.setError (Aborted,"Nothing selected");
714 parser.setError (Aborted,"Type of selection is not a branch");
715 } else if (parser.checkParCount(0))
719 /////////////////////////////////////////////////////////////////////
720 } else if (com=="exportASCII")
724 if (parser.parCount()>=1)
725 // Hey, we even have a filename
726 fname=parser.parString(ok,0);
729 parser.setError (Aborted,"Could not read filename");
732 exportASCII (fname,false);
734 /////////////////////////////////////////////////////////////////////
735 } else if (com=="exportImage")
739 if (parser.parCount()>=2)
740 // Hey, we even have a filename
741 fname=parser.parString(ok,0);
744 parser.setError (Aborted,"Could not read filename");
747 QString format="PNG";
748 if (parser.parCount()>=2)
750 format=parser.parString(ok,1);
752 exportImage (fname,false,format);
754 /////////////////////////////////////////////////////////////////////
755 } else if (com=="exportXHTML")
759 if (parser.parCount()>=2)
760 // Hey, we even have a filename
761 fname=parser.parString(ok,1);
764 parser.setError (Aborted,"Could not read filename");
767 exportXHTML (fname,false);
769 /////////////////////////////////////////////////////////////////////
770 } else if (com=="exportXML")
774 if (parser.parCount()>=2)
775 // Hey, we even have a filename
776 fname=parser.parString(ok,1);
779 parser.setError (Aborted,"Could not read filename");
782 exportXML (fname,false);
784 /////////////////////////////////////////////////////////////////////
785 } else if (com=="importDir")
787 if (xelection.isEmpty())
789 parser.setError (Aborted,"Nothing selected");
792 parser.setError (Aborted,"Type of selection is not a branch");
793 } else if (parser.checkParCount(1))
795 s=parser.parString(ok,0);
796 if (ok) importDirInt(s);
798 /////////////////////////////////////////////////////////////////////
799 } else if (com=="linkTo")
801 if (xelection.isEmpty())
803 parser.setError (Aborted,"Nothing selected");
806 if (parser.checkParCount(4))
808 // 0 selectstring of parent
809 // 1 num in parent (for branches)
810 // 2,3 x,y of mainbranch or mapcenter
811 s=parser.parString(ok,0);
812 LinkableMapObj *dst=model->findObjBySelect (s);
815 if (typeid(*dst) == typeid(BranchObj) )
817 // Get number in parent
818 n=parser.parInt (ok,1);
821 selb->linkTo ((BranchObj*)(dst),n);
824 } else if (typeid(*dst) == typeid(MapCenterObj) )
826 selb->linkTo ((BranchObj*)(dst),-1);
827 // Get coordinates of mainbranch
828 x=parser.parDouble(ok,2);
831 y=parser.parDouble(ok,3);
841 } else if ( xelection.type() == Selection::FloatImage)
843 if (parser.checkParCount(1))
845 // 0 selectstring of parent
846 s=parser.parString(ok,0);
847 LinkableMapObj *dst=model->findObjBySelect (s);
850 if (typeid(*dst) == typeid(BranchObj) ||
851 typeid(*dst) == typeid(MapCenterObj))
852 linkTo (dst->getSelectString());
854 parser.setError (Aborted,"Destination is not a branch");
857 parser.setError (Aborted,"Type of selection is not a floatimage or branch");
858 /////////////////////////////////////////////////////////////////////
859 } else if (com=="loadImage")
861 if (xelection.isEmpty())
863 parser.setError (Aborted,"Nothing selected");
866 parser.setError (Aborted,"Type of selection is not a branch");
867 } else if (parser.checkParCount(1))
869 s=parser.parString(ok,0);
870 if (ok) loadFloatImageInt (s);
872 /////////////////////////////////////////////////////////////////////
873 } else if (com=="moveBranchUp")
875 if (xelection.isEmpty() )
877 parser.setError (Aborted,"Nothing selected");
880 parser.setError (Aborted,"Type of selection is not a branch");
881 } else if (parser.checkParCount(0))
885 /////////////////////////////////////////////////////////////////////
886 } else if (com=="moveBranchDown")
888 if (xelection.isEmpty() )
890 parser.setError (Aborted,"Nothing selected");
893 parser.setError (Aborted,"Type of selection is not a branch");
894 } else if (parser.checkParCount(0))
898 /////////////////////////////////////////////////////////////////////
899 } else if (com=="move")
901 if (xelection.isEmpty() )
903 parser.setError (Aborted,"Nothing selected");
904 } else if ( xelection.type()!=Selection::Branch &&
905 xelection.type()!=Selection::MapCenter &&
906 xelection.type()!=Selection::FloatImage )
908 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
909 } else if (parser.checkParCount(2))
911 x=parser.parDouble (ok,0);
914 y=parser.parDouble (ok,1);
918 /////////////////////////////////////////////////////////////////////
919 } else if (com=="moveRel")
921 if (xelection.isEmpty() )
923 parser.setError (Aborted,"Nothing selected");
924 } else if ( xelection.type()!=Selection::Selection::Branch &&
925 xelection.type()!=Selection::Selection::MapCenter &&
926 xelection.type()!=Selection::Selection::FloatImage )
928 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
929 } else if (parser.checkParCount(2))
931 x=parser.parDouble (ok,0);
934 y=parser.parDouble (ok,1);
935 if (ok) moveRel (x,y);
938 /////////////////////////////////////////////////////////////////////
939 } else if (com=="nop")
941 /////////////////////////////////////////////////////////////////////
942 } else if (com=="paste")
944 if (xelection.isEmpty() )
946 parser.setError (Aborted,"Nothing selected");
949 parser.setError (Aborted,"Type of selection is not a branch");
950 } else if (parser.checkParCount(1))
952 n=parser.parInt (ok,0);
953 if (ok) pasteNoSave(n);
955 /////////////////////////////////////////////////////////////////////
956 } else if (com=="qa")
958 if (xelection.isEmpty() )
960 parser.setError (Aborted,"Nothing selected");
963 parser.setError (Aborted,"Type of selection is not a branch");
964 } else if (parser.checkParCount(4))
967 c=parser.parString (ok,0);
970 parser.setError (Aborted,"No comment given");
973 s=parser.parString (ok,1);
976 parser.setError (Aborted,"First parameter is not a string");
979 t=parser.parString (ok,2);
982 parser.setError (Aborted,"Condition is not a string");
985 u=parser.parString (ok,3);
988 parser.setError (Aborted,"Third parameter is not a string");
993 parser.setError (Aborted,"Unknown type: "+s);
998 parser.setError (Aborted,"Unknown operator: "+t);
1003 parser.setError (Aborted,"Type of selection is not a branch");
1006 if (selb->getHeading() == u)
1008 cout << "PASSED: " << c.ascii() << endl;
1011 cout << "FAILED: " << c.ascii() << endl;
1021 /////////////////////////////////////////////////////////////////////
1022 } else if (com=="saveImage")
1024 FloatImageObj *fio=xelection.getFloatImage();
1027 parser.setError (Aborted,"Type of selection is not an image");
1028 } else if (parser.checkParCount(2))
1030 s=parser.parString(ok,0);
1033 t=parser.parString(ok,1);
1034 if (ok) saveFloatImageInt (fio,t,s);
1037 /////////////////////////////////////////////////////////////////////
1038 } else if (com=="scroll")
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 if (!scrollBranch (selb))
1049 parser.setError (Aborted,"Could not scroll branch");
1051 /////////////////////////////////////////////////////////////////////
1052 } else if (com=="select")
1054 if (parser.checkParCount(1))
1056 s=parser.parString(ok,0);
1059 /////////////////////////////////////////////////////////////////////
1060 } else if (com=="selectLastBranch")
1062 if (xelection.isEmpty() )
1064 parser.setError (Aborted,"Nothing selected");
1067 parser.setError (Aborted,"Type of selection is not a branch");
1068 } else if (parser.checkParCount(0))
1070 BranchObj *bo=selb->getLastBranch();
1072 parser.setError (Aborted,"Could not select last branch");
1076 /////////////////////////////////////////////////////////////////////
1077 } else if (com=="selectLastImage")
1079 if (xelection.isEmpty() )
1081 parser.setError (Aborted,"Nothing selected");
1084 parser.setError (Aborted,"Type of selection is not a branch");
1085 } else if (parser.checkParCount(0))
1087 FloatImageObj *fio=selb->getLastFloatImage();
1089 parser.setError (Aborted,"Could not select last image");
1093 /////////////////////////////////////////////////////////////////////
1094 } else if (com=="selectLatestAdded")
1096 if (latestSelection.isEmpty() )
1098 parser.setError (Aborted,"No latest added object");
1101 if (!select (latestSelection))
1102 parser.setError (Aborted,"Could not select latest added object "+latestSelection);
1104 /////////////////////////////////////////////////////////////////////
1105 } else if (com=="setFrameType")
1107 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1109 parser.setError (Aborted,"Type of selection does not allow setting frame type");
1111 else if (parser.checkParCount(1))
1113 s=parser.parString(ok,0);
1114 if (ok) setFrameType (s);
1116 /////////////////////////////////////////////////////////////////////
1117 } else if (com=="setFramePenColor")
1119 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1121 parser.setError (Aborted,"Type of selection does not allow setting of pen color");
1123 else if (parser.checkParCount(1))
1125 QColor c=parser.parColor(ok,0);
1126 if (ok) setFramePenColor (c);
1128 /////////////////////////////////////////////////////////////////////
1129 } else if (com=="setFrameBrushColor")
1131 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1133 parser.setError (Aborted,"Type of selection does not allow setting brush color");
1135 else if (parser.checkParCount(1))
1137 QColor c=parser.parColor(ok,0);
1138 if (ok) setFrameBrushColor (c);
1140 /////////////////////////////////////////////////////////////////////
1141 } else if (com=="setFramePadding")
1143 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1145 parser.setError (Aborted,"Type of selection does not allow setting frame padding");
1147 else if (parser.checkParCount(1))
1149 n=parser.parInt(ok,0);
1150 if (ok) setFramePadding(n);
1152 /////////////////////////////////////////////////////////////////////
1153 } else if (com=="setFrameBorderWidth")
1155 if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1157 parser.setError (Aborted,"Type of selection does not allow setting frame border width");
1159 else if (parser.checkParCount(1))
1161 n=parser.parInt(ok,0);
1162 if (ok) setFrameBorderWidth (n);
1164 /////////////////////////////////////////////////////////////////////
1165 } else if (com=="setMapAuthor")
1167 if (parser.checkParCount(1))
1169 s=parser.parString(ok,0);
1170 if (ok) setMapAuthor (s);
1172 /////////////////////////////////////////////////////////////////////
1173 } else if (com=="setMapComment")
1175 if (parser.checkParCount(1))
1177 s=parser.parString(ok,0);
1178 if (ok) setMapComment(s);
1180 /////////////////////////////////////////////////////////////////////
1181 } else if (com=="setMapBackgroundColor")
1183 if (xelection.isEmpty() )
1185 parser.setError (Aborted,"Nothing selected");
1186 } else if (! xelection.getBranch() )
1188 parser.setError (Aborted,"Type of selection is not a branch");
1189 } else if (parser.checkParCount(1))
1191 QColor c=parser.parColor (ok,0);
1192 if (ok) setMapBackgroundColor (c);
1194 /////////////////////////////////////////////////////////////////////
1195 } else if (com=="setMapDefLinkColor")
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 QColor c=parser.parColor (ok,0);
1206 if (ok) setMapDefLinkColor (c);
1208 /////////////////////////////////////////////////////////////////////
1209 } else if (com=="setMapLinkStyle")
1211 if (parser.checkParCount(1))
1213 s=parser.parString (ok,0);
1214 if (ok) setMapLinkStyle(s);
1216 /////////////////////////////////////////////////////////////////////
1217 } else if (com=="setHeading")
1219 if (xelection.isEmpty() )
1221 parser.setError (Aborted,"Nothing selected");
1224 parser.setError (Aborted,"Type of selection is not a branch");
1225 } else if (parser.checkParCount(1))
1227 s=parser.parString (ok,0);
1231 /////////////////////////////////////////////////////////////////////
1232 } else if (com=="setHideExport")
1234 if (xelection.isEmpty() )
1236 parser.setError (Aborted,"Nothing selected");
1237 } else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage)
1239 parser.setError (Aborted,"Type of selection is not a branch or floatimage");
1240 } else if (parser.checkParCount(1))
1242 b=parser.parBool(ok,0);
1243 if (ok) setHideExport (b);
1245 /////////////////////////////////////////////////////////////////////
1246 } else if (com=="setIncludeImagesHorizontally")
1248 if (xelection.isEmpty() )
1250 parser.setError (Aborted,"Nothing selected");
1253 parser.setError (Aborted,"Type of selection is not a branch");
1254 } else if (parser.checkParCount(1))
1256 b=parser.parBool(ok,0);
1257 if (ok) setIncludeImagesHor(b);
1259 /////////////////////////////////////////////////////////////////////
1260 } else if (com=="setIncludeImagesVertically")
1262 if (xelection.isEmpty() )
1264 parser.setError (Aborted,"Nothing selected");
1267 parser.setError (Aborted,"Type of selection is not a branch");
1268 } else if (parser.checkParCount(1))
1270 b=parser.parBool(ok,0);
1271 if (ok) setIncludeImagesVer(b);
1273 /////////////////////////////////////////////////////////////////////
1274 } else if (com=="setHideLinkUnselected")
1276 if (xelection.isEmpty() )
1278 parser.setError (Aborted,"Nothing selected");
1279 } else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage)
1281 parser.setError (Aborted,"Type of selection does not allow hiding the link");
1282 } else if (parser.checkParCount(1))
1284 b=parser.parBool(ok,0);
1285 if (ok) setHideLinkUnselected(b);
1287 /////////////////////////////////////////////////////////////////////
1288 } else if (com=="setSelectionColor")
1290 if (parser.checkParCount(1))
1292 QColor c=parser.parColor (ok,0);
1293 if (ok) setSelectionColorInt (c);
1295 /////////////////////////////////////////////////////////////////////
1296 } else if (com=="setURL")
1298 if (xelection.isEmpty() )
1300 parser.setError (Aborted,"Nothing selected");
1303 parser.setError (Aborted,"Type of selection is not a branch");
1304 } else if (parser.checkParCount(1))
1306 s=parser.parString (ok,0);
1309 /////////////////////////////////////////////////////////////////////
1310 } else if (com=="setVymLink")
1312 if (xelection.isEmpty() )
1314 parser.setError (Aborted,"Nothing selected");
1317 parser.setError (Aborted,"Type of selection is not a branch");
1318 } else if (parser.checkParCount(1))
1320 s=parser.parString (ok,0);
1321 if (ok) setVymLinkInt(s);
1324 /////////////////////////////////////////////////////////////////////
1325 else if (com=="setFlag")
1327 if (xelection.isEmpty() )
1329 parser.setError (Aborted,"Nothing selected");
1332 parser.setError (Aborted,"Type of selection is not a branch");
1333 } else if (parser.checkParCount(1))
1335 s=parser.parString(ok,0);
1338 selb->activateStandardFlag(s);
1339 selb->updateFlagsToolbar();
1342 /////////////////////////////////////////////////////////////////////
1343 } else if (com=="setFrameType")
1345 if (xelection.isEmpty() )
1347 parser.setError (Aborted,"Nothing selected");
1350 parser.setError (Aborted,"Type of selection is not a branch");
1351 } else if (parser.checkParCount(1))
1353 s=parser.parString(ok,0);
1357 /////////////////////////////////////////////////////////////////////
1358 } else if (com=="sortChildren")
1360 if (xelection.isEmpty() )
1362 parser.setError (Aborted,"Nothing selected");
1365 parser.setError (Aborted,"Type of selection is not a branch");
1366 } else if (parser.checkParCount(0))
1370 /////////////////////////////////////////////////////////////////////
1371 } else if (com=="toggleFlag")
1373 if (xelection.isEmpty() )
1375 parser.setError (Aborted,"Nothing selected");
1378 parser.setError (Aborted,"Type of selection is not a branch");
1379 } else if (parser.checkParCount(1))
1381 s=parser.parString(ok,0);
1384 selb->toggleStandardFlag(s);
1385 selb->updateFlagsToolbar();
1388 /////////////////////////////////////////////////////////////////////
1389 } else if (com=="unscroll")
1391 if (xelection.isEmpty() )
1393 parser.setError (Aborted,"Nothing selected");
1396 parser.setError (Aborted,"Type of selection is not a branch");
1397 } else if (parser.checkParCount(0))
1399 if (!unscrollBranch (selb))
1400 parser.setError (Aborted,"Could not unscroll branch");
1402 /////////////////////////////////////////////////////////////////////
1403 } else if (com=="unscrollChilds")
1405 if (xelection.isEmpty() )
1407 parser.setError (Aborted,"Nothing selected");
1410 parser.setError (Aborted,"Type of selection is not a branch");
1411 } else if (parser.checkParCount(0))
1415 /////////////////////////////////////////////////////////////////////
1416 } else if (com=="unsetFlag")
1418 if (xelection.isEmpty() )
1420 parser.setError (Aborted,"Nothing selected");
1423 parser.setError (Aborted,"Type of selection is not a branch");
1424 } else if (parser.checkParCount(1))
1426 s=parser.parString(ok,0);
1429 selb->deactivateStandardFlag(s);
1430 selb->updateFlagsToolbar();
1434 parser.setError (Aborted,"Unknown command");
1437 if (parser.errorLevel()==NoError)
1439 // setChanged(); FIXME should not be called e.g. for export?!
1440 model->reposition();
1444 // TODO Error handling
1445 qWarning("MapEditor::parseAtom: Error!");
1446 qWarning(parser.errorMessage());
1450 void MapEditor::runScript (QString script)
1452 parser.setScript (script);
1454 while (parser.next() )
1455 parseAtom(parser.getAtom());
1458 bool MapEditor::isDefault()
1463 bool MapEditor::hasChanged()
1468 void MapEditor::setChanged()
1471 autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt());
1479 void MapEditor::closeMap()
1481 // Unselect before disabling the toolbar actions
1482 if (!xelection.isEmpty() ) xelection.unselect();
1490 void MapEditor::setFilePath(QString fpath, QString destname)
1492 if (fpath.isEmpty() || fpath=="")
1499 filePath=fpath; // becomes absolute path
1500 fileName=fpath; // gets stripped of path
1501 destPath=destname; // needed for vymlinks
1503 // If fpath is not an absolute path, complete it
1504 filePath=QDir(fpath).absPath();
1505 fileDir=filePath.left (1+filePath.findRev ("/"));
1507 // Set short name, too. Search from behind:
1508 int i=fileName.findRev("/");
1509 if (i>=0) fileName=fileName.remove (0,i+1);
1511 // Forget the .vym (or .xml) for name of map
1512 mapName=fileName.left(fileName.findRev(".",-1,true) );
1516 void MapEditor::setFilePath(QString fpath)
1518 setFilePath (fpath,fpath);
1521 QString MapEditor::getFilePath()
1526 QString MapEditor::getFileName()
1531 QString MapEditor::getMapName()
1536 QString MapEditor::getDestPath()
1541 ErrorCode MapEditor::load (QString fname, const LoadMode &lmode, const FileType &ftype)
1543 ErrorCode err=success;
1545 parseBaseHandler *handler;
1548 case VymMap: handler=new parseVYMHandler; break;
1549 case FreemindMap : handler=new parseFreemindHandler; break;
1551 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1552 "Unknown FileType in MapEditor::load()");
1557 if (xelection.isEmpty() ) xelection.unselect();
1560 model->setMapEditor(this);
1561 // (map state is set later at end of load...)
1564 BranchObj *bo=xelection.getBranch();
1565 if (!bo) return aborted;
1566 if (lmode==ImportAdd)
1567 saveStateChangingPart(
1570 QString("addMapInsert (%1)").arg(fname),
1571 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1573 saveStateChangingPart(
1576 QString("addMapReplace(%1)").arg(fname),
1577 QString("Add map %1 to %2").arg(fname).arg(getName(bo)));
1580 QFile file( fname );
1582 // I am paranoid: file should exist anyway
1583 // according to check in mainwindow.
1584 if (!file.exists() )
1586 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1587 tr("Couldn't open map " +fname)+".");
1591 bool blockSaveStateOrg=blockSaveState;
1592 blockReposition=true;
1593 blockSaveState=true;
1594 QXmlInputSource source( file);
1595 QXmlSimpleReader reader;
1596 reader.setContentHandler( handler );
1597 reader.setErrorHandler( handler );
1598 handler->setModel ( model);
1601 // We need to set the tmpDir in order to load files with rel. path
1602 QString tmpdir= fname.left(fname.findRev("/",-1));
1603 handler->setTmpDir (tmpdir);
1604 handler->setInputFile (file.name());
1605 handler->setLoadMode (lmode);
1606 bool ok = reader.parse( source );
1607 blockReposition=false;
1608 blockSaveState=blockSaveStateOrg;
1612 model->reposition();
1619 autosaveTimer->stop();
1623 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
1624 tr( handler->errorProtocol() ) );
1626 // Still return "success": the map maybe at least
1627 // partially read by the parser
1634 int MapEditor::save (const SaveMode &savemode)
1636 // Create mapName and fileDir
1637 makeSubDirs (fileDir);
1641 fname=mapName+".xml";
1643 // use name given by user, even if he chooses .doc
1648 if (savemode==CompleteMap || xelection.isEmpty())
1650 // Save complete map
1651 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL);
1654 autosaveTimer->stop();
1659 if (xelection.type()==Selection::FloatImage)
1662 saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch());
1663 // TODO take care of multiselections
1666 if (!saveStringToDisk(fileDir+fname,saveFile))
1673 void MapEditor::setZipped (bool z)
1678 bool MapEditor::saveZipped ()
1683 void MapEditor::print()
1687 printer = new QPrinter;
1688 printer->setColorMode (QPrinter::Color);
1689 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
1690 printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt());
1691 printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString());
1694 QRectF totalBBox=model->getTotalBBox();
1696 // Try to set orientation automagically
1697 // Note: Interpretation of generated postscript is amibiguous, if
1698 // there are problems with landscape mode, see
1699 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
1701 if (totalBBox.width()>totalBBox.height())
1702 // recommend landscape
1703 printer->setOrientation (QPrinter::Landscape);
1705 // recommend portrait
1706 printer->setOrientation (QPrinter::Portrait);
1708 if ( printer->setup(this) )
1709 // returns false, if printing is canceled
1711 QPainter pp(printer);
1713 pp.setRenderHint(QPainter::Antialiasing,true);
1715 // Don't print the visualisation of selection
1716 xelection.unselect();
1718 QRectF mapRect=totalBBox;
1719 QGraphicsRectItem *frame=NULL;
1723 // Print frame around map
1724 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
1725 totalBBox.width()+20, totalBBox.height()+20);
1726 frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush));
1727 frame->setZValue(0);
1732 double paperAspect = (double)printer->width() / (double)printer->height();
1733 double mapAspect = (double)mapRect.width() / (double)mapRect.height();
1735 if (mapAspect>=paperAspect)
1737 // Fit horizontally to paper width
1738 //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) );
1739 viewBottom=(int)(printer->width()/mapAspect);
1742 // Fit vertically to paper height
1743 //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height());
1744 viewBottom=printer->height();
1749 // Print footer below map
1751 font.setPointSize(10);
1753 QRectF footerBox(0,viewBottom,printer->width(),15);
1754 pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName);
1755 pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate));
1759 QRectF (0,0,printer->width(),printer->height()-15),
1760 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height())
1763 // Viewport has paper dimension
1764 if (frame) delete (frame);
1766 // Restore selection
1767 xelection.reselect();
1769 // Save settings in vymrc
1770 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1771 settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat());
1772 settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName());
1776 void MapEditor::setAntiAlias (bool b)
1778 setRenderHint(QPainter::Antialiasing,b);
1781 void MapEditor::setSmoothPixmap(bool b)
1783 setRenderHint(QPainter::SmoothPixmapTransform,b);
1786 QPixmap MapEditor::getPixmap()
1788 QRectF mapRect=model->getTotalBBox();
1789 QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+1);
1792 pp.setRenderHints(renderHints());
1794 // Don't print the visualisation of selection
1795 xelection.unselect();
1797 mapScene->render ( &pp,
1798 QRectF(0,0,mapRect.width()+2,mapRect.height()+2),
1799 QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() ));
1801 // Restore selection
1802 xelection.reselect();
1807 void MapEditor::setHideTmpMode (HideTmpMode mode)
1810 model->setHideTmp (hidemode);
1811 model->reposition();
1815 HideTmpMode MapEditor::getHideTmpMode()
1820 void MapEditor::setExportMode (bool b)
1822 // should be called before and after exports
1823 // depending on the settings
1824 if (b && settings.value("/export/useHideExport","true")=="true")
1825 setHideTmpMode (HideExport);
1827 setHideTmpMode (HideNone);
1830 void MapEditor::exportASCII(QString fname,bool askName)
1833 ex.setModel (model);
1835 ex.setFile (mapName+".txt");
1841 //ex.addFilter ("TXT (*.txt)");
1842 ex.setDir(lastImageDir);
1843 //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)"));
1848 setExportMode(true);
1850 setExportMode(false);
1854 void MapEditor::exportImage(QString fname, bool askName, QString format)
1858 fname=mapName+".png";
1865 QFileDialog *fd=new QFileDialog (this);
1866 fd->setCaption (tr("Export map as image"));
1867 fd->setDirectory (lastImageDir);
1868 fd->setFileMode(QFileDialog::AnyFile);
1869 fd->setFilters (imageIO.getFilters() );
1872 fl=fd->selectedFiles();
1874 format=imageIO.getType(fd->selectedFilter());
1878 setExportMode (true);
1879 QPixmap pix (getPixmap());
1880 pix.save(fname, format);
1881 setExportMode (false);
1884 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1888 ex.setModel (model);
1889 if (ex.setConfigFile(cf))
1891 setExportMode (true);
1892 ex.exportPresentation();
1893 setExportMode (false);
1897 void MapEditor::exportXHTML (const QString &dir, bool askForName)
1899 ExportXHTMLDialog dia(this);
1900 dia.setFilePath (filePath );
1901 dia.setMapName (mapName );
1903 if (dir!="") dia.setDir (dir);
1909 if (dia.exec()!=QDialog::Accepted)
1913 QDir d (dia.getDir());
1914 // Check, if warnings should be used before overwriting
1915 // the output directory
1916 if (d.exists() && d.count()>0)
1919 warn.showCancelButton (true);
1920 warn.setText(QString(
1921 "The directory %1 is not empty.\n"
1922 "Do you risk to overwrite some of its contents?").arg(d.path() ));
1923 warn.setCaption("Warning: Directory not empty");
1924 warn.setShowAgainName("mainwindow/overwrite-dir-xhtml");
1926 if (warn.exec()!=QDialog::Accepted) ok=false;
1933 exportXML (dia.getDir(),false );
1934 dia.doExport(mapName );
1935 //if (dia.hasChanged()) setChanged();
1939 void MapEditor::exportXML(QString dir, bool askForName)
1943 dir=browseDirectory(this,tr("Export XML to directory"));
1944 if (dir =="" && !reallyWriteDirectory(dir) )
1948 // Hide stuff during export, if settings want this
1949 setExportMode (true);
1951 // Create subdirectories
1954 // write to directory
1955 QString saveFile=saveToDir (dir,mapName+"-",true,model->getTotalBBox().topLeft() ,NULL);
1958 file.setName ( dir + "/"+mapName+".xml");
1959 if ( !file.open( QIODevice::WriteOnly ) )
1961 // This should neverever happen
1962 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1966 // Write it finally, and write in UTF8, no matter what
1967 QTextStream ts( &file );
1968 ts.setEncoding (QTextStream::UnicodeUTF8);
1972 // Now write image, too
1973 exportImage (dir+"/images/"+mapName+".png",false,"PNG");
1975 setExportMode (false);
1978 void MapEditor::clear()
1980 xelection.unselect();
1984 void MapEditor::copy()
1986 LinkableMapObj *sel=xelection.single();
1989 if (redosAvail == 0)
1992 QString s=sel->getSelectString();
1993 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel );
1994 curClipboard=curStep;
1997 // Copy also to global clipboard, because we are at last step in history
1998 QString bakMapName(QString("history-%1").arg(curStep));
1999 QString bakMapDir(tmpMapDir +"/"+bakMapName);
2000 copyDir (bakMapDir,clipboardDir );
2002 clipboardEmpty=false;
2007 void MapEditor::redo()
2009 // Can we undo at all?
2010 if (redosAvail<1) return;
2012 bool blockSaveStateOrg=blockSaveState;
2013 blockSaveState=true;
2017 if (undosAvail<stepsTotal) undosAvail++;
2019 if (curStep>stepsTotal) curStep=1;
2020 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
2021 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2022 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2023 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2024 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2025 QString version=undoSet.readEntry ("/history/version");
2027 /* TODO Maybe check for version, if we save the history
2028 if (!checkVersion(version))
2029 QMessageBox::warning(0,tr("Warning"),
2030 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2033 // Find out current undo directory
2034 QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
2038 cout << "ME::redo() begin\n";
2039 cout << " undosAvail="<<undosAvail<<endl;
2040 cout << " redosAvail="<<redosAvail<<endl;
2041 cout << " curStep="<<curStep<<endl;
2042 cout << " ---------------------------"<<endl;
2043 cout << " comment="<<comment.toStdString()<<endl;
2044 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2045 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2046 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2047 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2048 cout << " ---------------------------"<<endl<<endl;
2051 // select object before redo
2052 if (!redoSelection.isEmpty())
2053 select (redoSelection);
2056 parseAtom (redoCommand);
2057 model->reposition();
2059 blockSaveState=blockSaveStateOrg;
2061 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2062 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2063 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2064 undoSet.writeSettings(histPath);
2066 mainWindow->updateHistory (undoSet);
2069 /* TODO remove testing
2070 cout << "ME::redo() end\n";
2071 cout << " undosAvail="<<undosAvail<<endl;
2072 cout << " redosAvail="<<redosAvail<<endl;
2073 cout << " curStep="<<curStep<<endl;
2074 cout << " ---------------------------"<<endl<<endl;
2080 bool MapEditor::isRedoAvailable()
2082 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
2088 void MapEditor::undo()
2090 // Can we undo at all?
2091 if (undosAvail<1) return;
2093 mainWindow->statusMessage (tr("Autosave disabled during undo."));
2095 bool blockSaveStateOrg=blockSaveState;
2096 blockSaveState=true;
2098 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
2099 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
2100 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
2101 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
2102 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
2103 QString version=undoSet.readEntry ("/history/version");
2105 /* TODO Maybe check for version, if we save the history
2106 if (!checkVersion(version))
2107 QMessageBox::warning(0,tr("Warning"),
2108 tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion));
2111 // Find out current undo directory
2112 QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep));
2114 // select object before undo
2115 if (!undoSelection.isEmpty())
2116 select (undoSelection);
2120 cout << "ME::undo() begin\n";
2121 cout << " undosAvail="<<undosAvail<<endl;
2122 cout << " redosAvail="<<redosAvail<<endl;
2123 cout << " curStep="<<curStep<<endl;
2124 cout << " ---------------------------"<<endl;
2125 cout << " comment="<<comment.toStdString()<<endl;
2126 cout << " undoCom="<<undoCommand.toStdString()<<endl;
2127 cout << " undoSel="<<undoSelection.toStdString()<<endl;
2128 cout << " redoCom="<<redoCommand.toStdString()<<endl;
2129 cout << " redoSel="<<redoSelection.toStdString()<<endl;
2130 cout << " ---------------------------"<<endl<<endl;
2132 parseAtom (undoCommand);
2133 model->reposition();
2137 if (curStep<1) curStep=stepsTotal;
2141 blockSaveState=blockSaveStateOrg;
2142 /* TODO remove testing
2143 cout << "ME::undo() end\n";
2144 cout << " undosAvail="<<undosAvail<<endl;
2145 cout << " redosAvail="<<redosAvail<<endl;
2146 cout << " curStep="<<curStep<<endl;
2147 cout << " ---------------------------"<<endl<<endl;
2150 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
2151 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
2152 undoSet.setEntry ("/history/curStep",QString::number(curStep));
2153 undoSet.writeSettings(histPath);
2155 mainWindow->updateHistory (undoSet);
2158 ensureSelectionVisible();
2161 bool MapEditor::isUndoAvailable()
2163 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
2169 void MapEditor::gotoHistoryStep (int i)
2171 // Restore variables
2172 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
2173 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
2175 if (i<0) i=undosAvail+redosAvail;
2177 // Clicking above current step makes us undo things
2180 for (int j=0; j<undosAvail-i; j++) undo();
2183 // Clicking below current step makes us redo things
2185 for (int j=undosAvail; j<i; j++)
2187 cout << "redo "<<j<<"/"<<undosAvail<<" i="<<i<<endl;
2191 // And ignore clicking the current row ;-)
2194 void MapEditor::addMapReplaceInt(const QString &undoSel, const QString &path)
2196 QString pathDir=path.left(path.findRev("/"));
2202 // We need to parse saved XML data
2203 parseVYMHandler handler;
2204 QXmlInputSource source( file);
2205 QXmlSimpleReader reader;
2206 reader.setContentHandler( &handler );
2207 reader.setErrorHandler( &handler );
2208 handler.setModel ( model);
2209 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2210 if (undoSel.isEmpty())
2214 handler.setLoadMode (NewMap);
2218 handler.setLoadMode (ImportReplace);
2220 blockReposition=true;
2221 bool ok = reader.parse( source );
2222 blockReposition=false;
2225 // This should never ever happen
2226 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2227 handler.errorProtocol());
2230 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2233 void MapEditor::addMapInsertInt (const QString &path, int pos)
2235 BranchObj *sel=xelection.getBranch();
2238 QString pathDir=path.left(path.findRev("/"));
2244 // We need to parse saved XML data
2245 parseVYMHandler handler;
2246 QXmlInputSource source( file);
2247 QXmlSimpleReader reader;
2248 reader.setContentHandler( &handler );
2249 reader.setErrorHandler( &handler );
2250 handler.setModel (model);
2251 handler.setTmpDir ( pathDir ); // needed to load files with rel. path
2252 handler.setLoadMode (ImportAdd);
2253 blockReposition=true;
2254 bool ok = reader.parse( source );
2255 blockReposition=false;
2258 // This should never ever happen
2259 QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path),
2260 handler.errorProtocol());
2262 if (sel->getDepth()>0)
2263 sel->getLastBranch()->linkTo (sel,pos);
2265 QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path));
2269 void MapEditor::pasteNoSave(const int &n)
2271 bool old=blockSaveState;
2272 blockSaveState=true;
2273 if (redosAvail > 0 || n!=0)
2275 // Use the "historical" buffer
2276 QString bakMapName(QString("history-%1").arg(n));
2277 QString bakMapDir(tmpMapDir +"/"+bakMapName);
2278 load (bakMapDir+"/"+clipboardFile,ImportAdd, VymMap);
2280 // Use the global buffer
2281 load (clipboardDir+"/"+clipboardFile,ImportAdd, VymMap);
2285 void MapEditor::paste()
2287 BranchObj *sel=xelection.getBranch();
2290 saveStateChangingPart(
2293 QString ("paste (%1)").arg(curClipboard),
2294 QString("Paste to %1").arg( getName(sel))
2297 model->reposition();
2301 void MapEditor::cut()
2303 LinkableMapObj *sel=xelection.single();
2304 if ( sel && (xelection.type() == Selection::Branch ||
2305 xelection.type()==Selection::MapCenter ||
2306 xelection.type()==Selection::FloatImage))
2308 /* No savestate! savestate is called in cutNoSave
2309 saveStateChangingPart(
2313 QString("Cut %1").arg(getName(sel ))
2318 model->reposition();
2322 void MapEditor::move(const double &x, const double &y)
2324 LinkableMapObj *sel=xelection.single();
2327 QPointF ap(sel->getAbsPos());
2331 QString ps=qpointfToString(ap);
2332 QString s=xelection.single()->getSelectString();
2335 s, "move "+qpointfToString(to),
2336 QString("Move %1 to %2").arg(getName(sel)).arg(ps));
2338 model->reposition();
2344 void MapEditor::moveRel (const double &x, const double &y)
2346 LinkableMapObj *sel=xelection.single();
2349 QPointF rp(sel->getRelPos());
2353 QString ps=qpointfToString (sel->getRelPos());
2354 QString s=sel->getSelectString();
2357 s, "moveRel "+qpointfToString(to),
2358 QString("Move %1 to relative position %2").arg(getName(sel)).arg(ps));
2359 ((OrnamentedObj*)sel)->move2RelPos (x,y);
2360 model->reposition();
2367 void MapEditor::moveBranchUp()
2369 BranchObj* bo=xelection.getBranch();
2373 if (!bo->canMoveBranchUp()) return;
2374 par=(BranchObj*)(bo->getParObj());
2375 BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection
2376 saveState (bo->getSelectString(),"moveBranchDown ()",obo->getSelectString(),"moveBranchUp ()",QString("Move up %1").arg(getName(bo)));
2377 model->reposition();
2380 ensureSelectionVisible();
2384 void MapEditor::moveBranchDown()
2386 BranchObj* bo=xelection.getBranch();
2390 if (!bo->canMoveBranchDown()) return;
2391 par=(BranchObj*)(bo->getParObj());
2392 BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection
2393 saveState(bo->getSelectString(),"moveBranchUp ()",obo->getSelectString(),"moveBranchDown ()",QString("Move down %1").arg(getName(bo)));
2394 model->reposition();
2397 ensureSelectionVisible();
2401 void MapEditor::sortChildren()
2403 BranchObj* bo=xelection.getBranch();
2406 if(bo->countBranches()>1)
2408 saveStateChangingPart(bo,bo, "sortChildren ()",QString("Sort children of %1").arg(getName(bo)));
2410 model->reposition();
2411 ensureSelectionVisible();
2416 void MapEditor::linkTo(const QString &dstString)
2418 FloatImageObj *fio=xelection.getFloatImage();
2421 BranchObj *dst=(BranchObj*)(model->findObjBySelect(dstString));
2422 if (dst && (typeid(*dst)==typeid (BranchObj) ||
2423 typeid(*dst)==typeid (MapCenterObj)))
2425 LinkableMapObj *dstPar=dst->getParObj();
2426 QString parString=dstPar->getSelectString();
2427 QString fioPreSelectString=fio->getSelectString();
2428 QString fioPreParentSelectString=fio->getParObj()->getSelectString();
2429 ((BranchObj*)(dst))->addFloatImage (fio);
2430 xelection.unselect();
2431 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
2432 fio=((BranchObj*)(dst))->getLastFloatImage();
2435 xelection.select(fio);
2437 fio->getSelectString(),
2438 QString("linkTo (\"%1\")").arg(fioPreParentSelectString),
2440 QString ("linkTo (\"%1\")").arg(dstString),
2441 QString ("Link floatimage to %1").arg(getName(dst)));
2446 QString MapEditor::getHeading(bool &ok, QPoint &p)
2448 BranchObj *bo=xelection.getBranch();
2452 p=mapFromScene(bo->getAbsPos());
2453 return bo->getHeading();
2459 void MapEditor::setHeading(const QString &s)
2461 BranchObj *sel=xelection.getBranch();
2466 "setHeading (\""+sel->getHeading()+"\")",
2468 "setHeading (\""+s+"\")",
2469 QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) );
2470 sel->setHeading(s );
2471 model->reposition();
2473 ensureSelectionVisible();
2477 void MapEditor::setHeadingInt(const QString &s)
2479 BranchObj *bo=xelection.getBranch();
2483 model->reposition();
2485 ensureSelectionVisible();
2489 void MapEditor::setVymLinkInt (const QString &s)
2491 // Internal function, no saveState needed
2492 BranchObj *bo=xelection.getBranch();
2496 model->reposition();
2499 ensureSelectionVisible();
2503 BranchObj* MapEditor::addNewBranchInt(int num)
2505 // Depending on pos:
2506 // -3 insert in childs of parent above selection
2507 // -2 add branch to selection
2508 // -1 insert in childs of parent below selection
2509 // 0..n insert in childs of parent at pos
2510 BranchObj *newbo=NULL;
2511 BranchObj *bo=xelection.getBranch();
2516 // save scroll state. If scrolled, automatically select
2517 // new branch in order to tmp unscroll parent...
2518 newbo=bo->addBranch();
2523 bo=(BranchObj*)bo->getParObj();
2524 if (bo) newbo=bo->insertBranch(num);
2528 bo=(BranchObj*)bo->getParObj();
2529 if (bo) newbo=bo->insertBranch(num);
2531 if (!newbo) return NULL;
2536 BranchObj* MapEditor::addNewBranch(int pos)
2538 // Different meaning than num in addNewBranchInt!
2542 BranchObj *bo = xelection.getBranch();
2543 BranchObj *newbo=NULL;
2547 setCursor (Qt::ArrowCursor);
2549 newbo=addNewBranchInt (pos-2);
2557 QString ("addBranch (%1)").arg(pos),
2558 QString ("Add new branch to %1").arg(getName(bo)));
2560 model->reposition();
2562 latestSelection=newbo->getSelectString();
2563 // In Network mode, the client needs to know where the new branch is,
2564 // so we have to pass on this information via saveState.
2565 // TODO: Get rid of this positioning workaround
2566 QString ps=qpointfToString (newbo->getAbsPos());
2567 sendData ("selectLatestAdded ()");
2568 sendData (QString("move %1").arg(ps));
2576 BranchObj* MapEditor::addNewBranchBefore()
2578 BranchObj *newbo=NULL;
2579 BranchObj *bo = xelection.getBranch();
2580 if (bo && xelection.type()==Selection::Branch)
2581 // We accept no MapCenterObj here, so we _have_ a parent
2583 QPointF p=bo->getRelPos();
2586 BranchObj *parbo=(BranchObj*)(bo->getParObj());
2588 // add below selection
2589 newbo=parbo->insertBranch(bo->getNum()+1);
2592 newbo->move2RelPos (p);
2594 // Move selection to new branch
2595 bo->linkTo (newbo,-1);
2597 saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()",
2598 QString ("Add branch before %1").arg(getName(bo)));
2600 model->reposition();
2604 latestSelection=xelection.getSelectString();
2608 void MapEditor::deleteSelection()
2610 BranchObj *bo = xelection.getBranch();
2611 if (bo && xelection.type()==Selection::MapCenter)
2613 // BranchObj* par=(BranchObj*)(bo->getParObj());
2614 xelection.unselect();
2615 /* FIXME Note: does saveStateRemovingPart work for MCO? (No parent!)
2616 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2618 bo=model->removeMapCenter ((MapCenterObj*)bo);
2621 xelection.select (bo);
2622 ensureSelectionVisible();
2625 model->reposition();
2628 if (bo && xelection.type()==Selection::Branch)
2630 BranchObj* par=(BranchObj*)(bo->getParObj());
2631 xelection.unselect();
2632 saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo)));
2633 par->removeBranch(bo);
2634 xelection.select (par);
2635 ensureSelectionVisible();
2636 model->reposition();
2641 FloatImageObj *fio=xelection.getFloatImage();
2644 BranchObj* par=(BranchObj*)(fio->getParObj());
2645 saveStateChangingPart(
2649 QString("Delete %1").arg(getName(fio))
2651 xelection.unselect();
2652 par->removeFloatImage(fio);
2653 xelection.select (par);
2654 model->reposition();
2656 ensureSelectionVisible();
2661 LinkableMapObj* MapEditor::getSelection()
2663 return xelection.single();
2666 BranchObj* MapEditor::getSelectedBranch()
2668 return xelection.getBranch();
2671 FloatImageObj* MapEditor::getSelectedFloatImage()
2673 return xelection.getFloatImage();
2676 void MapEditor::unselect()
2678 xelection.unselect();
2681 void MapEditor::reselect()
2683 xelection.reselect();
2686 bool MapEditor::select (const QString &s)
2688 LinkableMapObj *lmo=model->findObjBySelect(s);
2690 // Finally select the found object
2693 xelection.unselect();
2694 xelection.select(lmo);
2696 ensureSelectionVisible();
2703 QString MapEditor::getSelectString()
2705 return xelection.getSelectString();
2708 void MapEditor::selectInt (LinkableMapObj *lmo)
2710 if (lmo && xelection.single()!= lmo && isSelectBlocked()==false )
2712 xelection.select(lmo);
2718 void MapEditor::selectNextBranchInt()
2720 // Increase number of branch
2721 LinkableMapObj *sel=xelection.single();
2724 QString s=sel->getSelectString();
2730 part=s.section(",",-1);
2732 num=part.right(part.length() - 3);
2734 s=s.left (s.length() -num.length());
2737 num=QString ("%1").arg(num.toUInt()+1);
2741 // Try to select this one
2742 if (select (s)) return;
2744 // We have no direct successor,
2745 // try to increase the parental number in order to
2746 // find a successor with same depth
2748 int d=xelection.single()->getDepth();
2753 while (!found && d>0)
2755 s=s.section (",",0,d-1);
2756 // replace substring of current depth in s with "1"
2757 part=s.section(",",-1);
2759 num=part.right(part.length() - 3);
2763 // increase number of parent
2764 num=QString ("%1").arg(num.toUInt()+1);
2765 s=s.section (",",0,d-2) + ","+ typ+num;
2768 // Special case, look at orientation
2769 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2770 num=QString ("%1").arg(num.toUInt()+1);
2772 num=QString ("%1").arg(num.toUInt()-1);
2777 // pad to oldDepth, select the first branch for each depth
2778 for (i=d;i<oldDepth;i++)
2783 if ( xelection.getBranch()->countBranches()>0)
2791 // try to select the freshly built string
2799 void MapEditor::selectPrevBranchInt()
2801 // Decrease number of branch
2802 BranchObj *bo=xelection.getBranch();
2805 QString s=bo->getSelectString();
2811 part=s.section(",",-1);
2813 num=part.right(part.length() - 3);
2815 s=s.left (s.length() -num.length());
2817 int n=num.toInt()-1;
2820 num=QString ("%1").arg(n);
2823 // Try to select this one
2824 if (n>=0 && select (s)) return;
2826 // We have no direct precessor,
2827 // try to decrease the parental number in order to
2828 // find a precessor with same depth
2830 int d=xelection.single()->getDepth();
2835 while (!found && d>0)
2837 s=s.section (",",0,d-1);
2838 // replace substring of current depth in s with "1"
2839 part=s.section(",",-1);
2841 num=part.right(part.length() - 3);
2845 // decrease number of parent
2846 num=QString ("%1").arg(num.toInt()-1);
2847 s=s.section (",",0,d-2) + ","+ typ+num;
2850 // Special case, look at orientation
2851 if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter)
2852 num=QString ("%1").arg(num.toInt()-1);
2854 num=QString ("%1").arg(num.toInt()+1);
2859 // pad to oldDepth, select the last branch for each depth
2860 for (i=d;i<oldDepth;i++)
2864 if ( xelection.getBranch()->countBranches()>0)
2865 s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 );
2872 // try to select the freshly built string
2880 void MapEditor::selectUpperBranch()
2882 if (isSelectBlocked() ) return;
2884 BranchObj *bo=xelection.getBranch();
2885 if (bo && xelection.type()==Selection::Branch)
2887 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2888 selectPrevBranchInt();
2890 if (bo->getDepth()==1)
2891 selectNextBranchInt();
2893 selectPrevBranchInt();
2897 void MapEditor::selectLowerBranch()
2899 if (isSelectBlocked() ) return;
2901 BranchObj *bo=xelection.getBranch();
2902 if (bo && xelection.type()==Selection::Branch)
2903 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2904 selectNextBranchInt();
2906 if (bo->getDepth()==1)
2907 selectPrevBranchInt();
2909 selectNextBranchInt();
2913 void MapEditor::selectLeftBranch()
2915 if (isSelectBlocked() ) return;
2919 LinkableMapObj *sel=xelection.single();
2922 if (xelection.type()== Selection::MapCenter)
2924 par=xelection.getBranch();
2925 bo=par->getLastSelectedBranch();
2928 // Workaround for reselecting on left and right side
2929 if (bo->getOrientation()==LinkableMapObj::RightOfCenter)
2930 bo=par->getLastBranch();
2933 bo=par->getLastBranch();
2934 xelection.select(bo);
2936 ensureSelectionVisible();
2942 par=(BranchObj*)(sel->getParObj());
2943 if (sel->getOrientation()==LinkableMapObj::RightOfCenter)
2945 if (xelection.type() == Selection::Branch ||
2946 xelection.type() == Selection::FloatImage)
2948 xelection.select(par);
2950 ensureSelectionVisible();
2955 if (xelection.type() == Selection::Branch )
2957 bo=xelection.getBranch()->getLastSelectedBranch();
2960 xelection.select(bo);
2962 ensureSelectionVisible();
2971 void MapEditor::selectRightBranch()
2973 if (isSelectBlocked() ) return;
2977 LinkableMapObj *sel=xelection.single();
2980 if (xelection.type()==Selection::MapCenter)
2982 par=xelection.getBranch();
2983 bo=par->getLastSelectedBranch();
2986 // Workaround for reselecting on left and right side
2987 if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
2988 bo=par->getFirstBranch();
2991 xelection.select(bo);
2993 ensureSelectionVisible();
2999 par=(BranchObj*)(xelection.single()->getParObj());
3000 if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter)
3002 if (xelection.type() == Selection::Branch ||
3003 xelection.type() == Selection::FloatImage)
3005 xelection.select(par);
3007 ensureSelectionVisible();
3012 if (xelection.type() == Selection::Branch)
3014 bo=xelection.getBranch()->getLastSelectedBranch();
3017 xelection.select(bo);
3019 ensureSelectionVisible();
3028 void MapEditor::selectFirstBranch()
3030 BranchObj *bo1=xelection.getBranch();
3035 par=(BranchObj*)(bo1->getParObj());
3036 bo2=par->getFirstBranch();
3038 xelection.select(bo2);
3040 ensureSelectionVisible();
3046 void MapEditor::selectLastBranch()
3048 BranchObj *bo1=xelection.getBranch();
3053 par=(BranchObj*)(bo1->getParObj());
3054 bo2=par->getLastBranch();
3057 xelection.select(bo2);
3059 ensureSelectionVisible();
3065 void MapEditor::selectMapBackgroundImage ()
3067 Q3FileDialog *fd=new Q3FileDialog( this);
3068 fd->setMode (Q3FileDialog::ExistingFile);
3069 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3070 ImagePreview *p =new ImagePreview (fd);
3071 fd->setContentsPreviewEnabled( TRUE );
3072 fd->setContentsPreview( p, p );
3073 fd->setPreviewMode( Q3FileDialog::Contents );
3074 fd->setCaption(vymName+" - " +tr("Load background image"));
3075 fd->setDir (lastImageDir);
3078 if ( fd->exec() == QDialog::Accepted )
3080 // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory();
3081 lastImageDir=QDir (fd->dirPath());
3082 setMapBackgroundImage (fd->selectedFile());
3086 void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate
3088 QColor oldcol=mapScene->backgroundBrush().color();
3092 QString ("setMapBackgroundImage (%1)").arg(oldcol.name()),
3094 QString ("setMapBackgroundImage (%1)").arg(col.name()),
3095 QString("Set background color of map to %1").arg(col.name()));
3098 brush.setTextureImage (QPixmap (fn));
3099 mapScene->setBackgroundBrush(brush);
3102 void MapEditor::selectMapBackgroundColor()
3104 QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this );
3105 if ( !col.isValid() ) return;
3106 setMapBackgroundColor( col );
3110 void MapEditor::setMapBackgroundColor(QColor col)
3112 QColor oldcol=mapScene->backgroundBrush().color();
3114 QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()),
3115 QString ("setMapBackgroundColor (\"%1\")").arg(col.name()),
3116 QString("Set background color of map to %1").arg(col.name()));
3117 mapScene->setBackgroundBrush(col);
3120 QColor MapEditor::getMapBackgroundColor()
3122 return mapScene->backgroundBrush().color();
3125 QColor MapEditor::getCurrentHeadingColor()
3127 BranchObj *bo=xelection.getBranch();
3128 if (bo) return bo->getColor();
3130 QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected"));
3134 void MapEditor::colorBranch (QColor c)
3136 BranchObj *bo=xelection.getBranch();
3141 QString ("colorBranch (\"%1\")").arg(bo->getColor().name()),
3143 QString ("colorBranch (\"%1\")").arg(c.name()),
3144 QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name())
3146 bo->setColor(c); // color branch
3150 void MapEditor::colorSubtree (QColor c)
3152 BranchObj *bo=xelection.getBranch();
3155 saveStateChangingPart(
3158 QString ("colorSubtree (\"%1\")").arg(c.name()),
3159 QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name())
3161 bo->setColorSubtree (c); // color links, color childs
3166 void MapEditor::toggleStandardFlag(QString f)
3168 BranchObj *bo=xelection.getBranch();
3172 if (bo->isSetStandardFlag(f))
3184 QString("%1 (\"%2\")").arg(u).arg(f),
3186 QString("%1 (\"%2\")").arg(r).arg(f),
3187 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
3188 bo->toggleStandardFlag (f,mainWindow->useFlagGroups());
3194 BranchObj* MapEditor::findText (QString s, bool cs)
3196 QTextDocument::FindFlags flags=0;
3197 if (cs) flags=QTextDocument::FindCaseSensitively;
3200 { // Nothing found or new find process
3202 // nothing found, start again
3204 itFind=model->first();
3206 bool searching=true;
3207 bool foundNote=false;
3208 while (searching && !EOFind)
3212 // Searching in Note
3213 if (itFind->getNote().contains(s,cs))
3215 if (xelection.single()!=itFind)
3217 xelection.select(itFind);
3218 ensureSelectionVisible();
3220 if (textEditor->findText(s,flags))
3226 // Searching in Heading
3227 if (searching && itFind->getHeading().contains (s,cs) )
3229 xelection.select(itFind);
3230 ensureSelectionVisible();
3236 itFind=model->next(itFind);
3237 if (!itFind) EOFind=true;
3241 return xelection.getBranch();
3246 void MapEditor::findReset()
3247 { // Necessary if text to find changes during a find process
3251 void MapEditor::setURL(const QString &url)
3253 BranchObj *bo=xelection.getBranch();
3256 QString oldurl=bo->getURL();
3260 QString ("setURL (\"%1\")").arg(oldurl),
3262 QString ("setURL (\"%1\")").arg(url),
3263 QString ("set URL of %1 to %2").arg(getName(bo)).arg(url)
3266 model->reposition();
3268 ensureSelectionVisible();
3272 void MapEditor::editURL()
3274 BranchObj *bo=xelection.getBranch();
3278 QString text = QInputDialog::getText(
3279 "VYM", tr("Enter URL:"), QLineEdit::Normal,
3280 bo->getURL(), &ok, this );
3282 // user entered something and pressed OK
3287 void MapEditor::editLocalURL()
3289 BranchObj *bo=xelection.getBranch();
3292 QStringList filters;
3293 filters <<"All files (*)";
3294 filters << tr("Text","Filedialog") + " (*.txt)";
3295 filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)";
3296 filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)";
3297 filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)";
3298 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Set URL to a local file"));
3299 fd->setFilters (filters);
3300 fd->setCaption(vymName+" - " +tr("Set URL to a local file"));
3301 fd->setDirectory (lastFileDir);
3302 if (! bo->getVymLink().isEmpty() )
3303 fd->selectFile( bo->getURL() );
3306 if ( fd->exec() == QDialog::Accepted )
3308 lastFileDir=QDir (fd->directory().path());
3309 setURL (fd->selectedFile() );
3314 QString MapEditor::getURL()
3316 BranchObj *bo=xelection.getBranch();
3318 return bo->getURL();
3323 QStringList MapEditor::getURLs()
3326 BranchObj *bo=xelection.getBranch();
3332 if (!bo->getURL().isEmpty()) urls.append( bo->getURL());
3340 void MapEditor::editHeading2URL()
3342 BranchObj *bo=xelection.getBranch();
3344 setURL (bo->getHeading());
3347 void MapEditor::editBugzilla2URL()
3349 BranchObj *bo=xelection.getBranch();
3352 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
3357 void MapEditor::editFATE2URL()
3359 BranchObj *bo=xelection.getBranch();
3362 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
3365 "setURL (\""+bo->getURL()+"\")",
3367 "setURL (\""+url+"\")",
3368 QString("Use heading of %1 as link to FATE").arg(getName(bo))
3375 void MapEditor::editVymLink()
3377 BranchObj *bo=xelection.getBranch();
3380 QStringList filters;
3381 filters <<"VYM map (*.vym)";
3382 QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map"));
3383 fd->setFilters (filters);
3384 fd->setCaption(vymName+" - " +tr("Link to another map"));
3385 fd->setDirectory (lastFileDir);
3386 if (! bo->getVymLink().isEmpty() )
3387 fd->selectFile( bo->getVymLink() );
3391 if ( fd->exec() == QDialog::Accepted )
3393 lastFileDir=QDir (fd->directory().path());
3396 "setVymLink (\""+bo->getVymLink()+"\")",
3398 "setVymLink (\""+fd->selectedFile()+"\")",
3399 QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())
3401 setVymLinkInt (fd->selectedFile() );
3406 void MapEditor::deleteVymLink()
3408 BranchObj *bo=xelection.getBranch();
3413 "setVymLink (\""+bo->getVymLink()+"\")",
3415 "setVymLink (\"\")",
3416 QString("Unset vymlink of %1").arg(getName(bo))
3418 bo->setVymLink ("" );
3420 model->reposition();
3425 void MapEditor::setHideExport(bool b)
3427 BranchObj *bo=xelection.getBranch();
3430 bo->setHideInExport (b);
3431 QString u= b ? "false" : "true";
3432 QString r=!b ? "false" : "true";
3436 QString ("setHideExport (%1)").arg(u),
3438 QString ("setHideExport (%1)").arg(r),
3439 QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r)
3442 model->reposition();
3448 void MapEditor::toggleHideExport()
3450 BranchObj *bo=xelection.getBranch();
3452 setHideExport ( !bo->hideInExport() );
3455 QString MapEditor::getVymLink()
3457 BranchObj *bo=xelection.getBranch();
3459 return bo->getVymLink();
3465 QStringList MapEditor::getVymLinks()
3468 BranchObj *bo=xelection.getBranch();
3474 if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink());
3482 void MapEditor::deleteKeepChilds()
3484 BranchObj *bo=xelection.getBranch();
3488 par=(BranchObj*)(bo->getParObj());
3489 QPointF p=bo->getRelPos();
3490 saveStateChangingPart(
3493 "deleteKeepChilds ()",
3494 QString("Remove %1 and keep its childs").arg(getName(bo))
3497 QString sel=bo->getSelectString();
3499 par->removeBranchHere(bo);
3500 model->reposition();
3502 xelection.getBranch()->move2RelPos (p);
3503 model->reposition();
3507 void MapEditor::deleteChilds()
3509 BranchObj *bo=xelection.getBranch();
3512 saveStateChangingPart(
3516 QString( "Remove childs of branch %1").arg(getName(bo))
3519 model->reposition();
3523 void MapEditor::editMapInfo()
3525 ExtraInfoDialog dia;
3526 dia.setMapName (getFileName() );
3527 dia.setAuthor (model->getAuthor() );
3528 dia.setComment(model->getComment() );
3532 stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6);
3542 if (!bo->getNote().isEmpty() ) n++;
3543 f+= bo->countFloatImages();
3545 xl+=bo->countXLinks();
3548 stats+=QString ("%1 branches\n").arg (b-1,6);
3549 stats+=QString ("%1 xLinks \n").arg (xl,6);
3550 stats+=QString ("%1 notes\n").arg (n,6);
3551 stats+=QString ("%1 images\n").arg (f,6);
3552 dia.setStats (stats);
3554 // Finally show dialog
3555 if (dia.exec() == QDialog::Accepted)
3557 setMapAuthor (dia.getAuthor() );
3558 setMapComment (dia.getComment() );
3562 void MapEditor::ensureSelectionVisible()
3564 LinkableMapObj *lmo=xelection.single();
3565 if (lmo) ensureVisible (lmo->getBBox() );
3569 void MapEditor::updateSelection()
3571 // Tell selection to update geometries
3575 void MapEditor::updateActions()
3577 // Tell mainwindow to update states of actions
3578 mainWindow->updateActions();
3579 // TODO maybe don't update if blockReposition is set
3582 void MapEditor::updateNoteFlag()
3585 BranchObj *bo=xelection.getBranch();
3588 bo->updateNoteFlag();
3589 mainWindow->updateActions();
3593 void MapEditor::setMapAuthor (const QString &s)
3596 QString ("setMapAuthor (\"%1\")").arg(model->getAuthor()),
3597 QString ("setMapAuthor (\"%1\")").arg(s),
3598 QString ("Set author of map to \"%1\"").arg(s)
3600 model->setAuthor (s);
3603 void MapEditor::setMapComment (const QString &s)
3606 QString ("setMapComment (\"%1\")").arg(model->getComment()),
3607 QString ("setMapComment (\"%1\")").arg(s),
3608 QString ("Set comment of map")
3610 model->setComment (s);
3613 void MapEditor::setMapLinkStyle (const QString & s)
3616 if (linkstyle==LinkableMapObj::Line)
3618 else if (linkstyle==LinkableMapObj::Parabel)
3619 snow="StyleParabel";
3620 else if (linkstyle==LinkableMapObj::PolyLine)
3621 snow="StylePolyLine";
3622 else if (linkstyle==LinkableMapObj::PolyParabel)
3623 snow="StyleParabel";
3626 QString("setMapLinkStyle (\"%1\")").arg(s),
3627 QString("setMapLinkStyle (\"%1\")").arg(snow),
3628 QString("Set map link style (\"%1\")").arg(s)
3632 linkstyle=LinkableMapObj::Line;
3633 else if (s=="StyleParabel")
3634 linkstyle=LinkableMapObj::Parabel;
3635 else if (s=="StylePolyLine")
3636 linkstyle=LinkableMapObj::PolyLine;
3638 linkstyle=LinkableMapObj::PolyParabel;
3645 bo->setLinkStyle(bo->getDefLinkStyle());
3648 model->reposition();
3651 LinkableMapObj::Style MapEditor::getMapLinkStyle ()
3656 void MapEditor::setMapDefLinkColor(QColor c)
3669 void MapEditor::setMapLinkColorHintInt()
3671 // called from setMapLinkColorHint(lch) or at end of parse
3681 void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch)
3684 setMapLinkColorHintInt();
3687 void MapEditor::toggleMapLinkColorHint()
3689 if (linkcolorhint==LinkableMapObj::HeadingColor)
3690 linkcolorhint=LinkableMapObj::DefaultColor;
3692 linkcolorhint=LinkableMapObj::HeadingColor;
3702 LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint()
3704 return linkcolorhint;
3707 QColor MapEditor::getMapDefLinkColor()
3709 return defLinkColor;
3712 void MapEditor::setMapDefXLinkColor(QColor col)
3717 QColor MapEditor::getMapDefXLinkColor()
3719 return defXLinkColor;
3722 void MapEditor::setMapDefXLinkWidth (int w)
3727 int MapEditor::getMapDefXLinkWidth()
3729 return defXLinkWidth;
3732 void MapEditor::selectMapLinkColor()
3734 QColor col = QColorDialog::getColor( defLinkColor, this );
3735 if ( !col.isValid() ) return;
3737 QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()),
3738 QString("setMapDefLinkColor (\"%1\")").arg(col.name()),
3739 QString("Set map link color to %1").arg(col.name())
3741 setMapDefLinkColor( col );
3744 void MapEditor::selectMapSelectionColor()
3746 QColor col = QColorDialog::getColor( defLinkColor, this );
3747 setSelectionColor (col);
3750 void MapEditor::setSelectionColorInt (QColor col)
3752 if ( !col.isValid() ) return;
3753 xelection.setColor (col);
3756 void MapEditor::setSelectionColor(QColor col)
3758 if ( !col.isValid() ) return;
3760 QString("setSelectionColor (%1)").arg(xelection.getColor().name()),
3761 QString("setSelectionColor (%1)").arg(col.name()),
3762 QString("Set color of selection box to %1").arg(col.name())
3764 setSelectionColorInt (col);
3767 QColor MapEditor::getSelectionColor()
3769 return xelection.getColor();
3772 bool MapEditor::scrollBranch(BranchObj *bo)
3776 if (bo->isScrolled()) return false;
3777 if (bo->countBranches()==0) return false;
3778 if (bo->getDepth()==0) return false;
3784 QString ("%1 ()").arg(u),
3786 QString ("%1 ()").arg(r),
3787 QString ("%1 %2").arg(r).arg(getName(bo))
3797 bool MapEditor::unscrollBranch(BranchObj *bo)
3801 if (!bo->isScrolled()) return false;
3802 if (bo->countBranches()==0) return false;
3803 if (bo->getDepth()==0) return false;
3809 QString ("%1 ()").arg(u),
3811 QString ("%1 ()").arg(r),
3812 QString ("%1 %2").arg(r).arg(getName(bo))
3822 void MapEditor::toggleScroll()
3824 BranchObj *bo=xelection.getBranch();
3825 if (xelection.type()==Selection::Branch )
3827 if (bo->isScrolled())
3828 unscrollBranch (bo);
3834 void MapEditor::unscrollChilds()
3836 BranchObj *bo=xelection.getBranch();
3842 if (bo->isScrolled()) unscrollBranch (bo);
3848 FloatImageObj* MapEditor::loadFloatImageInt (QString fn)
3850 BranchObj *bo=xelection.getBranch();
3854 bo->addFloatImage();
3855 fio=bo->getLastFloatImage();
3857 model->reposition();
3864 void MapEditor::loadFloatImage ()
3866 BranchObj *bo=xelection.getBranch();
3870 Q3FileDialog *fd=new Q3FileDialog( this);
3871 fd->setMode (Q3FileDialog::ExistingFiles);
3872 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
3873 ImagePreview *p =new ImagePreview (fd);
3874 fd->setContentsPreviewEnabled( TRUE );
3875 fd->setContentsPreview( p, p );
3876 fd->setPreviewMode( Q3FileDialog::Contents );
3877 fd->setCaption(vymName+" - " +tr("Load image"));
3878 fd->setDir (lastImageDir);
3881 if ( fd->exec() == QDialog::Accepted )
3883 // TODO loadFIO in QT4 use: lastImageDir=fd->directory();
3884 lastImageDir=QDir (fd->dirPath());
3887 for (int j=0; j<fd->selectedFiles().count(); j++)
3889 s=fd->selectedFiles().at(j);
3890 fio=loadFloatImageInt (s);
3893 (LinkableMapObj*)fio,
3896 QString ("loadImage (%1)").arg(s ),
3897 QString("Add image %1 to %2").arg(s).arg(getName(bo))
3900 // TODO loadFIO error handling
3901 qWarning ("Failed to load "+s);
3909 void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn)
3911 fio->save (fn,type);
3914 void MapEditor::saveFloatImage ()
3916 FloatImageObj *fio=xelection.getFloatImage();
3919 QFileDialog *fd=new QFileDialog( this);
3920 fd->setFilters (imageIO.getFilters());
3921 fd->setCaption(vymName+" - " +tr("Save image"));
3922 fd->setFileMode( QFileDialog::AnyFile );
3923 fd->setDirectory (lastImageDir);
3924 // fd->setSelection (fio->getOriginalFilename());
3928 if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1)
3930 fn=fd->selectedFiles().at(0);
3931 if (QFile (fn).exists() )
3933 QMessageBox mb( vymName,
3934 tr("The file %1 exists already.\n"
3935 "Do you want to overwrite it?").arg(fn),
3936 QMessageBox::Warning,
3937 QMessageBox::Yes | QMessageBox::Default,
3938 QMessageBox::Cancel | QMessageBox::Escape,
3939 QMessageBox::QMessageBox::NoButton );
3941 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
3942 mb.setButtonText( QMessageBox::No, tr("Cancel"));
3945 case QMessageBox::Yes:
3948 case QMessageBox::Cancel:
3955 saveFloatImageInt (fio,fd->selectedFilter(),fn );
3961 void MapEditor::setFrameType(const FrameObj::FrameType &t)
3963 BranchObj *bo=xelection.getBranch();
3966 QString s=bo->getFrameTypeName();
3967 bo->setFrameType (t);
3968 saveState (bo, QString("setFrameType (\"%1\")").arg(s),
3969 bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s));
3970 model->reposition();
3975 void MapEditor::setFrameType(const QString &s)
3977 BranchObj *bo=xelection.getBranch();
3980 saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),
3981 bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s));
3982 bo->setFrameType (s);
3983 model->reposition();
3988 void MapEditor::setFramePenColor(const QColor &c)
3990 BranchObj *bo=xelection.getBranch();
3993 saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ),
3994 bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() ));
3995 bo->setFramePenColor (c);
3999 void MapEditor::setFrameBrushColor(const QColor &c)
4001 BranchObj *bo=xelection.getBranch();
4004 saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ),
4005 bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() ));
4006 bo->setFrameBrushColor (c);
4010 void MapEditor::setFramePadding (const int &i)
4012 BranchObj *bo=xelection.getBranch();
4015 saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ),
4016 bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i));
4017 bo->setFramePadding (i);
4018 model->reposition();
4023 void MapEditor::setFrameBorderWidth(const int &i)
4025 BranchObj *bo=xelection.getBranch();
4028 saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ),
4029 bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i));
4030 bo->setFrameBorderWidth (i);
4031 model->reposition();
4036 void MapEditor::setIncludeImagesVer(bool b)
4038 BranchObj *bo=xelection.getBranch();
4041 QString u= b ? "false" : "true";
4042 QString r=!b ? "false" : "true";
4046 QString("setIncludeImagesVertically (%1)").arg(u),
4048 QString("setIncludeImagesVertically (%1)").arg(r),
4049 QString("Include images vertically in %1").arg(getName(bo))
4051 bo->setIncludeImagesVer(b);
4052 model->reposition();
4056 void MapEditor::setIncludeImagesHor(bool b)
4058 BranchObj *bo=xelection.getBranch();
4061 QString u= b ? "false" : "true";
4062 QString r=!b ? "false" : "true";
4066 QString("setIncludeImagesHorizontally (%1)").arg(u),
4068 QString("setIncludeImagesHorizontally (%1)").arg(r),
4069 QString("Include images horizontally in %1").arg(getName(bo))
4071 bo->setIncludeImagesHor(b);
4072 model->reposition();
4076 void MapEditor::setHideLinkUnselected (bool b)
4078 LinkableMapObj *sel=xelection.single();
4080 (xelection.type() == Selection::Branch ||
4081 xelection.type() == Selection::MapCenter ||
4082 xelection.type() == Selection::FloatImage ))
4084 QString u= b ? "false" : "true";
4085 QString r=!b ? "false" : "true";
4089 QString("setHideLinkUnselected (%1)").arg(u),
4091 QString("setHideLinkUnselected (%1)").arg(r),
4092 QString("Hide link of %1 if unselected").arg(getName(sel))
4094 sel->setHideLinkUnselected(b);
4098 void MapEditor::importDirInt(BranchObj *dst, QDir d)
4100 BranchObj *bo=xelection.getBranch();
4103 // Traverse directories
4104 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
4105 QFileInfoList list = d.entryInfoList();
4108 for (int i = 0; i < list.size(); ++i)
4111 if (fi.fileName() != "." && fi.fileName() != ".." )
4114 bo=dst->getLastBranch();
4115 bo->setHeading (fi.fileName() );
4116 bo->setColor (QColor("blue"));
4118 if ( !d.cd(fi.fileName()) )
4119 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
4122 // Recursively add subdirs
4123 importDirInt (bo,d);
4129 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
4130 list = d.entryInfoList();
4132 for (int i = 0; i < list.size(); ++i)
4136 bo=dst->getLastBranch();
4137 bo->setHeading (fi.fileName() );
4138 bo->setColor (QColor("black"));
4139 if (fi.fileName().right(4) == ".vym" )
4140 bo->setVymLink (fi.filePath());
4145 void MapEditor::importDirInt (const QString &s)
4147 BranchObj *bo=xelection.getBranch();
4150 saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s));
4153 importDirInt (bo,d);
4157 void MapEditor::importDir()
4159 BranchObj *bo=xelection.getBranch();
4162 QStringList filters;
4163 filters <<"VYM map (*.vym)";
4164 QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import"));
4165 fd->setMode (QFileDialog::DirectoryOnly);
4166 fd->setFilters (filters);
4167 fd->setCaption(vymName+" - " +tr("Choose directory structure to import"));
4171 if ( fd->exec() == QDialog::Accepted )
4173 importDirInt (fd->selectedFile() );
4174 model->reposition();
4180 void MapEditor::followXLink(int i)
4182 BranchObj *bo=xelection.getBranch();
4185 bo=bo->XLinkTargetAt(i);
4188 xelection.select(bo);
4189 ensureSelectionVisible();
4194 void MapEditor::editXLink(int i) // FIXME missing saveState
4196 BranchObj *bo=xelection.getBranch();
4199 XLinkObj *xlo=bo->XLinkAt(i);
4202 EditXLinkDialog dia;
4204 dia.setSelection(bo);
4205 if (dia.exec() == QDialog::Accepted)
4207 if (dia.useSettingsGlobal() )
4209 setMapDefXLinkColor (xlo->getColor() );
4210 setMapDefXLinkWidth (xlo->getWidth() );
4212 if (dia.deleteXLink())
4213 bo->deleteXLinkAt(i);
4219 AttributeTable* MapEditor::attributeTable()
4224 void MapEditor::testFunction1()
4227 BranchObj *bo=xelection.getBranch();
4228 if (bo) animObjList.append( bo );
4231 /* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere
4232 if (hidemode==HideNone)
4234 setHideTmpMode (HideExport);
4235 mapCenter->calcBBoxSizeWithChilds();
4236 QRectF totalBBox=mapCenter->getTotalBBox();
4237 QRectF mapRect=totalBBox;
4238 QCanvasRectangle *frame=NULL;
4240 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
4242 mapRect.setRect (totalBBox.x(), totalBBox.y(),
4243 totalBBox.width(), totalBBox.height());
4244 frame=new QCanvasRectangle (mapRect,mapScene);
4245 frame->setBrush (QColor(white));
4246 frame->setPen (QColor(black));
4247 frame->setZValue(0);
4252 setHideTmpMode (HideNone);
4254 cout <<" hidemode="<<hidemode<<endl;
4258 void MapEditor::testFunction2()
4261 cout << "Selection: "<<xelection.getSelectString().ascii()<<endl;
4262 // model->addMapCenter();
4266 if (hidemode==HideExport)
4267 setHideTmpMode (HideNone);
4269 setHideTmpMode (HideExport);
4272 LinkableMapObj *lmo=xelection.getBranch();
4275 cout << "LMO::id="<<lmo->getID().ascii()<<endl;
4276 cout << " BO::id="<<((BranchObj*)lmo)->getID().ascii()<<endl;
4281 void MapEditor::contextMenuEvent ( QContextMenuEvent * e )
4283 // Lineedits are already closed by preceding
4284 // mouseEvent, we don't need to close here.
4286 QPointF p = mapToScene(e->pos());
4287 LinkableMapObj* lmo=model->findMapObj(p, NULL);
4290 { // MapObj was found
4291 if (xelection.single() != lmo)
4293 // select the MapObj
4294 xelection.select(lmo);
4297 if (xelection.getBranch() )
4299 // Context Menu on branch or mapcenter
4301 branchContextMenu->popup(e->globalPos() );
4304 if (xelection.getFloatImage() )
4306 // Context Menu on floatimage
4308 floatimageContextMenu->popup(e->globalPos() );
4312 { // No MapObj found, we are on the Canvas itself
4313 // Context Menu on scene
4315 canvasContextMenu->popup(e->globalPos() );
4320 void MapEditor::keyPressEvent(QKeyEvent* e)
4322 if (e->modifiers() & Qt::ControlModifier)
4324 switch (mainWindow->getModMode())
4326 case Main::ModModeColor:
4327 setCursor (PickColorCursor);
4329 case Main::ModModeCopy:
4330 setCursor (CopyCursor);
4332 case Main::ModModeXLink:
4333 setCursor (XLinkCursor);
4336 setCursor (Qt::ArrowCursor);
4342 void MapEditor::keyReleaseEvent(QKeyEvent* e)
4344 if (!(e->modifiers() & Qt::ControlModifier))
4345 setCursor (Qt::ArrowCursor);
4348 void MapEditor::mousePressEvent(QMouseEvent* e)
4350 // Ignore right clicks, these will go to context menus
4351 if (e->button() == Qt::RightButton )
4357 //Ignore clicks while editing heading
4358 if (isSelectBlocked() )
4364 QPointF p = mapToScene(e->pos());
4365 LinkableMapObj* lmo=model->findMapObj(p, NULL);
4369 //Take care of system flags _or_ modifier modes
4371 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
4372 typeid(*lmo)==typeid(MapCenterObj) ))
4374 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
4375 if (!foname.isEmpty())
4377 // systemFlag clicked
4381 if (e->state() & Qt::ControlModifier)
4382 mainWindow->editOpenURLTab();
4384 mainWindow->editOpenURL();
4386 else if (foname=="vymLink")
4388 mainWindow->editOpenVymLink();
4389 // tabWidget may change, better return now
4390 // before segfaulting...
4391 } else if (foname=="note")
4392 mainWindow->windowToggleNoteEditor();
4393 else if (foname=="hideInExport")
4400 // No system flag clicked, take care of modmodes (CTRL-Click)
4401 if (e->state() & Qt::ControlModifier)
4403 if (mainWindow->getModMode()==Main::ModModeColor)
4406 setCursor (PickColorCursor);
4409 if (mainWindow->getModMode()==Main::ModModeXLink)
4411 BranchObj *bo_begin=NULL;
4413 bo_begin=(BranchObj*)(lmo);
4415 if (xelection.getBranch() )
4416 bo_begin=xelection.getBranch();
4420 linkingObj_src=bo_begin;
4421 tmpXLink=new XLinkObj (mapScene);
4422 tmpXLink->setBegin (bo_begin);
4423 tmpXLink->setEnd (p);
4424 tmpXLink->setColor(defXLinkColor);
4425 tmpXLink->setWidth(defXLinkWidth);
4426 tmpXLink->updateXLink();
4427 tmpXLink->setVisibility (true);
4431 } // End of modmodes
4435 // Select the clicked object
4438 // Left Button Move Branches
4439 if (e->button() == Qt::LeftButton )
4441 //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here
4442 //movingObj_start.setY( p.y() - selection->y() );
4443 movingObj_start.setX( p.x() - lmo->x() );
4444 movingObj_start.setY( p.y() - lmo->y() );
4445 movingObj_orgPos.setX (lmo->x() );
4446 movingObj_orgPos.setY (lmo->y() );
4447 movingObj_orgRelPos=lmo->getRelPos();
4449 // If modMode==copy, then we want to "move" the _new_ object around
4450 // then we need the offset from p to the _old_ selection, because of tmp
4451 if (mainWindow->getModMode()==Main::ModModeCopy &&
4452 e->state() & Qt::ControlModifier)
4454 BranchObj *bo=xelection.getBranch();
4458 bo->addBranch ((BranchObj*)xelection.single());
4460 xelection.select(bo->getLastBranch());
4461 model->reposition();
4465 movingObj=xelection.single();
4467 // Middle Button Toggle Scroll
4468 // (On Mac OS X this won't work, but we still have
4469 // a button in the toolbar)
4470 if (e->button() == Qt::MidButton )
4475 { // No MapObj found, we are on the scene itself
4476 // Left Button move Pos of sceneView
4477 if (e->button() == Qt::LeftButton )
4479 movingObj=NULL; // move Content not Obj
4480 movingObj_start=e->globalPos();
4481 movingCont_start=QPointF (
4482 horizontalScrollBar()->value(),
4483 verticalScrollBar()->value());
4484 movingVec=QPointF(0,0);
4485 setCursor(HandOpenCursor);
4490 void MapEditor::mouseMoveEvent(QMouseEvent* e)
4492 QPointF p = mapToScene(e->pos());
4493 LinkableMapObj *lmosel=xelection.single();
4495 // Move the selected MapObj
4496 if ( lmosel && movingObj)
4498 // reset cursor if we are moving and don't copy
4499 if (mainWindow->getModMode()!=Main::ModModeCopy)
4500 setCursor (Qt::ArrowCursor);
4502 // To avoid jumping of the sceneView, only
4503 // ensureSelectionVisible, if not tmp linked
4504 if (!lmosel->hasParObjTmp())
4505 ensureSelectionVisible ();
4507 // Now move the selection, but add relative position
4508 // (movingObj_start) where selection was chosen with
4509 // mousepointer. (This avoids flickering resp. jumping
4510 // of selection back to absPos)
4512 // Check if we could link
4513 LinkableMapObj* lmo=model->findMapObj(p, lmosel);
4516 FloatObj *fio=xelection.getFloatImage();
4519 fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4521 fio->updateLink(); //no need for reposition, if we update link here
4524 // Relink float to new mapcenter or branch, if shift is pressed
4525 // Only relink, if selection really has a new parent
4526 if ( (e->modifiers()==Qt::ShiftModifier) && lmo &&
4527 ( (typeid(*lmo)==typeid(BranchObj)) ||
4528 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
4529 ( lmo != fio->getParObj())
4532 if (typeid(*fio) == typeid(FloatImageObj) &&
4533 ( (typeid(*lmo)==typeid(BranchObj) ||
4534 typeid(*lmo)==typeid(MapCenterObj)) ))
4537 // Also save the move which was done so far
4538 QString pold=qpointfToString(movingObj_orgRelPos);
4539 QString pnow=qpointfToString(fio->getRelPos());
4545 QString("Move %1 to relative position %2").arg(getName(fio)).arg(pnow));
4546 fio->getParObj()->requestReposition();
4547 model->reposition();
4549 linkTo (lmo->getSelectString());
4551 //movingObj_orgRelPos=lmosel->getRelPos();
4553 model->reposition();
4557 { // selection != a FloatObj
4558 if (lmosel->getDepth()==0)
4561 if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
4562 ((MapCenterObj*)lmosel)->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4564 lmosel->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4565 model->updateRelPositions();
4568 if (lmosel->getDepth()==1)
4571 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
4572 lmosel->setRelPos();
4575 // Move ordinary branch
4576 if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter)
4577 // Add width of bbox here, otherwise alignRelTo will cause jumping around
4578 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
4579 p.y()-movingObj_start.y() +lmosel->getTopPad() );
4581 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
4584 // Maybe we can relink temporary?
4585 if (lmo && (lmo!=lmosel) && xelection.getBranch() &&
4586 (typeid(*lmo)==typeid(BranchObj) ||
4587 typeid(*lmo)==typeid(MapCenterObj)) )
4590 if (e->modifiers()==Qt::ControlModifier)
4592 // Special case: CTRL to link below lmo
4593 lmosel->setParObjTmp (lmo,p,+1);
4595 else if (e->modifiers()==Qt::ShiftModifier)
4596 lmosel->setParObjTmp (lmo,p,-1);
4598 lmosel->setParObjTmp (lmo,p,0);
4601 lmosel->unsetParObjTmp();
4603 // reposition subbranch
4604 lmosel->reposition();
4608 } // no FloatImageObj
4612 } // selection && moving_obj
4614 // Draw a link from one branch to another
4617 tmpXLink->setEnd (p);
4618 tmpXLink->updateXLink();
4622 if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton )
4624 QPointF p=e->globalPos();
4625 movingVec.setX(-p.x() + movingObj_start.x() );
4626 movingVec.setY(-p.y() + movingObj_start.y() );
4627 horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() ));
4628 verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) );
4633 void MapEditor::mouseReleaseEvent(QMouseEvent* e)
4635 QPointF p = mapToScene(e->pos());
4636 LinkableMapObj *dst;
4637 LinkableMapObj *lmosel=xelection.single();
4638 // Have we been picking color?
4642 setCursor (Qt::ArrowCursor);
4643 // Check if we are over another branch
4644 dst=model->findMapObj(p, NULL);
4647 if (e->state() & Qt::ShiftModifier)
4648 colorBranch (((BranchObj*)dst)->getColor());
4650 colorSubtree (((BranchObj*)dst)->getColor());
4655 // Have we been drawing a link?
4659 // Check if we are over another branch
4660 dst=model->findMapObj(p, NULL);
4663 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
4664 tmpXLink->updateXLink();
4665 tmpXLink->activate(); //FIXME savestate missing
4666 //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) );
4675 // Have we been moving something?
4676 if ( lmosel && movingObj )
4678 FloatImageObj *fo=xelection.getFloatImage();
4681 // Moved FloatObj. Maybe we need to reposition
4682 QString pold=qpointfToString(movingObj_orgRelPos);
4683 QString pnow=qpointfToString(fo->getRelPos());
4689 QString("Move %1 to relative position %2").arg(getName(fo)).arg(pnow));
4691 fo->getParObj()->requestReposition();
4692 model->reposition();
4695 // Check if we are over another branch, but ignore
4696 // any found LMOs, which are FloatObjs
4697 dst=model->findMapObj(mapToScene(e->pos() ), lmosel);
4699 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
4702 BranchObj *bo=xelection.getBranch();
4703 if (bo && bo->getDepth()==0)
4705 if (movingObj_orgPos != bo->getAbsPos())
4707 QString pold=qpointfToString(movingObj_orgPos);
4708 QString pnow=qpointfToString(bo->getAbsPos());
4714 QString("Move mapcenter %1 to position %2").arg(getName(bo)).arg(pnow));
4718 if (xelection.type() == Selection::Branch )
4719 { // A branch was moved
4721 // save the position in case we link to mapcenter
4722 QPointF savePos=QPointF (lmosel->getAbsPos() );
4724 // Reset the temporary drawn link to the original one
4725 lmosel->unsetParObjTmp();
4727 // For Redo we may need to save original selection
4728 QString preSelStr=lmosel->getSelectString();
4733 BranchObj* bsel=xelection.getBranch();
4734 BranchObj* bdst=(BranchObj*)dst;
4736 QString preParStr=(bsel->getParObj())->getSelectString();
4737 QString preNum=QString::number (bsel->getNum(),10);
4738 QString preDstParStr;
4740 if (e->state() & Qt::ShiftModifier && dst->getParObj())
4742 preDstParStr=dst->getParObj()->getSelectString();
4743 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum());
4745 if (e->state() & Qt::ControlModifier && dst->getParObj())
4748 preDstParStr=dst->getParObj()->getSelectString();
4749 bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1);
4752 preDstParStr=dst->getSelectString();
4753 bsel->linkTo (bdst,-1);
4754 if (dst->getDepth()==0) bsel->move (savePos);
4756 QString postSelStr=lmosel->getSelectString();
4757 QString postNum=QString::number (bsel->getNum(),10);
4759 QString undoCom="linkTo (\""+
4760 preParStr+ "\"," + preNum +"," +
4761 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")";
4763 QString redoCom="linkTo (\""+
4764 preDstParStr + "\"," + postNum + "," +
4765 QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")";
4770 QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) );
4772 if (lmosel->getDepth()==1)
4774 // The select string might be different _after_ moving around.
4775 // Therefor reposition and then use string of old selection, too
4776 model->reposition();
4778 QPointF rp(lmosel->getRelPos());
4779 if (rp != movingObj_orgRelPos)
4781 QString ps=qpointfToString(rp);
4783 lmosel->getSelectString(), "moveRel "+qpointfToString(movingObj_orgRelPos),
4784 preSelStr, "moveRel "+ps,
4785 QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps));
4788 // Draw the original link, before selection was moved around
4789 model->reposition();
4792 // Finally resize scene, if needed
4796 // Just make sure, that actions are still ok,e.g. the move branch up/down buttons...
4799 // maybe we moved View: set old cursor
4800 setCursor (Qt::ArrowCursor);
4804 void MapEditor::mouseDoubleClickEvent(QMouseEvent* e)
4806 if (isSelectBlocked() )
4812 if (e->button() == Qt::LeftButton )
4814 QPointF p = mapToScene(e->pos());
4815 LinkableMapObj *lmo=model->findMapObj(p, NULL);
4816 if (lmo) { // MapObj was found
4817 // First select the MapObj than edit heading
4818 xelection.select(lmo);
4819 mainWindow->editHeading();
4824 void MapEditor::resizeEvent (QResizeEvent* e)
4826 QGraphicsView::resizeEvent( e );
4829 void MapEditor::dragEnterEvent(QDragEnterEvent *event)
4831 //for (unsigned int i=0;event->format(i);i++) // Debug mime type
4832 // cerr << event->format(i) << endl;
4834 if (event->mimeData()->hasImage())
4835 event->acceptProposedAction();
4837 if (event->mimeData()->hasUrls())
4838 event->acceptProposedAction();
4841 void MapEditor::dragMoveEvent(QDragMoveEvent *)
4845 void MapEditor::dragLeaveEvent(QDragLeaveEvent *event)
4850 void MapEditor::dropEvent(QDropEvent *event)
4852 BranchObj *sel=xelection.getBranch();
4856 foreach (QString format,event->mimeData()->formats())
4857 cout << "MapEditor: Dropped format: "<<format.ascii()<<endl;
4861 if (event->mimeData()->hasImage())
4863 QVariant imageData = event->mimeData()->imageData();
4864 addFloatImageInt (qvariant_cast<QPixmap>(imageData));
4866 if (event->mimeData()->hasUrls())
4867 uris=event->mimeData()->urls();
4875 for (int i=0; i<uris.count();i++)
4877 // Workaround to avoid adding empty branches
4878 if (!uris.at(i).toString().isEmpty())
4880 bo=sel->addBranch();
4883 s=uris.at(i).toLocalFile();
4886 QString file = QDir::fromNativeSeparators(s);
4887 heading = QFileInfo(file).baseName();
4889 if (file.endsWith(".vym", false))
4890 bo->setVymLink(file);
4892 bo->setURL(uris.at(i).toString());
4895 bo->setURL(uris.at(i).toString());
4898 if (!heading.isEmpty())
4899 bo->setHeading(heading);
4901 bo->setHeading(uris.at(i).toString());
4905 model->reposition();
4908 event->acceptProposedAction();
4911 void MapEditor::timerEvent(QTimerEvent *event) //TODO animation
4915 cout << "ME::timerEvent\n";
4917 for (int i=0; i<animObjList.size(); ++i)
4919 animObjList.at(i)->animate();
4920 ((BranchObj*)animObjList.at(i))->move2RelPos (((BranchObj*)animObjList.at(i))->getRelPos() );
4922 model->reposition();
4926 void MapEditor::sendSelection()
4928 if (netstate!=Server) return;
4929 sendData (QString("select (\"%1\")").arg(xelection.getSelectString()) );
4932 void MapEditor::newServer()
4936 tcpServer = new QTcpServer(this);
4937 if (!tcpServer->listen(QHostAddress::Any,port)) {
4938 QMessageBox::critical(this, "vym server",
4939 QString("Unable to start the server: %1.").arg(tcpServer->errorString()));
4943 connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient()));
4945 cout<<"Server is running on port "<<tcpServer->serverPort()<<endl;
4948 void MapEditor::connectToServer()
4951 server="salam.suse.de";
4953 clientSocket = new QTcpSocket (this);
4954 clientSocket->abort();
4955 clientSocket->connectToHost(server ,port);
4956 connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData()));
4957 connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)),
4958 this, SLOT(displayNetworkError(QAbstractSocket::SocketError)));
4960 cout<<"connected to "<<server.ascii()<<" port "<<port<<endl;
4965 void MapEditor::newClient()
4967 QTcpSocket *newClient = tcpServer->nextPendingConnection();
4968 connect(newClient, SIGNAL(disconnected()),
4969 newClient, SLOT(deleteLater()));
4971 cout <<"ME::newClient at "<<newClient->peerAddress().toString().ascii()<<endl;
4973 clientList.append (newClient);
4977 void MapEditor::sendData(const QString &s)
4979 if (clientList.size()==0) return;
4981 // Create bytearray to send
4983 QDataStream out(&block, QIODevice::WriteOnly);
4984 out.setVersion(QDataStream::Qt_4_0);
4986 // Reserve some space for blocksize
4989 // Write sendCounter
4990 out << sendCounter++;
4995 // Go back and write blocksize so far
4996 out.device()->seek(0);
4997 quint16 bs=(quint16)(block.size() - 2*sizeof(quint16));
5001 cout << "ME::sendData bs="<<bs<<" counter="<<sendCounter<<" s="<<s.ascii()<<endl;
5003 for (int i=0; i<clientList.size(); ++i)
5005 //cout << "Sending \""<<s.ascii()<<"\" to "<<clientList.at(i)->peerAddress().toString().ascii()<<endl;
5006 clientList.at(i)->write (block);
5010 void MapEditor::readData ()
5012 while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) )
5015 cout <<"readData bytesAvail="<<clientSocket->bytesAvailable();
5019 QDataStream in(clientSocket);
5020 in.setVersion(QDataStream::Qt_4_0);
5028 cout << " t="<<t.ascii()<<endl;
5034 void MapEditor::displayNetworkError(QAbstractSocket::SocketError socketError)
5036 switch (socketError) {
5037 case QAbstractSocket::RemoteHostClosedError:
5039 case QAbstractSocket::HostNotFoundError:
5040 QMessageBox::information(this, vymName +" Network client",
5041 "The host was not found. Please check the "
5042 "host name and port settings.");
5044 case QAbstractSocket::ConnectionRefusedError:
5045 QMessageBox::information(this, vymName + " Network client",
5046 "The connection was refused by the peer. "
5047 "Make sure the fortune server is running, "
5048 "and check that the host name and port "
5049 "settings are correct.");
5052 QMessageBox::information(this, vymName + " Network client",
5053 QString("The following error occurred: %1.")
5054 .arg(clientSocket->errorString()));
5058 void MapEditor::autosave()
5060 // Disable autosave, while we have gone back in history
5061 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
5062 if (redosAvail>0) return;
5065 if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() )
5066 mainWindow->fileSave (this);
5070 /*TODO not needed? void MapEditor::contentsDropEvent(QDropEvent *event)
5073 } else if (event->provides("application/x-moz-file-promise-url") &&
5074 event->provides("application/x-moz-nativeimage"))
5076 // Contains url to the img src in unicode16
5077 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
5078 QString url = QString((const QChar*)d.data(),d.size()/2);
5082 } else if (event->provides ("text/uri-list"))
5083 { // Uris provided e.g. by konqueror
5084 Q3UriDrag::decode (event,uris);
5085 } else if (event->provides ("_NETSCAPE_URL"))
5086 { // Uris provided by Mozilla
5087 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
5090 } else if (event->provides("text/html")) {
5092 // Handels text mime types
5093 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
5094 QByteArray d = event->encodedData("text/html");
5097 text = QString((const QChar*)d.data(),d.size()/2);
5101 textEditor->setText(text);
5105 } else if (event->provides("text/plain")) {
5106 QByteArray d = event->encodedData("text/plain");
5109 text = QString((const QChar*)d.data(),d.size()/2);
5113 textEditor->setText(text);
5123 bool isUnicode16(const QByteArray &d)
5125 // TODO: make more precise check for unicode 16.
5126 // Guess unicode16 if any of second bytes are zero
5127 unsigned int length = max(0,d.size()-2)/2;
5128 for (unsigned int i = 0; i<length ; i++)
5129 if (d.at(i*2+1)==0) return true;
5133 void MapEditor::addFloatImageInt (const QPixmap &img)
5135 BranchObj *bo=xelection.getBranch();
5138 FloatImageObj *fio=bo->addFloatImage();
5140 fio->setOriginalFilename("No original filename (image added by dropevent)");
5141 QString s=bo->getSelectString();
5142 saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio );
5143 saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image");
5144 model->reposition();
5151 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /)
5153 if (!imageBuffer) imageBuffer = new QBuffer();
5154 if (!imageBuffer->isOpen()) {
5155 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
5157 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
5161 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
5163 if (nop->state()==Q3NetworkProtocol::StDone) {
5164 QPixmap img(imageBuffer->buffer());
5165 addFloatImageInt (img);
5169 imageBuffer->close();
5171 imageBuffer->close();
5178 void MapEditor::fetchImage(const QString &url)
5181 urlOperator->stop();
5182 disconnect(urlOperator);
5186 urlOperator = new Q3UrlOperator(url);
5187 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
5188 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
5190 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
5191 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));