Runs basically on Mac now. Undo debug output still enabled
3 #include <qstatusbar.h>
5 #include <qapplication.h>
7 #include <q3popupmenu.h>
9 #include <q3paintdevicemetrics.h>
11 #include <q3filedialog.h>
14 #include <QColorDialog>
16 #include <qinputdialog.h>
17 #include <q3dragobject.h>
18 #include <q3urloperator.h>
19 #include <q3networkprotocol.h>
22 #include <QResizeEvent>
23 #include <QContextMenuEvent>
26 #include <QMouseEvent>
27 #include <QDragEnterEvent>
28 #include <QTextStream>
30 #include <QActionGroup>
40 #include "editxlinkdialog.h"
42 #include "extrainfodialog.h"
44 #include "linkablemapobj.h"
45 #include "mainwindow.h"
47 #include "texteditor.h"
48 #include "warningdialog.h"
52 extern TextEditor *textEditor;
53 extern int statusbarTime;
54 extern Main *mainWindow;
55 extern QString tmpVymDir;
56 extern QString clipboardDir;
57 extern bool clipboardEmpty;
58 extern FlagRowObj *systemFlagsDefault;
59 extern FlagRowObj *standardFlagsDefault;
61 extern Q3PtrList <QAction> actionListBranches;
63 extern QAction *actionFileSave;
64 extern QAction *actionEditUndo;
65 extern QAction *actionEditRedo;
66 extern QAction *actionEditCopy;
67 extern QAction *actionEditCut;
68 extern QAction *actionEditPaste;
69 extern QAction *actionEditMoveUp;
70 extern QAction *actionEditMoveDown;
71 extern QAction *actionEditToggleScroll;
72 extern QAction *actionEditOpenURL;
73 extern QAction *actionEditOpenURLTab;
74 extern QAction *actionEditURL;
75 extern QAction *actionEditHeading2URL;
76 extern QAction *actionEditBugzilla2URL;
77 extern QAction *actionEditFATE2URL;
78 extern QAction *actionEditOpenVymLink;
79 extern QAction *actionEditVymLink;
80 extern QAction *actionEditDeleteVymLink;
81 extern QAction *actionEditToggleHideExport;
82 extern QAction *actionEditHeading;
83 extern QAction *actionEditDelete;
84 extern QAction *actionEditAddBranch;
85 extern QAction *actionEditAddBranchAbove;
86 extern QAction *actionEditAddBranchBelow;
87 extern QAction *actionEditRemoveBranchHere;
88 extern QAction *actionEditRemoveChilds;
89 extern QAction *actionEditImportAdd;
90 extern QAction *actionEditImportReplace;
91 extern QAction *actionEditSaveBranch;
92 extern QAction *actionEditSelectFirst;
93 extern QAction *actionEditSelectLast;
94 extern QAction *actionEditLoadImage;
96 extern QAction* actionFormatPickColor;
97 extern QAction* actionFormatColorBranch;
98 extern QAction* actionFormatColorSubtree;
99 extern QAction *actionFormatLinkColorHint;
100 extern QAction *actionFormatBackColor;
101 extern QAction *actionFormatLinkColor;
103 extern QActionGroup* actionGroupModModes;
104 extern QAction* actionModModeColor;
105 extern QAction* actionModModeLink;
106 extern QAction* actionModModeCopy;
108 extern QActionGroup *actionGroupFormatFrameTypes;
109 extern QAction *actionFormatFrameNone;
110 extern QAction *actionFormatFrameRectangle;
112 extern QActionGroup *actionGroupFormatLinkStyles;
113 extern QAction *actionFormatIncludeImagesVer;
114 extern QAction *actionFormatIncludeImagesHor;
115 extern QAction *actionFormatHideLinkUnselected;
116 extern QAction *actionFormatLinkStyleLine;
117 extern QAction *actionFormatLinkStyleParabel;
118 extern QAction *actionFormatLinkStylePolyLine;
119 extern QAction *actionFormatLinkStylePolyParabel;
121 extern QAction *actionViewToggleNoteEditor;
123 extern QAction *actionSettingsAutoedit;
124 extern QAction *actionSettingsAutoselectHeading;
125 extern QAction *actionSettingsAutoselectText;
126 extern QAction *actionSettingsPasteNewHeading;
127 extern QAction *actionSettingsUseFlagGroups;
129 extern QMenu* branchContextMenu;
130 extern QMenu* branchAddContextMenu;
131 extern QMenu* branchRemoveContextMenu;
132 extern QMenu* branchLinksContextMenuEdit;
133 extern QMenu* branchLinksContextMenuFollow;
134 extern QMenu* floatimageContextMenu;
135 extern QMenu* saveImageFormatMenu;
136 extern QMenu* canvasContextMenu;
137 extern QMenu* lastMapsMenu;
138 extern QMenu* importMenu;
139 extern QMenu* exportMenu;
142 extern Settings settings;
143 extern ImageIO imageIO;
145 extern QString iconPath;
146 extern QDir vymBaseDir;
147 extern QDir lastImageDir;
149 int MapEditor::mapNum=0; // make instance
151 ///////////////////////////////////////////////////////////////////////
152 ///////////////////////////////////////////////////////////////////////
153 MapEditor::MapEditor(
154 QWidget* parent, bool interactive, const char* name, Qt::WFlags f) :
155 Q3CanvasView(parent,name,f), urlOperator(0), imageBuffer(0)
157 //cout << "Constructor ME "<<this<<endl;
160 viewport()->setAcceptDrops(true);
162 mapCanvas = new Q3Canvas(width(),height());
163 mapCanvas->setAdvancePeriod(30);
164 mapCanvas->setBackgroundColor (Qt::white);
166 setCanvas (mapCanvas);
168 // Always show scroll bars (automatic would flicker sometimes)
169 setVScrollBarMode ( Q3ScrollView::AlwaysOn );
170 setHScrollBarMode ( Q3ScrollView::AlwaysOn );
172 mapCenter = new MapCenterObj(mapCanvas);
173 mapCenter->setVisibility (true);
174 mapCenter->setMapEditor (this);
175 mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map"));
176 mapCenter->move(mapCanvas->width()/2-mapCenter->width()/2,mapCanvas->height()/2-mapCenter->height()/2);
180 actColor=Qt::black; setColor (actColor);
181 defLinkColor=QColor (0,0,255);
182 defXLinkColor=QColor (180,180,180);
183 linkcolorhint=DefaultColor;
184 linkstyle=StylePolyParabel;
186 // Create bitmap cursors, patform dependant
187 #if defined(Q_OS_MACX)
188 handOpenCursor=QCursor ( QPixmap(iconPath+"cursorhandopen16.png") );
189 // set hot spot to tip of picker
190 pickColorCursor=QCursor ( QPixmap (iconPath+"cursorcolorpicker16.png"), 1,15 );
192 handOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen16.png"));
193 // set hot spot to tip of picker
194 pickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 );
206 xelection.setMapCenter (mapCenter);
209 defXLinkColor=QColor (230,230,230);
217 fileName=tr("unnamed");
220 undosTotal=settings.readNumEntry("/mapeditor/undoLevels",50);
222 // Initialize find routine
229 blockReposition=false;
230 blockSaveState=false;
234 isInteractive=interactive;
236 // Create temporary files
239 // Initially set movingCentre
242 // For testing purposes create history window
243 historyWindow = new ShowTextDialog (this);
244 historyWindow->setCaption (fileName);
246 mapCenter->reposition(); // for positioning heading
251 MapEditor::~MapEditor()
253 if (imageBuffer) delete imageBuffer;
259 //cout <<"Destructor MapEditor\n";
262 //settings.writeEntry( "/mapeditor/editmode/autoselect", );
266 QColor MapEditor::color()
271 QColor MapEditor::backgroundColor()
273 return mapCanvas->backgroundColor();
276 MapCenterObj* MapEditor::getMapCenter()
281 Q3Canvas* MapEditor::getCanvas()
286 void MapEditor::adjustCanvasSize()
288 // To adjust the canvas to map, viewport size and position, we have to
289 // do some coordinate magic...
291 // Get rectangle of (scroll-)view.
292 // We want to be in canvas coords, so
293 // we map. Important if view is zoomed...
294 QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(),
295 visibleWidth(), visibleHeight()) );
297 // Now we need the bounding box of view AND map to calc the correct canvas size.
298 // Why? Because if the map itself is moved out of view, the view has to be enlarged
299 // to avoid jumping aroung...
300 QRect map=mapCenter->getTotalBBox();
302 // right edge - left edge
303 int cw= max(map.x() + map.width(), view.x() + view.width()) - min(map.x(), view.x());
304 int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y());
307 if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) ||
308 !mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight())
311 // move the map on canvas (in order to not move it on screen) this is neccessary
312 // a) if topleft corner of canvas is left or above topleft corner of view and also left of
313 // above topleft corner of map. E.g. if map is completly inside view, but it would be possible
314 // to scroll to an empty area of canvas to the left.
315 // b) if topleft corner of map left of or above topleft of canvas
319 if (cw > mapCanvas->width() )
321 if (map.x()<0) dx=-map.x();
323 if (cw < mapCanvas->width() )
324 dx=-min (view.x(),map.x());
325 if (ch > mapCanvas->height() )
327 if (map.y()<0) dy=-map.y();
329 if (ch < mapCanvas->height() )
331 dy=-min (view.y(),map.y());
333 // We really have to resize now. Let's go...
334 mapCanvas->resize (cw,ch);
335 if ( (dx!=0) || (dy!=0) )
337 mapCenter->moveAllBy(dx,dy);
338 mapCenter->reposition();
339 // mapCenter->positionBBox(); // To move float
341 // scroll the view (in order to not move map on screen)
347 bool MapEditor::isRepositionBlocked()
349 return blockReposition;
352 QString MapEditor::getName (LinkableMapObj *lmo)
355 if (!lmo) return QString("Error: NULL has no name!");
357 if ((typeid(*lmo) == typeid(BranchObj) ||
358 typeid(*lmo) == typeid(MapCenterObj)))
361 s=(((BranchObj*)lmo)->getHeading());
362 if (s=="") s="unnamed";
363 return QString("branch (<font color=\"#0000ff\">%1</font>)").arg(s);
365 if ((typeid(*lmo) == typeid(FloatImageObj) ))
366 return QString ("floatimage [<font color=\"#0000ff\">%1</font>]").arg(((FloatImageObj*)lmo)->getOriginalFilename());
367 return QString("Unknown type has no name!");
370 void MapEditor::makeTmpDirs()
372 // Create unique temporary directories
373 tmpMapDir=QDir::convertSeparators (tmpVymDir+QString("/mapeditor-%1").arg(mapNum));
374 histPath=QDir::convertSeparators (tmpMapDir+"/history");
376 d.mkdir (tmpMapDir,true);
379 QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, LinkableMapObj *saveSelection)
381 // tmpdir temporary directory to which data will be written
382 // prefix mapname, which will be appended to images etc.
383 // writeflags Only write flags for "real" save of map, not undo
384 // offset offset of bbox of whole map in canvas.
385 // Needed for XML export
401 ls="StylePolyParabel";
405 QString s="<?xml version=\"1.0\" encoding=\"utf-8\"?><!DOCTYPE vymmap>\n";
407 if (linkcolorhint==HeadingColor)
408 colhint=attribut("linkColorHint","HeadingColor");
410 QString mapAttr=attribut("version",__VYM_VERSION);
412 mapAttr+= attribut("author",mapCenter->getAuthor()) +
413 attribut("comment",mapCenter->getComment()) +
414 attribut("date",mapCenter->getDate()) +
415 attribut("backgroundColor", mapCanvas->backgroundColor().name() ) +
416 attribut("linkStyle", ls ) +
417 attribut("linkColor", defLinkColor.name() ) +
418 attribut("defXLinkColor", defXLinkColor.name() ) +
419 attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) +
421 s+=beginElement("vymmap",mapAttr);
424 // Find the used flags while traversing the tree
425 standardFlagsDefault->resetUsedCounter();
427 // Reset the counters before saving
428 FloatImageObj (mapCanvas).resetSaveCounter();
430 // Build xml recursivly
432 s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset);
435 if ( typeid(*saveSelection) == typeid(BranchObj) )
436 s+=((BranchObj*)(saveSelection))->saveToDir(tmpdir,prefix,offset);
437 else if ( typeid(*saveSelection) == typeid(FloatImageObj) )
438 s+=((FloatImageObj*)(saveSelection))->saveToDir(tmpdir,prefix,offset);
440 else if (selection && typeid(*selection)==typeid(BranchObj))
441 // This is used if selected branch is saved from mainwindow
442 s+=((BranchObj*)selection)->saveToDir(tmpdir,prefix,offset);
445 // Save local settings
446 s+=settings.getXMLData (destPath);
449 if (selection && !saveSelection )
450 s+=valueElement("select",selection->getSelectString());
453 s+=endElement("vymmap");
456 standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags);
460 void MapEditor::saveStateComplete(const QString &comment)
463 saveState (CompleteMap,"",NULL,"",NULL, comment);
466 void MapEditor::saveStatePart(LinkableMapObj *undoSel, const QString &comment)
468 // save the selected part of the map
469 saveState (PartOfMap,"",undoSel,"",NULL, comment);
472 void MapEditor::saveStateConstSelection(const QString &uc, const QString &rc, const QString &comment)
474 // selection does not change during action,
475 // so just save commands for undo and redo
476 // and use current selection
477 saveState (UndoCommand,uc,selection,rc,selection, comment);
480 void MapEditor::saveStateX(LinkableMapObj *unsel, const QString &uncom, const QString &comment)
483 saveState (UndoCommand,uncom,unsel,"FIXME-redoCom",NULL, comment);
486 void MapEditor::saveState(const SaveMode &savemode, const QString &undoCom, LinkableMapObj *undoSel, const QString &redoCom, LinkableMapObj *redoSel, const QString &comment)
490 if (blockSaveState) return;
492 /* TODO remove after testing
494 cout << "ME::saveState() begin\n"<<endl;
495 cout << " undosTotal="<<undosTotal<<endl;
496 cout << " ---------------------------"<<endl;
498 historyWindow->append (comment);
502 int undosAvail=undoSet.readNumEntry ("/history/undosAvail",0);
503 int curStep=undoSet.readNumEntry ("/history/curStep",0);
504 // Find out current undo directory
505 if (undosAvail<undosTotal) undosAvail++;
507 if (curStep>undosTotal) curStep=1;
510 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
511 QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml");
513 // Create bakMapDir if not available
516 makeSubDirs (bakMapDir);
518 // Save current selection
519 QString redoSelection="";
521 redoSelection=redoSel->getSelectString();
523 // Save the object, which should be undone
524 QString undoSelection="";
526 undoSelection=undoSel->getSelectString();
528 // Save depending on how much needs to be saved
529 QString undoCommand="";
530 if (savemode==UndoCommand)
535 else if (savemode==PartOfMap && undoSel)
537 undoCommand="undoPart (\""+ undoSelection+"\",\""+bakMapPath+"\")";
538 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),undoSel);
541 undoCommand="undoMap (\""+bakMapPath+"\")";
542 backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),NULL);
545 if (!backupXML.isEmpty())
546 // Write XML Data to disk
547 saveStringToDisk (QString(bakMapPath),backupXML);
549 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
550 undoSet.setEntry ("/history/curStep",QString::number(curStep));
551 undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand);
552 undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection);
553 undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom);
554 undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection);
555 undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment);
556 undoSet.writeSettings(histPath);
558 /* TODO remove after testing
560 cout << " into="<< histPath.toStdString()<<endl;
561 cout << " undosAvail="<<undosAvail<<endl;
562 cout << " curStep="<<curStep<<endl;
563 cout << " ---------------------------"<<endl;
564 cout << " comment="<<comment.toStdString()<<endl;
565 cout << " undoCom="<<undoCommand.toStdString()<<endl;
566 cout << " undoSel="<<undoSelection.toStdString()<<endl;
567 cout << " redoCom="<<redoCom.toStdString()<<endl;
568 cout << " redoSel="<<redoSelection.toStdString()<<endl;
569 cout << " ---------------------------"<<endl<<endl;
572 void MapEditor::parseAtom(const QString &atom)
579 // Split string s into command and parameters
580 api.parseCommand (atom);
581 QString com=api.command();
584 if (com=="moveBranchUp")
586 else if (com=="moveBranchDown")
588 else if (com=="move")
590 if (api.checkParamCount(2) && selection )
600 else if (com=="delete")
602 if (api.checkParamCount(1) && selection )
604 s=api.parString(ok,0);
607 if (select (s)) deleteSelection();
611 else if (com=="linkBranchToPos")
613 if (selection && typeid(*selection) == typeid(BranchObj) )
615 if (api.checkParamCount(4))
617 s=api.parString(ok,0);
618 LinkableMapObj *dst=mapCenter->findObjBySelect (s);
621 if (typeid(*dst) == typeid(BranchObj) )
623 // Get number in parent
626 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),x);
627 } else if (typeid(*dst) == typeid(MapCenterObj) )
629 ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),-1);
630 // Get coordinates of mainbranch
635 if (ok) ((BranchObj*)selection)->move (x,y);
641 } else if (com=="setHeading")
643 if (api.checkParamCount(1))
645 s=api.parString (ok,0);
649 } else if (com=="setURL")
651 if (api.checkParamCount(1))
653 s=api.parString (ok,0);
654 if (ok) setURLInt(s);
656 } else if (com=="setVymLink")
658 if (api.checkParamCount(1))
660 s=api.parString (ok,0);
661 if (ok) setVymLinkInt(s);
664 else if (com=="setFlag")
666 if (selection && typeid(*selection) == typeid(BranchObj) )
668 if (api.checkParamCount(1) )
670 s=api.parString(ok,0);
671 if (ok) ((BranchObj*)selection)->activateStandardFlag(s);
675 else if (com=="unsetFlag")
677 if (selection && typeid(*selection) == typeid(BranchObj) )
679 if (api.checkParamCount(1) )
681 s=api.parString(ok,0);
682 if (ok) ((BranchObj*)selection)->deactivateStandardFlag(s);
686 // Internal commands, used for undo etc.
687 else if (com==QString("undoMap"))
689 if (api.checkParamCount(1))
690 undoXML("",api.parString (ok,0));
691 } else if (com==QString("undoPart"))
693 if (api.checkParamCount(2))
695 s=api.parString (ok,0);
696 t=api.parString (ok,1);
699 } else if (com=="select")
700 if (api.checkParamCount(1))
702 s=api.parString(ok,0);
707 api.setError ("Unknown command in: "+atom);
708 cout << "ME::parse api should have error now...\n";
714 qWarning("MapEditor::parseAtom: Error!");
715 qWarning(api.errorDesc());
719 void MapEditor::toggleHistoryWindow()
721 if (historyWindow->isVisible())
722 historyWindow->hide();
724 historyWindow->show();
728 bool MapEditor::isDefault()
733 bool MapEditor::isUnsaved()
738 bool MapEditor::hasChanged()
743 void MapEditor::setChanged()
748 actionEditUndo->setEnabled (true);
749 actionFileSave->setEnabled (true);
753 void MapEditor::closeMap()
755 // Unselect before disabling the toolbar actions
756 if (selection) selection->unselect();
764 void MapEditor::setFilePath(QString fname)
766 setFilePath (fname,fname);
769 void MapEditor::setFilePath(QString fname, QString destname)
771 if (fname.isEmpty() || fname=="")
778 filePath=fname; // becomes absolute path
779 fileName=fname; // gets stripped of path
780 destPath=destname; // needed for vymlinks
782 // If fname is not an absolute path, complete it
783 filePath=QDir(fname).absPath();
784 fileDir=filePath.left (1+filePath.findRev ("/"));
786 // Set short name, too. Search from behind:
787 int i=fileName.findRev("/");
788 if (i>=0) fileName=fileName.remove (0,i+1);
790 // Forget the .vym (or .xml) for name of map
791 mapName=fileName.left(fileName.findRev(".",-1,true) );
793 // Adjust history window
794 historyWindow->setCaption (fileName);
798 QString MapEditor::getFilePath()
803 QString MapEditor::getFileName()
808 QString MapEditor::getMapName()
813 QString MapEditor::getDestPath()
818 ErrorCode MapEditor::load (QString fname, LoadMode lmode)
820 ErrorCode err=success;
824 if (selection) selection->unselect();
827 mapCenter->setMapEditor(this);
828 // (map state is set later at end of load...)
831 saveStatePart(selection,"Load map");
835 mapBuilderHandler handler;
838 // I am paranoid: file should exist anyway
839 // according to check in mainwindow.
842 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
843 tr("Couldn't open map " +fname)+".");
847 blockReposition=true;
848 QXmlInputSource source( file);
849 QXmlSimpleReader reader;
850 reader.setContentHandler( &handler );
851 reader.setErrorHandler( &handler );
852 handler.setMapEditor( this );
853 handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path
854 handler.setInputFile (file.name());
855 handler.setLoadMode (lmode);
857 bool ok = reader.parse( source );
858 blockReposition=false;
859 blockSaveState=false;
863 mapCenter->reposition();
873 QMessageBox::critical( 0, tr( "Critical Parse Error" ),
874 tr( handler.errorProtocol() ) );
876 // Still return "success": the map maybe at least
877 // partially read by the parser
884 int MapEditor::save (const SaveMode &savemode)
888 // The SaveMode UndoCommand is not supported here
889 if (savemode==UndoCommand) return 1;
891 // Create mapName and fileDir
892 makeSubDirs (fileDir);
896 fname=mapName+".xml";
898 // use name given by user, even if he chooses .doc
903 if (savemode==CompleteMap || selection==NULL)
904 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),NULL);
906 saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),selection);
908 if (!saveStringToDisk(fileDir+fname,saveFile))
915 actionFileSave->setEnabled(false);
921 void MapEditor::setZipped (bool z)
926 bool MapEditor::saveZipped ()
931 void MapEditor::print()
935 printer = new QPrinter;
936 printer->setColorMode (QPrinter::Color);
937 printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString());
940 QRect totalBBox=mapCenter->getTotalBBox();
942 // Try to set orientation automagically
943 // Note: Interpretation of generated postscript is amibiguous, if
944 // there are problems with landscape mode, see
945 // http://sdb.suse.de/de/sdb/html/jsmeix_print-cups-landscape-81.html
947 if (totalBBox.width()>totalBBox.height())
948 // recommend landscape
949 printer->setOrientation (QPrinter::Landscape);
951 // recommend portrait
952 printer->setOrientation (QPrinter::Portrait);
954 if ( printer->setup(this) )
955 // returns false, if printing is canceled
957 QPainter pp(printer);
959 // Don't print the visualisation of selection
960 LinkableMapObj *oldselection=NULL;
963 oldselection=selection;
964 selection->unselect();
967 // Handle sizes of map and paper:
969 // setWindow defines which part of the canvas will be transformed
970 // setViewport defines area on paper in device coordinates (dpi)
971 // e.g. (0,50,700,700) is upper part on A4
972 // see also /usr/lib/qt3/doc/html/coordsys.html
974 Q3PaintDeviceMetrics metrics (printer);
976 double paperAspect = (double)metrics.width() / (double)metrics.height();
977 double mapAspect = (double)totalBBox.width() / (double)totalBBox.height();
979 QRect mapRect=totalBBox;
980 Q3CanvasRectangle *frame=NULL;
981 Q3CanvasText *footerFN=NULL;
982 Q3CanvasText *footerDate=NULL;
983 if (printFrame || printFooter)
988 // Print frame around map
989 mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10,
990 totalBBox.width()+20, totalBBox.height()+20);
991 frame=new Q3CanvasRectangle (mapRect,mapCanvas);
992 frame->setBrush (QColor(Qt::white));
993 frame->setPen (QColor(Qt::black));
997 /* TODO remove after testing
998 QCanvasLine *l=new QCanvasLine (mapCanvas);
999 l->setPoints (0,0,mapRect.width(),mapRect.height());
1000 l->setPen (QPen(QColor(black), 1));
1007 // Print footer below map
1009 font.setPointSize(10);
1010 footerFN=new Q3CanvasText (mapCanvas);
1011 footerFN->setText ("VYM - " + fileName);
1012 footerFN->setFont(font);
1013 footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() );
1014 footerFN->setZ(Z_TEXT);
1016 footerDate=new Q3CanvasText (mapCanvas);
1017 footerDate->setText (QDate::currentDate().toString(Qt::TextDate));
1018 footerDate->setFont(font);
1019 footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() );
1020 footerDate->setZ(Z_TEXT);
1023 pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()+20);
1026 pp.setWindow (mapRect);
1029 if (mapAspect>=paperAspect)
1031 // Fit horizontally to paper width
1032 pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) );
1035 // Fit vertically to paper height
1036 pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height());
1039 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to printer
1041 // Delete Frame and footer
1045 delete (footerDate);
1047 if (frame) delete (frame);
1049 // Restore selection
1052 selection=oldselection;
1053 selection->select();
1056 // Save settings in vymrc
1057 settings.writeEntry("/mainwindow/printerName",printer->printerName());
1061 QPixmap MapEditor::getPixmap()
1063 QRect mapRect=mapCenter->getTotalBBox();
1064 QPixmap pix (mapRect.size());
1067 // Don't print the visualisation of selection
1068 LinkableMapObj *oldselection=NULL;
1071 oldselection=selection;
1072 selection->unselect();
1075 pp.setWindow (mapRect);
1077 mapCanvas->drawArea(mapRect, &pp); // draw Canvas to painter
1080 // Restore selection
1083 selection=oldselection;
1084 selection->select();
1090 void MapEditor::setHideTmpMode (HideTmpMode mode)
1093 mapCenter->setHideTmp (hidemode);
1094 mapCenter->reposition();
1099 HideTmpMode MapEditor::getHideTmpMode()
1104 void MapEditor::exportImage(QString fn)
1106 setExportMode (true);
1107 QPixmap pix (getPixmap());
1108 pix.save(fn, "PNG");
1109 setExportMode (false);
1112 void MapEditor::setExportMode (bool b)
1114 // should be called before and after exports
1115 // depending on the settings
1116 if (b && settings.value("/export/useHideExport","yes")=="yes")
1117 setHideTmpMode (HideExport);
1119 setHideTmpMode (HideNone);
1122 void MapEditor::exportImage(QString fn, QString format)
1124 setExportMode (true);
1125 QPixmap pix (getPixmap());
1126 pix.save(fn, format);
1127 setExportMode (false);
1130 void MapEditor::exportOOPresentation(const QString &fn, const QString &cf)
1134 ex.setMapCenter(mapCenter);
1135 if (ex.setConfigFile(cf))
1137 setExportMode (true);
1138 ex.exportPresentation();
1139 setExportMode (false);
1145 void MapEditor::exportXML(const QString &dir)
1147 // Hide stuff during export, if settings want this
1148 setExportMode (true);
1150 // Create subdirectories
1153 // write to directory
1154 QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,NULL);
1157 file.setName ( dir + "/"+mapName+".xml");
1158 if ( !file.open( QIODevice::WriteOnly ) )
1160 // This should neverever happen
1161 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1165 // Write it finally, and write in UTF8, no matter what
1166 QTextStream ts( &file );
1167 ts.setEncoding (QTextStream::UnicodeUTF8);
1171 // Now write image, too
1172 exportImage (dir+"/images/"+mapName+".png");
1174 setExportMode (false);
1177 void MapEditor::clear()
1181 selection->unselect();
1188 void MapEditor::copy()
1192 // write to directory
1193 QString clipfile="part";
1194 QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPoint(),selection);
1197 file.setName ( clipboardDir + "/"+clipfile+".xml");
1198 if ( !file.open( QIODevice::WriteOnly ) )
1200 // This should neverever happen
1201 QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name()));
1205 // Write it finally, and write in UTF8, no matter what
1206 QTextStream ts( &file );
1207 ts.setEncoding (QTextStream::UnicodeUTF8);
1211 clipboardEmpty=false;
1216 void MapEditor::redo()
1218 blockSaveState=true;
1220 // Restore variables
1221 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1222 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1223 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1224 if (redosAvail>0) redosAvail--;
1225 if (undosAvail<undosTotal) undosAvail++;
1227 if (curStep>undosTotal) curStep=1;
1228 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1229 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1230 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1231 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1232 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1234 // Find out current undo directory
1235 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1237 /* TODO remove testing
1239 cout << "ME::redo() begin\n";
1240 cout << " undosAvail="<<undosAvail<<endl;
1241 cout << " redosAvail="<<redosAvail<<endl;
1242 cout << " curStep="<<curStep<<endl;
1243 cout << " ---------------------------"<<endl;
1244 cout << " comment="<<comment.toStdString()<<endl;
1245 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1246 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1247 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1248 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1249 cout << " ---------------------------"<<endl<<endl;
1251 // select object before redo
1252 // FIXME better give up if no selection there...
1253 if (!redoSelection.isEmpty())
1254 select (redoSelection);
1257 parseAtom (redoCommand);
1258 mapCenter->reposition();
1260 //if (!redoSelection.isEmpty())
1261 // select (redoSelection);
1263 blockSaveState=false;
1264 /* TODO remove testing
1266 cout << "ME::redo() end\n";
1267 cout << " undosAvail="<<undosAvail<<endl;
1268 cout << " redosAvail="<<redosAvail<<endl;
1269 cout << " curStep="<<curStep<<endl;
1270 cout << " ---------------------------"<<endl<<endl;
1273 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1274 undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail));
1275 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1276 undoSet.writeSettings(histPath);
1281 void MapEditor::undo()
1283 blockSaveState=true;
1285 // Restore variables
1286 int curStep=undoSet.readNumEntry (QString("/history/curStep"));
1287 int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail"));
1288 int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail"));
1289 QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep));
1290 QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep));
1291 QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep));
1292 QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep));
1293 QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep));
1295 // Find out current undo directory
1296 QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(curStep));
1298 // select object before undo
1299 if (!undoSelection.isEmpty())
1300 select (undoSelection);
1304 cout << "ME::undo() begin\n";
1305 cout << " undosAvail="<<undosAvail<<endl;
1306 cout << " redosAvail="<<redosAvail<<endl;
1307 cout << " curStep="<<curStep<<endl;
1308 cout << " ---------------------------"<<endl;
1309 cout << " comment="<<comment.toStdString()<<endl;
1310 cout << " undoCom="<<undoCommand.toStdString()<<endl;
1311 cout << " undoSel="<<undoSelection.toStdString()<<endl;
1312 cout << " redoCom="<<redoCommand.toStdString()<<endl;
1313 cout << " redoSel="<<redoSelection.toStdString()<<endl;
1314 cout << " ---------------------------"<<endl<<endl;
1315 parseAtom (undoCommand);
1316 mapCenter->reposition();
1318 //if (!redoSelection.isEmpty())
1319 // select (redoSelection);
1324 // Undo not longer available now
1325 actionEditUndo->setEnabled (false);
1327 curStep--; if (curStep<1) curStep=undosTotal;
1331 blockSaveState=false;
1332 /* TODO remove testing
1334 cout << "ME::undo() end\n";
1335 cout << " undosAvail="<<undosAvail<<endl;
1336 cout << " redosAvail="<<redosAvail<<endl;
1337 cout << " curStep="<<curStep<<endl;
1338 cout << " ---------------------------"<<endl<<endl;
1340 undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail));
1341 undoSet.setEntry ("/history/redosAvail",QString::number(undosAvail));
1342 undoSet.setEntry ("/history/curStep",QString::number(curStep));
1343 undoSet.writeSettings(histPath);
1348 void MapEditor::undoXML(const QString &undoSel, const QString &bakMapPath)
1350 QString bakMapDir=bakMapPath.left(bakMapPath.findRev("/"));
1352 QFile file (bakMapPath);
1356 // We need to parse saved XML data
1357 mapBuilderHandler handler;
1358 QXmlInputSource source( file);
1359 QXmlSimpleReader reader;
1360 reader.setContentHandler( &handler );
1361 reader.setErrorHandler( &handler );
1362 handler.setMapEditor( this );
1363 handler.setTmpDir ( bakMapDir ); // needed to load files with rel. path
1364 if (undoSel.isEmpty())
1368 handler.setLoadMode (NewMap);
1372 handler.setLoadMode (ImportReplace);
1374 blockReposition=true;
1375 bool ok = reader.parse( source );
1376 blockReposition=false;
1379 // This should never ever happen
1380 QMessageBox::critical( 0, tr( "Critical Parse Error by reading backupFile" ),
1381 tr( handler.errorProtocol() )+" in "+bakMapDir );
1385 QMessageBox::critical( 0, tr( "Critical Error" ),
1386 tr("Temporary directory %1 used for undo is gone. \n"
1387 "I will create a new one, but at the moment no undo is available.\n"
1388 "Maybe you want to reload your original data.\n\n"
1389 "Sorry for any inconveniences.").arg(bakMapDir) );
1394 void MapEditor::pasteNoSave()
1396 load (clipboardDir+"/part.xml",ImportAdd);
1399 void MapEditor::cutNoSave()
1405 void MapEditor::paste()
1407 if (selection && (typeid(*selection) == typeid(BranchObj) ||
1408 typeid(*selection) == typeid(MapCenterObj)))
1410 saveStatePart(selection,QString("Paste to %1").arg( getName(selection)));
1412 mapCenter->reposition();
1417 void MapEditor::cut()
1419 saveStatePart(selection->getParObj(),QString("Cut %1").arg(getName(selection)));
1422 mapCenter->reposition();
1426 void MapEditor::move(const int &x, const int &y)
1428 // TODO no saveState, because this is only internal at undo so far
1429 if (selection) selection->move(x,y);
1430 if (typeid(*selection) == typeid(FloatImageObj))
1431 ((FloatImageObj*)selection)->setRelPos();
1434 void MapEditor::moveBranchUp()
1438 if (typeid(*selection) == typeid(BranchObj) )
1440 bo=(BranchObj*)selection;
1441 if (!bo->canMoveBranchUp()) return;
1442 par=(BranchObj*)(bo->getParObj());
1443 selection->unselect();
1444 selection=par->moveBranchUp (bo);
1445 selection->select();
1446 saveStateX(bo,"moveBranchDown ()",QString("Move up %1").arg(getName(bo)));
1447 mapCenter->reposition();
1448 ensureSelectionVisible();
1452 void MapEditor::moveBranchDown()
1456 if (typeid(*selection) == typeid(BranchObj) )
1458 bo=(BranchObj*)selection;
1459 if (!bo->canMoveBranchDown()) return;
1460 par=(BranchObj*)(bo->getParObj());
1461 selection->unselect();
1462 selection=par->moveBranchDown(bo);
1463 selection->select();
1464 saveStateX(bo,"moveBranchUp ()",QString("Move down %1").arg(getName(bo)));
1465 mapCenter->reposition();
1466 ensureSelectionVisible();
1470 void MapEditor::editHeading()
1472 /* FIXME not needed any longer
1474 (typeid(*selection) == typeid(BranchObj) ||
1475 typeid(*selection) == typeid(MapCenterObj) ) )
1477 editingBO=(BranchObj*)selection;
1478 ensureSelectionVisible();
1479 QPoint p = worldMatrix().map(QPoint (editingBO->x(),editingBO->y()));
1481 QDialog *d =new QDialog(NULL);
1482 QLineEdit *le=new QLineEdit (d);
1483 d->setWindowFlags (Qt::FramelessWindowHint);
1484 QPoint q=mapToGlobal (QPoint(0,0));
1485 d->setGeometry(p.x()+q.x(),p.y()+q.y(),200,25);
1486 le->resize (d->size());
1487 le->setText (editingBO->getHeading());
1489 connect (le, SIGNAL (returnPressed()), d, SLOT (accept()));
1490 d->activateWindow();
1493 saveStateConstSelection(
1494 "setHeading (\""+editingBO->getHeading()+"\")",
1495 "setHeading (\""+le->text()+"\")",
1496 QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(le->text()) );
1497 editingBO->setHeading(le->text() );
1499 mapCenter->reposition();
1501 ensureSelectionVisible();
1507 QString MapEditor::getHeading(bool &ok, QPoint &p)
1510 (typeid(*selection) == typeid(BranchObj) ||
1511 typeid(*selection) == typeid(MapCenterObj) ) )
1514 ensureSelectionVisible();
1515 p = ((BranchObj*)selection)->getAbsPos();
1516 p.setY(p.y()+((BranchObj*)selection)->height()/2);
1517 // p = mapTo(mainWindow,worldMatrix().map( p));
1518 return ((BranchObj*)selection)->getHeading();
1524 void MapEditor::setHeading(const QString &s)
1526 // Internal function, no saveState needed
1528 (typeid(*selection) == typeid(BranchObj) ||
1529 typeid(*selection) == typeid(MapCenterObj) ) )
1531 editingBO=(BranchObj*)selection;
1532 saveStateConstSelection(
1533 "setHeading (\""+editingBO->getHeading()+"\")",
1534 "setHeading (\""+s+"\")",
1535 QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(s) );
1536 editingBO->setHeading(s );
1538 mapCenter->reposition();
1540 ensureSelectionVisible();
1544 void MapEditor::setURLInt (const QString &s)
1546 // Internal function, no saveState needed
1548 (typeid(*selection) == typeid(BranchObj) ||
1549 typeid(*selection) == typeid(MapCenterObj) ) )
1551 ((BranchObj*)selection)->setURL(s);
1552 mapCenter->reposition();
1554 ensureSelectionVisible();
1558 void MapEditor::setHeadingInt(const QString &s)
1561 (typeid(*selection) == typeid(BranchObj) ||
1562 typeid(*selection) == typeid(MapCenterObj) ) )
1564 ((BranchObj*)selection)->setHeading(s);
1565 mapCenter->reposition();
1567 ensureSelectionVisible();
1571 void MapEditor::setVymLinkInt (const QString &s)
1573 // Internal function, no saveState needed
1575 (typeid(*selection) == typeid(BranchObj) ||
1576 typeid(*selection) == typeid(MapCenterObj) ) )
1578 ((BranchObj*)selection)->setVymLink(s);
1579 mapCenter->reposition();
1581 ensureSelectionVisible();
1585 void MapEditor::addNewBranch(int pos)
1588 (typeid(*selection) == typeid(BranchObj) ||
1589 typeid(*selection) == typeid(MapCenterObj) ) )
1591 BranchObj* bo1 = (BranchObj*) selection;
1593 bool wasScrolled=false;
1594 BranchObj *newbo=NULL;
1597 // save scroll state. If scrolled, automatically select
1598 // new branch in order to tmp unscroll parent...
1599 wasScrolled=bo1->isScrolled();
1600 newbo=bo1->addBranch();
1603 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1607 // add above selection
1608 newbo=parbo->insertBranch(bo1->getNum());
1610 // add below selection
1611 newbo=parbo->insertBranch(bo1->getNum()+1);
1613 // This should not happen...
1614 // ...but it happens if CTRL-A is pressed on MCO,
1618 saveStateX(selection,QString ("delete (\"%1\")").arg(newbo->getSelectString()),QString("Add new branch to %1").arg(getName(bo1))); //TODO undoCommand
1620 LinkableMapObj *oldselection=selection;
1622 mapCenter->reposition();
1626 if (actionSettingsAutoedit->isOn() ||
1627 actionSettingsAutoselectHeading->isOn() )
1629 selection->unselect();
1631 selection->select();
1632 if (actionSettingsPasteNewHeading->isOn() )
1634 BranchObj *bo2= (BranchObj*)selection;
1635 bo2->setHeading("");
1637 if (actionSettingsAutoedit->isOn() )
1638 mainWindow->editHeading();
1639 if (!actionSettingsAutoselectHeading->isOn()
1642 selection->unselect();
1643 selection=oldselection;
1644 selection->select();
1651 void MapEditor::addNewBranchHere()
1654 (typeid(*selection) == typeid(BranchObj) ) )
1656 BranchObj* bo1 = (BranchObj*) selection;
1657 saveStatePart(selection, QString("Add new branch here").arg(getName(bo1)));
1659 bool wasScrolled=false;
1660 BranchObj *newbo=NULL;
1661 BranchObj *parbo=(BranchObj*)(selection->getParObj());
1664 // add below selection
1665 newbo=parbo->insertBranch(bo1->getNum()+1);
1668 LinkableMapObj *oldselection=selection;
1669 ((BranchObj*)selection)->moveBranchTo (newbo,-1);
1671 mapCenter->reposition();
1673 if (actionSettingsAutoedit->isOn() ||
1674 actionSettingsAutoselectHeading->isOn() )
1676 selection->unselect();
1678 selection->select();
1679 if (actionSettingsPasteNewHeading->isOn() )
1681 BranchObj *bo2= (BranchObj*)selection;
1682 bo2->setHeading("");
1684 if (actionSettingsAutoedit->isOn() )
1686 if (!actionSettingsAutoselectHeading->isOn()
1689 selection->unselect();
1690 selection=oldselection;
1691 selection->select();
1697 void MapEditor::deleteSelection()
1699 if (selection && typeid(*selection) ==typeid(BranchObj) )
1701 BranchObj* bo=dynamic_cast <BranchObj*> (selection);
1702 BranchObj* par=(BranchObj*)(bo->getParObj());
1704 if (selection->getDepth()>1)
1705 // Normal branch, save parent with childs
1706 saveStatePart(par,QString("Delete %1").arg(getName(bo)));
1708 // Mainbranch, save whole map
1709 // TODO Better would be to insert mainbranch again at pos
1710 // But undoCommand is missing right now
1711 saveStateComplete(QString("Delete %1").arg(getName(bo)));
1713 par->removeBranch(bo);
1715 selection->select();
1716 ensureSelectionVisible();
1717 mapCenter->reposition();
1720 if (selection && typeid(*selection) ==typeid(FloatImageObj) )
1722 FloatImageObj* fio=dynamic_cast <FloatImageObj*> (selection);
1723 BranchObj* par=(BranchObj*)(fio->getParObj());
1724 saveStatePart(par, QString("Delete %1").arg(getName(fio)));
1727 par->removeFloatImage(fio);
1729 selection->select();
1730 ensureSelectionVisible();
1731 mapCenter->reposition();
1736 LinkableMapObj* MapEditor::getSelection()
1741 void MapEditor::unselect()
1745 selectionLast=selection;
1746 selection->unselect();
1751 void MapEditor::reselect()
1755 selection=selectionLast;
1756 selection->select();
1761 bool MapEditor::select (const QString &s)
1763 LinkableMapObj *lmo=mapCenter->findObjBySelect(s);
1765 // Finally select the found object
1768 if (selection) unselect();
1770 selection->select();
1772 ensureSelectionVisible();
1778 void MapEditor::selectInt (LinkableMapObj *lmo)
1780 if (lmo && selection != lmo)
1782 // select the MapObj
1783 if (selection) selection->unselect();
1785 selection->select();
1792 void MapEditor::selectNextBranchInt()
1794 // Increase number of branch
1797 QString s=selection->getSelectString();
1803 part=s.section(",",-1);
1805 num=part.right(part.length() - 3);
1807 s=s.left (s.length() -num.length());
1810 num=QString ("%1").arg(num.toUInt()+1);
1814 // Try to select this one
1815 if (select (s)) return;
1817 // We have no direct successor,
1818 // try to increase the parental number in order to
1819 // find a successor with same depth
1821 int d=selection->getDepth();
1826 while (!found && d>0)
1828 s=s.section (",",0,d-1);
1829 // replace substring of current depth in s with "1"
1830 part=s.section(",",-1);
1832 num=part.right(part.length() - 3);
1836 // increase number of parent
1837 num=QString ("%1").arg(num.toUInt()+1);
1838 s=s.section (",",0,d-2) + ","+ typ+num;
1841 // Special case, look at orientation
1842 if (selection->getOrientation()==OrientRightOfCenter)
1843 num=QString ("%1").arg(num.toUInt()+1);
1845 num=QString ("%1").arg(num.toUInt()-1);
1850 // pad to oldDepth, select the first branch for each depth
1851 for (i=d;i<oldDepth;i++)
1856 if ( ((BranchObj*)selection)->countBranches()>0)
1864 // try to select the freshly built string
1872 void MapEditor::selectPrevBranchInt()
1874 // Decrease number of branch
1877 QString s=selection->getSelectString();
1883 part=s.section(",",-1);
1885 num=part.right(part.length() - 3);
1887 s=s.left (s.length() -num.length());
1890 num=QString ("%1").arg(num.toUInt()-1);
1894 // Try to select this one
1895 if (select (s)) return;
1897 // We have no direct precessor,
1898 // try to decrease the parental number in order to
1899 // find a precessor with same depth
1901 int d=selection->getDepth();
1906 while (!found && d>0)
1908 s=s.section (",",0,d-1);
1909 // replace substring of current depth in s with "1"
1910 part=s.section(",",-1);
1912 num=part.right(part.length() - 3);
1916 // decrease number of parent
1917 num=QString ("%1").arg(num.toUInt()-1);
1918 s=s.section (",",0,d-2) + ","+ typ+num;
1921 // Special case, look at orientation
1922 if (selection->getOrientation()==OrientRightOfCenter)
1923 num=QString ("%1").arg(num.toUInt()-1);
1925 num=QString ("%1").arg(num.toUInt()+1);
1930 // pad to oldDepth, select the last branch for each depth
1931 for (i=d;i<oldDepth;i++)
1935 if ( ((BranchObj*)selection)->countBranches()>0)
1936 s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 );
1943 // try to select the freshly built string
1951 void MapEditor::selectUpperBranch()
1955 if (typeid(*selection) == typeid(BranchObj))
1957 if (selection->getOrientation()==OrientRightOfCenter)
1958 selectPrevBranchInt();
1960 if (selection->getDepth()==1)
1961 selectNextBranchInt();
1963 selectPrevBranchInt();
1968 void MapEditor::selectLowerBranch()
1972 if (typeid(*selection) == typeid(BranchObj))
1974 if (selection->getOrientation()==OrientRightOfCenter)
1975 selectNextBranchInt();
1977 if (selection->getDepth()==1)
1978 selectPrevBranchInt();
1980 selectNextBranchInt();
1986 void MapEditor::selectLeftBranch()
1992 if (typeid(*selection) == typeid(MapCenterObj))
1994 par= (BranchObj*) selection;
1995 bo=par->getLastSelectedBranch();
1998 // Workaround for reselecting on left and right side
1999 if (bo->getOrientation()==OrientRightOfCenter)
2001 bo=par->getLastBranch();
2007 selection->select();
2009 ensureSelectionVisible();
2014 par=(BranchObj*)(selection->getParObj());
2015 if (selection->getOrientation()==OrientRightOfCenter)
2017 if (typeid(*selection) == typeid(BranchObj) ||
2018 typeid(*selection) == typeid(FloatImageObj))
2020 selection->unselect();
2022 selection->select();
2024 ensureSelectionVisible();
2028 if (typeid(*selection) == typeid(BranchObj) )
2030 bo=((BranchObj*)selection)->getLastSelectedBranch();
2033 selection->unselect();
2035 selection->select();
2037 ensureSelectionVisible();
2045 void MapEditor::selectRightBranch()
2052 if (typeid(*selection) == typeid(MapCenterObj))
2054 par= (BranchObj*) selection;
2055 bo=par->getLastSelectedBranch();
2058 // Workaround for reselecting on left and right side
2059 if (bo->getOrientation()==OrientLeftOfCenter)
2060 bo=par->getFirstBranch();
2065 selection->select();
2066 ensureSelectionVisible();
2071 par=(BranchObj*)(selection->getParObj());
2072 if (selection->getOrientation()==OrientLeftOfCenter)
2074 if (typeid(*selection) == typeid(BranchObj) ||
2075 typeid(*selection) == typeid(FloatImageObj))
2077 selection->unselect();
2079 selection->select();
2081 ensureSelectionVisible();
2085 if (typeid(*selection) == typeid(BranchObj) )
2087 bo=((BranchObj*)selection)->getLastSelectedBranch();
2090 selection->unselect();
2092 selection->select();
2094 ensureSelectionVisible();
2102 void MapEditor::selectFirstBranch()
2108 if (typeid(*selection) == typeid(BranchObj))
2110 bo1= (BranchObj*) selection;
2111 par=(BranchObj*)(bo1->getParObj());
2112 bo2=par->getFirstBranch();
2116 selection->select();
2117 ensureSelectionVisible();
2124 void MapEditor::selectLastBranch()
2130 if (typeid(*selection) == typeid(BranchObj))
2132 bo1= (BranchObj*) selection;
2133 par=(BranchObj*)(bo1->getParObj());
2134 bo2=par->getLastBranch();
2138 selection->select();
2139 ensureSelectionVisible();
2146 void MapEditor::setColor(QColor c)
2151 void MapEditor::selectBackgroundColor()
2153 QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this );
2154 if ( !col.isValid() ) return;
2155 setBackgroundColor( col );
2157 saveStateComplete(QString("Set background color of map to %1").arg(col.name()));
2160 void MapEditor::setBackgroundColor(QColor c)
2162 mapCanvas->setBackgroundColor (c);
2165 QColor MapEditor::pickColor()
2169 if (typeid(*selection) == typeid(BranchObj) ||
2170 typeid(*selection) == typeid(MapCenterObj))
2172 BranchObj *bo=(BranchObj*)selection;
2173 actColor=bo->getColor();
2179 void MapEditor::colorItem()
2183 if (typeid(*selection) == typeid(BranchObj) ||
2184 typeid(*selection) == typeid(MapCenterObj))
2186 BranchObj *bo=(BranchObj*)selection;
2187 saveStatePart(selection, QString("Set color of %1 to %2").arg(getName(bo)).arg(actColor.name())); //TODO undoCommand
2188 bo->setColor(actColor); // color branch
2193 void MapEditor::colorBranch()
2197 if (typeid(*selection) == typeid(BranchObj) ||
2198 typeid(*selection) == typeid(MapCenterObj))
2200 BranchObj *bo=(BranchObj*)selection;
2201 saveStatePart(selection, QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(actColor.name())); //TODO undoCommand
2202 bo->setColorChilds(actColor); // color links, color childs
2208 void MapEditor::toggleStandardFlag(QString f)
2212 if (typeid(*selection) == typeid(BranchObj) ||
2213 typeid(*selection) == typeid(MapCenterObj))
2215 BranchObj *bo=(BranchObj*)selection;
2217 if (bo->isSetStandardFlag(f))
2227 saveStateConstSelection(QString("%1 (\"%2\")").arg(u).arg(f),
2228 QString("%1 (\"%2\")").arg(r).arg(f),
2229 QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo)));
2230 bo->toggleStandardFlag (f,actionSettingsUseFlagGroups->isOn());
2236 void MapEditor::setViewCenter()
2238 // transform to CanvasView Coord:
2239 QPoint p=worldMatrix().map(movingCenter);
2240 center ( p.x(), p.y());
2244 BranchObj* MapEditor::findText (QString s, bool cs)
2246 QTextDocument::FindFlags flags=0;
2247 if (cs) flags=QTextDocument::QTextDocument::FindCaseSensitively;
2250 { // Nothing found or new find process
2252 // nothing found, start again
2254 itFind=mapCenter->first();
2256 bool searching=true;
2257 bool foundNote=false;
2258 while (searching && !EOFind)
2262 // Searching in Note
2263 if (itFind->getNote().contains(s,cs))
2265 if (selection!=itFind)
2267 if (selection) ((BranchObj*)selection)->unselect();
2269 selection->select();
2271 ensureSelectionVisible();
2273 if (textEditor->findText(s,flags))
2279 // Searching in Heading
2280 if (searching && itFind->getHeading().contains (s,cs) )
2282 if (selection) ((BranchObj*)selection)->unselect();
2284 selection->select();
2286 ensureSelectionVisible();
2292 itFind=itFind->next();
2293 if (!itFind) EOFind=true;
2299 return (BranchObj*)selection;
2304 void MapEditor::findReset()
2305 { // Necessary if text to find changes during a find process
2310 void MapEditor::editURL()
2312 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2313 typeid(*selection) == typeid(MapCenterObj)) )
2316 BranchObj *bo=(BranchObj*)selection;
2317 QString text = QInputDialog::getText(
2318 "VYM", tr("Enter URL:"), QLineEdit::Normal,
2319 bo->getURL(), &ok, this );
2322 // user entered something and pressed OK
2323 saveStateConstSelection("setURL (\""+bo->getURL()+"\")","setURL (\""+text+"\")", QString("Set URL of %1 to %21").arg(getName(bo)).arg(text));
2330 QString MapEditor::getURL()
2332 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2333 typeid(*selection) == typeid(MapCenterObj)) )
2334 return ((BranchObj*)selection)->getURL();
2339 void MapEditor::editHeading2URL()
2341 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2342 typeid(*selection) == typeid(MapCenterObj)) )
2344 BranchObj *bo=(BranchObj*)selection;
2345 saveStateConstSelection("setURL (\""+bo->getURL()+"\")","setURL (\""+bo->getHeading()+"\")",QString("Copy heading of %1 to URL").arg(getName(bo)));
2346 bo->setURL (bo->getHeading());
2351 void MapEditor::editBugzilla2URL()
2353 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2354 typeid(*selection) == typeid(MapCenterObj)) )
2356 BranchObj *bo=(BranchObj*)selection;
2357 QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading();
2358 saveStateConstSelection("setURL (\""+bo->getURL()+"\")","setURL (\""+url+"\")",QString("Use heading of %1 as link to Novell Bugzilla").arg(getName(bo)));
2364 void MapEditor::editFATE2URL()
2366 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2367 typeid(*selection) == typeid(MapCenterObj)) )
2369 BranchObj *bo=(BranchObj*)selection;
2370 QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading();
2371 saveStateConstSelection("setURL (\""+bo->getURL()+"\")","setURL (\""+url+"\")",QString("Use heading of %1 as link to FATE").arg(getName(bo)));
2377 void MapEditor::editVymLink()
2379 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2380 typeid(*selection) == typeid(MapCenterObj)) )
2382 BranchObj *bo=(BranchObj*)selection;
2383 Q3FileDialog *fd=new Q3FileDialog( this,__VYM " - " +tr("Link to another map"));
2384 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
2385 fd->setCaption(__VYM " - " +tr("Link to another map"));
2386 if (! bo->getVymLink().isEmpty() )
2387 fd->setSelection( bo->getVymLink() );
2391 if ( fd->exec() == QDialog::Accepted )
2393 saveStateConstSelection("setVymLink (\""+bo->getVymLink()+"\")","setVymLink (\""+fd->selectedFile()+"\")",QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile()));
2394 bo->setVymLink (fd->selectedFile() );
2396 mapCenter->reposition();
2403 void MapEditor::deleteVymLink()
2405 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2406 typeid(*selection) == typeid(MapCenterObj)) )
2408 BranchObj *bo=(BranchObj*)selection;
2409 saveStateConstSelection("setVymLink (\""+bo->getVymLink()+"\")","setVymLink (\"\")",QString("Unset vymlink of %1").arg(getName(bo)));
2410 bo->setVymLink ("" );
2412 mapCenter->reposition();
2418 void MapEditor::toggleHideExport()
2420 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2421 typeid(*selection) == typeid(MapCenterObj)) ||
2422 (typeid(*selection)==typeid(FloatImageObj))
2425 OrnamentedObj *oo=(OrnamentedObj*)selection;
2427 if (oo->hideInExport())
2429 oo->setHideInExport(false);
2434 oo->setHideInExport(true);
2437 saveStateComplete(QString ("%1 hide export flag of %2").arg(s).arg(getName(selection))); //TODO undoCommand
2438 actionEditToggleHideExport->setOn (oo->hideInExport());
2440 mapCenter->reposition();
2446 QString MapEditor::getVymLink()
2448 if (selection && (typeid(*selection) == typeid(BranchObj) ||
2449 typeid(*selection) == typeid(MapCenterObj)) )
2451 return ((BranchObj*)selection)->getVymLink();
2457 void MapEditor::removeBranchKeepChilds()
2459 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2461 BranchObj* bo=(BranchObj*)selection;
2462 BranchObj* par=(BranchObj*)(bo->getParObj());
2463 QString s=QString("Remove %1 and keep its childs").arg(getName(bo));
2464 if (bo->getDepth()==1)
2465 saveStateComplete(s);
2467 saveStatePart(selection->getParObj(),s); // TODO undoCommand
2468 QString sel=selection->getSelectString();
2470 par->removeBranchHere(bo);
2471 mapCenter->reposition();
2476 void MapEditor::removeChilds()
2478 if (selection && (typeid(*selection) == typeid(BranchObj) ))
2480 saveStatePart(selection->getParObj(), QString("Remove childs of branch %1").arg(getName(selection)));
2481 ((BranchObj*)selection)->removeChilds();
2482 mapCenter->reposition();
2486 void MapEditor::editMapInfo()
2488 ExtraInfoDialog dia;
2489 dia.setMapName (getFileName() );
2490 dia.setAuthor (mapCenter->getAuthor() );
2491 dia.setComment(mapCenter->getComment() );
2496 Q3CanvasItemList l=canvas()->allItems();
2497 for (Q3CanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it)
2499 stats+=QString ("%1 items on canvas\n").arg (i,6);
2506 bo=mapCenter->first();
2509 if (!bo->getNote().isEmpty() ) n++;
2510 f+= bo->countFloatImages();
2512 xl+=bo->countXLinks();
2515 stats+=QString ("%1 branches\n").arg (b-1,6);
2516 stats+=QString ("%1 xLinks \n").arg (xl,6);
2517 stats+=QString ("%1 notes\n").arg (n,6);
2518 stats+=QString ("%1 images\n").arg (f,6);
2519 dia.setStats (stats);
2521 // Finally show dialog
2522 if (dia.exec() == QDialog::Accepted)
2524 saveStateComplete("Edit info about map"); //TODO undoCommand
2525 mapCenter->setAuthor (dia.getAuthor() );
2526 mapCenter->setComment (dia.getComment() );
2530 void MapEditor::updateActions()
2533 if (getLinkColorHint()==HeadingColor)
2534 actionFormatLinkColorHint->setOn(true);
2536 actionFormatLinkColorHint->setOn(false);
2541 actionFormatLinkStyleLine->setOn(true);
2544 actionFormatLinkStyleParabel->setOn(true);
2547 actionFormatLinkStylePolyLine->setOn(true);
2549 case StylePolyParabel:
2550 actionFormatLinkStylePolyParabel->setOn(true);
2556 QPixmap pix( 16, 16 );
2557 pix.fill( mapCanvas->backgroundColor() );
2558 actionFormatBackColor->setIconSet( pix );
2559 pix.fill( defLinkColor );
2560 actionFormatLinkColor->setIconSet( pix );
2562 actionFileSave->setEnabled( mapUnsaved );
2563 if (undoSet.readNumEntry("/history/undosAvail",0)>0)
2564 actionEditUndo->setEnabled( true);
2566 actionEditUndo->setEnabled( false);
2568 if (undoSet.readNumEntry("/history/redosAvail",0)>0)
2569 actionEditRedo->setEnabled( true);
2571 actionEditRedo->setEnabled( false);
2575 if ( (typeid(*selection) == typeid(BranchObj)) ||
2576 (typeid(*selection) == typeid(MapCenterObj)) )
2578 BranchObj *bo=(BranchObj*)selection;
2579 // Take care of links
2580 if (bo->countXLinks()==0)
2582 branchLinksContextMenuEdit->clear();
2583 branchLinksContextMenuFollow->clear();
2588 branchLinksContextMenuEdit->clear();
2589 branchLinksContextMenuFollow->clear();
2590 for (int i=0; i<=bo->countXLinks();i++)
2592 bot=bo->XLinkTargetAt(i);
2595 s=bot->getHeading();
2598 branchLinksContextMenuFollow->addAction (s);
2599 branchLinksContextMenuEdit->addAction (s);
2604 standardFlagsDefault->setEnabled (true);
2606 actionEditToggleScroll->setEnabled (true);
2607 if ( bo->isScrolled() )
2608 actionEditToggleScroll->setOn(true);
2610 actionEditToggleScroll->setOn(false);
2612 if ( bo->getURL().isEmpty() )
2614 actionEditOpenURL->setEnabled (false);
2615 actionEditOpenURLTab->setEnabled (false);
2619 actionEditOpenURL->setEnabled (true);
2620 actionEditOpenURLTab->setEnabled (true);
2622 if ( bo->getVymLink().isEmpty() )
2624 actionEditOpenVymLink->setEnabled (false);
2625 actionEditDeleteVymLink->setEnabled (false);
2628 actionEditOpenVymLink->setEnabled (true);
2629 actionEditDeleteVymLink->setEnabled (true);
2632 if (bo->canMoveBranchUp())
2633 actionEditMoveUp->setEnabled (true);
2635 actionEditMoveUp->setEnabled (false);
2636 if (bo->canMoveBranchDown())
2637 actionEditMoveDown->setEnabled (true);
2639 actionEditMoveDown->setEnabled (false);
2642 actionEditToggleHideExport->setEnabled (true);
2643 actionEditToggleHideExport->setOn (bo->hideInExport() );
2645 actionEditCopy->setEnabled (true);
2646 actionEditCut->setEnabled (true);
2647 if (!clipboardEmpty)
2648 actionEditPaste->setEnabled (true);
2650 actionEditPaste->setEnabled (false);
2651 for (a=actionListBranches.first();a;a=actionListBranches.next())
2652 a->setEnabled(true);
2653 actionEditDelete->setEnabled (true);
2654 switch (selection->getFrameType())
2657 actionFormatFrameNone->setOn(true);
2660 actionFormatFrameRectangle->setOn(true);
2665 actionFormatIncludeImagesVer->setOn
2666 ( ((BranchObj*)selection)->getIncludeImagesVer());
2667 actionFormatIncludeImagesHor->setOn
2668 ( ((BranchObj*)selection)->getIncludeImagesHor());
2669 actionFormatHideLinkUnselected->setOn
2670 (selection->getHideLinkUnselected());
2672 if ( (typeid(*selection) == typeid(FloatImageObj)) )
2674 FloatObj *fo=(FloatImageObj*)selection;
2675 //FIXME do this in mainwindow standardFlagsDefault->setEnabled (false);
2677 actionEditOpenURL->setEnabled (false);
2678 actionEditOpenVymLink->setEnabled (false);
2679 actionEditDeleteVymLink->setEnabled (false);
2680 actionEditToggleHideExport->setEnabled (true);
2681 actionEditToggleHideExport->setOn (fo->hideInExport() );
2684 actionEditCopy->setEnabled (true);
2685 actionEditCut->setEnabled (true);
2686 actionEditPaste->setEnabled (false);
2687 for (a=actionListBranches.first();a;a=actionListBranches.next())
2688 a->setEnabled(false);
2689 actionEditDelete->setEnabled (true);
2690 actionFormatHideLinkUnselected->setOn
2691 ( selection->getHideLinkUnselected());
2692 actionEditMoveUp->setEnabled (false);
2693 actionEditMoveDown->setEnabled (false);
2698 //FIXME do this in mainwindow standardFlagsDefault->setEnabled (false);
2700 actionEditCopy->setEnabled (false);
2701 actionEditCut->setEnabled (false);
2702 actionEditPaste->setEnabled (false);
2703 for (a=actionListBranches.first();a;a=actionListBranches.next())
2704 a->setEnabled(false);
2706 actionEditToggleScroll->setEnabled (false);
2707 actionEditOpenURL->setEnabled (false);
2708 actionEditOpenVymLink->setEnabled (false);
2709 actionEditDeleteVymLink->setEnabled (false);
2710 actionEditHeading2URL->setEnabled (false);
2711 actionEditDelete->setEnabled (false);
2712 actionEditMoveUp->setEnabled (false);
2713 actionEditMoveDown->setEnabled (false);
2714 actionEditToggleHideExport->setEnabled (false);
2718 void MapEditor::updateNoteFlag()
2721 if ( (typeid(*selection) == typeid(BranchObj)) ||
2722 (typeid(*selection) == typeid(MapCenterObj)) )
2723 ((BranchObj*)selection)->updateNoteFlag();
2726 void MapEditor::setLinkStyle (LinkStyle ls)
2730 saveStateComplete("Set link style"); // TODO undoCommand
2732 bo=mapCenter->first();
2736 bo->setLinkStyle(bo->getDefLinkStyle());
2739 mapCenter->reposition();
2742 LinkStyle MapEditor::getLinkStyle ()
2747 void MapEditor::setLinkColor(QColor c)
2753 void MapEditor::setLinkColorHint()
2755 // called from setLinkColorHint(lch) or at end of parse
2757 bo=mapCenter->first();
2765 void MapEditor::setLinkColorHint(LinkColorHint lch)
2771 void MapEditor::toggleLinkColorHint()
2773 if (linkcolorhint==HeadingColor)
2774 linkcolorhint=DefaultColor;
2776 linkcolorhint=HeadingColor;
2778 bo=mapCenter->first();
2786 LinkColorHint MapEditor::getLinkColorHint()
2788 return linkcolorhint;
2791 QColor MapEditor::getDefLinkColor()
2793 return defLinkColor;
2796 void MapEditor::setDefXLinkColor(QColor col)
2801 QColor MapEditor::getDefXLinkColor()
2803 return defXLinkColor;
2806 void MapEditor::setDefXLinkWidth (int w)
2811 int MapEditor::getDefXLinkWidth()
2813 return defXLinkWidth;
2816 void MapEditor::selectLinkColor()
2818 QColor col = QColorDialog::getColor( defLinkColor, this );
2819 if ( !col.isValid() ) return;
2820 setLinkColor( col );
2821 saveStateComplete(QString("Set link color to %1").arg(col.name())); //TODO undoCommand
2825 void MapEditor::toggleScroll()
2827 if (selection && (typeid(*selection) == typeid(BranchObj)) )
2829 BranchObj *bo=((BranchObj*)selection);
2830 if (bo->countBranches()==0) return;
2831 if (bo->getDepth()==0) return;
2833 if (bo->isScrolled())
2837 saveStatePart(selection, QString ("%1 %2").arg(s).arg(getName(bo)));
2844 void MapEditor::unScrollAll()
2847 bo=mapCenter->first();
2850 if (bo->isScrolled()) bo->toggleScroll();
2855 void MapEditor::loadFloatImage ()
2858 (typeid(*selection) == typeid(BranchObj)) ||
2859 (typeid(*selection) == typeid(MapCenterObj)) )
2861 BranchObj *bo=((BranchObj*)selection);
2863 Q3FileDialog *fd=new Q3FileDialog( this);
2864 fd->setMode (Q3FileDialog::ExistingFiles);
2865 fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"));
2866 ImagePreview *p =new ImagePreview (fd);
2867 fd->setContentsPreviewEnabled( TRUE );
2868 fd->setContentsPreview( p, p );
2869 fd->setPreviewMode( Q3FileDialog::Contents );
2870 fd->setCaption(__VYM " - " +tr("Load image"));
2871 fd->setDir (lastImageDir);
2875 if ( fd->exec() == QDialog::Accepted )
2877 saveStatePart(selection, QString("Add floatimage to %1").arg(getName(selection)));
2878 // FIXME in QT4 use: lastImageDir=fd->directory();
2879 lastImageDir=QDir (fd->dirPath());
2880 QStringList flist = fd->selectedFiles();
2881 QStringList::Iterator it = flist.begin();
2882 while( it != flist.end() )
2885 bo->addFloatImage();
2886 // TODO check if load was successful
2887 bo->getLastFloatImage()->load(*it);
2888 bo->getLastFloatImage()->setOriginalFilename(fn);
2892 mapCenter->reposition();
2901 void MapEditor::saveFloatImage ()
2904 (typeid(*selection) == typeid(FloatImageObj)) )
2906 FloatImageObj *fio=((FloatImageObj*)selection);
2907 QFileDialog *fd=new QFileDialog( this);
2908 fd->setFilters (imageIO.getFilters());
2909 fd->setCaption(__VYM " - " +tr("Save image"));
2910 fd->setFileMode( QFileDialog::AnyFile );
2911 fd->setDirectory (lastImageDir);
2912 // fd->setSelection (fio->getOriginalFilename());
2916 if ( fd->exec() == QDialog::Accepted )
2918 if (QFile (fd->selectedFile()).exists() )
2920 QMessageBox mb( __VYM,
2921 tr("The file %1 exists already.\n"
2922 "Do you want to overwrite it?").arg(fd->selectedFile()),
2923 QMessageBox::Warning,
2924 QMessageBox::Yes | QMessageBox::Default,
2925 QMessageBox::Cancel | QMessageBox::Escape,
2926 QMessageBox::QMessageBox::NoButton );
2928 mb.setButtonText( QMessageBox::Yes, tr("Overwrite") );
2929 mb.setButtonText( QMessageBox::No, tr("Cancel"));
2932 case QMessageBox::Yes:
2935 case QMessageBox::Cancel:
2941 fio->save (fd->selectedFile(),imageIO.getType (fd->selectedFilter() ) );
2946 void MapEditor::setFrame(const FrameType &t)
2949 (typeid(*selection) == typeid(BranchObj)) ||
2950 (typeid(*selection) == typeid(MapCenterObj)) )
2952 selection->setFrameType (t);
2953 mapCenter->reposition();
2954 selection->updateLink();
2958 void MapEditor::setIncludeImagesVer(bool b)
2961 (typeid(*selection) == typeid(BranchObj)) ||
2962 (typeid(*selection) == typeid(MapCenterObj)) )
2963 ((BranchObj*)selection)->setIncludeImagesVer(b);
2964 mapCenter->reposition();
2967 void MapEditor::setIncludeImagesHor(bool b)
2970 (typeid(*selection) == typeid(BranchObj)) ||
2971 (typeid(*selection) == typeid(MapCenterObj)) )
2972 ((BranchObj*)selection)->setIncludeImagesHor(b);
2973 mapCenter->reposition();
2976 void MapEditor::setHideLinkUnselected (bool b)
2979 (typeid(*selection) == typeid(BranchObj)) ||
2980 (typeid(*selection) == typeid(MapCenterObj)) ||
2981 (typeid(*selection) == typeid(FloatImageObj)) )
2982 selection->setHideLinkUnselected(b);
2985 void MapEditor::importDirInt(BranchObj *dst, QDir d)
2988 (typeid(*selection) == typeid(BranchObj)) ||
2989 (typeid(*selection) == typeid(MapCenterObj)) )
2993 // Traverse directories
2994 d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks );
2995 QFileInfoList list = d.entryInfoList();
2998 for (int i = 0; i < list.size(); ++i)
3001 if (fi.fileName() != "." && fi.fileName() != ".." )
3004 bo=dst->getLastBranch();
3005 bo->setHeading (fi.fileName() );
3006 bo->setColor (QColor("blue"));
3008 if ( !d.cd(fi.fileName()) )
3009 QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName()));
3012 // Recursively add subdirs
3013 importDirInt (bo,d);
3019 d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks );
3020 list = d.entryInfoList();
3022 for (int i = 0; i < list.size(); ++i)
3026 bo=dst->getLastBranch();
3027 bo->setHeading (fi.fileName() );
3028 bo->setColor (QColor("black"));
3029 if (fi.fileName().right(4) == ".vym" )
3030 bo->setVymLink (fi.filePath());
3035 void MapEditor::importDir()
3038 (typeid(*selection) == typeid(BranchObj)) ||
3039 (typeid(*selection) == typeid(MapCenterObj)) )
3041 Q3FileDialog *fd=new Q3FileDialog( this,__VYM " - " +tr("Choose directory structure to import"));
3042 fd->setMode (Q3FileDialog::DirectoryOnly);
3043 fd->addFilter (QString (tr("vym map") + " (*.vym)"));
3044 fd->setCaption(__VYM " - " +tr("Choose directory structure to import"));
3048 if ( fd->exec() == QDialog::Accepted )
3050 BranchObj *bo=((BranchObj*)selection);
3051 importDirInt (bo,QDir(fd->selectedFile()) );
3052 mapCenter->reposition();
3059 void MapEditor::followXLink(int i)
3062 (typeid(*selection) == typeid(BranchObj)) ||
3063 (typeid(*selection) == typeid(MapCenterObj)) )
3065 BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i);
3068 selection->unselect();
3070 selection->select();
3071 ensureSelectionVisible();
3076 void MapEditor::editXLink(int i)
3078 qDebug ("ko."); //FIXME Huh?
3080 (typeid(*selection) == typeid(BranchObj)) ||
3081 (typeid(*selection) == typeid(MapCenterObj)) )
3083 XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i);
3086 EditXLinkDialog dia;
3088 dia.setSelection(selection);
3089 if (dia.exec() == QDialog::Accepted)
3091 if (dia.useSettingsGlobal() )
3093 setDefXLinkColor (xlo->getColor() );
3094 setDefXLinkWidth (xlo->getWidth() );
3096 if (dia.deleteXLink())
3097 ((BranchObj*)selection)->deleteXLinkAt(i);
3098 saveStateComplete("Edit xLink"); //TODO undoCommand
3104 void MapEditor::testFunction()
3106 cout << "MapEditor::testFunction() called\n";
3110 QString text = QInputDialog::getText(
3112 tr("QInputDialog::getText()"),
3113 tr("User name:"), QLineEdit::Normal,
3114 QDir::home().dirName(), &ok, Qt::FramelessWindowHint);
3117 QDialog *d =new QDialog(NULL);
3118 QLineEdit *le=new QLineEdit (d);
3119 // d->setModal (true);
3120 d->setWindowFlags (Qt::FramelessWindowHint);
3122 le->setText ("Foo");
3124 connect (le, SIGNAL (returnPressed()), d, SLOT (accept()));
3126 qWarning( le->text());
3133 dia.setCancelButton (true);
3134 dia.setText("This is a longer \nWarning");
3135 dia.setCaption("Warning: Flux problem");
3136 dia.setShowAgainName("/warnings/mapeditor");
3137 dia.setWindowFlags (Qt::FramelessWindowHint);
3138 if (dia.exec()==QDialog::Accepted)
3139 cout << "accepted!\n";
3141 cout << "canceled!\n";
3145 /* Hide hidden stuff temporary, maybe add this as regular function somewhere
3146 if (hidemode==HideNone)
3148 setHideTmpMode (HideExport);
3149 mapCenter->calcBBoxSizeWithChilds();
3150 QRect totalBBox=mapCenter->getTotalBBox();
3151 QRect mapRect=totalBBox;
3152 QCanvasRectangle *frame=NULL;
3154 cout << " map has =("<<totalBBox.x()<<","<<totalBBox.y()<<","<<totalBBox.width()<<","<<totalBBox.height()<<")\n";
3156 mapRect.setRect (totalBBox.x(), totalBBox.y(),
3157 totalBBox.width(), totalBBox.height());
3158 frame=new QCanvasRectangle (mapRect,mapCanvas);
3159 frame->setBrush (QColor(white));
3160 frame->setPen (QColor(black));
3166 setHideTmpMode (HideNone);
3168 cout <<" hidemode="<<hidemode<<endl;
3172 void MapEditor::ensureSelectionVisible()
3176 LinkableMapObj* lmo= dynamic_cast <LinkableMapObj*> (selection);
3178 if (selection->getOrientation() == OrientLeftOfCenter)
3179 p= worldMatrix().map(QPoint (lmo->x(),lmo->y()));
3181 p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height()));
3182 ensureVisible (p.x(), p.y() );
3187 void MapEditor::updateViewCenter()
3189 // Update movingCenter, so that we can zoom comfortably later
3190 QRect rc = QRect( contentsX(), contentsY(),
3191 visibleWidth(), visibleHeight() );
3192 QRect canvasRect = inverseWorldMatrix().mapRect(rc);
3193 movingCenter.setX((canvasRect.right() + canvasRect.left())/2);
3194 movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2);
3197 void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e )
3199 // Lineedits are already closed by preceding
3200 // mouseEvent, we don't need to close here.
3202 QPoint p = inverseWorldMatrix().map(e->pos());
3203 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3206 { // MapObj was found
3207 if (selection != lmo)
3209 // select the MapObj
3210 if (selection) selection->unselect();
3212 selection->select();
3218 if (typeid(*selection)==typeid(BranchObj) ||
3219 typeid(*selection)==typeid(MapCenterObj) )
3221 // Context Menu on branch or mapcenter
3223 branchContextMenu->popup(e->globalPos() );
3225 if (typeid(*selection)==typeid(FloatImageObj))
3227 // Context Menu on floatimage
3229 floatimageContextMenu->popup(e->globalPos() );
3233 { // No MapObj found, we are on the Canvas itself
3234 // Context Menu on Canvas
3236 canvasContextMenu->popup(e->globalPos() );
3241 void MapEditor::contentsMousePressEvent(QMouseEvent* e)
3243 // Ignore right clicks, these will go to context menus
3244 if (e->button() == Qt::RightButton )
3250 QPoint p = inverseWorldMatrix().map(e->pos());
3251 LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL);
3255 //Take care of clickdesystem flags _or_ modifier modes
3257 if (lmo && (typeid(*lmo)==typeid(BranchObj) ||
3258 typeid(*lmo)==typeid(MapCenterObj) ))
3260 QString foname=((BranchObj*)lmo)->getSystemFlagName(p);
3261 if (!foname.isEmpty())
3263 // systemFlag clicked
3267 if (e->state() & Qt::ControlModifier)
3268 mainWindow->editOpenURLTab();
3270 mainWindow->editOpenURL();
3272 else if (foname=="vymLink")
3274 mainWindow->editOpenVymLink();
3275 // tabWidget may change, better return now
3276 // before segfaulting...
3277 } else if (foname=="note")
3278 mainWindow->windowToggleNoteEditor();
3279 else if (foname=="hideInExport")
3284 // No system flag clicked, take care of modmodes
3286 // Special case: CTRL is pressed
3287 if (e->state() & Qt::ControlModifier)
3289 if (actionModModeColor->isOn())
3292 setCursor (pickColorCursor);
3295 if (actionModModeLink->isOn())
3297 BranchObj *bo_begin=NULL;
3299 bo_begin=(BranchObj*)(lmo);
3302 ((typeid(*selection) == typeid(BranchObj)) ||
3303 (typeid(*selection) == typeid(MapCenterObj))) )
3304 bo_begin=(BranchObj*)selection;
3308 linkingObj_src=bo_begin;
3309 tmpXLink=new XLinkObj (mapCanvas);
3310 tmpXLink->setBegin (bo_begin);
3311 tmpXLink->setEnd (p);
3312 tmpXLink->setColor(defXLinkColor);
3313 tmpXLink->setWidth(defXLinkWidth);
3314 tmpXLink->updateXLink();
3315 tmpXLink->setVisibility (true);
3323 // Left Button Move Branches
3324 if (e->button() == Qt::LeftButton )
3326 movingObj_start.setX( p.x() - selection->x() );
3327 movingObj_start.setY( p.y() - selection->y() );
3328 movingObj_orgPos.setX (lmo->x() );
3329 movingObj_orgPos.setY (lmo->y() );
3331 // If modMode==copy, then we want to "move" the _new_ object around
3332 // then we need the offset from p to the _old_ selection, because of tmp
3333 if (actionModModeCopy->isOn() &&
3334 e->state() & Qt::ControlModifier)
3336 if (typeid(*selection)==typeid(BranchObj) )
3339 mapCenter->addBranch ((BranchObj*)selection);
3341 selection=mapCenter->getLastBranch();
3342 selection->select();
3343 mapCenter->reposition();
3346 movingObj=selection;
3348 // Middle Button Toggle Scroll
3349 // (On Mac OS X this won't work, but we still have
3350 // a button in the toolbar)
3351 if (e->button() == Qt::MidButton )
3355 { // No MapObj found, we are on the Canvas itself
3356 // Left Button move Pos of CanvasView
3357 if (e->button() == Qt::LeftButton )
3359 movingObj=NULL; // move Content not Obj
3360 movingObj_start=e->globalPos();
3361 movingCont_start=QPoint (contentsX(), contentsY() );
3362 movingVec=QPoint(0,0);
3363 setCursor(handOpenCursor);
3368 void MapEditor::contentsMouseMoveEvent(QMouseEvent* e)
3370 QPoint p = inverseWorldMatrix().map(e->pos());
3372 // Move the selected MapObj
3373 if ( selection && movingObj)
3375 // To avoid jumping of the CanvasView, only
3376 // ensureSelectionVisible, if not tmp linked
3377 if (!selection->hasParObjTmp())
3378 ensureSelectionVisible ();
3380 // Now move the selection, but add relative position
3381 // (movingObj_start) where selection was chosen with
3382 // mousepointer. (This avoids flickering resp. jumping
3383 // of selection back to absPos)
3385 LinkableMapObj *lmosel;
3386 lmosel = dynamic_cast <LinkableMapObj*> (selection);
3388 // Check if we could link
3389 LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel);
3392 if (typeid(*selection) == typeid(FloatImageObj))
3394 FloatObj *fo=(FloatObj*)selection;
3395 saveStateConstSelection(
3396 "move "+qpointToString(movingObj_orgPos),fo->getSelectString() ,
3397 QString("Move %1").arg(getName(selection)));
3398 fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3402 // Relink float to new mapcenter or branch, if shift is pressed
3403 // Only relink, if selection really has a new parent
3404 if ( (e->state() & Qt::ShiftModifier) && lmo &&
3405 ( (typeid(*lmo)==typeid(BranchObj)) ||
3406 (typeid(*lmo)==typeid(MapCenterObj)) ) &&
3407 ( lmo != fo->getParObj())
3410 if (typeid(*fo) == typeid(FloatImageObj))
3413 saveStateComplete(QString("Relink %1 to %2").arg(getName(fo)).arg(getName(lmo) ) );
3414 FloatImageObj *fio=(FloatImageObj*)(fo);
3415 ((BranchObj*)(lmo))->addFloatImage (fio);
3417 ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio);
3418 fio=((BranchObj*)(lmo))->getLastFloatImage();
3421 selection=(LinkableMapObj*)(fio);
3422 selection->select();
3423 movingObj=(MapObj*)(fio);
3426 } else // selection != a FloatObj
3428 if (lmosel->getDepth()==0)
3430 if (e->state() == Qt::LeftButton && e->modifiers()==Qt::ShiftModifier)
3431 // If mapCenter is moved, move all the rest by default, too.
3432 mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3434 mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3437 if (lmosel->getDepth()==1)
3439 // depth==1, mainbranch
3440 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() );
3444 if (lmosel->getOrientation() == OrientLeftOfCenter)
3445 // Add width of bbox here, otherwise alignRelTo will cause jumping around
3446 lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(),
3447 p.y()-movingObj_start.y() +lmosel->getTopPad() );
3449 lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad());
3451 // reposition subbranch
3452 lmosel->reposition();
3453 //ensureSelectionVisible();
3455 if (lmo && (lmo!=selection) &&
3456 (typeid(*lmo) == typeid(BranchObj) ||
3457 (typeid(*lmo) == typeid(MapCenterObj) )
3460 if (e->state() & Qt::ControlModifier)
3462 // Special case: CTRL to link below lmo
3463 lmosel->setParObjTmp (lmo,p,+1);
3465 else if (e->state() & Qt::ShiftModifier)
3466 lmosel->setParObjTmp (lmo,p,-1);
3468 lmosel->setParObjTmp (lmo,p,0);
3471 lmosel->unsetParObjTmp();
3475 } // no FloatImageObj
3479 } // selection && moving_obj
3481 // Draw a link from one branch to another
3484 tmpXLink->setEnd (p);
3485 tmpXLink->updateXLink();
3489 if (!movingObj && !pickingColor &&!drawingLink)
3491 QPoint p=e->globalPos();
3492 movingVec.setX(-p.x() + movingObj_start.x() );
3493 movingVec.setY(-p.y() + movingObj_start.y() );
3494 setContentsPos( movingCont_start.x() + movingVec.x(),
3495 movingCont_start.y() + movingVec.y());
3502 void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e)
3504 LinkableMapObj *dst;
3505 // Have we been picking color?
3509 setCursor (Qt::ArrowCursor);
3510 // Check if we are over another branch
3511 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3512 if (dst && selection)
3514 if (e->state() & Qt::ShiftModifier)
3516 ((BranchObj*)selection)->setColor (((BranchObj*)(dst))->getColor());
3517 ((BranchObj*)selection)->setLinkColor ();
3521 ((BranchObj*)selection)->setColorChilds (((BranchObj*)(dst))->getColor());
3522 ((BranchObj*)selection)->setLinkColor ();
3528 // Have we been drawing a link?
3532 // Check if we are over another branch
3533 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL);
3534 if (dst && selection)
3536 tmpXLink->setEnd ( ((BranchObj*)(dst)) );
3537 tmpXLink->updateXLink();
3538 tmpXLink->activate();
3539 saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //TODO undoCommand
3548 // Have we been moving something?
3549 if ( selection && movingObj )
3551 // Moved FloatObj? Maybe we need to reposition
3552 if(typeid(*selection)==typeid (FloatImageObj))
3554 selection->getParObj()->requestReposition();
3555 mapCenter->reposition();
3558 // Check if we are over another branch, but ignore
3559 // any found LMOs, which are FloatObjs
3560 dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ),
3561 ((LinkableMapObj*)selection) );
3563 if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj)))
3566 // Now check, if we have been moving a branch
3567 if (typeid(*selection) == typeid(BranchObj) )
3569 // save the position in case we link to mapcenter
3570 QPoint savePos=QPoint (selection->x(),selection->y() );
3572 // Reset the temporary drawn link to the original one
3573 ((LinkableMapObj*)selection)->unsetParObjTmp();
3579 BranchObj* bs=((BranchObj*)selection);
3580 QString undoCom="linkBranchToPos (\""+
3581 (bs->getParObj())->getSelectString()+
3583 QString("%1").arg(bs->getNum())+
3585 QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+
3587 // TODO we also could check, if dest and src are on same branch,
3588 // then it would be sufficient to saveState of this branch
3590 // Modifiers allow to insert above/below dst
3591 if (e->state() & Qt::ShiftModifier)
3593 bs->moveBranchTo ( (BranchObj*)(dst->getParObj()), ((BranchObj*)(dst))->getNum());
3595 if (e->state() & Qt::ControlModifier)
3597 bs->moveBranchTo ( (BranchObj*)(dst->getParObj()), ((BranchObj*)(dst))->getNum()+1);
3600 bs->moveBranchTo ((BranchObj*)(dst),-1);
3601 if (dst->getDepth()==0)
3604 saveStateConstSelection (undoCom,bs->getSelectString(),QString("Relink %1 to %2").arg(getName(bs)).arg(getName(dst)) );
3606 if (selection->getDepth()==1)
3607 // If we have moved mainbranch only save endposition
3608 saveStateConstSelection("move "+qpointToString(movingObj_orgPos), selection->getSelectString(), QString("Move %1 to %2").arg(getName(selection)).arg(qpointToString(movingObj_orgPos)));
3610 // Draw the original link, before selection was moved around
3611 mapCenter->reposition();
3613 // Finally resize canvas, if needed
3618 // maybe we moved View: set old cursor
3619 setCursor (Qt::ArrowCursor);
3623 void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e)
3625 if (e->button() == Qt::LeftButton )
3627 QPoint p = inverseWorldMatrix().map(e->pos());
3628 LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL);
3629 if (lmo) { // MapObj was found
3630 // First select the MapObj than edit heading
3631 if (selection) selection->unselect();
3633 selection->select();
3639 void MapEditor::resizeEvent (QResizeEvent* e)
3641 Q3CanvasView::resizeEvent( e );
3645 void MapEditor::contentsDragEnterEvent(QDragEnterEvent *event)
3648 // for (unsigned int i=0;event->format(i);i++) // Debug mime type
3649 // cerr << event->format(i) << endl;
3652 (typeid(*selection) == typeid(BranchObj)) ||
3653 (typeid(*selection) == typeid(MapCenterObj))) {
3655 // If QImageDrag can decode mime type
3656 if (Q3ImageDrag::canDecode(event)) {
3661 // If image are dragged from firefox
3662 if (event->provides("application/x-moz-file-promise-url") &&
3663 event->provides("application/x-moz-nativeimage")) {
3664 event->accept(true);
3668 // If QUriDrag can decode mime type
3669 if (Q3UriDrag::canDecode(event)) {
3674 // If Uri are dragged from firefox
3675 if (event->provides("_NETSCAPE_URL")){
3680 // If QTextDrag can decode mime type
3681 if (Q3TextDrag::canDecode(event)) {
3690 bool isUnicode16(const QByteArray &d)
3692 // TODO: make more precise check for unicode 16.
3693 // Guess unicode16 if any of second bytes are zero
3694 unsigned int length = max(0,d.size()-2)/2;
3695 for (unsigned int i = 0; i<length ; i++)
3696 if (d.at(i*2+1)==0) return true;
3700 void MapEditor::contentsDropEvent(QDropEvent *event)
3703 (typeid(*selection) == typeid(BranchObj)) ||
3704 (typeid(*selection) == typeid(MapCenterObj)))
3709 if (event->provides("image/png"))
3712 if (Q3ImageDrag::decode(event, pix))
3720 } else if (event->provides("application/x-moz-file-promise-url") &&
3721 event->provides("application/x-moz-nativeimage"))
3723 // Contains url to the img src in unicode16
3724 QByteArray d = event->encodedData("application/x-moz-file-promise-url");
3725 QString url = QString((const QChar*)d.data(),d.size()/2);
3729 } else if (event->provides ("text/uri-list"))
3730 { // Uris provided e.g. by konqueror
3731 Q3UriDrag::decode (event,uris);
3732 } else if (event->provides ("_NETSCAPE_URL"))
3733 { // Uris provided by Mozilla
3734 QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL"));
3737 } else if (event->provides("text/html")) {
3739 // Handels text mime types
3740 // Look like firefox allways handle text as unicode16 (2 bytes per char.)
3741 QByteArray d = event->encodedData("text/html");
3744 text = QString((const QChar*)d.data(),d.size()/2);
3748 textEditor->setText(text);
3752 } else if (event->provides("text/plain")) {
3753 QByteArray d = event->encodedData("text/plain");
3756 text = QString((const QChar*)d.data(),d.size()/2);
3760 textEditor->setText(text);
3772 for (const char* u=uris.first(); u; u=uris.next())
3774 bo=((BranchObj*)selection)->addBranch();
3777 s=Q3UriDrag::uriToLocalFile(u);
3780 QString file = QDir::convertSeparators(s);
3781 heading = QFileInfo(file).baseName();
3783 if (file.endsWith(".vym", false))
3784 bo->setVymLink(file);
3793 if (!heading.isEmpty())
3794 bo->setHeading(heading);
3804 //FIXME saveState has to be called earlier for each of the drops...
3805 saveStateComplete("Drop Event"); //TODO undo Command
3806 mapCenter->reposition();
3813 void MapEditor::addFloatImage(const QPixmap &img)
3816 (typeid(*selection) == typeid(BranchObj)) ||
3817 (typeid(*selection) == typeid(MapCenterObj)) )
3819 BranchObj *bo=((BranchObj*)selection);
3820 saveStatePart(selection,QString("Add floatimage to %1").arg(getName(bo)));
3821 //QString fn=fd->selectedFile();
3822 //lastImageDir=fn.left(fn.findRev ("/"));
3823 bo->addFloatImage();
3824 // FIXME check if load was successful
3825 bo->getLastFloatImage()->load(img);
3826 //bo->getLastFloatImage()->setOriginalFilename(fn);
3827 mapCenter->reposition();
3834 void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation */*nop*/)
3836 if (!imageBuffer) imageBuffer = new QBuffer();
3837 if (!imageBuffer->isOpen()) {
3838 imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append);
3840 imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a));
3844 void MapEditor::imageDataFinished(Q3NetworkOperation *nop)
3846 if (nop->state()==Q3NetworkProtocol::StDone) {
3847 QPixmap img(imageBuffer->buffer());
3852 imageBuffer->close();
3854 imageBuffer->close();
3861 void MapEditor::fetchImage(const QString &url)
3864 urlOperator->stop();
3865 disconnect(urlOperator);
3869 urlOperator = new Q3UrlOperator(url);
3870 connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)),
3871 this, SLOT(imageDataFinished(Q3NetworkOperation*)));
3873 connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)),
3874 this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *)));