# HG changeset patch # User insilmaril # Date 1216286840 0 # Node ID e37153bea487db698000c8f5a0f880401681131d # Parent 49a910838042cf38cca8e1e73a054f287ab32e10 removed pixel garbage on right side of exported images diff -r 49a910838042 -r e37153bea487 mapeditor.cpp --- a/mapeditor.cpp Sun Jan 30 12:59:03 2005 +0000 +++ b/mapeditor.cpp Thu Jul 17 09:27:20 2008 +0000 @@ -1,323 +1,121 @@ #include "mapeditor.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include +#include #include -#include "version.h" - -#include "xml.h" +#include "parser.h" +#include "editxlinkdialog.h" +#include "exports.h" +#include "exportxhtmldialog.h" +#include "extrainfodialog.h" +#include "file.h" +#include "linkablemapobj.h" +#include "mainwindow.h" +#include "misc.h" #include "texteditor.h" -#include "linkablemapobj.h" -#include "exports.h" -#include "misc.h" -#include "mainwindow.h" -#include "extrainfodialog.h" -#include "settings.h" - -#include "icons/flag-note.xpm" -#include "icons/flag-url.xpm" -#include "icons/flag-vymlink.xpm" -#include "icons/flag-scrolled-right.xpm" -#include "icons/flag-tmpUnscrolled-right.xpm" -#include "icons/flag-questionmark.xpm" -#include "icons/flag-exclamationmark.xpm" -#include "icons/flag-hook-green.xpm" -#include "icons/flag-cross-red.xpm" -#include "icons/flag-stopsign.xpm" -#include "icons/flag-smiley-good.xpm" -#include "icons/flag-smiley-sad.xpm" -#include "icons/flag-clock.xpm" -#include "icons/flag-lamp.xpm" -#include "icons/flag-arrow-up.xpm" -#include "icons/flag-arrow-down.xpm" -#include "icons/flag-thumb-up.xpm" -#include "icons/flag-thumb-down.xpm" -#include "icons/flag-heart.xpm" -#include "icons/flag-flash.xpm" -#include "icons/flag-lifebelt.xpm" +#include "warningdialog.h" +#include "xml-freemind.h" +#include "xml-vym.h" + extern TextEditor *textEditor; extern int statusbarTime; extern Main *mainWindow; -extern FlagRowObj *systemFlagsDefault; +extern QString tmpVymDir; +extern QString clipboardDir; +extern QString clipboardFile; +extern bool clipboardEmpty; +extern bool debug; extern FlagRowObj *standardFlagsDefault; -extern MapEditor *clipboardME; - -extern QAction *actionFileSave; -extern QAction *actionEditUndo; -extern QAction *actionEditCopy; -extern QAction *actionEditCut; -extern QAction *actionEditPaste; -extern QAction *actionEditMoveUp; -extern QAction *actionEditMoveDown; -extern QAction *actionEditToggleScroll; -extern QAction *actionEditOpenURL; -extern QAction *actionEditURL; -extern QAction *actionEditHeading2URL; -extern QAction *actionEditBugzilla2URL; -extern QAction *actionEditOpenVymLink; -extern QAction *actionEditVymLink; -extern QAction *actionEditDeleteVymLink; -extern QAction *actionEditHeading; -extern QAction *actionEditDelete; -extern QAction *actionEditAddBranch; -extern QAction *actionEditAddBranchAbove; -extern QAction *actionEditAddBranchBelow; -extern QAction *actionEditImportAdd; -extern QAction *actionEditImportReplace; -extern QAction *actionEditSaveBranch; -extern QAction *actionEditSelectFirst; -extern QAction *actionEditSelectLast; -extern QAction *actionEditLoadImage; -extern QAction *actionEditToggleFloatExport; - -extern QAction* actionFormatPickColor; -extern QAction* actionFormatColorBranch; -extern QAction* actionFormatColorSubtree; -extern QAction *actionFormatLinkColorHint; -extern QAction *actionFormatBackColor; -extern QAction *actionFormatLinkColor; - -extern QActionGroup *actionGroupFormatFrameTypes; -extern QAction *actionFormatFrameNone; -extern QAction *actionFormatFrameRectangle; - -extern QActionGroup *actionGroupFormatLinkStyles; -extern QAction *actionFormatLinkStyleLine; -extern QAction *actionFormatLinkStyleParabel; -extern QAction *actionFormatLinkStylePolyLine; -extern QAction *actionFormatLinkStylePolyParabel; - -extern QAction *actionViewToggleNoteEditor; - -extern QAction *actionSettingsAutoedit; -extern QAction *actionSettingsAutoselectHeading; -extern QAction *actionSettingsAutoselectText; -extern QAction *actionSettingsPasteNewHeading; - -extern QPopupMenu *branchContextMenu; -extern QPopupMenu *floatimageContextMenu; -extern QPopupMenu *saveImageFormatMenu; -extern QPopupMenu *exportImageFormatMenu; -extern QPopupMenu *canvasContextMenu; + +extern QMenu* branchContextMenu; +extern QMenu* branchAddContextMenu; +extern QMenu* branchRemoveContextMenu; +extern QMenu* branchLinksContextMenu; +extern QMenu* branchXLinksContextMenuEdit; +extern QMenu* branchXLinksContextMenuFollow; +extern QMenu* floatimageContextMenu; +extern QMenu* canvasContextMenu; + extern Settings settings; - +extern ImageIO imageIO; + +extern QString vymName; +extern QString vymVersion; + +extern QString iconPath; +extern QDir vymBaseDir; +extern QDir lastImageDir; +extern QDir lastFileDir; + +int MapEditor::mapNum=0; // make instance /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// -MapEditor::MapEditor( - QWidget* parent, bool interactive, const char* name, WFlags f) : - QCanvasView(parent,name,f) -{ +MapEditor::MapEditor( QWidget* parent) : + QGraphicsView(parent) +{ + setObjectName ("MapEditor"); + //cout << "Constructor ME "<setAdvancePeriod(30); - - setCanvas (mapCanvas); - - setVScrollBarMode ( QScrollView::AlwaysOn ); - setHScrollBarMode ( QScrollView::AlwaysOn ); - - // Now create the _global_ system flags _once_: - // (Later all OrnamentedObj copy from this - // and set their own canvas) - if (!systemFlagsDefault) - { - systemFlagsDefault = new FlagRowObj (mapCanvas); - systemFlagsDefault->setVisibility (false); - systemFlagsDefault->setName ("systemFlagsDef"); - - FlagObj *fo = new FlagObj (mapCanvas); - fo->load(QPixmap(flag_note_xpm)); - fo->setName("note"); - fo->setToolTip(tr("Note")); - systemFlagsDefault->addFlag (fo); // makes deep copy - - fo->load(QPixmap(flag_url_xpm)); - fo->setName("url"); - fo->setToolTip(tr("WWW Document (external)")); - systemFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_vymlink_xpm)); - fo->setName("vymLink"); - fo->setToolTip(tr("Link to another vym map")); - systemFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_scrolled_right_xpm)); - fo->setName("scrolledright"); - fo->setToolTip(tr("subtree is scrolled")); - systemFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_tmpUnscrolled_right_xpm)); - fo->setName("tmpUnscrolledright"); - fo->setToolTip(tr("subtree is temporary scrolled")); - systemFlagsDefault->addFlag (fo); - delete (fo); - } - if (!standardFlagsDefault) - { - standardFlagsDefault = new FlagRowObj (mapCanvas); - standardFlagsDefault->setVisibility (false); - standardFlagsDefault->setName ("standardFlagsDef"); - - FlagObj *fo = new FlagObj (mapCanvas); - fo->load(QPixmap(flag_exclamationmark_xpm)); - fo->setName("exclamationmark"); - fo->setToolTip(tr("Take care!")); - standardFlagsDefault->addFlag (fo); // makes deep copy - - fo->load(QPixmap(flag_questionmark_xpm)); - fo->setName("questionmark"); - fo->setToolTip(tr("Really?")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_hook_green_xpm)); - fo->setName("hook-green"); - fo->setToolTip(tr("ok!")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_cross_red_xpm)); - fo->setName("cross-red"); - fo->setToolTip(tr("Not ok!")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_stopsign_xpm)); - fo->setName("stopsign"); - fo->setToolTip(tr("This won't work!")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_smiley_good_xpm)); - fo->setName("smiley-good"); - fo->setToolTip(tr("Good")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_smiley_sad_xpm)); - fo->setName("smiley-sad"); - fo->setToolTip(tr("Bad")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_clock_xpm)); - fo->setName("clock"); - fo->setToolTip(tr("Time critical")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_lamp_xpm)); - fo->setName("lamp"); - fo->setToolTip(tr("Idea!")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_arrow_up_xpm)); - fo->setName("arrow-up"); - fo->setToolTip(tr("Important")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_arrow_down_xpm)); - fo->setName("arrow-down"); - fo->setToolTip(tr("Unimportant")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_thumb_up_xpm)); - fo->setName("thumb-up"); - fo->setToolTip(tr("I like this")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_thumb_down_xpm)); - fo->setName("thumb-down"); - fo->setToolTip(tr("I do not like this")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_heart_xpm)); - fo->setName("heart"); - fo->setToolTip(tr("I just love... ")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_flash_xpm)); - fo->setName("flash"); - fo->setToolTip(tr("Dangerous")); - standardFlagsDefault->addFlag (fo); - - fo->load(QPixmap(flag_lifebelt_xpm)); - fo->setName("lifebelt"); - fo->setToolTip(tr("This will help")); - standardFlagsDefault->addFlag (fo); - delete (fo); - - } - - mapCenter = new MapCenterObj(mapCanvas); - mapCenter->setVisibility (true); - mapCenter->setMapEditor (this); - mapCenter->setHeading (tr("New Map")); + mapNum++; + + + mapScene= new QGraphicsScene(parent); + //mapScene= new QGraphicsScene(QRectF(0,0,width(),height()), parent); + mapScene->setBackgroundBrush (QBrush(Qt::white, Qt::SolidPattern)); + + model=new VymModel(); + model->setScene (mapScene); + model->setMapEditor (this); + + setScene (mapScene); printer=NULL; - lineedit = new QLineEdit(this, "lineedit" ); - connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEditNoSave() ) ); - lineedit->hide(); - - actColor=black; setColor (actColor); - deflinkcolor=QColor (0,0,255); - linkcolorhint=DefaultColor; - linkstyle=StylePolyParabel; - mapCanvas->setBackgroundColor (white); - - // Create bitmap cursors, patform dependant - #if defined(Q_OS_MACX) - #include "icons/cursorhandopen16.xpm" - #include "icons/cursorcolorpicker16.xpm" - QBitmap cb( 16, 16, chandopen, TRUE ); - QBitmap cm( 16, 16, chandopenmask, TRUE ); - handOpenCursor=QCursor ( cb, cm ); - // set hot spot to tip of picker - pickColorCursor=QCursor ( cursorcolorpicker_xpm, 1,15 ); - #else - #include "icons/cursorhandopen.xpm" - #include "icons/cursorcolorpicker.xpm" - - QBitmap cb( 32, 32, chandopen, TRUE ); - QBitmap cm( 32, 32, chandopenmask, TRUE ); - handOpenCursor=QCursor ( cb, cm ); - // set hot spot to tip of picker - pickColorCursor=QCursor ( cursorcolorpicker_xpm, 5,27 ); - #endif - + defLinkColor=QColor (0,0,255); + defXLinkColor=QColor (180,180,180); + linkcolorhint=LinkableMapObj::DefaultColor; + linkstyle=LinkableMapObj::PolyParabel; + + // Create bitmap cursors, platform dependant + HandOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen.png"),1,1); + PickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 ); + CopyCursor=QCursor ( QPixmap(iconPath+"cursorcopy.png"), 1,1 ); + XLinkCursor=QCursor ( QPixmap(iconPath+"cursorxlink.png"), 1,7 ); + + setFocusPolicy (Qt::StrongFocus); pickingColor=false; + drawingLink=false; + copyingObj=false; editingBO=NULL; - selection=NULL; - selectionLast=NULL; movingObj=NULL; + xelection.setModel (model); + xelection.unselect(); + + defXLinkWidth=1; + defXLinkColor=QColor (230,230,230); + mapChanged=false; mapDefault=true; mapUnsaved=false; - undoSelection=NULL; zipped=true; filePath=""; - fileName="unnamed"; + fileName=tr("unnamed"); mapName=""; + stepsTotal=settings.readNumEntry("/mapeditor/stepsTotal",100); + undoSet.setEntry ("/history/stepsTotal",QString::number(stepsTotal)); + mainWindow->updateHistory (undoSet); + // Initialize find routine itFind=NULL; EOFind=false; @@ -325,159 +123,167 @@ printFrame=true; printFooter=true; - blockreposition=false; - isInteractive=interactive; - if (isInteractive) - // Create temporary files - makeTmpDirs(); - - // Initially set movingCentre - updateViewCenter(); - - mapCenter->reposition(); // for positioning heading -} - -MapEditor::~MapEditor() -{ - //cout <<"Destructor MapEditor\n"; - if (isInteractive) delTmpDirs(); - - // Save Settings - //settings.writeEntry( "/vym/mapeditor/editmode/autoselect", ); - -} - -QColor MapEditor::color() -{ - return actColor; -} - -QColor MapEditor::backgroundColor() -{ - return mapCanvas->backgroundColor(); -} - -MapCenterObj* MapEditor::getMapCenter() -{ - return mapCenter; -} - -QCanvas* MapEditor::getCanvas() -{ - return mapCanvas; -} - -void MapEditor::adjustCanvasSize() -{ - // To adjust the canvas to map, viewport size and position, we have to - // do some coordinate magic... - // - // Get rectangle of (scroll-)view. - // We want to be in canvas coords, so - // we map. Important if view is zoomed... - QRect view = inverseWorldMatrix().mapRect( QRect( contentsX(), contentsY(), - visibleWidth(), visibleHeight()) ); - - // Now we need the bounding box of view AND map to calc the correct canvas size. - // Why? Because if the map itself is moved out of view, the view has to be enlarged - // to avoid jumping aroung... - QRect map=mapCenter->getTotalBBox(); - - // right edge - left edge - int cw= max(map.x() + map.width(), view.x() + view.width()) - min(map.x(), view.x()); - int ch= max(map.y() + map.height(), view.y() + view.height()) - min(map.y(), view.y()); - - - if ( (cw!=mapCanvas->width()) || (ch!=mapCanvas->height()) || - !mapCanvas->onCanvas (map.topLeft()) || !mapCanvas->onCanvas (map.bottomRight()) - ) - { - // move the map on canvas (in order to not move it on screen) this is neccessary - // a) if topleft corner of canvas is left or above topleft corner of view and also left of - // above topleft corner of map. E.g. if map is completly inside view, but it would be possible - // to scroll to an empty area of canvas to the left. - // b) if topleft corner of map left of or above topleft of canvas - int dx=0; - int dy=0; - - if (cw > mapCanvas->width() ) - { - if (map.x()<0) dx=-map.x(); - } - if (cw < mapCanvas->width() ) - dx=-min (view.x(),map.x()); - if (ch > mapCanvas->height() ) - { - if (map.y()<0) dy=-map.y(); - } - if (ch < mapCanvas->height() ) - { - dy=-min (view.y(),map.y()); - } - // We really have to resize now. Let's go... - mapCanvas->resize (cw,ch); - if ( (dx!=0) || (dy!=0) ) - { - mapCenter->moveAllBy(dx,dy); - mapCenter->reposition(); - - // scroll the view (in order to not move map on screen) - scrollBy (dx,dy); - } + blockReposition=false; + blockSaveState=false; + + hidemode=HideNone; + + // Create temporary files + makeTmpDirs(); + + curStep=0; + redosAvail=0; + undosAvail=0; + + setAcceptDrops (true); + + model->reposition(); + + // autosave + autosaveTimer=new QTimer (this); + connect(autosaveTimer, SIGNAL(timeout()), this, SLOT(autosave())); + + fileChangedTimer=new QTimer (this); + fileChangedTimer->start(3000); + connect(fileChangedTimer, SIGNAL(timeout()), this, SLOT(fileChanged())); + + // Network + netstate=Offline; + + // Attributes //FIXME testing only... + QString k; + AttributeDef *ad; + attrTable= new AttributeTable(); + k="A - StringList"; + ad=attrTable->addKey (k,StringList); + if (ad) + { + QStringList sl; + sl <<"val 1"<<"val 2"<< "val 3"; + ad->setValue (QVariant (sl)); + } + //attrTable->addValue ("Key A","P 1"); + //attrTable->addValue ("Key A","P 2"); + //attrTable->addValue ("Key A","P 3"); + //attrTable->addValue ("Key A","P 4"); + k="B - FreeString"; + ad=attrTable->addKey (k,FreeString); + if (ad) + { + //attrTable->addValue ("Key B","w1"); + //attrTable->addValue ("Key B","w2"); + } + k="C - UniqueString"; + ad=attrTable->addKey (k,UniqueString); + if (ad) + { + //attrTable->addKey ("Key Prio"); + //attrTable->addValue ("Key Prio","Prio 1"); + //attrTable->addValue ("Key Prio","Prio 2"); } } -bool MapEditor::blockReposition() -{ - return blockreposition; +MapEditor::~MapEditor() +{ + //cout <<"Destructor MapEditor\n"; + autosaveTimer->stop(); + fileChangedTimer->stop(); + + // tmpMapDir is in tmpVymDir, so it gets removed automagically when vym closes + + //removeDir(QDir(tmpMapDir)); + delete (model); } +VymModel* MapEditor::getModel() +{ + return model; +} + +QGraphicsScene * MapEditor::getScene() +{ + return mapScene; +} + +MapEditor::State MapEditor::getState() +{ + return state; +} + +void MapEditor::setStateEditHeading(bool s) +{ + if (s) + { + if (state==Idle) state=EditHeading; + } + else + state=Idle; +} + +bool MapEditor::isRepositionBlocked() +{ + return blockReposition; +} + +void MapEditor::setSaveStateBlocked(bool b) +{ + blockSaveState=b; +} + +bool MapEditor::isSelectBlocked() +{ + if (state==EditHeading) + return true; + else + return false; +} + +QString MapEditor::getName (const LinkableMapObj *lmo) +{ + QString s; + if (!lmo) return QString("Error: NULL has no name!"); + + if ((typeid(*lmo) == typeid(BranchObj) || + typeid(*lmo) == typeid(MapCenterObj))) + { + + s=(((BranchObj*)lmo)->getHeading()); + if (s=="") s="unnamed"; + return QString("branch (%1)").arg(s); + } + if ((typeid(*lmo) == typeid(FloatImageObj) )) + return QString ("floatimage [%1]").arg(((FloatImageObj*)lmo)->getOriginalFilename()); + return QString("Unknown type has no name!"); +} + void MapEditor::makeTmpDirs() { // Create unique temporary directories - char tmpdir[]="/tmp/vym-XXXXXX"; - bakMapDir=mkdtemp(tmpdir); - makeSubDirs(bakMapDir); - // FIXME set permissions - // and maybe use QT method for portability + tmpMapDir = tmpVymDir+QString("/mapeditor-%1").arg(mapNum); + histPath = tmpMapDir+"/history"; + QDir d; + d.mkdir (tmpMapDir); } -void MapEditor::delTmpDirs() -{ - //FIXME delete tmp directory, better use QT methods here: - system ( "rm -rf "+ bakMapDir ); -} - - -void MapEditor::makeSubDirs(const QString &s) -{ - QDir d(s); - d.mkdir ("images"); - d.mkdir ("flags"); -} - - -QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, SaveMode savemode) -{ - // tmpdir temporary directory to which data will be writte +QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPointF &offset, LinkableMapObj *saveSel) +{ + // tmpdir temporary directory to which data will be written // prefix mapname, which will be appended to images etc. // writeflags Only write flags for "real" save of map, not undo - // offset offset of bbox of whole map in canvas. + // offset offset of bbox of whole map in scene. // Needed for XML export - // completeMap if false, only vympart will be written, without - // mapcenter // Save Header QString ls; switch (linkstyle) { - case StyleLine: + case LinkableMapObj::Line: ls="StyleLine"; break; - case StyleParabel: + case LinkableMapObj::Parabel: ls="StyleParabel"; break; - case StylePolyLine: + case LinkableMapObj::PolyLine: ls="StylePolyLine"; break; default: @@ -487,17 +293,20 @@ QString s="\n"; QString colhint=""; - if (linkcolorhint==HeadingColor) + if (linkcolorhint==LinkableMapObj::HeadingColor) colhint=attribut("linkColorHint","HeadingColor"); - QString mapAttr=attribut("version",__VYM_VERSION__); - if (savemode==CompleteMap) - mapAttr+= attribut("author",mapCenter->getAuthor()) + - attribut("comment",mapCenter->getComment()) + - attribut("date",mapCenter->getDate()) + - attribut("backgroundColor", mapCanvas->backgroundColor().name() ) + + QString mapAttr=attribut("version",vymVersion); + if (!saveSel) + mapAttr+= attribut("author",model->getAuthor()) + + attribut("comment",model->getComment()) + + attribut("date",model->getDate()) + + attribut("backgroundColor", mapScene->backgroundBrush().color().name() ) + + attribut("selectionColor", xelection.getColor().name() ) + attribut("linkStyle", ls ) + - attribut("linkColor", deflinkcolor.name() ) + + attribut("linkColor", defLinkColor.name() ) + + attribut("defXLinkColor", defXLinkColor.name() ) + + attribut("defXLinkWidth", QString().setNum(defXLinkWidth,10) ) + colhint; s+=beginElement("vymmap",mapAttr); incIndent(); @@ -505,92 +314,1170 @@ // Find the used flags while traversing the tree standardFlagsDefault->resetUsedCounter(); + // Reset the counters before saving + // TODO constr. of FIO creates lots of objects, better do this in some other way... + FloatImageObj (mapScene).resetSaveCounter(); + // Build xml recursivly - if (savemode==CompleteMap) - s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset); + if (!saveSel || typeid (*saveSel) == typeid (MapCenterObj)) + // Save complete map, if saveSel not set + s+=model->saveToDir(tmpdir,prefix,writeflags,offset); else { - if ( undoSelection && - typeid(*undoSelection) == typeid(BranchObj) ) - s+=((BranchObj*)(undoSelection))->saveToDir(tmpdir,prefix,offset); + if ( typeid(*saveSel) == typeid(BranchObj) ) + // Save Subtree + s+=((BranchObj*)(saveSel))->saveToDir(tmpdir,prefix,offset); + else if ( typeid(*saveSel) == typeid(FloatImageObj) ) + // Save image + s+=((FloatImageObj*)(saveSel))->saveToDir(tmpdir,prefix); } // Save local settings - s+=settings.getXMLData (destPath); + s+=settings.getDataXML (destPath); // Save selection - if (selection) - s+=valueElement("select",selection->getSelectString()); + if (!xelection.isEmpty() && !saveSel ) + s+=valueElement("select",xelection.getSelectString()); decIndent(); s+=endElement("vymmap"); if (writeflags) standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags); - return s; } -void MapEditor::saveState() -{ - saveState (CompleteMap,NULL); +QString MapEditor::getHistoryDir() +{ + QString histName(QString("history-%1").arg(curStep)); + return (tmpMapDir+"/"+histName); } -void MapEditor::saveState(const SaveMode &mode, LinkableMapObj *part) -{ - // all binary data is saved in bakMapDir (created in Constructor) - // the xml data itself is kept in memory in backupXML - // - // For faster write/read of data, a part of the map can be - // written. Then the undoSelection will mark, which part of the - // map should be replaced if an undo is wanted later. - - if (mode==PartOfMap && part && (typeid(*part) == typeid (BranchObj) ) ) - { - // Writing a vympart only is useful for BranchObj - undoSelection=part; - backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),PartOfMap); - } else - { - undoSelection=NULL; - backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),CompleteMap); +void MapEditor::saveState(const SaveMode &savemode, const QString &undoSelection, const QString &undoCom, const QString &redoSelection, const QString &redoCom, const QString &comment, LinkableMapObj *saveSel) +{ + sendData(redoCom); //FIXME testing + + // Main saveState + + + if (blockSaveState) return; + + if (debug) cout << "ME::saveState() for "<stepsTotal) curStep=1; + + QString backupXML=""; + QString histDir=getHistoryDir(); + QString bakMapPath=histDir+"/map.xml"; + + // Create histDir if not available + QDir d(histDir); + if (!d.exists()) + makeSubDirs (histDir); + + // Save depending on how much needs to be saved + if (saveSel) + backupXML=saveToDir (histDir,mapName+"-",false, QPointF (),saveSel); + + QString undoCommand=""; + if (savemode==UndoCommand) + { + undoCommand=undoCom; } + else if (savemode==PartOfMap ) + { + undoCommand=undoCom; + undoCommand.replace ("PATH",bakMapPath); + } + + if (!backupXML.isEmpty()) + // Write XML Data to disk + saveStringToDisk (bakMapPath,backupXML); + + // We would have to save all actions in a tree, to keep track of + // possible redos after a action. Possible, but we are too lazy: forget about redos. + redosAvail=0; + + // Write the current state to disk + undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail)); + undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail)); + undoSet.setEntry ("/history/curStep",QString::number(curStep)); + undoSet.setEntry (QString("/history/step-%1/undoCommand").arg(curStep),undoCommand); + undoSet.setEntry (QString("/history/step-%1/undoSelection").arg(curStep),undoSelection); + undoSet.setEntry (QString("/history/step-%1/redoCommand").arg(curStep),redoCom); + undoSet.setEntry (QString("/history/step-%1/redoSelection").arg(curStep),redoSelection); + undoSet.setEntry (QString("/history/step-%1/comment").arg(curStep),comment); + undoSet.setEntry (QString("/history/version"),vymVersion); + undoSet.writeSettings(histPath); + + if (debug) + { + // TODO remove after testing + //cout << " into="<< histPath.toStdString()<updateHistory (undoSet); + setChanged(); + updateActions(); } -void MapEditor::finishedLineEditNoSave() -{ - // This is called by finishedLineEdit or any MapEditor method, - // which wants to assure, that lineedits finish, before e.g. a branch is - // deleted - - // After calling LineEdit and using the clipboard, the - // focus is not any longer on the main widget, we - // have to restore it using parentWidget()->setFocus() - - if (editingBO!=NULL) - { - editingBO->setHeading(lineedit->text() ); - editingBO=NULL; - lineedit->releaseKeyboard(); - lineedit->hide(); - parentWidget()->setFocus(); - mapCenter->reposition(); - adjustCanvasSize(); - ensureSelectionVisible(); - } + +void MapEditor::saveStateChangingPart(LinkableMapObj *undoSel, LinkableMapObj* redoSel, const QString &rc, const QString &comment) +{ + // save the selected part of the map, Undo will replace part of map + QString undoSelection=""; + if (undoSel) + undoSelection=model->getSelectString(undoSel); + else + qWarning ("MapEditor::saveStateChangingPart no undoSel given!"); + QString redoSelection=""; + if (redoSel) + redoSelection=model->getSelectString(undoSel); + else + qWarning ("MapEditor::saveStateChangingPart no redoSel given!"); + + + saveState (PartOfMap, + undoSelection, "addMapReplace (\"PATH\")", + redoSelection, rc, + comment, + undoSel); } +void MapEditor::saveStateRemovingPart(LinkableMapObj *redoSel, const QString &comment) +{ + if (!redoSel) + { + qWarning ("MapEditor::saveStateRemovingPart no redoSel given!"); + return; + } + QString undoSelection=model->getSelectString (redoSel->getParObj()); + QString redoSelection=model->getSelectString(redoSel); + if (typeid(*redoSel) == typeid(BranchObj) ) + { + // save the selected branch of the map, Undo will insert part of map + saveState (PartOfMap, + undoSelection, QString("addMapInsert (\"PATH\",%1)").arg(((BranchObj*)redoSel)->getNum()), + redoSelection, "delete ()", + comment, + redoSel); + } +} + + +void MapEditor::saveState(LinkableMapObj *undoSel, const QString &uc, LinkableMapObj *redoSel, const QString &rc, const QString &comment) +{ + // "Normal" savestate: save commands, selections and comment + // so just save commands for undo and redo + // and use current selection + + QString redoSelection=""; + if (redoSel) redoSelection=model->getSelectString(redoSel); + QString undoSelection=""; + if (undoSel) undoSelection=model->getSelectString(undoSel); + + saveState (UndoCommand, + undoSelection, uc, + redoSelection, rc, + comment, + NULL); +} + +void MapEditor::saveState(const QString &undoSel, const QString &uc, const QString &redoSel, const QString &rc, const QString &comment) +{ + // "Normal" savestate: save commands, selections and comment + // so just save commands for undo and redo + // and use current selection + saveState (UndoCommand, + undoSel, uc, + redoSel, rc, + comment, + NULL); +} + +void MapEditor::saveState(const QString &uc, const QString &rc, const QString &comment) +{ + // "Normal" savestate applied to model (no selection needed): + // save commands and comment + saveState (UndoCommand, + NULL, uc, + NULL, rc, + comment, + NULL); +} + + +void MapEditor::parseAtom(const QString &atom) +{ + BranchObj *selb=xelection.getBranch(); + QString s,t; + double x,y; + int n; + bool b,ok; + + // Split string s into command and parameters + parser.parseAtom (atom); + QString com=parser.getCommand(); + + // External commands + ///////////////////////////////////////////////////////////////////// + if (com=="addBranch") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else + { + QList pl; + pl << 0 <<1; + if (parser.checkParCount(pl)) + { + if (parser.parCount()==0) + addNewBranch (0); + else + { + n=parser.parInt (ok,0); + if (ok ) addNewBranch (n); + } + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="addBranchBefore") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else + { + if (parser.parCount()==0) + { + addNewBranchBefore (); + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com==QString("addMapCenter")) + { + if (parser.checkParCount(2)) + { + x=parser.parDouble (ok,0); + if (ok) + { + y=parser.parDouble (ok,1); + if (ok) model->addMapCenter (QPointF(x,y)); + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com==QString("addMapReplace")) + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + //s=parser.parString (ok,0); // selection + t=parser.parString (ok,0); // path to map + if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t); + addMapReplaceInt(model->getSelectString(selb),t); + } + ///////////////////////////////////////////////////////////////////// + } else if (com==QString("addMapInsert")) + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else + { + if (parser.checkParCount(2)) + { + t=parser.parString (ok,0); // path to map + n=parser.parInt(ok,1); // position + if (QDir::isRelativePath(t)) t=(tmpMapDir + "/"+t); + addMapInsertInt(t,n); + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="clearFlags") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + selb->clearStandardFlags(); + selb->updateFlagsToolbar(); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="colorBranch") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + QColor c=parser.parColor (ok,0); + if (ok) colorBranch (c); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="colorSubtree") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + QColor c=parser.parColor (ok,0); + if (ok) colorSubtree (c); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="copy") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + //FIXME missing action for copy + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="cut") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if ( xelection.type()!=Selection::Branch && + xelection.type()!=Selection::MapCenter && + xelection.type()!=Selection::FloatImage ) + { + parser.setError (Aborted,"Type of selection is not a branch or floatimage"); + } else if (parser.checkParCount(0)) + { + cut(); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="delete") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } + /*else if (xelection.type() != Selection::Branch && xelection.type() != Selection::FloatImage ) + { + parser.setError (Aborted,"Type of selection is wrong."); + } + */ + else if (parser.checkParCount(0)) + { + deleteSelection(); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="deleteKeepChilds") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + deleteKeepChilds(); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="deleteChilds") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + deleteChilds(); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="exportASCII") + { + QString fname=""; + ok=true; + if (parser.parCount()>=1) + // Hey, we even have a filename + fname=parser.parString(ok,0); + if (!ok) + { + parser.setError (Aborted,"Could not read filename"); + } else + { + exportASCII (fname,false); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="exportImage") + { + QString fname=""; + ok=true; + if (parser.parCount()>=2) + // Hey, we even have a filename + fname=parser.parString(ok,0); + if (!ok) + { + parser.setError (Aborted,"Could not read filename"); + } else + { + QString format="PNG"; + if (parser.parCount()>=2) + { + format=parser.parString(ok,1); + } + exportImage (fname,false,format); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="exportXHTML") + { + QString fname=""; + ok=true; + if (parser.parCount()>=2) + // Hey, we even have a filename + fname=parser.parString(ok,1); + if (!ok) + { + parser.setError (Aborted,"Could not read filename"); + } else + { + exportXHTML (fname,false); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="exportXML") + { + QString fname=""; + ok=true; + if (parser.parCount()>=2) + // Hey, we even have a filename + fname=parser.parString(ok,1); + if (!ok) + { + parser.setError (Aborted,"Could not read filename"); + } else + { + exportXML (fname,false); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="importDir") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) importDirInt(s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="linkTo") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if ( selb) + { + if (parser.checkParCount(4)) + { + // 0 selectstring of parent + // 1 num in parent (for branches) + // 2,3 x,y of mainbranch or mapcenter + s=parser.parString(ok,0); + LinkableMapObj *dst=model->findObjBySelect (s); + if (dst) + { + if (typeid(*dst) == typeid(BranchObj) ) + { + // Get number in parent + n=parser.parInt (ok,1); + if (ok) + { + selb->linkTo ((BranchObj*)(dst),n); + xelection.update(); + } + } else if (typeid(*dst) == typeid(MapCenterObj) ) + { + selb->linkTo ((BranchObj*)(dst),-1); + // Get coordinates of mainbranch + x=parser.parDouble(ok,2); + if (ok) + { + y=parser.parDouble(ok,3); + if (ok) + { + selb->move (x,y); + xelection.update(); + } + } + } + } + } + } else if ( xelection.type() == Selection::FloatImage) + { + if (parser.checkParCount(1)) + { + // 0 selectstring of parent + s=parser.parString(ok,0); + LinkableMapObj *dst=model->findObjBySelect (s); + if (dst) + { + if (typeid(*dst) == typeid(BranchObj) || + typeid(*dst) == typeid(MapCenterObj)) + linkTo (model->getSelectString(dst)); + } else + parser.setError (Aborted,"Destination is not a branch"); + } + } else + parser.setError (Aborted,"Type of selection is not a floatimage or branch"); + ///////////////////////////////////////////////////////////////////// + } else if (com=="loadImage") + { + if (xelection.isEmpty()) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) loadFloatImageInt (s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="moveBranchUp") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + moveBranchUp(); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="moveBranchDown") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + moveBranchDown(); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="move") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if ( xelection.type()!=Selection::Branch && + xelection.type()!=Selection::MapCenter && + xelection.type()!=Selection::FloatImage ) + { + parser.setError (Aborted,"Type of selection is not a branch or floatimage"); + } else if (parser.checkParCount(2)) + { + x=parser.parDouble (ok,0); + if (ok) + { + y=parser.parDouble (ok,1); + if (ok) move (x,y); + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="moveRel") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if ( xelection.type()!=Selection::Branch && + xelection.type()!=Selection::MapCenter && + xelection.type()!=Selection::FloatImage ) + { + parser.setError (Aborted,"Type of selection is not a branch or floatimage"); + } else if (parser.checkParCount(2)) + { + x=parser.parDouble (ok,0); + if (ok) + { + y=parser.parDouble (ok,1); + if (ok) moveRel (x,y); + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="nop") + { + ///////////////////////////////////////////////////////////////////// + } else if (com=="paste") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + n=parser.parInt (ok,0); + if (ok) pasteNoSave(n); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="qa") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(4)) + { + QString c,u; + c=parser.parString (ok,0); + if (!ok) + { + parser.setError (Aborted,"No comment given"); + } else + { + s=parser.parString (ok,1); + if (!ok) + { + parser.setError (Aborted,"First parameter is not a string"); + } else + { + t=parser.parString (ok,2); + if (!ok) + { + parser.setError (Aborted,"Condition is not a string"); + } else + { + u=parser.parString (ok,3); + if (!ok) + { + parser.setError (Aborted,"Third parameter is not a string"); + } else + { + if (s!="heading") + { + parser.setError (Aborted,"Unknown type: "+s); + } else + { + if (! (t=="eq") ) + { + parser.setError (Aborted,"Unknown operator: "+t); + } else + { + if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else + { + if (selb->getHeading() == u) + { + cout << "PASSED: " << qPrintable (c) << endl; + } else + { + cout << "FAILED: " << qPrintable (c) << endl; + } + } + } + } + } + } + } + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="saveImage") + { + FloatImageObj *fio=xelection.getFloatImage(); + if (!fio) + { + parser.setError (Aborted,"Type of selection is not an image"); + } else if (parser.checkParCount(2)) + { + s=parser.parString(ok,0); + if (ok) + { + t=parser.parString(ok,1); + if (ok) saveFloatImageInt (fio,t,s); + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="scroll") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + if (!scrollBranch (selb)) + parser.setError (Aborted,"Could not scroll branch"); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="select") + { + if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) select (s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="selectLastBranch") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + BranchObj *bo=selb->getLastBranch(); + if (!bo) + parser.setError (Aborted,"Could not select last branch"); + selectInt (bo); + + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="selectLastImage") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + FloatImageObj *fio=selb->getLastFloatImage(); + if (!fio) + parser.setError (Aborted,"Could not select last image"); + selectInt (fio); + + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="selectLatestAdded") + { + if (latestSelection.isEmpty() ) + { + parser.setError (Aborted,"No latest added object"); + } else + { + if (!select (latestSelection)) + parser.setError (Aborted,"Could not select latest added object "+latestSelection); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setFrameType") + { + if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage) + { + parser.setError (Aborted,"Type of selection does not allow setting frame type"); + } + else if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) setFrameType (s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setFramePenColor") + { + if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage) + { + parser.setError (Aborted,"Type of selection does not allow setting of pen color"); + } + else if (parser.checkParCount(1)) + { + QColor c=parser.parColor(ok,0); + if (ok) setFramePenColor (c); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setFrameBrushColor") + { + if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage) + { + parser.setError (Aborted,"Type of selection does not allow setting brush color"); + } + else if (parser.checkParCount(1)) + { + QColor c=parser.parColor(ok,0); + if (ok) setFrameBrushColor (c); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setFramePadding") + { + if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage) + { + parser.setError (Aborted,"Type of selection does not allow setting frame padding"); + } + else if (parser.checkParCount(1)) + { + n=parser.parInt(ok,0); + if (ok) setFramePadding(n); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setFrameBorderWidth") + { + if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage) + { + parser.setError (Aborted,"Type of selection does not allow setting frame border width"); + } + else if (parser.checkParCount(1)) + { + n=parser.parInt(ok,0); + if (ok) setFrameBorderWidth (n); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setMapAuthor") + { + if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) setMapAuthor (s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setMapComment") + { + if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) setMapComment(s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setMapBackgroundColor") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! xelection.getBranch() ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + QColor c=parser.parColor (ok,0); + if (ok) setMapBackgroundColor (c); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setMapDefLinkColor") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + QColor c=parser.parColor (ok,0); + if (ok) setMapDefLinkColor (c); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setMapLinkStyle") + { + if (parser.checkParCount(1)) + { + s=parser.parString (ok,0); + if (ok) setMapLinkStyle(s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setHeading") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + s=parser.parString (ok,0); + if (ok) + setHeading (s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setHideExport") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (xelection.type()!=Selection::Branch && xelection.type() != Selection::MapCenter &&xelection.type()!=Selection::FloatImage) + { + parser.setError (Aborted,"Type of selection is not a branch or floatimage"); + } else if (parser.checkParCount(1)) + { + b=parser.parBool(ok,0); + if (ok) setHideExport (b); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setIncludeImagesHorizontally") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + b=parser.parBool(ok,0); + if (ok) setIncludeImagesHor(b); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setIncludeImagesVertically") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + b=parser.parBool(ok,0); + if (ok) setIncludeImagesVer(b); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setHideLinkUnselected") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if ( xelection.type()!=Selection::Branch && xelection.type()!= Selection::MapCenter && xelection.type()!=Selection::FloatImage) + { + parser.setError (Aborted,"Type of selection does not allow hiding the link"); + } else if (parser.checkParCount(1)) + { + b=parser.parBool(ok,0); + if (ok) setHideLinkUnselected(b); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setSelectionColor") + { + if (parser.checkParCount(1)) + { + QColor c=parser.parColor (ok,0); + if (ok) setSelectionColorInt (c); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setURL") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + s=parser.parString (ok,0); + if (ok) setURL(s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setVymLink") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + s=parser.parString (ok,0); + if (ok) setVymLinkInt(s); + } + } + ///////////////////////////////////////////////////////////////////// + else if (com=="setFlag") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) + { + selb->activateStandardFlag(s); + selb->updateFlagsToolbar(); + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="setFrameType") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) + setFrameType (s); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="sortChildren") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + sortChildren(); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="toggleFlag") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) + { + selb->toggleStandardFlag(s); + selb->updateFlagsToolbar(); + } + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="unscroll") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + if (!unscrollBranch (selb)) + parser.setError (Aborted,"Could not unscroll branch"); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="unscrollChilds") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(0)) + { + unscrollChilds (); + } + ///////////////////////////////////////////////////////////////////// + } else if (com=="unsetFlag") + { + if (xelection.isEmpty() ) + { + parser.setError (Aborted,"Nothing selected"); + } else if (! selb ) + { + parser.setError (Aborted,"Type of selection is not a branch"); + } else if (parser.checkParCount(1)) + { + s=parser.parString(ok,0); + if (ok) + { + selb->deactivateStandardFlag(s); + selb->updateFlagsToolbar(); + } + } + } else + parser.setError (Aborted,"Unknown command"); + + // Any errors? + if (parser.errorLevel()==NoError) + { + // setChanged(); FIXME should not be called e.g. for export?! + model->reposition(); + } + else + { + // TODO Error handling + qWarning("MapEditor::parseAtom: Error!"); + qWarning(parser.errorMessage()); + } +} + +void MapEditor::runScript (QString script) +{ + parser.setScript (script); + parser.runScript(); + while (parser.next() ) + parseAtom(parser.getAtom()); +} bool MapEditor::isDefault() { return mapDefault; } -bool MapEditor::isUnsaved() -{ - return mapUnsaved; -} - bool MapEditor::hasChanged() { return mapChanged; @@ -598,49 +1485,55 @@ void MapEditor::setChanged() { + if (!mapChanged) + autosaveTimer->start(settings.value("/mapeditor/autosave/ms/",300000).toInt()); mapChanged=true; mapDefault=false; mapUnsaved=true; - actionEditUndo->setEnabled (true); - actionFileSave->setEnabled (true); findReset(); + } void MapEditor::closeMap() { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - // Unselect before disabling the toolbar actions - if (selection) selection->unselect(); - selection=NULL; + if (!xelection.isEmpty() ) xelection.unselect(); + xelection.clear(); updateActions(); clear(); - close(); + // close(); FIXME needed? } -void MapEditor::setFilePath(QString fname) -{ - setFilePath (fname,fname); +void MapEditor::setFilePath(QString fpath, QString destname) +{ + if (fpath.isEmpty() || fpath=="") + { + filePath=""; + fileName=""; + destPath=""; + } else + { + filePath=fpath; // becomes absolute path + fileName=fpath; // gets stripped of path + destPath=destname; // needed for vymlinks and during load to reset fileChangedTime + + // If fpath is not an absolute path, complete it + filePath=QDir(fpath).absPath(); + fileDir=filePath.left (1+filePath.findRev ("/")); + + // Set short name, too. Search from behind: + int i=fileName.findRev("/"); + if (i>=0) fileName=fileName.remove (0,i+1); + + // Forget the .vym (or .xml) for name of map + mapName=fileName.left(fileName.findRev(".",-1,true) ); + } } -void MapEditor::setFilePath(QString fname, QString destname) -{ - filePath=fname; - fileName=fname; - destPath=destname; - - // If fname is not an absolute path, complete it - filePath=QDir(fname).absPath(); - fileDir=filePath.left (1+filePath.findRev ("/")); - - // Set short name, too. Search from behind: - int i=fileName.findRev("/"); - if (i>=0) fileName=fileName.remove (0,i+1); - - // Forget the .vym (or .xml) for name of map - mapName=fileName.left(fileName.findRev(".",-1,true) ); +void MapEditor::setFilePath(QString fpath) +{ + setFilePath (fpath,fpath); } QString MapEditor::getFilePath() @@ -663,150 +1556,311 @@ return destPath; } -int MapEditor::load (QString &fname, const LoadMode &lmode) -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - int returnCode=0; - +ErrorCode MapEditor::load (QString fname, const LoadMode &lmode, const FileType &ftype) +{ + ErrorCode err=success; + + parseBaseHandler *handler; + fileType=ftype; + switch (fileType) + { + case VymMap: handler=new parseVYMHandler; break; + case FreemindMap : handler=new parseFreemindHandler; break; + default: + QMessageBox::critical( 0, tr( "Critical Parse Error" ), + "Unknown FileType in MapEditor::load()"); + return aborted; + } if (lmode==NewMap) { - if (selection) selection->unselect(); - selection=NULL; - mapCenter->clear(); - mapCenter->setMapEditor(this); + xelection.clear(); + model->setMapEditor(this); // (map state is set later at end of load...) } else { - setChanged(); - saveState(PartOfMap,selection); + BranchObj *bo=xelection.getBranch(); + if (!bo) return aborted; + if (lmode==ImportAdd) + saveStateChangingPart( + bo, + bo, + QString("addMapInsert (%1)").arg(fname), + QString("Add map %1 to %2").arg(fname).arg(getName(bo))); + else + saveStateChangingPart( + bo, + bo, + QString("addMapReplace(%1)").arg(fname), + QString("Add map %1 to %2").arg(fname).arg(getName(bo))); } - - mapBuilderHandler handler; - QFile file( fname ); + + // Create temporary directory for packing + bool ok; + QString tmpZipDir=makeTmpDir (ok,"vym-pack"); + if (!ok) + { + QMessageBox::critical( 0, tr( "Critical Load Error" ), + tr("Couldn't create temporary directory before load\n")); + return aborted; + } + + // Try to unzip file + err=unzipDir (tmpZipDir,fname); + QString xmlfile; + if (err==nozip) + { + xmlfile=fname; + zipped=false; + } else + { + zipped=true; + + // Look for mapname.xml + xmlfile= fname.left(fname.findRev(".",-1,true)); + xmlfile=xmlfile.section( '/', -1 ); + QFile mfile( tmpZipDir + "/" + xmlfile + ".xml"); + if (!mfile.exists() ) + { + // mapname.xml does not exist, well, + // maybe someone renamed the mapname.vym file... + // Try to find any .xml in the toplevel + // directory of the .vym file + QStringList flist=QDir (tmpZipDir).entryList("*.xml"); + if (flist.count()==1) + { + // Only one entry, take this one + xmlfile=tmpZipDir + "/"+flist.first(); + } else + { + for ( QStringList::Iterator it = flist.begin(); it != flist.end(); ++it ) + *it=tmpZipDir + "/" + *it; + // TODO Multiple entries, load all (but only the first one into this ME) + //mainWindow->fileLoadFromTmp (flist); + //returnCode=1; // Silently forget this attempt to load + qWarning ("MainWindow::load (fn) multimap found..."); + } + + if (flist.isEmpty() ) + { + QMessageBox::critical( 0, tr( "Critical Load Error" ), + tr("Couldn't find a map (*.xml) in .vym archive.\n")); + err=aborted; + } + } //file doesn't exist + else + xmlfile=mfile.name(); + } + + QFile file( xmlfile); // I am paranoid: file should exist anyway // according to check in mainwindow. if (!file.exists() ) { QMessageBox::critical( 0, tr( "Critical Parse Error" ), - tr("Couldn't open map " +fname)+"."); - returnCode=1; + tr(QString("Couldn't open map %1").arg(file.name()))); + err=aborted; } else { - blockreposition=true; + bool blockSaveStateOrg=blockSaveState; + blockReposition=true; + blockSaveState=true; QXmlInputSource source( file); QXmlSimpleReader reader; - reader.setContentHandler( &handler ); - reader.setErrorHandler( &handler ); - handler.setMapEditor( this ); - handler.setTmpDir (filePath.left(filePath.findRev("/",-1))); // needed to load files with rel. path - handler.setLoadMode (lmode); + reader.setContentHandler( handler ); + reader.setErrorHandler( handler ); + handler->setModel ( model); + + + // We need to set the tmpDir in order to load files with rel. path + QString tmpdir; + if (zipped) + tmpdir=tmpZipDir; + else + tmpdir=fname.left(fname.findRev("/",-1)); + handler->setTmpDir (tmpdir); + handler->setInputFile (file.name()); + handler->setLoadMode (lmode); bool ok = reader.parse( source ); - blockreposition=false; + blockReposition=false; + blockSaveState=blockSaveStateOrg; file.close(); if ( ok ) { - mapCenter->reposition(); - adjustCanvasSize(); + model->reposition(); // FIXME reposition the view instead... + xelection.update(); if (lmode==NewMap) { mapDefault=false; mapChanged=false; mapUnsaved=false; + autosaveTimer->stop(); } + + // Reset timestamp to check for later updates of file + fileChangedTime=QFileInfo (destPath).lastModified(); } else { QMessageBox::critical( 0, tr( "Critical Parse Error" ), - tr( handler.errorProtocol() ) ); + tr( handler->errorProtocol() ) ); // returnCode=1; // Still return "success": the map maybe at least // partially read by the parser } } + + // Delete tmpZipDir + removeDir (QDir(tmpZipDir)); + updateActions(); - return returnCode; + + return err; } -int MapEditor::save (const SaveMode &savemode) -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - int returnCode=0; +ErrorCode MapEditor::save (const SaveMode &savemode) +{ + QString tmpZipDir; + QString mapFileName; + QString safeFilePath; + + ErrorCode err=success; + + if (zipped) + // save as .xml + mapFileName=mapName+".xml"; + else + // use name given by user, even if he chooses .doc + mapFileName=fileName; + + // Look, if we should zip the data: + if (!zipped) + { + QMessageBox mb( vymName, + tr("The map %1\ndid not use the compressed " + "vym file format.\nWriting it uncompressed will also write images \n" + "and flags and thus may overwrite files in the " + "given directory\n\nDo you want to write the map").arg(filePath), + QMessageBox::Warning, + QMessageBox::Yes | QMessageBox::Default, + QMessageBox::No , + QMessageBox::Cancel | QMessageBox::Escape); + mb.setButtonText( QMessageBox::Yes, tr("compressed (vym default)") ); + mb.setButtonText( QMessageBox::No, tr("uncompressed") ); + mb.setButtonText( QMessageBox::Cancel, tr("Cancel")); + switch( mb.exec() ) + { + case QMessageBox::Yes: + // save compressed (default file format) + zipped=true; + break; + case QMessageBox::No: + // save uncompressed + zipped=false; + break; + case QMessageBox::Cancel: + // do nothing + return aborted; + break; + } + } + + // First backup existing file, we + // don't want to add to old zip archives + QFile f(destPath); + if (f.exists()) + { + if ( settings.value ("/mapeditor/writeBackupFile").toBool()) + { + QString backupFileName(destPath + "~"); + QFile backupFile(backupFileName); + if (backupFile.exists() && !backupFile.remove()) + { + QMessageBox::warning(0, tr("Save Error"), + tr("%1\ncould not be removed before saving").arg(backupFileName)); + } + else if (!f.rename(backupFileName)) + { + QMessageBox::warning(0, tr("Save Error"), + tr("%1\ncould not be renamed before saving").arg(destPath)); + } + } + } + + if (zipped) + { + // Create temporary directory for packing + bool ok; + tmpZipDir=makeTmpDir (ok,"vym-zip"); + if (!ok) + { + QMessageBox::critical( 0, tr( "Critical Load Error" ), + tr("Couldn't create temporary directory before save\n")); + return aborted; + } + + safeFilePath=filePath; + setFilePath (tmpZipDir+"/"+ mapName+ ".xml", safeFilePath); + } // zipped // Create mapName and fileDir makeSubDirs (fileDir); - QString fname; - if (saveZipped()) - // save as .xml - fname=mapName+".xml"; - else - // use name given by user, even if he chooses .doc - fname=fileName; - - - // Check if fname is writeable - QFile file( fileDir+fname); - if (!file.open( IO_WriteOnly ) ) - { - QMessageBox::critical( 0, tr( "Critical Save Error" ), - tr("Couldn't write to ") +fileDir+fname); - return 1; - } - file.close(); QString saveFile; - saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),savemode); - - file.setName ( fileDir + fname); - if ( !file.open( IO_WriteOnly ) ) - { - // This should neverever happen - QMessageBox::critical(0, tr("Critcal save error"),"MapEditor::save() Couldn't open "+file.name()); - return 1; - } - - // Write it finally, and write in UTF8, no matter what - QTextStream ts( &file ); - ts.setEncoding (QTextStream::UnicodeUTF8); - ts << saveFile; - file.close(); - - if (returnCode==0) - { + if (savemode==CompleteMap || xelection.isEmpty()) + { + // Save complete map + saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),NULL); mapChanged=false; mapUnsaved=false; - actionFileSave->setEnabled(false); + autosaveTimer->stop(); } - - return returnCode; + else + { + // Save part of map + if (xelection.type()==Selection::FloatImage) + saveFloatImage(); + else + saveFile=saveToDir (fileDir,mapName+"-",true,QPointF(),xelection.getBranch()); + // TODO take care of multiselections + } + + if (!saveStringToDisk(fileDir+mapFileName,saveFile)) + { + err=aborted; + qWarning ("ME::saveStringToDisk failed!"); + } + + if (zipped) + { + // zip + if (err==success) err=zipDir (tmpZipDir,destPath); + + // Delete tmpDir + removeDir (QDir(tmpZipDir)); + + // Restore original filepath outside of tmp zip dir + setFilePath (safeFilePath); + } + + updateActions(); + fileChangedTime=QFileInfo (destPath).lastModified(); + return err; } -void MapEditor::setZipped (bool z) -{ - zipped=z; -} - -bool MapEditor::saveZipped () -{ - return zipped; -} void MapEditor::print() { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - if ( !printer ) { printer = new QPrinter; printer->setColorMode (QPrinter::Color); + printer->setPrinterName (settings.value("/mainwindow/printerName",printer->printerName()).toString()); + printer->setOutputFormat((QPrinter::OutputFormat)settings.value("/mainwindow/printerFormat",printer->outputFormat()).toInt()); + printer->setOutputFileName(settings.value("/mainwindow/printerFileName",printer->outputFileName()).toString()); } - QRect totalBBox=mapCenter->getTotalBBox(); + QRectF totalBBox=model->getTotalBBox(); // Try to set orientation automagically // Note: Interpretation of generated postscript is amibiguous, if @@ -825,208 +1879,256 @@ { QPainter pp(printer); + pp.setRenderHint(QPainter::Antialiasing,true); + // Don't print the visualisation of selection - LinkableMapObj *oldselection=NULL; - if (selection) + xelection.unselect(); + + QRectF mapRect=totalBBox; + QGraphicsRectItem *frame=NULL; + + if (printFrame) { - oldselection=selection; - selection->unselect(); - } - - // Handle sizes of map and paper: - // - // setWindow defines which part of the canvas will be transformed - // setViewport defines area on paper in device coordinates (dpi) - // e.g. (0,50,700,700) is upper part on A4 - // see also /usr/lib/qt3/doc/html/coordsys.html - - QPaintDeviceMetrics metrics (printer); - - double paperAspect = (double)metrics.width() / (double)metrics.height(); - double mapAspect = (double)totalBBox.width() / (double)totalBBox.height(); - - QRect mapRect=mapCenter->getTotalBBox(); - QCanvasRectangle *frame=NULL; - QCanvasText *footerFN=NULL; - QCanvasText *footerDate=NULL; - if (printFrame || printFooter) - { - - if (printFrame) - { - // Print frame around map - mapRect.setRect (mapRect.x()-10, mapRect.y()-10, - mapRect.width()+20, mapRect.height()+20); - frame=new QCanvasRectangle (mapRect,mapCanvas); - frame->setBrush (QColor(white)); - frame->setPen (QColor(black)); - frame->setZ(0); - frame->show(); - } - if (printFooter) - { - // Print footer below map - QFont font; - font.setPointSize(10); - footerFN=new QCanvasText (mapCanvas); - footerFN->setText ("VYM - " + fileName); - footerFN->setFont(font); - footerFN->move (mapRect.x(), mapRect.y() + mapRect.height() ); - footerFN->setZ(Z_TEXT); - footerFN->show(); - footerDate=new QCanvasText (mapCanvas); - footerDate->setText (QDate::currentDate().toString(Qt::TextDate)); - footerDate->setFont(font); - footerDate->move (mapRect.x()+mapRect.width()-footerDate->boundingRect().width(), mapRect.y() + mapRect.height() ); - footerDate->setZ(Z_TEXT); - footerDate->show(); - mapRect.setRect (mapRect.x(), mapRect.y(), - mapRect.width(), mapRect.height()+20); - } - pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()); - } else - { - pp.setWindow (mapRect); - } - + // Print frame around map + mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10, + totalBBox.width()+20, totalBBox.height()+20); + frame=mapScene->addRect (mapRect, QPen(Qt::black),QBrush(Qt::NoBrush)); + frame->setZValue(0); + frame->show(); + } + + + double paperAspect = (double)printer->width() / (double)printer->height(); + double mapAspect = (double)mapRect.width() / (double)mapRect.height(); + int viewBottom; if (mapAspect>=paperAspect) { // Fit horizontally to paper width - pp.setViewport(0,0, metrics.width(),(int)(metrics.width()/mapAspect) ); + //pp.setViewport(0,0, printer->width(),(int)(printer->width()/mapAspect) ); + viewBottom=(int)(printer->width()/mapAspect); } else { // Fit vertically to paper height - pp.setViewport(0,0,(int)(metrics.height()*mapAspect),metrics.height()); + //pp.setViewport(0,0,(int)(printer->height()*mapAspect),printer->height()); + viewBottom=printer->height(); } - - mapCanvas->drawArea(mapRect, &pp); // draw Canvas to printer - - // Delete Frame and footer - if (footerFN) + + if (printFooter) { - delete (footerFN); - delete (footerDate); - } + // Print footer below map + QFont font; + font.setPointSize(10); + pp.setFont (font); + QRectF footerBox(0,viewBottom,printer->width(),15); + pp.drawText ( footerBox,Qt::AlignLeft,"VYM - " +fileName); + pp.drawText ( footerBox, Qt::AlignRight, QDate::currentDate().toString(Qt::TextDate)); + } + mapScene->render ( + &pp, + QRectF (0,0,printer->width(),printer->height()-15), + QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height()) + ); + + // Viewport has paper dimension if (frame) delete (frame); // Restore selection - if (oldselection) - { - selection=oldselection; - selection->select(); - } + xelection.reselect(); + + // Save settings in vymrc + settings.writeEntry("/mainwindow/printerName",printer->printerName()); + settings.writeEntry("/mainwindow/printerFormat",printer->outputFormat()); + settings.writeEntry("/mainwindow/printerFileName",printer->outputFileName()); } } +void MapEditor::setAntiAlias (bool b) +{ + setRenderHint(QPainter::Antialiasing,b); +} + +void MapEditor::setSmoothPixmap(bool b) +{ + setRenderHint(QPainter::SmoothPixmapTransform,b); +} + QPixmap MapEditor::getPixmap() { - QRect mapRect=mapCenter->getTotalBBox(); - QPixmap pix (mapRect.size()); + QRectF mapRect=model->getTotalBBox(); + QPixmap pix((int)mapRect.width()+2,(int)mapRect.height()+1); QPainter pp (&pix); + + pp.setRenderHints(renderHints()); // Don't print the visualisation of selection - LinkableMapObj *oldselection=NULL; - if (selection) - { - oldselection=selection; - selection->unselect(); - } - - pp.setWindow (mapRect); - - mapCanvas->drawArea(mapRect, &pp); // draw Canvas to painter - + xelection.unselect(); + + mapScene->render ( &pp, + QRectF(0,0,mapRect.width()+1,mapRect.height()+1), + QRectF(mapRect.x(),mapRect.y(),mapRect.width(),mapRect.height() )); // Restore selection - if (oldselection) - { - selection=oldselection; - selection->select(); - } + xelection.reselect(); return pix; } -void MapEditor::exportImage(QString fn) -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - QPixmap pix (getPixmap()); - pix.save(fn, "PNG"); +void MapEditor::setHideTmpMode (HideTmpMode mode) +{ + hidemode=mode; + model->setHideTmp (hidemode); + model->reposition(); + scene()->update(); } -void MapEditor::exportImage(QString fn, int item) -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - QPixmap pix (getPixmap()); - pix.save(fn, exportImageFormatMenu->text(item) ); +HideTmpMode MapEditor::getHideTmpMode() +{ + return hidemode; } -void MapEditor::exportASCII() -{ - // FIXME still experimental - QFileDialog *fd=new QFileDialog( this, tr("VYM - Export (ASCII)")); - fd->addFilter ("TXT (*.txt)"); - fd->setCaption("VYM - Export (ASCII) (still experimental)"); - fd->setMode( QFileDialog::AnyFile ); - fd->show(); - - if ( fd->exec() == QDialog::Accepted ) - { - if (QFile (fd->selectedFile()).exists() ) - { - QMessageBox mb( "VYM", - tr("The file ") + fd->selectedFile() + - tr(" exists already. Do you want to overwrite it?"), - QMessageBox::Warning, - QMessageBox::Yes | QMessageBox::Default, - QMessageBox::Cancel | QMessageBox::Escape, - QMessageBox::NoButton ); - - mb.setButtonText( QMessageBox::Yes, tr("Overwrite") ); - mb.setButtonText( QMessageBox::No, tr("Cancel")); - Export ex; - switch( mb.exec() ) - { - case QMessageBox::Yes: - // save - if (!ex.setOutputDir ("out")) - { - QMessageBox::critical (0,tr("Critical Export Error "),tr("Couldn't create directory ") + "out"); - return; - } - break;; - case QMessageBox::Cancel: - // do nothing - return; - break; - } - } - Export ex; - ex.setPath (fd->selectedFile() ); - ex.setMapCenter(mapCenter); - ex.exportMap(); +void MapEditor::setExportMode (bool b) +{ + // should be called before and after exports + // depending on the settings + if (b && settings.value("/export/useHideExport","true")=="true") + setHideTmpMode (HideExport); + else + setHideTmpMode (HideNone); +} + +void MapEditor::exportASCII(QString fname,bool askName) +{ + ExportASCII ex; + ex.setModel (model); + if (fname=="") + ex.setFile (mapName+".txt"); + else + ex.setFile (fname); + + if (askName) + { + //ex.addFilter ("TXT (*.txt)"); + ex.setDir(lastImageDir); + //ex.setCaption(vymName+ " -" +tr("Export as ASCII")+" "+tr("(still experimental)")); + ex.execDialog() ; + } + if (!ex.canceled()) + { + setExportMode(true); + ex.doExport(); + setExportMode(false); } } - -void MapEditor::exportXML(const QString &dir) -{ +void MapEditor::exportImage(QString fname, bool askName, QString format) +{ + if (fname=="") + { + fname=mapName+".png"; + format="PNG"; + } + + if (askName) + { + QStringList fl; + QFileDialog *fd=new QFileDialog (this); + fd->setCaption (tr("Export map as image")); + fd->setDirectory (lastImageDir); + fd->setFileMode(QFileDialog::AnyFile); + fd->setFilters (imageIO.getFilters() ); + if (fd->exec()) + { + fl=fd->selectedFiles(); + fname=fl.first(); + format=imageIO.getType(fd->selectedFilter()); + } + } + + setExportMode (true); + QPixmap pix (getPixmap()); + pix.save(fname, format); + setExportMode (false); +} + +void MapEditor::exportOOPresentation(const QString &fn, const QString &cf) +{ + ExportOO ex; + ex.setFile (fn); + ex.setModel (model); + if (ex.setConfigFile(cf)) + { + setExportMode (true); + ex.exportPresentation(); + setExportMode (false); + } +} + +void MapEditor::exportXHTML (const QString &dir, bool askForName) +{ + ExportXHTMLDialog dia(this); + dia.setFilePath (filePath ); + dia.setMapName (mapName ); + dia.readSettings(); + if (dir!="") dia.setDir (dir); + + bool ok=true; + + if (askForName) + { + if (dia.exec()!=QDialog::Accepted) + ok=false; + else + { + QDir d (dia.getDir()); + // Check, if warnings should be used before overwriting + // the output directory + if (d.exists() && d.count()>0) + { + WarningDialog warn; + warn.showCancelButton (true); + warn.setText(QString( + "The directory %1 is not empty.\n" + "Do you risk to overwrite some of its contents?").arg(d.path() )); + warn.setCaption("Warning: Directory not empty"); + warn.setShowAgainName("mainwindow/overwrite-dir-xhtml"); + + if (warn.exec()!=QDialog::Accepted) ok=false; + } + } + } + + if (ok) + { + exportXML (dia.getDir(),false ); + dia.doExport(mapName ); + //if (dia.hasChanged()) setChanged(); + } +} + +void MapEditor::exportXML(QString dir, bool askForName) +{ + if (askForName) + { + dir=browseDirectory(this,tr("Export XML to directory")); + if (dir =="" && !reallyWriteDirectory(dir) ) + return; + } + + // Hide stuff during export, if settings want this + setExportMode (true); + // Create subdirectories makeSubDirs (dir); // write to directory - QString saveFile=saveToDir (dir,mapName+"-",true,mapCenter->getTotalBBox().topLeft() ,CompleteMap); + QString saveFile=saveToDir (dir,mapName+"-",true,model->getTotalBBox().topLeft() ,NULL); QFile file; file.setName ( dir + "/"+mapName+".xml"); - if ( !file.open( IO_WriteOnly ) ) + if ( !file.open( QIODevice::WriteOnly ) ) { // This should neverever happen - QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open ")+file.name()); + QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name())); return; } @@ -1037,494 +2139,783 @@ file.close(); // Now write image, too - exportImage (dir+"/images/"+mapName+".png"); + exportImage (dir+"/images/"+mapName+".png",false,"PNG"); + + setExportMode (false); } void MapEditor::clear() { - if (selection) - { - selection->unselect(); - selection=NULL; + xelection.unselect(); + model->clear(); +} + +void MapEditor::copy() +{ + LinkableMapObj *sel=xelection.single(); + if (sel) + { + if (redosAvail == 0) + { + // Copy to history + QString s=model->getSelectString(sel); + saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy selection to clipboard",sel ); + curClipboard=curStep; + } + + // Copy also to global clipboard, because we are at last step in history + QString bakMapName(QString("history-%1").arg(curStep)); + QString bakMapDir(tmpMapDir +"/"+bakMapName); + copyDir (bakMapDir,clipboardDir ); + + clipboardEmpty=false; + updateActions(); + } +} + +void MapEditor::redo() +{ + // Can we undo at all? + if (redosAvail<1) return; + + bool blockSaveStateOrg=blockSaveState; + blockSaveState=true; + + redosAvail--; + + if (undosAvailstepsTotal) curStep=1; + QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep)); + QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep)); + QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep)); + QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep)); + QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep)); + QString version=undoSet.readEntry ("/history/version"); + + /* TODO Maybe check for version, if we save the history + if (!checkVersion(version)) + QMessageBox::warning(0,tr("Warning"), + tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion)); + */ + + // Find out current undo directory + QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep)); + + if (debug) + { + cout << "ME::redo() begin\n"; + cout << " undosAvail="<reposition(); + + blockSaveState=blockSaveStateOrg; + + undoSet.setEntry ("/history/undosAvail",QString::number(undosAvail)); + undoSet.setEntry ("/history/redosAvail",QString::number(redosAvail)); + undoSet.setEntry ("/history/curStep",QString::number(curStep)); + undoSet.writeSettings(histPath); + + mainWindow->updateHistory (undoSet); + updateActions(); + + /* TODO remove testing + cout << "ME::redo() end\n"; + cout << " undosAvail="<0) + return true; + else + return false; +} + +void MapEditor::undo() +{ + // Can we undo at all? + if (undosAvail<1) return; + + mainWindow->statusMessage (tr("Autosave disabled during undo.")); + + bool blockSaveStateOrg=blockSaveState; + blockSaveState=true; + + QString undoCommand= undoSet.readEntry (QString("/history/step-%1/undoCommand").arg(curStep)); + QString undoSelection=undoSet.readEntry (QString("/history/step-%1/undoSelection").arg(curStep)); + QString redoCommand= undoSet.readEntry (QString("/history/step-%1/redoCommand").arg(curStep)); + QString redoSelection=undoSet.readEntry (QString("/history/step-%1/redoSelection").arg(curStep)); + QString comment=undoSet.readEntry (QString("/history/step-%1/comment").arg(curStep)); + QString version=undoSet.readEntry ("/history/version"); + + /* TODO Maybe check for version, if we save the history + if (!checkVersion(version)) + QMessageBox::warning(0,tr("Warning"), + tr("Version %1 of saved undo/redo data\ndoes not match current vym version %2.").arg(version).arg(vymVersion)); + */ + + // Find out current undo directory + QString bakMapDir(QString(tmpMapDir+"/undo-%1").arg(curStep)); + + // select object before undo + if (!undoSelection.isEmpty()) + select (undoSelection); + + if (debug) + { + cout << "ME::undo() begin\n"; + cout << " undosAvail="<clear(); + parseAtom (undoCommand); + model->reposition(); + + undosAvail--; + curStep--; + if (curStep<1) curStep=stepsTotal; + + redosAvail++; + + blockSaveState=blockSaveStateOrg; +/* TODO remove testing + cout << "ME::undo() end\n"; + cout << " undosAvail="<updateHistory (undoSet); + updateActions(); + xelection.update(); + ensureSelectionVisible(); } -void MapEditor::undo() -{ - QDir d; - d.setPath(bakMapDir); +bool MapEditor::isUndoAvailable() +{ + if (undoSet.readNumEntry("/history/undosAvail",0)>0) + return true; + else + return false; +} + +void MapEditor::gotoHistoryStep (int i) +{ + // Restore variables + int undosAvail=undoSet.readNumEntry (QString("/history/undosAvail")); + int redosAvail=undoSet.readNumEntry (QString("/history/redosAvail")); + + if (i<0) i=undosAvail+redosAvail; + + // Clicking above current step makes us undo things + if (iundosAvail) + for (int j=undosAvail; junselect(); - selection=NULL; - } - - mapBuilderHandler handler; - QXmlInputSource source; - source.setData(backupXML); + // We need to parse saved XML data + parseVYMHandler handler; + QXmlInputSource source( file); QXmlSimpleReader reader; reader.setContentHandler( &handler ); reader.setErrorHandler( &handler ); - handler.setMapEditor( this ); - handler.setTmpDir ( bakMapDir ); // needed to load files with rel. path - if (undoSelection) + handler.setModel ( model); + handler.setTmpDir ( pathDir ); // needed to load files with rel. path + if (undoSel.isEmpty()) { - selection=undoSelection; - selection->select(); - handler.setLoadMode (ImportReplace); - + unselect(); + model->clear(); + handler.setLoadMode (NewMap); } else { - mapCenter->clear(); - handler.setLoadMode (NewMap); + select (undoSel); + handler.setLoadMode (ImportReplace); } - blockreposition=true; + blockReposition=true; bool ok = reader.parse( source ); - blockreposition=false; - if ( ok ) - mapCenter->reposition(); - - else + blockReposition=false; + if (! ok ) { // This should never ever happen - QMessageBox::critical( 0, tr( "Critical Parse Error by reading backupFile" ), - tr( handler.errorProtocol() )+" in "+backupXML ); + QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path), + handler.errorProtocol()); } - // Undo not longer available now - actionEditUndo->setEnabled (false); - undoSelection=false; - mapChanged=false; - return; } else - { - QMessageBox::critical( 0, tr( "Critical Error" ), - "Temporary directory " +bakMapDir + - tr (" used for undo is gone. \n" - "I will create a new one, but at the moment no undo is available.\n" - "Maybe you want to reload your original data.\n\n" - "Sorry for any inconveniences.") ); - makeTmpDirs(); - } + QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path)); } -void MapEditor::copy() -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - if (selection) - { - if (typeid(*selection) == typeid(BranchObj) ) +void MapEditor::addMapInsertInt (const QString &path, int pos) +{ + BranchObj *sel=xelection.getBranch(); + if (sel) + { + QString pathDir=path.left(path.findRev("/")); + QDir d(pathDir); + QFile file (path); + + if (d.exists() ) { - BranchObj* to; - BranchObj* from; - clipboardME->clear(); - clipboardME->getMapCenter()->addBranch(); - to=clipboardME->getMapCenter()->getLastBranch(); - if (to) - { - from=(BranchObj*)(selection); - to->copy(from); - - // keep position relative to parent - to->move2RelPos ( from->getRelPos()); - - // select data in clipboard - clipboardME->select ("bo:0"); - - // repositioning makes testing nicer, - // but is not needed usually: - if (clipboardME->isVisible()) - { - clipboardME->getMapCenter()->reposition(); - } - else - clipboardME->hide(); + // We need to parse saved XML data + parseVYMHandler handler; + QXmlInputSource source( file); + QXmlSimpleReader reader; + reader.setContentHandler( &handler ); + reader.setErrorHandler( &handler ); + handler.setModel (model); + handler.setTmpDir ( pathDir ); // needed to load files with rel. path + handler.setLoadMode (ImportAdd); + blockReposition=true; + bool ok = reader.parse( source ); + blockReposition=false; + if (! ok ) + { + // This should never ever happen + QMessageBox::critical( 0, tr( "Critical Parse Error while reading %1").arg(path), + handler.errorProtocol()); } - } - if (typeid(*selection) == typeid(FloatImageObj) ) - { - FloatImageObj* to; - FloatImageObj* from; - clipboardME->clear(); - clipboardME->getMapCenter()->addFloatImage(); - to=clipboardME->getMapCenter()->getLastFloatImage(); - if (to) - { - from=(FloatImageObj*)(selection); - to->copy(from); - - // select data in clipboard - clipboardME->select ("fi:0"); - - // repositioning makes testing nicer, - // but is not needed usually: - if (clipboardME->isVisible()) - { - clipboardME->getMapCenter()->reposition(); - } - else - clipboardME->hide(); - } - } - } + if (sel->getDepth()>0) + sel->getLastBranch()->linkTo (sel,pos); + } else + QMessageBox::critical( 0, tr( "Critical Error" ), tr("Could not read %1").arg(path)); + } } -LinkableMapObj* MapEditor::pasteNoSave() -{ - return pasteAtNoSave (-1); +void MapEditor::pasteNoSave(const int &n) +{ + bool old=blockSaveState; + blockSaveState=true; + bool zippedOrg=zipped; + if (redosAvail > 0 || n!=0) + { + // Use the "historical" buffer + QString bakMapName(QString("history-%1").arg(n)); + QString bakMapDir(tmpMapDir +"/"+bakMapName); + load (bakMapDir+"/"+clipboardFile,ImportAdd, VymMap); + } else + // Use the global buffer + load (clipboardDir+"/"+clipboardFile,ImportAdd, VymMap); + zipped=zippedOrg; + blockSaveState=old; } -LinkableMapObj* MapEditor::pasteAtNoSave(int pos) -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - LinkableMapObj *fromLMO=clipboardME->getSelection(); - LinkableMapObj *returnLMO=NULL; - - if (selection && fromLMO) - { - - if (typeid(*fromLMO) == typeid(BranchObj) ) - { - if (typeid(*selection) == typeid(MapCenterObj)) - { - returnLMO=mapCenter->addBranch( (BranchObj*)(fromLMO) ); - ((BranchObj*)(returnLMO))->move2RelPos(normalise(fromLMO->getRelPos() ) ); - } - if (typeid(*selection) == typeid(BranchObj)) - if (pos<0) - returnLMO=((BranchObj*)(selection))->addBranch((BranchObj*)(fromLMO) ); - else - { - BranchObj *par=(BranchObj*)(selection->getParObj()); - if (par) returnLMO=par->insertBranch((BranchObj*)(fromLMO),pos ); - } - } - - if (typeid(*fromLMO) == typeid(FloatImageObj) && - (typeid(*selection) == typeid (BranchObj) || - typeid(*selection)==typeid(MapCenterObj)) ) - returnLMO=((BranchObj*) (selection))->addFloatImage ((FloatImageObj*)(fromLMO)); - - } - return returnLMO; +void MapEditor::paste() +{ + BranchObj *sel=xelection.getBranch(); + if (sel) + { + saveStateChangingPart( + sel, + sel, + QString ("paste (%1)").arg(curClipboard), + QString("Paste to %1").arg( getName(sel)) + ); + pasteNoSave(0); + model->reposition(); + } } -void MapEditor::cutNoSave() -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - BranchObj* bo; - BranchObj* par; - if (selection != NULL) { - if (typeid(*selection) == typeid(BranchObj) ) - { - bo=(BranchObj*)(selection); - par=(BranchObj*)(bo->getParObj()); - bo->unselect(); - selection=NULL; - par->removeBranch(bo); - selection=par; - selection->select(); - } - if (typeid(*selection) == typeid(FloatImageObj) ) - { - FloatImageObj* fio=(FloatImageObj*)(selection); - par=(BranchObj*)(fio->getParObj()); - fio->unselect(); - selection=NULL; - par->removeFloatImage(fio); - selection=par; - selection->select(); - } - } +void MapEditor::cut() +{ + LinkableMapObj *sel=xelection.single(); + if ( sel && (xelection.type() == Selection::Branch || + xelection.type()==Selection::MapCenter || + xelection.type()==Selection::FloatImage)) + { + /* No savestate! savestate is called in cutNoSave + saveStateChangingPart( + sel->getParObj(), + sel, + "cut ()", + QString("Cut %1").arg(getName(sel )) + ); + */ + copy(); + deleteSelection(); + model->reposition(); + } } -void MapEditor::paste() -{ - setChanged(); - saveState(PartOfMap,selection); - pasteNoSave(); - mapCenter->reposition(); - adjustCanvasSize(); +void MapEditor::move(const double &x, const double &y) +{ + LinkableMapObj *sel=xelection.single(); + if (sel) + { + QPointF ap(sel->getAbsPos()); + QPointF to(x, y); + if (ap != to) + { + QString ps=qpointfToString(ap); + QString s=xelection.getSelectString(); + saveState( + s, "move "+ps, + s, "move "+qpointfToString(to), + QString("Move %1 to %2").arg(getName(sel)).arg(ps)); + sel->move(x,y); + model->reposition(); + xelection.update(); + } + } } -void MapEditor::cut() -{ - setChanged(); - saveState(PartOfMap,selection->getParObj()); - copy(); - cutNoSave(); - mapCenter->reposition(); - adjustCanvasSize(); +void MapEditor::moveRel (const double &x, const double &y) +{ + LinkableMapObj *sel=xelection.single(); + if (sel) + { + QPointF rp(sel->getRelPos()); + QPointF to(x, y); + if (rp != to) + { + QString ps=qpointfToString (sel->getRelPos()); + QString s=model->getSelectString(sel); + saveState( + s, "moveRel "+ps, + s, "moveRel "+qpointfToString(to), + QString("Move %1 to relative position %2").arg(getName(sel)).arg(ps)); + ((OrnamentedObj*)sel)->move2RelPos (x,y); + model->reposition(); + sel->updateLink(); + xelection.update(); + } + } } void MapEditor::moveBranchUp() { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - BranchObj* bo; + BranchObj* bo=xelection.getBranch(); BranchObj* par; - if (typeid(*selection) == typeid(BranchObj) ) - { - setChanged(); - saveState(PartOfMap,selection->getParObj()); - bo=(BranchObj*)(selection); + if (bo) + { + if (!bo->canMoveBranchUp()) return; par=(BranchObj*)(bo->getParObj()); - selection->unselect(); - selection=par->moveBranchUp (bo); - selection->select(); - mapCenter->reposition(); + BranchObj *obo=par->moveBranchUp (bo); // bo will be the one below selection + saveState (model->getSelectString(bo),"moveBranchDown ()",model->getSelectString(obo),"moveBranchUp ()",QString("Move up %1").arg(getName(bo))); + model->reposition(); + scene()->update(); + xelection.update(); ensureSelectionVisible(); } } void MapEditor::moveBranchDown() { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - BranchObj* bo; + BranchObj* bo=xelection.getBranch(); BranchObj* par; - if (typeid(*selection) == typeid(BranchObj) ) - { - setChanged(); - saveState(PartOfMap,selection->getParObj()); - bo=(BranchObj*)(selection); + if (bo) + { + if (!bo->canMoveBranchDown()) return; par=(BranchObj*)(bo->getParObj()); - selection->unselect(); - selection=par->moveBranchDown(bo); - selection->select(); - mapCenter->reposition(); + BranchObj *obo=par->moveBranchDown(bo); // bo will be the one above selection + saveState(model->getSelectString(bo),"moveBranchUp ()",model->getSelectString(obo),"moveBranchDown ()",QString("Move down %1").arg(getName(bo))); + model->reposition(); + scene()->update(); + xelection.update(); ensureSelectionVisible(); } } -void MapEditor::editHeading() -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - if (selection && - (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj) ) ) - { - setChanged(); - saveState(PartOfMap,selection); - +void MapEditor::sortChildren() +{ + BranchObj* bo=xelection.getBranch(); + if (bo) + { + if(bo->countBranches()>1) + { + saveStateChangingPart(bo,bo, "sortChildren ()",QString("Sort children of %1").arg(getName(bo))); + bo->sortChildren(); + model->reposition(); + ensureSelectionVisible(); + } + } +} + +void MapEditor::linkTo(const QString &dstString) +{ + FloatImageObj *fio=xelection.getFloatImage(); + if (fio) + { + BranchObj *dst=(BranchObj*)(model->findObjBySelect(dstString)); + if (dst && (typeid(*dst)==typeid (BranchObj) || + typeid(*dst)==typeid (MapCenterObj))) + { + LinkableMapObj *dstPar=dst->getParObj(); + QString parString=model->getSelectString(dstPar); + QString fioPreSelectString=model->getSelectString(fio); + QString fioPreParentSelectString=model->getSelectString (fio->getParObj()); + ((BranchObj*)(dst))->addFloatImage (fio); + xelection.unselect(); + ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio); + fio=((BranchObj*)(dst))->getLastFloatImage(); + fio->setRelPos(); + fio->reposition(); + xelection.select(fio); + saveState( + model->getSelectString(fio), + QString("linkTo (\"%1\")").arg(fioPreParentSelectString), + fioPreSelectString, + QString ("linkTo (\"%1\")").arg(dstString), + QString ("Link floatimage to %1").arg(getName(dst))); + } + } +} + +QString MapEditor::getHeading(bool &ok, QPoint &p) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + ok=true; + p=mapFromScene(bo->getAbsPos()); + return bo->getHeading(); + } + ok=false; + return QString(); +} + +void MapEditor::setHeading(const QString &s) +{ + BranchObj *sel=xelection.getBranch(); + if (sel) + { + saveState( + sel, + "setHeading (\""+sel->getHeading()+"\")", + sel, + "setHeading (\""+s+"\")", + QString("Set heading of %1 to \"%2\"").arg(getName(sel)).arg(s) ); + sel->setHeading(s ); + model->reposition(); + xelection.update(); ensureSelectionVisible(); - BranchObj *bo=(BranchObj*)(selection); - editingBO=(BranchObj*)(selection); - QPoint p = worldMatrix().map(QPoint (bo->x(),bo->y())); - lineedit->setGeometry(p.x()-contentsX(),p.y()-contentsY(),200,25); - QString s=bo->getHeading(); - lineedit->setText(s); - lineedit->setCursorPosition(1); - if (actionSettingsAutoselectText->isOn() && !s.isEmpty() && actionSettingsPasteNewHeading->isOn() ) - lineedit->selectAll(); - lineedit->show(); - - lineedit->grabKeyboard(); - lineedit->setFocus(); - } + } } - -void MapEditor::addNewBranch(int pos) -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - if (selection && - (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj) ) ) - { - setChanged(); - saveState(PartOfMap,selection); - - BranchObj* bo1 = (BranchObj*) (selection); - bool wasScrolled=false; - BranchObj *newbo=NULL; - if (pos==0) +void MapEditor::setHeadingInt(const QString &s) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + bo->setHeading(s); + model->reposition(); + xelection.update(); + ensureSelectionVisible(); + } +} + +void MapEditor::setVymLinkInt (const QString &s) +{ + // Internal function, no saveState needed + BranchObj *bo=xelection.getBranch(); + if (bo) + { + bo->setVymLink(s); + model->reposition(); + updateActions(); + xelection.update(); + ensureSelectionVisible(); + } +} + +BranchObj* MapEditor::addMapCenter () +{ + MapCenterObj *mco= model->addMapCenter(contextMenuPos); + xelection.select (mco); + updateActions(); + ensureSelectionVisible(); + saveState ( + mco, + "delete()", + NULL, + QString ("addMapCenter (%1,%2)").arg (contextMenuPos.x()).arg(contextMenuPos.y()), + QString ("Adding MapCenter to (%1,%2").arg (contextMenuPos.x()).arg(contextMenuPos.y()) + ); + return mco; +} + +BranchObj* MapEditor::addNewBranchInt(int num) +{ + // Depending on pos: + // -3 insert in childs of parent above selection + // -2 add branch to selection + // -1 insert in childs of parent below selection + // 0..n insert in childs of parent at pos + BranchObj *newbo=NULL; + BranchObj *bo=xelection.getBranch(); + if (bo) + { + if (num==-2) { // save scroll state. If scrolled, automatically select // new branch in order to tmp unscroll parent... - wasScrolled=bo1->isScrolled(); - newbo=bo1->addBranch(); - } else + newbo=bo->addBranch(); + + }else if (num==-1) { - BranchObj *parbo=(BranchObj*)(selection->getParObj()); - if (parbo) - { - if (pos<0) - // add above selection - newbo=parbo->insertBranch(bo1->getNum()); - else - // add below selection - newbo=parbo->insertBranch(bo1->getNum()+1); - } else - // This should not happen... - return; - + num=bo->getNum()+1; + bo=(BranchObj*)bo->getParObj(); + if (bo) newbo=bo->insertBranch(num); + }else if (num==-3) + { + num=bo->getNum(); + bo=(BranchObj*)bo->getParObj(); + if (bo) newbo=bo->insertBranch(num); + } + if (!newbo) return NULL; + } + return newbo; +} + +BranchObj* MapEditor::addNewBranch(int pos) +{ + // Different meaning than num in addNewBranchInt! + // -1 add above + // 0 add as child + // +1 add below + BranchObj *bo = xelection.getBranch(); + BranchObj *newbo=NULL; + + if (bo) + { + setCursor (Qt::ArrowCursor); + + newbo=addNewBranchInt (pos-2); + + if (newbo) + { + saveState( + newbo, + "delete ()", + bo, + QString ("addBranch (%1)").arg(pos), + QString ("Add new branch to %1").arg(getName(bo))); + + model->reposition(); + xelection.update(); + latestSelection=model->getSelectString(newbo); + // In Network mode, the client needs to know where the new branch is, + // so we have to pass on this information via saveState. + // TODO: Get rid of this positioning workaround + QString ps=qpointfToString (newbo->getAbsPos()); + sendData ("selectLatestAdded ()"); + sendData (QString("move %1").arg(ps)); + sendSelection(); + } + } + return newbo; +} + + +BranchObj* MapEditor::addNewBranchBefore() +{ + BranchObj *newbo=NULL; + BranchObj *bo = xelection.getBranch(); + if (bo && xelection.type()==Selection::Branch) + // We accept no MapCenterObj here, so we _have_ a parent + { + QPointF p=bo->getRelPos(); + + + BranchObj *parbo=(BranchObj*)(bo->getParObj()); + + // add below selection + newbo=parbo->insertBranch(bo->getNum()+1); + if (newbo) + { + newbo->move2RelPos (p); + + // Move selection to new branch + bo->linkTo (newbo,-1); + + saveState (newbo, "deleteKeepChilds ()", newbo, "addBranchBefore ()", + QString ("Add branch before %1").arg(getName(bo))); + + model->reposition(); + xelection.update(); + } + } + latestSelection=xelection.getSelectString(); + return newbo; +} + +void MapEditor::deleteSelection() +{ + BranchObj *bo = xelection.getBranch(); + if (bo && xelection.type()==Selection::MapCenter) + { + // BranchObj* par=(BranchObj*)(bo->getParObj()); + xelection.unselect(); + /* FIXME Note: does saveStateRemovingPart work for MCO? (No parent!) + saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo))); + */ + bo=model->removeMapCenter ((MapCenterObj*)bo); + if (bo) + { + xelection.select (bo); + ensureSelectionVisible(); + xelection.update(); } - - LinkableMapObj *oldselection=selection; - - mapCenter->reposition(); - adjustCanvasSize(); - if (actionSettingsAutoedit->isOn() || - actionSettingsAutoselectHeading->isOn() ) - { - selection->unselect(); - selection=newbo; - selection->select(); - if (actionSettingsPasteNewHeading->isOn() ) - { - BranchObj *bo2= (BranchObj*)(selection); - bo2->setHeading(""); - } - if (actionSettingsAutoedit->isOn() ) - editHeading(); - if (!actionSettingsAutoselectHeading->isOn() - && !wasScrolled) - { - selection->unselect(); - selection=oldselection; - selection->select(); - } - } + model->reposition(); + return; + } + if (bo && xelection.type()==Selection::Branch) + { + BranchObj* par=(BranchObj*)bo->getParObj(); + xelection.unselect(); + saveStateRemovingPart (bo, QString ("Delete %1").arg(getName(bo))); + par->removeBranch(bo); + xelection.select (par); + ensureSelectionVisible(); + model->reposition(); +// xelection.update(); + xelection.update(); + return; + } + FloatImageObj *fio=xelection.getFloatImage(); + if (fio) + { + BranchObj* par=(BranchObj*)fio->getParObj(); + saveStateChangingPart( + par, + fio, + "delete ()", + QString("Delete %1").arg(getName(fio)) + ); + xelection.unselect(); + par->removeFloatImage(fio); + xelection.select (par); + model->reposition(); + xelection.update(); + ensureSelectionVisible(); + return; + } +} + +LinkableMapObj* MapEditor::getSelection() +{ + return xelection.single(); +} + +BranchObj* MapEditor::getSelectedBranch() +{ + return xelection.getBranch(); +} + +FloatImageObj* MapEditor::getSelectedFloatImage() +{ + return xelection.getFloatImage(); +} + +void MapEditor::unselect() +{ + xelection.unselect(); +} + +void MapEditor::reselect() +{ + xelection.reselect(); +} + +bool MapEditor::select (const QString &s) +{ + if (xelection.select(s)) + { + xelection.update(); + ensureSelectionVisible(); + sendSelection (); + return true; + } + return false; +} + +bool MapEditor::select (LinkableMapObj *lmo) +{ + if (xelection.select(lmo)) + { + xelection.update(); + ensureSelectionVisible(); + sendSelection (); + return true; + } + return false; +} + +QString MapEditor::getSelectString() +{ + return xelection.getSelectString(); +} + +void MapEditor::selectInt (LinkableMapObj *lmo) +{ + if (lmo && xelection.single()!= lmo && isSelectBlocked()==false ) + { + xelection.select(lmo); + xelection.update(); + sendSelection (); } } -void MapEditor::deleteSelection() -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - if (selection && typeid(*selection) ==typeid(BranchObj) ) - { - setChanged(); - saveState(PartOfMap,selection->getParObj()); - BranchObj* bo=dynamic_cast (selection); - BranchObj* par=(BranchObj*)(bo->getParObj()); - bo->unselect(); - selection=NULL; - par->removeBranch(bo); - selection=par; - selection->select(); - ensureSelectionVisible(); - mapCenter->reposition(); - adjustCanvasSize(); - } - if (selection && typeid(*selection) ==typeid(FloatImageObj) ) - { - setChanged(); - saveState(PartOfMap,selection->getParObj()); - FloatImageObj* fio=dynamic_cast (selection); - BranchObj* par=(BranchObj*)(fio->getParObj()); - fio->unselect(); - selection=NULL; - par->removeFloatImage(fio); - selection=par; - selection->select(); - ensureSelectionVisible(); - mapCenter->reposition(); - adjustCanvasSize(); - } -} - -LinkableMapObj* MapEditor::getSelection() -{ - return selection; -} - -bool MapEditor::select (QString s) -{ - LinkableMapObj *lmo=mapCenter; - QString part; - QString typ; - QString num; - while (!s.isEmpty() ) - { - part=s.section(",",0,0); - typ=part.left (3); - num=part.right(part.length() - 3); - - if (typ=="mc:") - { - if (num=="") - break; - else - lmo=mapCenter->getBranchNum (num.toUInt()); - } else - if (typ=="bo:") - lmo=((BranchObj*)(lmo))->getBranchNum (num.toUInt()); - else - if (typ=="fi:") - lmo=((BranchObj*)(lmo))->getFloatImageNum (num.toUInt()); - - - - if (!lmo) break; - - if (s.contains(",")) - s=s.right(s.length() - part.length() -1 ); - else - break; - } - - // Finally select the found object - if (lmo) - { - if (selection) selection->unselect(); - selection=lmo; - selection->select(); - adjustCanvasSize(); - ensureSelectionVisible(); - return true; - } else - return false; - - -} - -void MapEditor::unselect() -{ - if (selection) - { - selectionLast=selection; - selection->unselect(); - selection=NULL; - } -} - -void MapEditor::reselect() -{ - if (selectionLast) - { - selection=selectionLast; - selection->select(); - selectionLast=NULL; - } -} - -void MapEditor::selectNextBranch() +void MapEditor::selectNextBranchInt() { // Increase number of branch - if (selection) - { - QString s=selection->getSelectString(); + LinkableMapObj *sel=xelection.single(); + if (sel) + { + QString s=xelection.getSelectString(); QString part; QString typ; QString num; @@ -1548,7 +2939,7 @@ // try to increase the parental number in order to // find a successor with same depth - int d=selection->getDepth(); + int d=xelection.single()->getDepth(); int oldDepth=d; int i; bool found=false; @@ -1569,7 +2960,7 @@ } else { // Special case, look at orientation - if (selection->getOrientation()==OrientRightOfCenter) + if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter) num=QString ("%1").arg(num.toUInt()+1); else num=QString ("%1").arg(num.toUInt()-1); @@ -1583,7 +2974,7 @@ b=select (s); if (b) { - if ( ((BranchObj*)(selection))->countBranches()>0) + if ( xelection.getBranch()->countBranches()>0) s+=",bo:0"; else break; @@ -1599,12 +2990,13 @@ } } -void MapEditor::selectPrevBranch() +void MapEditor::selectPrevBranchInt() { // Decrease number of branch - if (selection) - { - QString s=selection->getSelectString(); + BranchObj *bo=xelection.getBranch(); + if (bo) + { + QString s=xelection.getSelectString(); QString part; QString typ; QString num; @@ -1616,19 +3008,20 @@ s=s.left (s.length() -num.length()); + int n=num.toInt()-1; + // Go to next lmo - num=QString ("%1").arg(num.toUInt()-1); - + num=QString ("%1").arg(n); s=s+num; // Try to select this one - if (select (s)) return; + if (n>=0 && select (s)) return; // We have no direct precessor, // try to decrease the parental number in order to // find a precessor with same depth - int d=selection->getDepth(); + int d=xelection.single()->getDepth(); int oldDepth=d; int i; bool found=false; @@ -1644,15 +3037,15 @@ if (d>1) { // decrease number of parent - num=QString ("%1").arg(num.toUInt()-1); + num=QString ("%1").arg(num.toInt()-1); s=s.section (",",0,d-2) + ","+ typ+num; } else { // Special case, look at orientation - if (selection->getOrientation()==OrientRightOfCenter) - num=QString ("%1").arg(num.toUInt()-1); + if (xelection.single()->getOrientation()==LinkableMapObj::RightOfCenter) + num=QString ("%1").arg(num.toInt()-1); else - num=QString ("%1").arg(num.toUInt()+1); + num=QString ("%1").arg(num.toInt()+1); s=typ+num; } @@ -1662,8 +3055,8 @@ { b=select (s); if (b) - if ( ((BranchObj*)(selection))->countBranches()>0) - s+=",bo:"+ QString ("%1").arg( ((BranchObj*)(selection))->countBranches()-1 ); + if ( xelection.getBranch()->countBranches()>0) + s+=",bo:"+ QString ("%1").arg( xelection.getBranch()->countBranches()-1 ); else break; else @@ -1680,100 +3073,90 @@ void MapEditor::selectUpperBranch() { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - if (selection) - { - if (typeid(*selection) == typeid(BranchObj)) - { - if (selection->getOrientation()==OrientRightOfCenter) - selectPrevBranch(); + if (isSelectBlocked() ) return; + + BranchObj *bo=xelection.getBranch(); + if (bo && xelection.type()==Selection::Branch) + { + if (bo->getOrientation()==LinkableMapObj::RightOfCenter) + selectPrevBranchInt(); + else + if (bo->getDepth()==1) + selectNextBranchInt(); else - if (selection->getDepth()==1) - selectNextBranch(); - else - selectPrevBranch(); - } + selectPrevBranchInt(); } } void MapEditor::selectLowerBranch() { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - if (selection) - { - if (typeid(*selection) == typeid(BranchObj)) - { - if (selection->getOrientation()==OrientRightOfCenter) - selectNextBranch(); + if (isSelectBlocked() ) return; + + BranchObj *bo=xelection.getBranch(); + if (bo && xelection.type()==Selection::Branch) + { + if (bo->getOrientation()==LinkableMapObj::RightOfCenter) + selectNextBranchInt(); + else + if (bo->getDepth()==1) + selectPrevBranchInt(); else - if (selection->getDepth()==1) - selectPrevBranch(); - else - selectNextBranch(); - } - } + selectNextBranchInt(); + } } void MapEditor::selectLeftBranch() { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (isSelectBlocked() ) return; BranchObj* bo; BranchObj* par; - if (selection) - { - if (typeid(*selection) == typeid(MapCenterObj)) + LinkableMapObj *sel=xelection.single(); + if (sel) + { + if (xelection.type()== Selection::MapCenter) { - par= (BranchObj*) (selection); + par=xelection.getBranch(); bo=par->getLastSelectedBranch(); if (bo) { // Workaround for reselecting on left and right side - if (bo->getOrientation()==OrientRightOfCenter) + if (bo->getOrientation()==LinkableMapObj::RightOfCenter) + bo=par->getLastBranch(); + if (bo) { bo=par->getLastBranch(); - } - if (bo) - { - par->unselect(); - selection=bo; - selection->select(); - adjustCanvasSize(); + xelection.select(bo); + xelection.update(); ensureSelectionVisible(); + sendSelection(); } } } else { - par=(BranchObj*)(selection->getParObj()); - if (selection->getOrientation()==OrientRightOfCenter) + par=(BranchObj*)(sel->getParObj()); + if (sel->getOrientation()==LinkableMapObj::RightOfCenter) { - if (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(FloatImageObj)) + if (xelection.type() == Selection::Branch || + xelection.type() == Selection::FloatImage) { - selection->unselect(); - selection=par; - selection->select(); - adjustCanvasSize(); + xelection.select(par); + xelection.update(); ensureSelectionVisible(); + sendSelection(); } } else { - if (typeid(*selection) == typeid(BranchObj) ) + if (xelection.type() == Selection::Branch ) { - bo=((BranchObj*)(selection))->getLastSelectedBranch(); + bo=xelection.getBranch()->getLastSelectedBranch(); if (bo) { - selection->unselect(); - selection=bo; - selection->select(); - adjustCanvasSize(); + xelection.select(bo); + xelection.update(); ensureSelectionVisible(); + sendSelection(); } } } @@ -1783,57 +3166,54 @@ void MapEditor::selectRightBranch() { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (isSelectBlocked() ) return; BranchObj* bo; BranchObj* par; - - if (selection) - { - if (typeid(*selection) == typeid(MapCenterObj)) + LinkableMapObj *sel=xelection.single(); + if (sel) + { + if (xelection.type()==Selection::MapCenter) { - par= (BranchObj*) (selection); + par=xelection.getBranch(); bo=par->getLastSelectedBranch(); if (bo) { - // Workaround for relecting on left and right side - if (bo->getOrientation()==OrientLeftOfCenter) + // Workaround for reselecting on left and right side + if (bo->getOrientation()==LinkableMapObj::LeftOfCenter) bo=par->getFirstBranch(); if (bo) { - par->unselect(); - selection=bo; - selection->select(); + xelection.select(bo); + xelection.update(); ensureSelectionVisible(); + sendSelection(); } } } else { - par=(BranchObj*)(selection->getParObj()); - if (selection->getOrientation()==OrientLeftOfCenter) + par=(BranchObj*)(xelection.single()->getParObj()); + if (xelection.single()->getOrientation()==LinkableMapObj::LeftOfCenter) { - if (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(FloatImageObj)) + if (xelection.type() == Selection::Branch || + xelection.type() == Selection::FloatImage) { - selection->unselect(); - selection=par; - selection->select(); - adjustCanvasSize(); + xelection.select(par); + xelection.update(); ensureSelectionVisible(); + sendSelection(); } } else { - if (typeid(*selection) == typeid(BranchObj) ) + if (xelection.type() == Selection::Branch) { - bo=((BranchObj*)(selection))->getLastSelectedBranch(); + bo=xelection.getBranch()->getLastSelectedBranch(); if (bo) { - selection->unselect(); - selection=bo; - selection->select(); - adjustCanvasSize(); + xelection.select(bo); + xelection.update(); ensureSelectionVisible(); + sendSelection(); } } } @@ -1843,146 +3223,183 @@ void MapEditor::selectFirstBranch() { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - BranchObj *bo1; + BranchObj *bo1=xelection.getBranch(); BranchObj *bo2; BranchObj* par; - if (selection) { - if (typeid(*selection) == typeid(BranchObj)) + if (bo1) + { + par=(BranchObj*)(bo1->getParObj()); + if (!par) return; + bo2=par->getFirstBranch(); + if (bo2) { + xelection.select(bo2); + xelection.update(); + ensureSelectionVisible(); + sendSelection(); + } + } +} + +void MapEditor::selectLastBranch() +{ + BranchObj *bo1=xelection.getBranch(); + BranchObj *bo2; + BranchObj* par; + if (bo1) + { + par=(BranchObj*)(bo1->getParObj()); + if (!par) return; + bo2=par->getLastBranch(); + if (bo2) { - bo1= (BranchObj*) (selection); - par=(BranchObj*)(bo1->getParObj()); - bo2=par->getFirstBranch(); - if (bo2) { - bo1->unselect(); - selection=bo2; - selection->select(); - ensureSelectionVisible(); - } - } - adjustCanvasSize(); + xelection.select(bo2); + xelection.update(); + ensureSelectionVisible(); + sendSelection(); + } + } +} + +void MapEditor::selectMapBackgroundImage () +{ + Q3FileDialog *fd=new Q3FileDialog( this); + fd->setMode (Q3FileDialog::ExistingFile); + fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)")); + ImagePreview *p =new ImagePreview (fd); + fd->setContentsPreviewEnabled( TRUE ); + fd->setContentsPreview( p, p ); + fd->setPreviewMode( Q3FileDialog::Contents ); + fd->setCaption(vymName+" - " +tr("Load background image")); + fd->setDir (lastImageDir); + fd->show(); + + if ( fd->exec() == QDialog::Accepted ) + { + // TODO selectMapBackgroundImg in QT4 use: lastImageDir=fd->directory(); + lastImageDir=QDir (fd->dirPath()); + setMapBackgroundImage (fd->selectedFile()); + } +} + +void MapEditor::setMapBackgroundImage (const QString &fn) //FIXME missing savestate +{ + QColor oldcol=mapScene->backgroundBrush().color(); + /* + saveState( + selection, + QString ("setMapBackgroundImage (%1)").arg(oldcol.name()), + selection, + QString ("setMapBackgroundImage (%1)").arg(col.name()), + QString("Set background color of map to %1").arg(col.name())); + */ + QBrush brush; + brush.setTextureImage (QPixmap (fn)); + mapScene->setBackgroundBrush(brush); +} + +void MapEditor::selectMapBackgroundColor() +{ + QColor col = QColorDialog::getColor( mapScene->backgroundBrush().color(), this ); + if ( !col.isValid() ) return; + setMapBackgroundColor( col ); +} + + +void MapEditor::setMapBackgroundColor(QColor col) +{ + QColor oldcol=mapScene->backgroundBrush().color(); + saveState( + QString ("setMapBackgroundColor (\"%1\")").arg(oldcol.name()), + QString ("setMapBackgroundColor (\"%1\")").arg(col.name()), + QString("Set background color of map to %1").arg(col.name())); + mapScene->setBackgroundBrush(col); +} + +QColor MapEditor::getMapBackgroundColor() +{ + return mapScene->backgroundBrush().color(); +} + +QColor MapEditor::getCurrentHeadingColor() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) return bo->getColor(); + + QMessageBox::warning(0,tr("Warning"),tr("Can't get color of heading,\nthere's no branch selected")); + return Qt::black; +} + +void MapEditor::colorBranch (QColor c) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + saveState( + bo, + QString ("colorBranch (\"%1\")").arg(bo->getColor().name()), + bo, + QString ("colorBranch (\"%1\")").arg(c.name()), + QString("Set color of %1 to %2").arg(getName(bo)).arg(c.name()) + ); + bo->setColor(c); // color branch } } -void MapEditor::selectLastBranch() -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - BranchObj *bo1; - BranchObj *bo2; - BranchObj* par; - if (selection) { - if (typeid(*selection) == typeid(BranchObj)) - { - bo1= (BranchObj*) (selection); - par=(BranchObj*)(bo1->getParObj()); - bo2=par->getLastBranch(); - if (bo2) { - bo1->unselect(); - selection=bo2; - selection->select(); - ensureSelectionVisible(); - } - } - adjustCanvasSize(); +void MapEditor::colorSubtree (QColor c) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + saveStateChangingPart( + bo, + bo, + QString ("colorSubtree (\"%1\")").arg(c.name()), + QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(c.name()) + ); + bo->setColorSubtree (c); // color links, color childs } } -void MapEditor::setColor(QColor c) -{ - actColor=c; -} - -void MapEditor::selectBackgroundColor() -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this ); - if ( !col.isValid() ) return; - setBackgroundColor( col ); - setChanged(); -} - -void MapEditor::setBackgroundColor(QColor c) -{ - mapCanvas->setBackgroundColor (c); -} - -QColor MapEditor::pickColor() -{ - if (selection) - { - if (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) + +void MapEditor::toggleStandardFlag(QString f) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + QString u,r; + if (bo->isSetStandardFlag(f)) { - BranchObj *bo=(BranchObj*)(selection); - actColor=bo->getColor(); - } - } - return actColor; -} - -void MapEditor::colorItem() -{ - if (selection) - { - if (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) + r="unsetFlag"; + u="setFlag"; + } + else { - setChanged(); - saveState(PartOfMap,selection); - BranchObj *bo=(BranchObj*)(selection); - bo->setColor(actColor, false); // color links, color childs - } + u="unsetFlag"; + r="setFlag"; + } + saveState( + bo, + QString("%1 (\"%2\")").arg(u).arg(f), + bo, + QString("%1 (\"%2\")").arg(r).arg(f), + QString("Toggling standard flag \"%1\" of %2").arg(f).arg(getName(bo))); + bo->toggleStandardFlag (f,mainWindow->useFlagGroups()); + xelection.update(); } } -void MapEditor::colorBranch() -{ - if (selection) - { - if (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) - { - setChanged(); - saveState(PartOfMap,selection); - BranchObj *bo=(BranchObj*)(selection); - bo->setColor(actColor, true); // color links, color childs - } - } -} - - -void MapEditor::toggleStandardFlag(QString f) -{ - if (selection) - { - setChanged(); - saveState(PartOfMap,selection); - ((BranchObj*)(selection))->toggleStandardFlag (f); - } -} - -void MapEditor::setViewCenter() -{ - // transform to CanvasView Coord: - QPoint p=worldMatrix().map(movingCenter); - center ( p.x(), p.y()); -} - BranchObj* MapEditor::findText (QString s, bool cs) { + QTextDocument::FindFlags flags=0; + if (cs) flags=QTextDocument::FindCaseSensitively; + if (!itFind) { // Nothing found or new find process if (EOFind) // nothing found, start again EOFind=false; - itFind=mapCenter->first(); + itFind=model->first(); } bool searching=true; bool foundNote=false; @@ -1993,15 +3410,12 @@ // Searching in Note if (itFind->getNote().contains(s,cs)) { - if (selection!=itFind) + if (xelection.single()!=itFind) { - if (selection) ((BranchObj*)(selection))->unselect(); - selection=itFind; - selection->select(); - adjustCanvasSize(); + xelection.select(itFind); ensureSelectionVisible(); } - if (textEditor->findText(s,cs)) + if (textEditor->findText(s,flags)) { searching=false; foundNote=true; @@ -2010,25 +3424,21 @@ // Searching in Heading if (searching && itFind->getHeading().contains (s,cs) ) { - if (selection) ((BranchObj*)(selection))->unselect(); - selection=itFind; - selection->select(); - adjustCanvasSize(); + xelection.select(itFind); ensureSelectionVisible(); searching=false; } } if (!foundNote) { - itFind=itFind->next(); + itFind=model->next(itFind); if (!itFind) EOFind=true; } + //cout <<"still searching... "<getHeading())<getURL(); - - QProcess *proc = new QProcess( this ); - -#if !defined(Q_OS_MACX) - proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL","konqueror" )); -#else - proc->addArgument( settings.readEntry("/vym/mainwindow/readerURL", - "/Applications/Safari.app/Contents/MacOS/Safari" )); -#endif - - proc->addArgument( url); - - if ( !proc->start() ) - // error handling - if (mainWindow->settingsURL() ) - openURL(); - } - } -} +void MapEditor::setURL(const QString &url) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + QString oldurl=bo->getURL(); + bo->setURL (url); + saveState ( + bo, + QString ("setURL (\"%1\")").arg(oldurl), + bo, + QString ("setURL (\"%1\")").arg(url), + QString ("set URL of %1 to %2").arg(getName(bo)).arg(url) + ); + updateActions(); + model->reposition(); + xelection.update(); + ensureSelectionVisible(); + } +} void MapEditor::editURL() { - if (selection && (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) ) + BranchObj *bo=xelection.getBranch(); + if (bo) { bool ok; QString text = QInputDialog::getText( "VYM", tr("Enter URL:"), QLineEdit::Normal, - ((BranchObj*)(selection))->getURL(), &ok, this ); + bo->getURL(), &ok, this ); if ( ok) - { // user entered something and pressed OK - ((BranchObj*)(selection))->setURL (text); - updateActions(); - setChanged(); - } + setURL (text); } } +void MapEditor::editLocalURL() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + QStringList filters; + filters <<"All files (*)"; + filters << tr("Text","Filedialog") + " (*.txt)"; + filters << tr("Spreadsheet","Filedialog") + " (*.odp,*.sxc)"; + filters << tr("Textdocument","Filedialog") +" (*.odw,*.sxw)"; + filters << tr("Images","Filedialog") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)"; + QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Set URL to a local file")); + fd->setFilters (filters); + fd->setCaption(vymName+" - " +tr("Set URL to a local file")); + fd->setDirectory (lastFileDir); + if (! bo->getVymLink().isEmpty() ) + fd->selectFile( bo->getURL() ); + fd->show(); + + if ( fd->exec() == QDialog::Accepted ) + { + lastFileDir=QDir (fd->directory().path()); + setURL (fd->selectedFile() ); + } + } +} + +QString MapEditor::getURL() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + return bo->getURL(); + else + return ""; +} + +QStringList MapEditor::getURLs() +{ + QStringList urls; + BranchObj *bo=xelection.getBranch(); + if (bo) + { + bo=bo->first(); + while (bo) + { + if (!bo->getURL().isEmpty()) urls.append( bo->getURL()); + bo=bo->next(); + } + } + return urls; +} + + void MapEditor::editHeading2URL() { - if (selection && (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) ) + BranchObj *bo=xelection.getBranch(); + if (bo) + setURL (bo->getHeading()); +} + +void MapEditor::editBugzilla2URL() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) { - BranchObj *b=(BranchObj*)(selection); - b->setURL (b->getHeading()); - updateActions(); - setChanged(); + QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading(); + setURL (url); } } -void MapEditor::editBugzilla2URL() -{ - if (selection && (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) ) +void MapEditor::editFATE2URL() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) { - BranchObj *b=(BranchObj*)(selection); - b->setURL ("http://bugzilla.suse.de/show_bug.cgi?id="+b->getHeading()); + QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading(); + saveState( + bo, + "setURL (\""+bo->getURL()+"\")", + bo, + "setURL (\""+url+"\")", + QString("Use heading of %1 as link to FATE").arg(getName(bo)) + ); + bo->setURL (url); updateActions(); - setChanged(); } } void MapEditor::editVymLink() { - if (selection && (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) ) + BranchObj *bo=xelection.getBranch(); + if (bo) { - QFileDialog *fd=new QFileDialog( this,tr("VYM - Link to another map")); - fd->addFilter (QString (tr("vym map") + " (*.vym)")); - fd->setCaption(tr("VYM - Link to another map")); - if (! ((BranchObj*)(selection))->getVymLink().isEmpty() ) - fd->setSelection( ((BranchObj*)(selection))->getVymLink() ); + QStringList filters; + filters <<"VYM map (*.vym)"; + QFileDialog *fd=new QFileDialog( this,vymName+" - " +tr("Link to another map")); + fd->setFilters (filters); + fd->setCaption(vymName+" - " +tr("Link to another map")); + fd->setDirectory (lastFileDir); + if (! bo->getVymLink().isEmpty() ) + fd->selectFile( bo->getVymLink() ); fd->show(); QString fn; if ( fd->exec() == QDialog::Accepted ) - ((BranchObj*)(selection))->setVymLink (fd->selectedFile() ); - updateActions(); - mapCenter->reposition(); - adjustCanvasSize(); - canvas()->update(); - setChanged(); + { + lastFileDir=QDir (fd->directory().path()); + saveState( + bo, + "setVymLink (\""+bo->getVymLink()+"\")", + bo, + "setVymLink (\""+fd->selectedFile()+"\")", + QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile()) + ); + setVymLinkInt (fd->selectedFile() ); + } } } void MapEditor::deleteVymLink() { - if (selection && (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) ) + BranchObj *bo=xelection.getBranch(); + if (bo) { - ((BranchObj*)(selection))->setVymLink ("" ); + saveState( + bo, + "setVymLink (\""+bo->getVymLink()+"\")", + bo, + "setVymLink (\"\")", + QString("Unset vymlink of %1").arg(getName(bo)) + ); + bo->setVymLink ("" ); updateActions(); - mapCenter->reposition(); - adjustCanvasSize(); - canvas()->update(); - setChanged(); + model->reposition(); + scene()->update(); } } +void MapEditor::setHideExport(bool b) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + bo->setHideInExport (b); + QString u= b ? "false" : "true"; + QString r=!b ? "false" : "true"; + + saveState( + bo, + QString ("setHideExport (%1)").arg(u), + bo, + QString ("setHideExport (%1)").arg(r), + QString ("Set HideExport flag of %1 to %2").arg(getName(bo)).arg (r) + ); + updateActions(); + model->reposition(); + xelection.update(); + scene()->update(); + } +} + +void MapEditor::toggleHideExport() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + setHideExport ( !bo->hideInExport() ); +} + QString MapEditor::getVymLink() { - if (selection && (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) ) - { - return ((BranchObj*)(selection))->getVymLink(); - } - return ""; + BranchObj *bo=xelection.getBranch(); + if (bo) + return bo->getVymLink(); + else + return ""; } +QStringList MapEditor::getVymLinks() +{ + QStringList links; + BranchObj *bo=xelection.getBranch(); + if (bo) + { + bo=bo->first(); + while (bo) + { + if (!bo->getVymLink().isEmpty()) links.append( bo->getVymLink()); + bo=bo->next(); + } + } + return links; +} + + +void MapEditor::deleteKeepChilds() +{ + BranchObj *bo=xelection.getBranch(); + BranchObj *par; + if (bo) + { + par=(BranchObj*)(bo->getParObj()); + QPointF p=bo->getRelPos(); + saveStateChangingPart( + bo->getParObj(), + bo, + "deleteKeepChilds ()", + QString("Remove %1 and keep its childs").arg(getName(bo)) + ); + + QString sel=model->getSelectString(bo); + unselect(); + par->removeBranchHere(bo); + model->reposition(); + select (sel); + xelection.getBranch()->move2RelPos (p); + model->reposition(); + } +} + +void MapEditor::deleteChilds() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + saveStateChangingPart( + bo, + bo, + "deleteChilds ()", + QString( "Remove childs of branch %1").arg(getName(bo)) + ); + bo->removeChilds(); + model->reposition(); + } +} + void MapEditor::editMapInfo() { ExtraInfoDialog dia; dia.setMapName (getFileName() ); - dia.setAuthor (mapCenter->getAuthor() ); - dia.setComment(mapCenter->getComment() ); + dia.setAuthor (model->getAuthor() ); + dia.setComment(model->getComment() ); // Calc some stats QString stats; - int i=0; - QCanvasItemList l=canvas()->allItems(); - for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) - i++; - stats+=QString ("%1 items on canvas\n").arg (i,6); + stats+=tr("%1 items on map\n","Info about map").arg (mapScene->items().size(),6); uint b=0; uint f=0; uint n=0; + uint xl=0; BranchObj *bo; - bo=mapCenter->first(); + bo=model->first(); while (bo) { if (!bo->getNote().isEmpty() ) n++; f+= bo->countFloatImages(); b++; - bo=bo->next(); + xl+=bo->countXLinks(); + bo=model->next(bo); } stats+=QString ("%1 branches\n").arg (b-1,6); + stats+=QString ("%1 xLinks \n").arg (xl,6); stats+=QString ("%1 notes\n").arg (n,6); stats+=QString ("%1 images\n").arg (f,6); dia.setStats (stats); @@ -2192,350 +3753,389 @@ // Finally show dialog if (dia.exec() == QDialog::Accepted) { - mapCenter->setAuthor (dia.getAuthor() ); - mapCenter->setComment (dia.getComment() ); - setChanged(); + setMapAuthor (dia.getAuthor() ); + setMapComment (dia.getComment() ); } } +void MapEditor::ensureSelectionVisible() +{ + LinkableMapObj *lmo=xelection.single(); + if (lmo) ensureVisible (lmo->getBBox() ); + +} + +void MapEditor::updateSelection() +{ + // Tell selection to update geometries + xelection.update(); +} + void MapEditor::updateActions() { - if (getLinkColorHint()==HeadingColor) - actionFormatLinkColorHint->setOn(true); - else - actionFormatLinkColorHint->setOn(false); - - switch (linkstyle) - { - case StyleLine: - actionFormatLinkStyleLine->setOn(true); - break; - case StyleParabel: - actionFormatLinkStyleParabel->setOn(true); - break; - case StylePolyLine: - actionFormatLinkStylePolyLine->setOn(true); - break; - case StylePolyParabel: - actionFormatLinkStylePolyParabel->setOn(true); - break; - default: - break; - } - - QPixmap pix( 16, 16 ); - pix.fill( mapCanvas->backgroundColor() ); - actionFormatBackColor->setIconSet( pix ); - pix.fill( deflinkcolor ); - actionFormatLinkColor->setIconSet( pix ); - - actionEditUndo->setEnabled( mapChanged ); - actionFileSave->setEnabled( mapUnsaved ); - - if (selection) - { - if ( (typeid(*selection) == typeid(BranchObj)) || - (typeid(*selection) == typeid(MapCenterObj)) ) - { - standardFlagsDefault->setEnabled (true); - - if ( ((BranchObj*)(selection))->getURL().isEmpty() ) - actionEditOpenURL->setEnabled (false); - else - actionEditOpenURL->setEnabled (true); - actionEditURL->setEnabled (true); - actionEditHeading2URL->setEnabled (true); - actionEditBugzilla2URL->setEnabled (true); - - if ( ((BranchObj*)(selection))->getVymLink().isEmpty() ) - { - actionEditOpenVymLink->setEnabled (false); - actionEditDeleteVymLink->setEnabled (false); - } else - { - actionEditOpenVymLink->setEnabled (true); - actionEditDeleteVymLink->setEnabled (true); - } - actionEditVymLink->setEnabled (true); - - actionEditCopy->setEnabled (true); - actionEditCut->setEnabled (true); - actionEditPaste->setEnabled (true); - actionEditMoveUp->setEnabled (true); - actionEditMoveDown->setEnabled (true); - actionEditToggleScroll->setEnabled (true); - actionEditHeading->setEnabled (true); - actionEditDelete->setEnabled (true); - actionEditAddBranch->setEnabled (true); - actionEditAddBranchAbove->setEnabled (true); - actionEditAddBranchBelow->setEnabled (true); - actionEditImportAdd->setEnabled (true); - actionEditImportReplace->setEnabled (true); - actionEditSaveBranch->setEnabled (true); - actionEditSelectFirst->setEnabled (true); - actionEditSelectLast->setEnabled (true); - actionEditToggleFloatExport->setEnabled (false); - actionFormatPickColor->setEnabled (true); - actionFormatColorBranch->setEnabled (true); - actionFormatColorSubtree->setEnabled (true); - switch (selection->getFrameType()) - { - case NoFrame: - actionFormatFrameNone->setOn(true); - break; - case Rectangle: - actionFormatFrameRectangle->setOn(true); - break; - default: - break; - } - } - if ( (typeid(*selection) == typeid(FloatImageObj)) ) - { - standardFlagsDefault->setEnabled (false); - - actionEditOpenURL->setEnabled (false); - actionEditURL->setEnabled (false); - actionEditHeading2URL->setEnabled (false); - actionEditBugzilla2URL->setEnabled (false); - actionEditOpenVymLink->setEnabled (false); - actionEditVymLink->setEnabled (false); - actionEditDeleteVymLink->setEnabled (false); - - actionEditCopy->setEnabled (true); - actionEditCut->setEnabled (true); - actionEditPaste->setEnabled (false); //FIXME - actionEditMoveUp->setEnabled (false); - actionEditMoveDown->setEnabled (false); - actionEditToggleScroll->setEnabled (false); - actionEditHeading->setEnabled (false); - actionEditDelete->setEnabled (true); - actionEditAddBranch->setEnabled (false); - actionEditAddBranchAbove->setEnabled (false); - actionEditAddBranchBelow->setEnabled (false); - actionEditImportAdd->setEnabled (false); - actionEditSaveBranch->setEnabled (false); - actionEditImportReplace->setEnabled (false); - actionEditSelectFirst->setEnabled (false); - actionEditSelectLast->setEnabled (false); - actionEditToggleFloatExport->setOn - ( ((FloatImageObj*)(selection))->getFloatExport() ); - actionFormatPickColor->setEnabled (false); - actionFormatColorBranch->setEnabled (false); - actionFormatColorSubtree->setEnabled (false); - } - - } else - { - standardFlagsDefault->setEnabled (false); - - actionEditCopy->setEnabled (false); - actionEditCut->setEnabled (false); - actionEditPaste->setEnabled (false); - actionEditMoveUp->setEnabled (false); - actionEditMoveDown->setEnabled (false); - actionEditToggleScroll->setEnabled (false); - actionEditOpenURL->setEnabled (false); - actionEditURL->setEnabled (false); - actionEditOpenVymLink->setEnabled (false); - actionEditVymLink->setEnabled (false); - actionEditDeleteVymLink->setEnabled (false); - actionEditHeading2URL->setEnabled (false); - actionEditBugzilla2URL->setEnabled (false); - actionEditHeading->setEnabled (false); - actionEditDelete->setEnabled (false); - actionEditAddBranch->setEnabled (false); - actionEditAddBranchAbove->setEnabled (false); - actionEditAddBranchBelow->setEnabled (false); - actionEditSaveBranch->setEnabled (false); - actionEditImportReplace->setEnabled (false); - actionEditSelectFirst->setEnabled (false); - actionEditSelectLast->setEnabled (false); - actionEditToggleFloatExport->setEnabled (false); - actionFormatPickColor->setEnabled (false); - actionFormatColorBranch->setEnabled (false); - actionFormatColorSubtree->setEnabled (false); + // Tell mainwindow to update states of actions + mainWindow->updateActions(); + // TODO maybe don't update if blockReposition is set +} + +void MapEditor::updateNoteFlag() +{ + setChanged(); + BranchObj *bo=xelection.getBranch(); + if (bo) + { + bo->updateNoteFlag(); + mainWindow->updateActions(); } } -void MapEditor::setLinkStyle (LinkStyle ls) -{ - linkstyle=ls; +void MapEditor::setMapAuthor (const QString &s) +{ + saveState ( + QString ("setMapAuthor (\"%1\")").arg(model->getAuthor()), + QString ("setMapAuthor (\"%1\")").arg(s), + QString ("Set author of map to \"%1\"").arg(s) + ); + model->setAuthor (s); +} + +void MapEditor::setMapComment (const QString &s) +{ + saveState ( + QString ("setMapComment (\"%1\")").arg(model->getComment()), + QString ("setMapComment (\"%1\")").arg(s), + QString ("Set comment of map") + ); + model->setComment (s); +} + +void MapEditor::setMapLinkStyle (const QString & s) +{ + QString snow; + if (linkstyle==LinkableMapObj::Line) + snow="StyleLine"; + else if (linkstyle==LinkableMapObj::Parabel) + snow="StyleParabel"; + else if (linkstyle==LinkableMapObj::PolyLine) + snow="StylePolyLine"; + else if (linkstyle==LinkableMapObj::PolyParabel) + snow="StyleParabel"; + + saveState ( + QString("setMapLinkStyle (\"%1\")").arg(s), + QString("setMapLinkStyle (\"%1\")").arg(snow), + QString("Set map link style (\"%1\")").arg(s) + ); + + if (s=="StyleLine") + linkstyle=LinkableMapObj::Line; + else if (s=="StyleParabel") + linkstyle=LinkableMapObj::Parabel; + else if (s=="StylePolyLine") + linkstyle=LinkableMapObj::PolyLine; + else + linkstyle=LinkableMapObj::PolyParabel; BranchObj *bo; - bo=mapCenter->first(); - bo=bo->next(); + bo=model->first(); + bo=model->next(bo); while (bo) { bo->setLinkStyle(bo->getDefLinkStyle()); - bo=bo->next(); + bo=model->next(bo); } - //setChanged(); - //saveState(); + model->reposition(); } -LinkStyle MapEditor::getLinkStyle () +LinkableMapObj::Style MapEditor::getMapLinkStyle () { return linkstyle; } -void MapEditor::setLinkColor(QColor c) -{ - deflinkcolor=c; +void MapEditor::setMapDefLinkColor(QColor c) +{ + defLinkColor=c; + BranchObj *bo; + bo=model->first(); + while (bo) + { + bo->setLinkColor(); + bo=model->next(bo); + } updateActions(); } -void MapEditor::setLinkColorHint() -{ - // called from setLinkColorHint(lch) or at end of parse +void MapEditor::setMapLinkColorHintInt() +{ + // called from setMapLinkColorHint(lch) or at end of parse BranchObj *bo; - bo=mapCenter->first(); + bo=model->first(); while (bo) { bo->setLinkColor(); - bo=bo->next(); + bo=model->next(bo); } } -void MapEditor::setLinkColorHint(LinkColorHint lch) +void MapEditor::setMapLinkColorHint(LinkableMapObj::ColorHint lch) { linkcolorhint=lch; - setLinkColorHint(); + setMapLinkColorHintInt(); } -void MapEditor::toggleLinkColorHint() -{ - if (linkcolorhint==HeadingColor) - linkcolorhint=DefaultColor; +void MapEditor::toggleMapLinkColorHint() +{ + if (linkcolorhint==LinkableMapObj::HeadingColor) + linkcolorhint=LinkableMapObj::DefaultColor; else - linkcolorhint=HeadingColor; + linkcolorhint=LinkableMapObj::HeadingColor; BranchObj *bo; - bo=mapCenter->first(); + bo=model->first(); while (bo) { bo->setLinkColor(); - bo=bo->next(); + bo=model->next(bo); } } -LinkColorHint MapEditor::getLinkColorHint() +LinkableMapObj::ColorHint MapEditor::getMapLinkColorHint() { return linkcolorhint; } -QColor MapEditor::getDefLinkColor() -{ - return deflinkcolor; +QColor MapEditor::getMapDefLinkColor() +{ + return defLinkColor; } -void MapEditor::selectLinkColor() -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - QColor col = QColorDialog::getColor( deflinkcolor, this ); +void MapEditor::setMapDefXLinkColor(QColor col) +{ + defXLinkColor=col; +} + +QColor MapEditor::getMapDefXLinkColor() +{ + return defXLinkColor; +} + +void MapEditor::setMapDefXLinkWidth (int w) +{ + defXLinkWidth=w; +} + +int MapEditor::getMapDefXLinkWidth() +{ + return defXLinkWidth; +} + +void MapEditor::selectMapLinkColor() +{ + QColor col = QColorDialog::getColor( defLinkColor, this ); if ( !col.isValid() ) return; - setLinkColor( col ); - setChanged(); + saveState ( + QString("setMapDefLinkColor (\"%1\")").arg(getMapDefLinkColor().name()), + QString("setMapDefLinkColor (\"%1\")").arg(col.name()), + QString("Set map link color to %1").arg(col.name()) + ); + setMapDefLinkColor( col ); } +void MapEditor::selectMapSelectionColor() +{ + QColor col = QColorDialog::getColor( defLinkColor, this ); + setSelectionColor (col); +} + +void MapEditor::setSelectionColorInt (QColor col) +{ + if ( !col.isValid() ) return; + xelection.setColor (col); +} + +void MapEditor::setSelectionColor(QColor col) +{ + if ( !col.isValid() ) return; + saveState ( + QString("setSelectionColor (%1)").arg(xelection.getColor().name()), + QString("setSelectionColor (%1)").arg(col.name()), + QString("Set color of selection box to %1").arg(col.name()) + ); + setSelectionColorInt (col); +} + +QColor MapEditor::getSelectionColor() +{ + return xelection.getColor(); +} + +bool MapEditor::scrollBranch(BranchObj *bo) +{ + if (bo) + { + if (bo->isScrolled()) return false; + if (bo->countBranches()==0) return false; + if (bo->getDepth()==0) return false; + QString u,r; + r="scroll"; + u="unscroll"; + saveState( + bo, + QString ("%1 ()").arg(u), + bo, + QString ("%1 ()").arg(r), + QString ("%1 %2").arg(r).arg(getName(bo)) + ); + bo->toggleScroll(); + xelection.update(); + scene()->update(); + return true; + } + return false; +} + +bool MapEditor::unscrollBranch(BranchObj *bo) +{ + if (bo) + { + if (!bo->isScrolled()) return false; + if (bo->countBranches()==0) return false; + if (bo->getDepth()==0) return false; + QString u,r; + u="scroll"; + r="unscroll"; + saveState( + bo, + QString ("%1 ()").arg(u), + bo, + QString ("%1 ()").arg(r), + QString ("%1 %2").arg(r).arg(getName(bo)) + ); + bo->toggleScroll(); + xelection.update(); + scene()->update(); + return true; + } + return false; +} + void MapEditor::toggleScroll() { - if (selection && (typeid(*selection) == typeid(BranchObj)) ) - { - BranchObj *bo=((BranchObj*)(selection)); - if (bo->countBranches()==0) return; - if (bo->getDepth()==0) return; - setChanged(); - saveState(PartOfMap,selection); - bo->toggleScroll(); - adjustCanvasSize(); - canvas()->update(); + BranchObj *bo=xelection.getBranch(); + if (xelection.type()==Selection::Branch ) + { + if (bo->isScrolled()) + unscrollBranch (bo); + else + scrollBranch (bo); } } -void MapEditor::unScrollAll() -{ - BranchObj *bo; - bo=mapCenter->first(); - while (bo) - { - if (bo->isScrolled()) bo->toggleScroll(); - bo=bo->next(); +void MapEditor::unscrollChilds() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + bo->first(); + while (bo) + { + if (bo->isScrolled()) unscrollBranch (bo); + bo=bo->next(); + } + } +} + +FloatImageObj* MapEditor::loadFloatImageInt (QString fn) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + FloatImageObj *fio; + bo->addFloatImage(); + fio=bo->getLastFloatImage(); + fio->load(fn); + model->reposition(); + scene()->update(); + return fio; } -} + return NULL; +} void MapEditor::loadFloatImage () { - if (selection && - (typeid(*selection) == typeid(BranchObj)) || - (typeid(*selection) == typeid(MapCenterObj)) ) - { - BranchObj *bo=((BranchObj*)(selection)); - - QFileDialog *fd=new QFileDialog( this,tr("vym - load image")); + BranchObj *bo=xelection.getBranch(); + if (bo) + { + + Q3FileDialog *fd=new Q3FileDialog( this); + fd->setMode (Q3FileDialog::ExistingFiles); fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)")); ImagePreview *p =new ImagePreview (fd); fd->setContentsPreviewEnabled( TRUE ); fd->setContentsPreview( p, p ); - fd->setPreviewMode( QFileDialog::Contents ); - fd->setCaption(tr("vym - Load image")); + fd->setPreviewMode( Q3FileDialog::Contents ); + fd->setCaption(vymName+" - " +tr("Load image")); fd->setDir (lastImageDir); fd->show(); - QString fn; if ( fd->exec() == QDialog::Accepted ) { - setChanged(); - saveState(PartOfMap,selection); - QString fn=fd->selectedFile(); - lastImageDir=fn.left(fn.findRev ("/")); - bo->addFloatImage(); - // FIXME check if load was successful - bo->getLastFloatImage()->load(fn); - bo->getLastFloatImage()->setOriginalFilename(fn); - mapCenter->reposition(); - adjustCanvasSize(); - canvas()->update(); + // TODO loadFIO in QT4 use: lastImageDir=fd->directory(); + lastImageDir=QDir (fd->dirPath()); + QString s; + FloatImageObj *fio; + for (int j=0; jselectedFiles().count(); j++) + { + s=fd->selectedFiles().at(j); + fio=loadFloatImageInt (s); + if (fio) + saveState( + (LinkableMapObj*)fio, + "delete ()", + bo, + QString ("loadImage (%1)").arg(s ), + QString("Add image %1 to %2").arg(s).arg(getName(bo)) + ); + else + // TODO loadFIO error handling + qWarning ("Failed to load "+s); + } } + delete (p); + delete (fd); } } -void MapEditor::saveFloatImage (int item) -{ - if (selection && - (typeid(*selection) == typeid(FloatImageObj)) ) - { - FloatImageObj *fio=((FloatImageObj*)(selection)); - const char* fmt = saveImageFormatMenu->text(item); - - QFileDialog *fd=new QFileDialog( this, tr("vym - save image as") + fmt); - fd->addFilter ("PNG (*.png)"); - fd->addFilter ("BMP (*.bmp)"); - fd->addFilter ("XBM (*.xbm)"); - fd->addFilter ("JPG (*.jpg)"); - fd->addFilter ("XPM (*.xpm)"); - fd->addFilter ("GIF (*.gif)"); - fd->addFilter ("PNM (*.pnm)"); - fd->addFilter (QString (tr("Images") + " (*.png *.bmp *.xbm *.jpg *.png *.xpm *.gif *.pnm)")); - fd->setCaption(tr("vym - Save image as ") + fmt); - fd->setMode( QFileDialog::AnyFile ); - fd->setSelection (fio->getOriginalFilename()); +void MapEditor::saveFloatImageInt (FloatImageObj *fio, const QString &type, const QString &fn) +{ + fio->save (fn,type); +} + +void MapEditor::saveFloatImage () +{ + FloatImageObj *fio=xelection.getFloatImage(); + if (fio) + { + QFileDialog *fd=new QFileDialog( this); + fd->setFilters (imageIO.getFilters()); + fd->setCaption(vymName+" - " +tr("Save image")); + fd->setFileMode( QFileDialog::AnyFile ); + fd->setDirectory (lastImageDir); +// fd->setSelection (fio->getOriginalFilename()); fd->show(); QString fn; - if ( fd->exec() == QDialog::Accepted ) + if ( fd->exec() == QDialog::Accepted && fd->selectedFiles().count()==1) { - if (QFile (fd->selectedFile()).exists() ) + fn=fd->selectedFiles().at(0); + if (QFile (fn).exists() ) { - QMessageBox mb( "VYM", - tr("The file ") + fd->selectedFile() + - tr(" exists already. " - "Do you want to overwrite it?"), + QMessageBox mb( vymName, + tr("The file %1 exists already.\n" + "Do you want to overwrite it?").arg(fn), QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, QMessageBox::Cancel | QMessageBox::Escape, - QMessageBox::QMessageBox::NoButton ); + QMessageBox::NoButton ); mb.setButtonText( QMessageBox::Yes, tr("Overwrite") ); mb.setButtonText( QMessageBox::No, tr("Cancel")); @@ -2543,170 +4143,351 @@ { case QMessageBox::Yes: // save - break;; + break; case QMessageBox::Cancel: // do nothing + delete (fd); return; break; } } - fio->save (fd->selectedFile(),fmt); + saveFloatImageInt (fio,fd->selectedFilter(),fn ); + } + delete (fd); + } +} + +void MapEditor::setFrameType(const FrameObj::FrameType &t) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + QString s=bo->getFrameTypeName(); + bo->setFrameType (t); + saveState (bo, QString("setFrameType (\"%1\")").arg(s), + bo, QString ("setFrameType (\"%1\")").arg(bo->getFrameTypeName()),QString ("set type of frame to %1").arg(s)); + model->reposition(); + bo->updateLink(); + } +} + +void MapEditor::setFrameType(const QString &s) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + saveState (bo, QString("setFrameType (\"%1\")").arg(bo->getFrameTypeName()), + bo, QString ("setFrameType (\"%1\")").arg(s),QString ("set type of frame to %1").arg(s)); + bo->setFrameType (s); + model->reposition(); + bo->updateLink(); + } +} + +void MapEditor::setFramePenColor(const QColor &c) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + saveState (bo, QString("setFramePenColor (\"%1\")").arg(bo->getFramePenColor().name() ), + bo, QString ("setFramePenColor (\"%1\")").arg(c.name() ),QString ("set pen color of frame to %1").arg(c.name() )); + bo->setFramePenColor (c); + } +} + +void MapEditor::setFrameBrushColor(const QColor &c) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + saveState (bo, QString("setFrameBrushColor (\"%1\")").arg(bo->getFrameBrushColor().name() ), + bo, QString ("setFrameBrushColor (\"%1\")").arg(c.name() ),QString ("set brush color of frame to %1").arg(c.name() )); + bo->setFrameBrushColor (c); + } +} + +void MapEditor::setFramePadding (const int &i) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + saveState (bo, QString("setFramePadding (\"%1\")").arg(bo->getFramePadding() ), + bo, QString ("setFramePadding (\"%1\")").arg(i),QString ("set brush color of frame to %1").arg(i)); + bo->setFramePadding (i); + model->reposition(); + bo->updateLink(); + } +} + +void MapEditor::setFrameBorderWidth(const int &i) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + saveState (bo, QString("setFrameBorderWidth (\"%1\")").arg(bo->getFrameBorderWidth() ), + bo, QString ("setFrameBorderWidth (\"%1\")").arg(i),QString ("set border width of frame to %1").arg(i)); + bo->setFrameBorderWidth (i); + model->reposition(); + bo->updateLink(); + } +} + +void MapEditor::setIncludeImagesVer(bool b) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + QString u= b ? "false" : "true"; + QString r=!b ? "false" : "true"; + + saveState( + bo, + QString("setIncludeImagesVertically (%1)").arg(u), + bo, + QString("setIncludeImagesVertically (%1)").arg(r), + QString("Include images vertically in %1").arg(getName(bo)) + ); + bo->setIncludeImagesVer(b); + model->reposition(); + } +} + +void MapEditor::setIncludeImagesHor(bool b) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + QString u= b ? "false" : "true"; + QString r=!b ? "false" : "true"; + + saveState( + bo, + QString("setIncludeImagesHorizontally (%1)").arg(u), + bo, + QString("setIncludeImagesHorizontally (%1)").arg(r), + QString("Include images horizontally in %1").arg(getName(bo)) + ); + bo->setIncludeImagesHor(b); + model->reposition(); + } +} + +void MapEditor::setHideLinkUnselected (bool b) +{ + LinkableMapObj *sel=xelection.single(); + if (sel && + (xelection.type() == Selection::Branch || + xelection.type() == Selection::MapCenter || + xelection.type() == Selection::FloatImage )) + { + QString u= b ? "false" : "true"; + QString r=!b ? "false" : "true"; + + saveState( + sel, + QString("setHideLinkUnselected (%1)").arg(u), + sel, + QString("setHideLinkUnselected (%1)").arg(r), + QString("Hide link of %1 if unselected").arg(getName(sel)) + ); + sel->setHideLinkUnselected(b); + } +} + +void MapEditor::importDirInt(BranchObj *dst, QDir d) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + // Traverse directories + d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks ); + QFileInfoList list = d.entryInfoList(); + QFileInfo fi; + + for (int i = 0; i < list.size(); ++i) + { + fi=list.at(i); + if (fi.fileName() != "." && fi.fileName() != ".." ) + { + dst->addBranch(); + bo=dst->getLastBranch(); + bo->setHeading (fi.fileName() ); + bo->setColor (QColor("blue")); + bo->toggleScroll(); + if ( !d.cd(fi.fileName()) ) + QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory %1").arg(fi.fileName())); + else + { + // Recursively add subdirs + importDirInt (bo,d); + d.cdUp(); + } + } + } + // Traverse files + d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks ); + list = d.entryInfoList(); + + for (int i = 0; i < list.size(); ++i) + { + fi=list.at(i); + dst->addBranch(); + bo=dst->getLastBranch(); + bo->setHeading (fi.fileName() ); + bo->setColor (QColor("black")); + if (fi.fileName().right(4) == ".vym" ) + bo->setVymLink (fi.filePath()); + } + } +} + +void MapEditor::importDirInt (const QString &s) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + saveStateChangingPart (bo,bo,QString ("importDir (\"%1\")").arg(s),QString("Import directory structure from %1").arg(s)); + + QDir d(s); + importDirInt (bo,d); + } +} + +void MapEditor::importDir() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + QStringList filters; + filters <<"VYM map (*.vym)"; + QFileDialog *fd=new QFileDialog( this,vymName+ " - " +tr("Choose directory structure to import")); + fd->setMode (QFileDialog::DirectoryOnly); + fd->setFilters (filters); + fd->setCaption(vymName+" - " +tr("Choose directory structure to import")); + fd->show(); + + QString fn; + if ( fd->exec() == QDialog::Accepted ) + { + importDirInt (fd->selectedFile() ); + model->reposition(); + scene()->update(); + } + } +} + +void MapEditor::followXLink(int i) +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + bo=bo->XLinkTargetAt(i); + if (bo) + { + xelection.select(bo); + ensureSelectionVisible(); } } } -void MapEditor::toggleFloatExport() -{ - if (selection && - (typeid(*selection) == typeid(FloatImageObj))|| - (typeid(*selection) == typeid(FloatObj)) ) - { - FloatImageObj *fio=((FloatImageObj*)(selection)); - fio->setFloatExport (actionEditToggleFloatExport->isOn() ); +void MapEditor::editXLink(int i) // FIXME missing saveState +{ + BranchObj *bo=xelection.getBranch(); + if (bo) + { + XLinkObj *xlo=bo->XLinkAt(i); + if (xlo) + { + EditXLinkDialog dia; + dia.setXLink (xlo); + dia.setSelection(bo); + if (dia.exec() == QDialog::Accepted) + { + if (dia.useSettingsGlobal() ) + { + setMapDefXLinkColor (xlo->getColor() ); + setMapDefXLinkWidth (xlo->getWidth() ); + } + if (dia.deleteXLink()) + bo->deleteXLinkAt(i); + } + } } } -void MapEditor::setFrame(const FrameType &t) -{ - if (selection && - (typeid(*selection) == typeid(BranchObj)) || - (typeid(*selection) == typeid(MapCenterObj)) ) - { - selection->setFrameType (t); - mapCenter->reposition(); - selection->updateLink(); - } +AttributeTable* MapEditor::attributeTable() +{ + return attrTable; } -void MapEditor::importDir(BranchObj *dst, QDir d) -{ - if (selection && - (typeid(*selection) == typeid(BranchObj)) || - (typeid(*selection) == typeid(MapCenterObj)) ) - { - BranchObj *bo; - - // Traverse directories - d.setFilter( QDir::Dirs| QDir::Hidden | QDir::NoSymLinks ); - const QFileInfoList *dirlist = d.entryInfoList(); - QFileInfoListIterator itdir( *dirlist ); - QFileInfo *fi; - - while ( (fi = itdir.current()) != 0 ) - { - if (fi->fileName() != "." && fi->fileName() != ".." ) - { - dst->addBranch(); - bo=dst->getLastBranch(); - bo->setHeading (fi->fileName() ); - bo->setColor (QColor("blue"),false); - bo->toggleScroll(); - if ( !d.cd(fi->fileName()) ) - QMessageBox::critical (0,tr("Critical Import Error"),tr("Cannot find the directory")); - else - { - importDir (bo,d); - d.cdUp(); - } - } - ++itdir; - } - // Traverse files - d.setFilter( QDir::Files| QDir::Hidden | QDir::NoSymLinks ); - const QFileInfoList *filelist = d.entryInfoList(); - QFileInfoListIterator itfile( *filelist ); - - while ( (fi = itfile.current()) != 0 ) - { - dst->addBranch(); - bo=dst->getLastBranch(); - bo->setHeading (fi->fileName() ); - bo->setColor (QColor("black"),false); - ++itfile; - } - } +void MapEditor::testFunction1() +{ + BranchObj *bo=xelection.getBranch(); + if (bo) model->moveAway (bo); + +/* TODO Hide hidden stuff temporary, maybe add this as regular function somewhere + if (hidemode==HideNone) + { + setHideTmpMode (HideExport); + mapCenter->calcBBoxSizeWithChilds(); + QRectF totalBBox=mapCenter->getTotalBBox(); + QRectF mapRect=totalBBox; + QCanvasRectangle *frame=NULL; + + cout << " map has =("<setBrush (QColor(white)); + frame->setPen (QColor(black)); + frame->setZValue(0); + frame->show(); + } + else + { + setHideTmpMode (HideNone); + } + cout <<" hidemode="<setMode (QFileDialog::DirectoryOnly); - fd->addFilter (QString (tr("vym map") + " (*.vym)")); - fd->setCaption(tr("VYM - Choose directory structur to import")); - fd->show(); - - QString fn; - if ( fd->exec() == QDialog::Accepted ) - { - BranchObj *bo=((BranchObj*)(selection)); - importDir (bo,QDir(fd->selectedFile()) ); - mapCenter->reposition(); - adjustCanvasSize(); - canvas()->update(); - } - } -} - -void MapEditor::testFunction() -{ - cout << "MapEditor::testFunction() called\n"; -} - -void MapEditor::ensureSelectionVisible() -{ - LinkableMapObj* lmo= dynamic_cast (selection); - QPoint p; - if (selection->getOrientation() == OrientLeftOfCenter) - p= worldMatrix().map(QPoint (lmo->x(),lmo->y())); - else - p= worldMatrix().map(QPoint (lmo->x()+lmo->width(),lmo->y()+lmo->height())); - ensureVisible (p.x(), p.y() ); - -} - -void MapEditor::updateViewCenter() -{ - // Update movingCenter, so that we can zoom comfortably later - QRect rc = QRect( contentsX(), contentsY(), - visibleWidth(), visibleHeight() ); - QRect canvasRect = inverseWorldMatrix().mapRect(rc); - movingCenter.setX((canvasRect.right() + canvasRect.left())/2); - movingCenter.setY((canvasRect.top() + canvasRect.bottom())/2); -} - -void MapEditor::contentsContextMenuEvent ( QContextMenuEvent * e ) +void MapEditor::contextMenuEvent ( QContextMenuEvent * e ) { // Lineedits are already closed by preceding // mouseEvent, we don't need to close here. - QPoint p = inverseWorldMatrix().map(e->pos()); - LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL); + QPointF p = mapToScene(e->pos()); + LinkableMapObj* lmo=model->findMapObj(p, NULL); if (lmo) { // MapObj was found - if (selection != lmo) + if (xelection.single() != lmo) { // select the MapObj - if (selection) selection->unselect(); - selection=lmo; - selection->select(); - adjustCanvasSize(); + xelection.select(lmo); } // Context Menu - if (selection) + if (xelection.getBranch() ) { - if (typeid(*selection)==typeid(BranchObj) || - typeid(*selection)==typeid(MapCenterObj) ) - { - // Context Menu on branch or mapcenter - updateActions(); - branchContextMenu->popup(e->globalPos() ); - } - if (typeid(*selection)==typeid(FloatImageObj)) + // Context Menu on branch or mapcenter + updateActions(); + branchContextMenu->popup(e->globalPos() ); + } else + { + if (xelection.getFloatImage() ) { // Context Menu on floatimage updateActions(); @@ -2715,348 +4496,947 @@ } } else { // No MapObj found, we are on the Canvas itself - // Context Menu on Canvas + // Context Menu on scene updateActions(); + contextMenuPos=p; canvasContextMenu->popup(e->globalPos() ); } + e->accept(); } -void MapEditor::contentsMousePressEvent(QMouseEvent* e) -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - QPoint p = inverseWorldMatrix().map(e->pos()); - LinkableMapObj* lmo=mapCenter->findMapObj(p, NULL); - - // Special case: CTRL is pressed, don't select anything - if (e->state() & QMouseEvent::ControlButton) - { - pickingColor=true; - setCursor (pickColorCursor); +void MapEditor::keyPressEvent(QKeyEvent* e) +{ + if (e->modifiers() & Qt::ControlModifier) + { + switch (mainWindow->getModMode()) + { + case Main::ModModeColor: + setCursor (PickColorCursor); + break; + case Main::ModModeCopy: + setCursor (CopyCursor); + break; + case Main::ModModeXLink: + setCursor (XLinkCursor); + break; + default : + setCursor (Qt::ArrowCursor); + break; + } + } +} + +void MapEditor::keyReleaseEvent(QKeyEvent* e) +{ + if (!(e->modifiers() & Qt::ControlModifier)) + setCursor (Qt::ArrowCursor); +} + +void MapEditor::mousePressEvent(QMouseEvent* e) +{ + // Ignore right clicks, these will go to context menus + if (e->button() == Qt::RightButton ) + { + e->ignore(); return; } + //Ignore clicks while editing heading + if (isSelectBlocked() ) + { + e->ignore(); + return; + } + + QPointF p = mapToScene(e->pos()); + LinkableMapObj* lmo=model->findMapObj(p, NULL); + + e->accept(); + + //Take care of system flags _or_ modifier modes + // + if (lmo && (typeid(*lmo)==typeid(BranchObj) || + typeid(*lmo)==typeid(MapCenterObj) )) + { + QString foname=((BranchObj*)lmo)->getSystemFlagName(p); + if (!foname.isEmpty()) + { + // systemFlag clicked + selectInt (lmo); + if (foname=="url") + { + if (e->state() & Qt::ControlModifier) + mainWindow->editOpenURLTab(); + else + mainWindow->editOpenURL(); + } + else if (foname=="vymLink") + { + mainWindow->editOpenVymLink(); + // tabWidget may change, better return now + // before segfaulting... + } else if (foname=="note") + mainWindow->windowToggleNoteEditor(); + else if (foname=="hideInExport") + toggleHideExport(); + xelection.update(); + return; + } + } + + // No system flag clicked, take care of modmodes (CTRL-Click) + if (e->state() & Qt::ControlModifier) + { + if (mainWindow->getModMode()==Main::ModModeColor) + { + pickingColor=true; + setCursor (PickColorCursor); + return; + } + if (mainWindow->getModMode()==Main::ModModeXLink) + { + BranchObj *bo_begin=NULL; + if (lmo) + bo_begin=(BranchObj*)(lmo); + else + if (xelection.getBranch() ) + bo_begin=xelection.getBranch(); + if (bo_begin) + { + drawingLink=true; + linkingObj_src=bo_begin; + tmpXLink=new XLinkObj (mapScene); + tmpXLink->setBegin (bo_begin); + tmpXLink->setEnd (p); + tmpXLink->setColor(defXLinkColor); + tmpXLink->setWidth(defXLinkWidth); + tmpXLink->updateXLink(); + tmpXLink->setVisibility (true); + return; + } + } + } // End of modmodes + if (lmo) - { // MapObj was found - if (selection != lmo) + { + // Select the clicked object + selectInt (lmo); + + // Left Button Move Branches + if (e->button() == Qt::LeftButton ) { - // select the MapObj - if (selection) selection->unselect(); - selection=lmo; - selection->select(); - - adjustCanvasSize(); - } - - // Check, if systemFlag clicked - if (typeid(*selection)==typeid(BranchObj) || - typeid(*selection)==typeid(MapCenterObj) ) - { - QString foname=((BranchObj*)(selection))->getSystemFlagName(p); - if (!foname.isEmpty()) + //movingObj_start.setX( p.x() - selection->x() );// TODO replaced selection->lmo here + //movingObj_start.setY( p.y() - selection->y() ); + movingObj_start.setX( p.x() - lmo->x() ); + movingObj_start.setY( p.y() - lmo->y() ); + movingObj_orgPos.setX (lmo->x() ); + movingObj_orgPos.setY (lmo->y() ); + movingObj_orgRelPos=lmo->getRelPos(); + + // If modMode==copy, then we want to "move" the _new_ object around + // then we need the offset from p to the _old_ selection, because of tmp + if (mainWindow->getModMode()==Main::ModModeCopy && + e->state() & Qt::ControlModifier) { - // Do not move, if systemFlag clicked - if (foname=="url") - openURL(); - else - if (foname=="vymLink") - { - mainWindow->editOpenVymLink(); - // tabWidget may change, better return now - // before segfaulting... - return; - } else - if (foname=="note") - mainWindow->windowToggleNoteEditor(); - } - } - - // Left Button Move Branches - if (e->button() == QMouseEvent::LeftButton ) - { - movingObj=selection; - movingObj_start.setX( p.x() - selection->x() ); - movingObj_start.setY( p.y() - selection->y() ); + BranchObj *bo=xelection.getBranch(); + if (bo) + { + copyingObj=true; + bo->addBranch ((BranchObj*)xelection.single()); + unselect(); + xelection.select(bo->getLastBranch()); + model->reposition(); + } + } + + movingObj=xelection.single(); } else // Middle Button Toggle Scroll // (On Mac OS X this won't work, but we still have // a button in the toolbar) - if (e->button() == QMouseEvent::MidButton ) - { + if (e->button() == Qt::MidButton ) toggleScroll(); - } updateActions(); + xelection.update(); } else - { // No MapObj found, we are on the Canvas itself - // Left Button move Pos of CanvasView - if (e->button() == QMouseEvent::LeftButton ) + { // No MapObj found, we are on the scene itself + // Left Button move Pos of sceneView + if (e->button() == Qt::LeftButton ) { movingObj=NULL; // move Content not Obj movingObj_start=e->globalPos(); - movingCont_start=QPoint (contentsX(), contentsY() ); - movingVec=QPoint(0,0); - setCursor(handOpenCursor); + movingCont_start=QPointF ( + horizontalScrollBar()->value(), + verticalScrollBar()->value()); + movingVec=QPointF(0,0); + setCursor(HandOpenCursor); } } } -void MapEditor::contentsMouseMoveEvent(QMouseEvent* e) -{ +void MapEditor::mouseMoveEvent(QMouseEvent* e) +{ + QPointF p = mapToScene(e->pos()); + LinkableMapObj *lmosel=xelection.single(); + // Move the selected MapObj - if ( selection && movingObj) + if ( lmosel && movingObj) { - QPoint p = inverseWorldMatrix().map(e->pos()); + // reset cursor if we are moving and don't copy + if (mainWindow->getModMode()!=Main::ModModeCopy) + setCursor (Qt::ArrowCursor); + + // To avoid jumping of the sceneView, only + // ensureSelectionVisible, if not tmp linked + if (!lmosel->hasParObjTmp()) + ensureSelectionVisible (); - // Now move the selection, but add relative position (movingObj_start) - // where selection - // was chosen with mousepointer. (This avoids flickering resp. jumping + // Now move the selection, but add relative position + // (movingObj_start) where selection was chosen with + // mousepointer. (This avoids flickering resp. jumping // of selection back to absPos) - LinkableMapObj *lmosel; - lmosel = dynamic_cast (selection); - // Check if we could link - LinkableMapObj* lmo=mapCenter->findMapObj(p, lmosel); + LinkableMapObj* lmo=model->findMapObj(p, lmosel); - if (typeid(*selection) == typeid(FloatImageObj)) + FloatObj *fio=xelection.getFloatImage(); + if (fio) { - setChanged(); - saveState(); - FloatObj *fo=(FloatObj*)(selection); - if (fo->getLinkStyle()==StyleUndef) - { - fo->setLinkStyle(fo->getDefLinkStyle()); - fo->setLinkColor(fo->getParObj()->getLinkColor()); - } - fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); - fo->setRelPos(); - fo->reposition(); + fio->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); + fio->setRelPos(); + fio->updateLink(); //no need for reposition, if we update link here + xelection.update(); // Relink float to new mapcenter or branch, if shift is pressed // Only relink, if selection really has a new parent - if ( (e->state() & QMouseEvent::ShiftButton) && lmo && + if ( (e->modifiers()==Qt::ShiftModifier) && lmo && ( (typeid(*lmo)==typeid(BranchObj)) || (typeid(*lmo)==typeid(MapCenterObj)) ) && - ( lmo != fo->getParObj()) + ( lmo != fio->getParObj()) ) { - if (typeid(*fo) == typeid(FloatImageObj)) + if (typeid(*fio) == typeid(FloatImageObj) && + ( (typeid(*lmo)==typeid(BranchObj) || + typeid(*lmo)==typeid(MapCenterObj)) )) { - FloatImageObj *fio=(FloatImageObj*)(fo); - ((BranchObj*)(lmo))->addFloatImage (fio); - fio->unselect(); - ((BranchObj*)(fio->getParObj()))->removeFloatImage (fio); - fio=((BranchObj*)(lmo))->getLastFloatImage(); - fio->setRelPos(); - fio->reposition(); - selection=(LinkableMapObj*)(fio); - selection->select(); - movingObj=(MapObj*)(fio); - // setLinkStyle calls updateLink, only set it once - if (fio->getLinkStyle()!=fio->getDefLinkStyle() ) - fio->setLinkStyle (fio->getDefLinkStyle()); - + + // Also save the move which was done so far + QString pold=qpointfToString(movingObj_orgRelPos); + QString pnow=qpointfToString(fio->getRelPos()); + saveState( + fio, + "moveRel "+pold, + fio, + "moveRel "+pnow, + QString("Move %1 to relative position %2").arg(getName(fio)).arg(pnow)); + fio->getParObj()->requestReposition(); + model->reposition(); + + linkTo (model->getSelectString(lmo)); + //movingObj=lmosel; + //movingObj_orgRelPos=lmosel->getRelPos(); + + model->reposition(); } - // TODO if (typeid(*selection) == typeid(FloatTextObj)) } - } else // selection != a FloatObj - { + } else + { // selection != a FloatObj if (lmosel->getDepth()==0) { - if (e->state() == (LeftButton | !ShiftButton)) - // If mapCenter is moved, move all the rest by default, too. - mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); + // Move MapCenter + if (e->buttons()== Qt::LeftButton && e->modifiers()==Qt::ShiftModifier) + ((MapCenterObj*)lmosel)->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); else - mapCenter->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); + lmosel->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); + model->updateRelPositions(); } else { if (lmosel->getDepth()==1) { - // depth==1, mainbranch - setChanged(); - saveState(PartOfMap,lmosel); + // Move mainbranch lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); + lmosel->setRelPos(); } else { - // depth>1 - if (lmosel->getOrientation() == OrientLeftOfCenter) + // Move ordinary branch + if (lmosel->getOrientation() == LinkableMapObj::LeftOfCenter) // Add width of bbox here, otherwise alignRelTo will cause jumping around lmosel->move(p.x() -movingObj_start.x()+lmosel->getBBox().width(), - p.y()-movingObj_start.y() ); + p.y()-movingObj_start.y() +lmosel->getTopPad() ); else - lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); + lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() -lmosel->getTopPad()); } - // reposition subbranch - lmosel->reposition(); - ensureSelectionVisible(); - - if (lmo && (lmo!=selection) && - (typeid(*lmo) == typeid(BranchObj) || - (typeid(*lmo) == typeid(MapCenterObj) ) - ) ) + + // Maybe we can relink temporary? + if (lmo && (lmo!=lmosel) && xelection.getBranch() && + (typeid(*lmo)==typeid(BranchObj) || + typeid(*lmo)==typeid(MapCenterObj)) ) + { - if (e->state() & QMouseEvent::ControlButton) + if (e->modifiers()==Qt::ControlModifier) { // Special case: CTRL to link below lmo lmosel->setParObjTmp (lmo,p,+1); } - else if (e->state() & QMouseEvent::ShiftButton) + else if (e->modifiers()==Qt::ShiftModifier) lmosel->setParObjTmp (lmo,p,-1); else lmosel->setParObjTmp (lmo,p,0); } else { - if (lmo &&(lmo==selection)) - // Could link to myself (happens sometimes...) - lmosel->unsetParObjTmp(); - if (!lmo) - // no Obj under selection, go back to original Parent - lmosel->unsetParObjTmp(); + lmosel->unsetParObjTmp(); } + // reposition subbranch + lmosel->reposition(); } // depth>0 + xelection.update(); } // no FloatImageObj - canvas()->update(); + scene()->update(); return; } // selection && moving_obj - // Move CanvasView - if (!movingObj && !pickingColor) - { - QPoint p=e->globalPos(); + // Draw a link from one branch to another + if (drawingLink) + { + tmpXLink->setEnd (p); + tmpXLink->updateXLink(); + } + + // Move sceneView + if (!movingObj && !pickingColor &&!drawingLink && e->buttons() == Qt::LeftButton ) + { + QPointF p=e->globalPos(); movingVec.setX(-p.x() + movingObj_start.x() ); movingVec.setY(-p.y() + movingObj_start.y() ); - setContentsPos( movingCont_start.x() + movingVec.x(), - movingCont_start.y() + movingVec.y()); - - updateViewCenter(); + horizontalScrollBar()->setSliderPosition((int)( movingCont_start.x()+movingVec.x() )); + verticalScrollBar()->setSliderPosition((int)( movingCont_start.y()+movingVec.y() ) ); } } -void MapEditor::contentsMouseReleaseEvent(QMouseEvent* e) -{ +void MapEditor::mouseReleaseEvent(QMouseEvent* e) +{ + QPointF p = mapToScene(e->pos()); LinkableMapObj *dst; + LinkableMapObj *lmosel=xelection.single(); // Have we been picking color? if (pickingColor) { pickingColor=false; - setCursor (ArrowCursor); + setCursor (Qt::ArrowCursor); // Check if we are over another branch - dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL); - if (dst && selection) + dst=model->findMapObj(p, NULL); + if (dst && lmosel) { - if (e->state() & QMouseEvent::ShiftButton) - { - ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),false); - ((BranchObj*)(selection))->setLinkColor (); - } + if (e->state() & Qt::ShiftModifier) + colorBranch (((BranchObj*)dst)->getColor()); else - { - ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),true); - ((BranchObj*)(selection))->setLinkColor (); - } + colorSubtree (((BranchObj*)dst)->getColor()); } return; } + + // Have we been drawing a link? + if (drawingLink) + { + drawingLink=false; + // Check if we are over another branch + dst=model->findMapObj(p, NULL); + if (dst && lmosel) + { + tmpXLink->setEnd ( ((BranchObj*)(dst)) ); + tmpXLink->updateXLink(); + tmpXLink->activate(); //FIXME savestate missing + //saveStateComplete(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); + } else + { + delete(tmpXLink); + tmpXLink=NULL; + } + return; + } + // Have we been moving something? - if ( selection && movingObj ) + if ( lmosel && movingObj ) { + FloatImageObj *fo=xelection.getFloatImage(); + if(fo) + { + // Moved FloatObj. Maybe we need to reposition + QString pold=qpointfToString(movingObj_orgRelPos); + QString pnow=qpointfToString(fo->getRelPos()); + saveState( + fo, + "moveRel "+pold, + fo, + "moveRel "+pnow, + QString("Move %1 to relative position %2").arg(getName(fo)).arg(pnow)); + + fo->getParObj()->requestReposition(); + model->reposition(); + } + // Check if we are over another branch, but ignore // any found LMOs, which are FloatObjs - dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), - ((LinkableMapObj*)(selection)) ); - - if (dst && - (typeid(*dst)!=typeid(BranchObj)&&typeid(*dst)!=typeid(MapCenterObj))) - { + dst=model->findMapObj(mapToScene(e->pos() ), lmosel); + + if (dst && (typeid(*dst)!=typeid(BranchObj) && typeid(*dst)!=typeid(MapCenterObj))) dst=NULL; - } - // Now check, if we have been moving a branch - if (typeid(*selection) == typeid(BranchObj) ) - { + BranchObj *bo=xelection.getBranch(); + if (bo && bo->getDepth()==0) + { + if (movingObj_orgPos != bo->getAbsPos()) + { + QString pold=qpointfToString(movingObj_orgPos); + QString pnow=qpointfToString(bo->getAbsPos()); + saveState( + fo, + "move "+pold, + fo, + "move "+pnow, + QString("Move mapcenter %1 to position %2").arg(getName(bo)).arg(pnow)); + } + } + + if (xelection.type() == Selection::Branch ) + { // A branch was moved + // save the position in case we link to mapcenter - QPoint savePos=QPoint (selection->x(),selection->y() ); + QPointF savePos=QPointF (lmosel->getAbsPos() ); // Reset the temporary drawn link to the original one - ((LinkableMapObj*)(selection))->unsetParObjTmp(); - + lmosel->unsetParObjTmp(); + + // For Redo we may need to save original selection + QString preSelStr=model->getSelectString(lmosel); + + copyingObj=false; if (dst ) - { - setChanged(); - saveState(); - // TODO we also could check, if dest and src are on same branch, - // then it would be sufficient to saveState of this branch - - // FIXME better introduce BO::move to speed up and keep IDs - copy(); // copy selection to clipboard - cutNoSave(); // remove selection here - - selection->unselect(); - selection=dst; - // Modifiers allow to insert above/below dst - if (e->state() & QMouseEvent::ShiftButton) + { + // We have a destination, relink to that + + BranchObj* bsel=xelection.getBranch(); + BranchObj* bdst=(BranchObj*)dst; + + QString preParStr=model->getSelectString (bsel->getParObj()); + QString preNum=QString::number (bsel->getNum(),10); + QString preDstParStr; + + if (e->state() & Qt::ShiftModifier && dst->getParObj()) + { // Link above dst + preDstParStr=model->getSelectString (dst->getParObj()); + bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()); + } else + if (e->state() & Qt::ControlModifier && dst->getParObj()) { - selection=pasteAtNoSave (((BranchObj*)(dst))->getNum()); - if (selection) selection->select(); - } - else if (e->state() & QMouseEvent::ControlButton) + // Link below dst + preDstParStr=model->getSelectString (dst->getParObj()); + bsel->linkTo ( (BranchObj*)(bdst->getParObj()), bdst->getNum()+1); + } else + { // Append to dst + preDstParStr=model->getSelectString(dst); + bsel->linkTo (bdst,-1); + if (dst->getDepth()==0) bsel->move (savePos); + } + QString postSelStr=model->getSelectString(lmosel); + QString postNum=QString::number (bsel->getNum(),10); + + QString undoCom="linkTo (\""+ + preParStr+ "\"," + preNum +"," + + QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ ")"; + + QString redoCom="linkTo (\""+ + preDstParStr + "\"," + postNum + "," + + QString ("%1,%2").arg(savePos.x()).arg(savePos.y())+ ")"; + + saveState ( + postSelStr,undoCom, + preSelStr, redoCom, + QString("Relink %1 to %2").arg(getName(bsel)).arg(getName(dst)) ); + + model->reposition(); // not necessary if we undo temporary move below + } else + { + // No destination, undo temporary move + + if (lmosel->getDepth()==1) { - selection=pasteAtNoSave (((BranchObj*)(dst))->getNum()+1); - if (selection) selection->select(); - } - else + // The select string might be different _after_ moving around. + // Therefor reposition and then use string of old selection, too + model->reposition(); + + QPointF rp(lmosel->getRelPos()); + if (rp != movingObj_orgRelPos) + { + QString ps=qpointfToString(rp); + saveState( + model->getSelectString(lmosel), "moveRel "+qpointfToString(movingObj_orgRelPos), + preSelStr, "moveRel "+ps, + QString("Move %1 to relative position %2").arg(getName(lmosel)).arg(ps)); + } + } + + // Draw the original link, before selection was moved around + if (settings.value("/animation/use",false).toBool() && lmosel->getDepth()>1) { - selection=pasteNoSave(); - selection->select(); - if (dst->getDepth()==0) - ((BranchObj*)(selection))->move (savePos); - } - } - // Draw the original link, before selection was moved around - mapCenter->reposition(); + QPointF p=bo->getParObj()->getChildPos(); + lmosel->setRelPos(); // calc relPos first + model->startAnimation( + lmosel->getRelPos(), + QPointF (movingObj_orgPos.x() - p.x(), movingObj_orgPos.y() - p.y() ) + ); + } else + model->reposition(); + } } - // Finally resize canvas, if needed - adjustCanvasSize(); - canvas()->update(); + xelection.update(); + // Finally resize scene, if needed + scene()->update(); movingObj=NULL; + + // Just make sure, that actions are still ok,e.g. the move branch up/down buttons... + updateActions(); } else - { // maybe we moved View: set old cursor - setCursor (ArrowCursor); - } + // maybe we moved View: set old cursor + setCursor (Qt::ArrowCursor); + } -void MapEditor::contentsMouseDoubleClickEvent(QMouseEvent* e) -{ - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - if (e->button() == QMouseEvent::LeftButton ) - { - QPoint p = inverseWorldMatrix().map(e->pos()); - LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL); +void MapEditor::mouseDoubleClickEvent(QMouseEvent* e) +{ + if (isSelectBlocked() ) + { + e->ignore(); + return; + } + + if (e->button() == Qt::LeftButton ) + { + QPointF p = mapToScene(e->pos()); + LinkableMapObj *lmo=model->findMapObj(p, NULL); if (lmo) { // MapObj was found // First select the MapObj than edit heading - if (selection) selection->unselect(); - selection=lmo; - selection->select(); - setChanged(); - saveState(PartOfMap,selection); - editHeading(); + xelection.select(lmo); + mainWindow->editHeading(); } } } void MapEditor::resizeEvent (QResizeEvent* e) { - QCanvasView::resizeEvent( e ); + QGraphicsView::resizeEvent( e ); +} + +void MapEditor::dragEnterEvent(QDragEnterEvent *event) +{ + //for (unsigned int i=0;event->format(i);i++) // Debug mime type + // cerr << event->format(i) << endl; + + if (event->mimeData()->hasImage()) + event->acceptProposedAction(); + else + if (event->mimeData()->hasUrls()) + event->acceptProposedAction(); +} + +void MapEditor::dragMoveEvent(QDragMoveEvent *) +{ +} + +void MapEditor::dragLeaveEvent(QDragLeaveEvent *event) +{ + event->accept(); +} + +void MapEditor::dropEvent(QDropEvent *event) +{ + BranchObj *sel=xelection.getBranch(); + if (sel) + { + if (debug) + foreach (QString format,event->mimeData()->formats()) + cout << "MapEditor: Dropped format: "< uris; + if (event->mimeData()->hasImage()) + { + QVariant imageData = event->mimeData()->imageData(); + addFloatImageInt (qvariant_cast(imageData)); + } else + if (event->mimeData()->hasUrls()) + uris=event->mimeData()->urls(); + + if (uris.count()>0) + { + QStringList files; + QString s; + QString heading; + BranchObj *bo; + for (int i=0; iaddBranch(); + if (bo) + { + s=uris.at(i).toLocalFile(); + if (!s.isEmpty()) + { + QString file = QDir::fromNativeSeparators(s); + heading = QFileInfo(file).baseName(); + files.append(file); + if (file.endsWith(".vym", false)) + bo->setVymLink(file); + else + bo->setURL(uris.at(i).toString()); + } else + { + bo->setURL(uris.at(i).toString()); + } + + if (!heading.isEmpty()) + bo->setHeading(heading); + else + bo->setHeading(uris.at(i).toString()); + } + } + } + model->reposition(); + } + } + event->acceptProposedAction(); +} + + +void MapEditor::sendSelection() +{ + if (netstate!=Server) return; + sendData (QString("select (\"%1\")").arg(xelection.getSelectString()) ); +} + +void MapEditor::newServer() +{ + port=54321; + sendCounter=0; + tcpServer = new QTcpServer(this); + if (!tcpServer->listen(QHostAddress::Any,port)) { + QMessageBox::critical(this, "vym server", + QString("Unable to start the server: %1.").arg(tcpServer->errorString())); + close(); + return; + } + connect(tcpServer, SIGNAL(newConnection()), this, SLOT(newClient())); + netstate=Server; + cout<<"Server is running on port "<serverPort()<abort(); + clientSocket->connectToHost(server ,port); + connect(clientSocket, SIGNAL(readyRead()), this, SLOT(readData())); + connect(clientSocket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(displayNetworkError(QAbstractSocket::SocketError))); + netstate=Client; + cout<<"connected to "<nextPendingConnection(); + connect(newClient, SIGNAL(disconnected()), + newClient, SLOT(deleteLater())); + + cout <<"ME::newClient at "<peerAddress().toString() )<seek(0); + quint16 bs=(quint16)(block.size() - 2*sizeof(quint16)); + out << bs; + + if (debug) + cout << "ME::sendData bs="<peerAddress().toString())<write (block); + } +} + +void MapEditor::readData () +{ + while (clientSocket->bytesAvailable() >=(int)sizeof(quint16) ) + { + if (debug) + cout <<"readData bytesAvail="<bytesAvailable(); + quint16 recCounter; + quint16 blockSize; + + QDataStream in(clientSocket); + in.setVersion(QDataStream::Qt_4_0); + + in >> blockSize; + in >> recCounter; + + QString t; + in >>t; + if (debug) + cout << " t="<errorString())); + } +} + +void MapEditor::autosave() +{ + QDateTime now=QDateTime().currentDateTime(); + /* FIXME debug + cout << "ME::autosave checking "<0) return; + + // Also disable autosave for new map without filename + if (filePath.isEmpty()) return; + + + if (mapUnsaved &&mapChanged && settings.value ("/mapeditor/autosave/use",true).toBool() ) + { + if (QFileInfo(filePath).lastModified()<=fileChangedTime) + mainWindow->fileSave (this); + else + if (debug) + cout <<" ME::autosave rejected, file on disk is newer than last save.\n"; + + } +} + +void MapEditor::fileChanged() +{ + // Check if file on disk has changed meanwhile + if (!filePath.isEmpty()) + { + QDateTime tmod=QFileInfo (filePath).lastModified(); + if (tmod>fileChangedTime) + { + + /* FIXME debug message, sometimes there's a glitch in the metrics... + cout << "ME::fileChanged()\n" + << " last saved: "<provides("application/x-moz-file-promise-url") && + event->provides("application/x-moz-nativeimage")) + { + // Contains url to the img src in unicode16 + QByteArray d = event->encodedData("application/x-moz-file-promise-url"); + QString url = QString((const QChar*)d.data(),d.size()/2); + fetchImage(url); + event->accept(); + update=true; + } else if (event->provides ("text/uri-list")) + { // Uris provided e.g. by konqueror + Q3UriDrag::decode (event,uris); + } else if (event->provides ("_NETSCAPE_URL")) + { // Uris provided by Mozilla + QStringList l = QStringList::split("\n", event->encodedData("_NETSCAPE_URL")); + uris.append(l[0]); + heading = l[1]; + } else if (event->provides("text/html")) { + + // Handels text mime types + // Look like firefox allways handle text as unicode16 (2 bytes per char.) + QByteArray d = event->encodedData("text/html"); + QString text; + if (isUnicode16(d)) + text = QString((const QChar*)d.data(),d.size()/2); + else + text = QString(d); + + textEditor->setText(text); + + event->accept(); + update=true; + } else if (event->provides("text/plain")) { + QByteArray d = event->encodedData("text/plain"); + QString text; + if (isUnicode16(d)) + text = QString((const QChar*)d.data(),d.size()/2); + else + text = QString(d); + + textEditor->setText(text); + + event->accept(); + update= true; + } + + */ + + + +bool isUnicode16(const QByteArray &d) +{ + // TODO: make more precise check for unicode 16. + // Guess unicode16 if any of second bytes are zero + unsigned int length = max(0,d.size()-2)/2; + for (unsigned int i = 0; iaddFloatImage(); + fio->load(img); + fio->setOriginalFilename("No original filename (image added by dropevent)"); + QString s=model->getSelectString(bo); + saveState (PartOfMap, s, "nop ()", s, "copy ()","Copy dropped image to clipboard",fio ); + saveState (fio,"delete ()", bo,QString("paste(%1)").arg(curStep),"Pasting dropped image"); + model->reposition(); + scene()->update(); + } +} + +/* + +void MapEditor::imageDataFetched(const QByteArray &a, Q3NetworkOperation * / *nop* /) +{ + if (!imageBuffer) imageBuffer = new QBuffer(); + if (!imageBuffer->isOpen()) { + imageBuffer->open(QIODevice::WriteOnly | QIODevice::Append); + } + imageBuffer->at(imageBuffer->at()+imageBuffer->writeBlock(a)); +} + + +void MapEditor::imageDataFinished(Q3NetworkOperation *nop) +{ + if (nop->state()==Q3NetworkProtocol::StDone) { + QPixmap img(imageBuffer->buffer()); + addFloatImageInt (img); + } + + if (imageBuffer) { + imageBuffer->close(); + if (imageBuffer) { + imageBuffer->close(); + delete imageBuffer; + imageBuffer = 0; + } + } +} + +void MapEditor::fetchImage(const QString &url) +{ + if (urlOperator) { + urlOperator->stop(); + disconnect(urlOperator); + delete urlOperator; + } + + urlOperator = new Q3UrlOperator(url); + connect(urlOperator, SIGNAL(finished(Q3NetworkOperation *)), + this, SLOT(imageDataFinished(Q3NetworkOperation*))); + + connect(urlOperator, SIGNAL(data(const QByteArray &, Q3NetworkOperation *)), + this, SLOT(imageDataFetched(const QByteArray &, Q3NetworkOperation *))); + urlOperator->get(); +} +*/ + diff -r 49a910838042 -r e37153bea487 tex/vym.changelog --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tex/vym.changelog Thu Jul 17 09:27:20 2008 +0000 @@ -0,0 +1,1277 @@ +------------------------------------------------------------------- +Thu Jul 17 11:25:39 CEST 2008 - uwedr@suse.de + +- Bugfix: smaller image for export to elliminate pixel jitter on right + side + +------------------------------------------------------------------- +Fri Jul 11 14:01:31 CEST 2008 - uwedr@suse.de + +- Bugfix: bnc#407600 vym fails with non-ASCI characters in path names + +------------------------------------------------------------------- +Tue Jun 8 10:34:12 CEST 2008 - uwedr@suse.de + +- Bugfix: bnc#396365 vym cannot load maps saved with Qt 4.4 + +------------------------------------------------------------------- +Wed May 14 17:00:36 CEST 2008 - uwedr@suse.de + +- Version: 1.12.0 RC 2 +- Feature: Russian translation + +------------------------------------------------------------------- +Wed May 7 10:30:21 CEST 2008 - uwedr@suse.de + +- Bugfix: bnc#327078 + +------------------------------------------------------------------- +Tue May 6 11:45:46 CEST 2008 - uwedr@suse.de + +- Version: 1.12.0 + +------------------------------------------------------------------- +Wed Apr 30 18:13:43 CEST 2008 - uwedr@suse.de + +- Version: 1.11.9 +- Bugfix: Some minor code cleanup + +------------------------------------------------------------------- +Thu Apr 10 22:45:55 CEST 2008 - uwedr@suse.de + +- Version: 1.11.8 +- Feature: Copy to new map now also in branch context menu + +------------------------------------------------------------------- +Thu Apr 10 17:11:14 CEST 2008 - uwedr@suse.de + +- Bugfix: New map is not autosaved, if no filename is known yet + +------------------------------------------------------------------- +Tue Apr 8 09:59:11 CEST 2008 - uwedr@suse.de + +- Version: 1.11.7 +- Bugfix: Hangup when find function did not find anything + +------------------------------------------------------------------- +Thu Mar 13 02:06:59 CET 2008 - uwedr@suse.de + +- Bugfix: vym no longer forgets that a map is zipped + +------------------------------------------------------------------- +Sun Mar 9 13:36:20 CET 2008 - uwedr@suse.de + +- Bugfix: Segfault when pressing Home or End on MapCenter + +------------------------------------------------------------------- +Wed Mar 5 17:54:12 CET 2008 - uwedr@suse.de + +- Bugfix: Broken paths to floatimages + +------------------------------------------------------------------- +Wed Feb 27 17:07:57 CET 2008 - uwedr@suse.de + +- Bugfix: Fixed some issues with autosave and regulard file checks + +------------------------------------------------------------------- +Mon Feb 11 12:22:58 CET 2008 - uwedr@suse.de + +- Version: 1.11.6 +- Feature: vym now checks regulary if map has changed on disk and + asks for reload if necessary + +------------------------------------------------------------------- +Mon Jan 21 22:52:18 CET 2008 - uwedr@suse.de + +- Bugfix: No more warning dialog for overwriting note, when note is + empty + +------------------------------------------------------------------- +Tue Jan 8 22:20:29 CET 2008 - uwedr@suse.de + +- Version: 1.11.5 +- Feature: Started to implement multiple MapCenters in one map + +------------------------------------------------------------------- +Mon Jan 7 14:59:56 CET 2008 - uwedr@suse.de + +- Bugfix: vym.pro includes french translation now + +------------------------------------------------------------------- +Mon Dec 17 16:32:48 CET 2007 - uwedr@suse.de + +- Bugfix: bnc#341952 corrupted positions of mainbranches after updating to + newer vym +------------------------------------------------------------------- +Wed Dec 12 17:12:50 CET 2007 - uwedr@suse.de + +- Bugfix: Overloaded key shortcut for Alt-N (Network and Next window) + +------------------------------------------------------------------- +Tue Dec 4 11:46:02 CET 2007 - uwedr@suse.de + +- Bugfix: Temporary hide stuff during export +- Bugfix: Save parts of map + +------------------------------------------------------------------- +Mon Dec 3 20:57:15 CET 2007 - uwedr@suse.de + +- Bugfix: (Maint.) Exchanged pre- and postscript in XHTML Export dialog + +------------------------------------------------------------------- +Fri Nov 9 10:44:59 CET 2007 - uwedr@suse.de + +- Version: 1.11.3 +- Feature: Added patches for better windows support by Andrew Ng + +------------------------------------------------------------------- +Tue Nov 6 22:36:38 CET 2007 - uwedr@suse.de + +- Version: 1.11.2 +- Feature: Split up helper functions, started to write attributes + +------------------------------------------------------------------- +Tue Nov 6 14:36:38 CET 2007 - uwedr@suse.de + +- Version: 1.11.1 +- Bugfix: sort branches has undo/redo now + +------------------------------------------------------------------- +Fri Oct 26 11:22:20 CEST 2007 - uwedr@suse.de + +- Bugfix: zip state is changed now, when a .xml is save as .vym + +------------------------------------------------------------------- +Wed Oct 24 14:11:36 CEST 2007 - uwedr@suse.de + +- Feature: Improved ascii export +- Bugfix: Present flag now does not set down arrows any longer + +------------------------------------------------------------------- +Tue Oct 23 13:11:52 CEST 2007 - uwedr@suse.de + +- Bugfix: included more for compiling with new gcc 4.3 + +------------------------------------------------------------------- +Fri Oct 19 18:08:27 CEST 2007 - uwedr@suse.de + +- Version: 1.11.0 +- Feature: Added patches from Till Maas for better path handling to ease + integration into various operating systems +- Feature: Added patch from Till Maas to use xdg-open as default browser +- Feature: Added patch from ????? to sort branches lexically +- Feature: Added patches from Juha Ruotsalainen for compiling on win32 + +------------------------------------------------------------------- +Tue Oct 16 11:51:43 CEST 2007 - uwedr@suse.de + +- Bugfix: included for compiling in beta + +------------------------------------------------------------------- +Wed Oct 04 12:43:48 CEST 2007 - uwedr@suse.de + +- Version: 1.10.1 +- Bugfix: Missing action for editing URL in context menu +- Bugfix: "Hide in Export" didn't work + +------------------------------------------------------------------- +Mon Sep 04 15:52:22 CEST 2007 - uwedr@suse.de + +- Bugfix: xLinks were not loaded from previously saved maps +- Bugfix: Find manual in /usr/share/doc/packages/vym +- Bugfix: Updated README.txt + +------------------------------------------------------------------- +Mon Aug 20 17:09:28 CEST 2007 - uwedr@suse.de + +- Version: 1.10.0 Release Candidate +- Bugfix: Added missing standard flag (one of the smileys got lost) +- Bugfix: Wrong parsing of relative positions after load of + previously zoomed map + +------------------------------------------------------------------- +Tue Jul 31 22:09:01 CEST 2007 - uwedr@suse.de + +- Bugfix: Smother parabel links (Alexander Rettig) + +------------------------------------------------------------------- +Fri Jul 27 13:31:41 CEST 2007 - uwedr@suse.de + +- Version: 1.9.4 +- Feature: Restructured internal handling of XML based maps +- Feature: Switched from QSimpleTextItem to QTextItem for Freemind support + +------------------------------------------------------------------- +Mon Jul 23 14:40:38 CEST 2007 - uwedr + +- Version: 1.9.3 +- Feature: Import of Freemind maps + +------------------------------------------------------------------- +Tue Jul 17 13:16:25 CEST 2007 - uwedr + +- Version: 1.9.2 +- Bugfix: Workaround for wrong XML generated by QT with in QRichText + list items +- Bugfix: No output from tags in ASCII export any longer + +------------------------------------------------------------------- +Wed Jul 11 15:49:10 CEST 2007 - uwedr + +- Version: 1.9.1 +- Bugfix: Don't ask for directory in XML-based exports like + KDE-bookmarks + +------------------------------------------------------------------- +Tue Jul 4 10:57:04 CEST 2007 - uwedr + +- Version: 1.9.0 +- Bugfix: auto-select/auto-edit new branches + +------------------------------------------------------------------- +Fri Jun 29 11:12:55 CEST 2007 - uwedr + +- Version: 1.8.76 +- Feature: Extended fileformat with object IDs to ease export from + tomboy to vym +- Bugfix: Visibility of BranchProperty window is saved now + +------------------------------------------------------------------- +Mon Jun 25 14:53:10 CEST 2007 - uwedr + +- Version: 1.8.75 +- Feature: Completed german translation + +------------------------------------------------------------------- +Wed Jun 20 13:52:37 CEST 2007 - uwedr + +- Version: 1.8.74 +- Feature: Center on selection with "." +- Feature: Most important exports can be scripted now + +------------------------------------------------------------------- +Mon Jun 18 17:08:46 CEST 2007 - uwedr + +- Version: 1.8.73 - entering beta testing + +------------------------------------------------------------------- +Mon June 18 17:01:16 CEST 2007 - uwe + +- Feature: Creating new map with selection as MapCenter +- Feature: Simple export to CSV spreadsheet +- Feature: Copy from past steps in history to current one +- Bugfix: Undo/Redo dropping images into map +- Bugfix: Undo/Redo of copy/paste steps +- Bugfix: NoteEditor now appears on first click (not 2nd) +- Bugfix: Disable autosave while there are redos available +- Bugfix: After changing link color, that color is applied to all links + now +- Bugfix: Pasting of FIOs +- Bugfix: No selection of branches while editing heading +- Bugfix: geometry of selection box gets updated while setting scroll or + hide flag +- Bugfix: Possible segfault when redoing deleteChilds() + +------------------------------------------------------------------- +Mon May 7 09:37:29 CEST 2007 - uwedr + +- Version: 1.8.72 +- Bugfix: autosave timeout now read from settings file +- Bugfix: Settings for historywindow correclty read now +- Bugfix: Closing property window toggle corresponding button + +------------------------------------------------------------------- +Thu Apr 26 10:34:48 CEST 2007 - uwe + +- Feature: Editing of frame attributes in branch property window +- Feature: autosave +- Feature: number of undo/redo levels can be changed in settings +- Feature: branch property window settings are saved +- Bugfix: Unscroll all childs has saveState now +- Bugfix: Invisible selection after switching mapeditor + +------------------------------------------------------------------- +Tue Apr 10 15:18:39 CEST 2007 - uwedr + +- Version: 1.8.71 +- Feature: Added basic macros and documentation + +------------------------------------------------------------------- +Sat Mar 31 10:59:55 CEST 2007 - uwe + +- Version: 1.8.70 +- Feature: Color of selection can be changed now +- Feature: Pen and brush for frames can be set +- Bugfix: For frames the links always were drawn at bottom of heading +- Bugfix: BranchPropertyWindow updates when selection is changed + +------------------------------------------------------------------- +Mon Mar 6 22:10:26 CET 2007 - uwe + +- Version: 1.8.69 +- Feature: Simple Editor for scripts +- Feature: Added syntax highlighting for editor + +------------------------------------------------------------------- +Tue Feb 20 22:16:09 CET 2007 - uwe + +- Version: 1.8.68 +- Bugfix: Crash when trying to temporary link to floatimage + +------------------------------------------------------------------- +Mon Feb 17 16:32:53 CET 2007 - uwedr + +- Version: 1.8.67 +- Feature: Unscroll all now only affects selected subtree +- Bugfix: Drawing error when temporary linking subtrees +- Bugfix: Import of KDE Bookmarks +- Bugfix: Export to KDE Bookmarks +- Bugfix: Export to XHTML +- Bugfix: Drag and Drop of URLs now only creates one branch + +------------------------------------------------------------------- +Wed Feb 07 17:27:31 CET 2007 - uwedr + +- Version: 1.8.66 +- Feature: Using a new class to select objects +- Bugfix: Remember last directory before ASCII/LaTeX export +- Bugfix: Editing in NoteEditor now updates actions (save) again +- Bugfix: Deleting last branch automatically unscrolls parent now +- Bugfix: Scroll/Unscroll has undo/redo now + +------------------------------------------------------------------- +Fri Jan 19 22:53:27 CET 2007 - uwe + +- Version: 1.8.65 +- Feature: New Frame format +- Feature: New vym file format to support new frames +- Bugfix: xml-parsing code simplified +- Bugfix: Fixed pretty annoying repositioning of view after editing a + heading. (don't call show() before positioning in heading...) +- Bugfix: Wrong Cursors after pressing CTRL and inserting/relinking +- Bugfix: Save PNG images with quality 100 to workaround image problems +- Bugfix: Remember last directory before XML export + +------------------------------------------------------------------- +Thu Jan 11 16:05:49 CET 2007 - uwedr + +- Version: 1.8.65 +- Feature: Properties dialog for branches instead of context menu entries + +------------------------------------------------------------------- +Wed Jan 10 19:48:32 CET 2007 - uwe + +- Version: 1.8.64 +- Bugfix: move branch up/down calls scene()->update() now => much faster +- Bugfix: Relinking of floatimages undo/redo + +------------------------------------------------------------------- +Tue Jan 2 19:30:50 CET 2007 - uwedr + +- Version: 1.8.64 +- Bugfix: printing scales correctly again +- Bugfix: Drag & Drop (basically) works again +- Bugfix: Crash caused by BranchObj::getLastSelected +- Bugfix: Signal handling by changes in TextEditor: Much faster now + +------------------------------------------------------------------- +Thu Dec 21 14:13:13 CET 2006 - uwedr + +- Version: 1.8.63 +- Bugfix: printing is working again + +------------------------------------------------------------------- +Mon Dec 11 12:31:46 CET 2006 - uwedr + +- Version: 1.8.61 +- Bugfix: move up/down to next subtree is working again + +------------------------------------------------------------------- +Mon Dec 6 22:48:07 CET 2006 - uwe + +- Version: 1.8.61 +- Bugfix: Flags are working again +- Bugfix: Floatimages have correct select box again + +------------------------------------------------------------------- +Wed Nov 29 13:48:35 CET 2006 - uwedr + +- Version: 1.8.60 +- Bugfix: Image format is saved with floatimage +- Feature: Only one history window for all editors. State is saved. +- Feature: Canvas ported to QT 4.2 GraphicsView +- Feature: Options to use AntiaAliasing and smooth pixmap + transformations +- Feature: Thick links use polygons now, less objects in scene + +------------------------------------------------------------------- +Thu Nov 16 14:41:44 CET 2006 - uwedr + +- Bugfix: New recent file handling, fixes crash on Mac OS X + +------------------------------------------------------------------- +Tue Nov 14 10:00:12 CET 2006 - uwedr + +- Feature: Modifier Modes now change cursor when CTRL is pressed + +------------------------------------------------------------------- +Fri Nov 10 10:28:55 CEST 2006 - uwe + +- Feature: vym opens spanish documentation, if locale is es* +- Bugfix: Position of floatimages is saved again +- Bugfix: Position of floatimages survives adjustCanvasSize() +- Bugfix: Adding branch to scrolled branch unscroll the former +- Bugfix: More undo commands (removed saveStateComplete) + +------------------------------------------------------------------- +Tue Oct 24 17:24:22 CEST 2006 - uwedr + +- Version: 1.8.58 +- Feature: More undo commands (and fixes there) + +------------------------------------------------------------------- +Mon Oct 16 14:41:03 CEST 2006 - uwedr + +- Feature: Code simplification + +------------------------------------------------------------------- +Thu Sep 14 12:01:28 CEST 2006 - uwedr + +- Version: 1.8.57 +- Feature: Note Editor completly based on QT4 now. + +------------------------------------------------------------------- +Wed Sep 13 16:43:09 CEST 2006 - uwedr + +- Version: 1.8.56 +- Feature: New History window, All designer elements ported to QT4 +- Bugfix: No more hopping around of floats, when canvas is resized + (by using relative positions for mainbranches. This might + confuse parsing 1.8.56 documents with vym <= 1.8.1 + +------------------------------------------------------------------- +Wed Sep 6 09:48:12 CEST 2006 - uwedr + +- Bugfix: Mac - XSL stylesheets are found +- Bugfix: Mac - fonts are scaling +- Bugfix: Mac - hand cursor is shown correctly + +------------------------------------------------------------------- +Tue Sep 5 15:38:20 CEST 2006 - uwedr + +- Version: 1.8.55 +- Bugfix: Undo/Redo moving floatimages +- Bugfix: Shortcuts for scrolling branches/removing branch +- Bugfix: update-bookmarks script is not only executed, but + also found now... +- Feature: Findwindow ported to QT4 + +------------------------------------------------------------------- +Tue Sep 5 09:55:55 CEST 2006 - uwedr + +- Bugfix: More undo/redo (move of floatimages, relinking of branches) + +------------------------------------------------------------------- +Thu Aug 31 13:54:30 CEST 2006 - uwedr + +- Bugfix: More undo/redo commands +- Bugfix: Actions updated after moving a branch now +- Bugfix: vym refuses to start if vymTmpDir can't be created + +------------------------------------------------------------------- +Wed Aug 30 14:14:56 CEST 2006 - uwedr + +- Version: 1.8.54 +- Bugfix: Editing headings now works both on Mac and Linux + +------------------------------------------------------------------- +Mon Aug 28 13:15:35 CEST 2006 - uwe + +- Version: 1.8.53 +- Feature: Opening of all URLs in a subtree +- Feature: Opening of all vymLinks in a subtree + +------------------------------------------------------------------- +Tue Aug 15 13:39:42 CEST 2006 - uwedr + +- Version: 1.8.52 +- Feature: Changed format of configuration file a bit (new file anyway + with introduction of QT4) +- Feature: Toolbar Layout is saved now + +------------------------------------------------------------------- +Thu Jul 27 14:28:54 CEST 2006 - uwedr + +- Bugfix: Floatimages internally are saved as png, preserving the alpha + channel + +------------------------------------------------------------------- +Thu Jul 13 10:39:26 CEST 2006 - uwedr + +- Bugfix: Fixed broken check for non-existent OO-export configuration + +------------------------------------------------------------------- +Tue Jul 4 12:32:28 CEST 2006 - uwedr + +- Feature: Moved floats in XML Export, e.g. XHTML shows floatimages at + beginning of export now + +------------------------------------------------------------------- +Mon July 10 16:53:29 CEST 2006 - uwedr + +- Version: 1.8.50 +- Feature: Beginning of QT4 port + +------------------------------------------------------------------- +Thu June 1 16:53:29 CEST 2006 - uwedr + +- Version: 1.7.18 +- Feature: Opening of tabs in Firefox or Mozilla +- Feature: Documentation is up to date now +- Bugfix: No more duplicate xLinks +- Bugfix: Saving original filename of floatimages finally works +- Bugfix: Positioning of floatimages while adjusting canvas size (also + optimized code a bit) + +------------------------------------------------------------------- +Tue May 9 10:05:52 CEST 2006 - uwedr + +- Version: 1.7.17 +- Bugfix: Right click e.g. on URL Flag opened URL _and_ context menu +- Bugfix: Deleting selection works also if Delkey is disabled. + +------------------------------------------------------------------- +Mon May 8 10:29:25 CEST 2006 - uwedr + +- Bugfix: Exclusive flags did not work properly. +- Bugfix: Wrong icon in texteditor for text underline +- Bugfix: Changed screenshots in docu to represent new look +- Bugfix: Fixed z-plane of floatimage. Images did hide flags. + +------------------------------------------------------------------- +Mon Apr 24 11:59:22 CEST 2006 - uwedr + +- Bugfix: wrong paths in XHTML export (bnc#168033), caused by wrong + vymBaseDir + +------------------------------------------------------------------- +Mon Apr 10 13:23:02 CEST 2006 - uwedr + +- Feature: More icons + +------------------------------------------------------------------- +Fri Mar 31 14:18:38 CEST 2006 - uwe + +- Feature: New environment variable VYMHOME + +------------------------------------------------------------------- +Thu Mar 30 11:00:21 CEST 2006 - uwedr + +- Version: 1.7.15 +- Feature: New icons. Icons and flags are not longer linked statically. + +------------------------------------------------------------------- +Tue Mar 28 21:54:31 CEST 2006 - uwe + +- Version: 1.7.13 +- Feature: Konqueror can open URLs in new tabs now. + +------------------------------------------------------------------- +Thu Mar 23 13:26:46 CET 2006 - uwedr + +- Version: 1.7.12 +- Bugfix: Problem with vymlinks pointing to higher directories (bnc#159770) +- Bugfix: All exports support hiding of objects now +- Bugfix: exportDir in XHTML export is correctly saved in map and + defaults to current directory + +------------------------------------------------------------------- +Wed Mar 15 11:43:02 CET 2006 - uwedr + +- Version: 1.7.11 +- Bugfix: Workaround QT problem, where QT writes invalid XML code by not + escaping & in fontnames +- Feature: Hide Export Flag lets you hide objects in exports +- Feature: Floatimages now are basically ornamented objects. They could + have e.g. an URL later +- Feature: On error the XML Parser shows the line which is causing the + error + +------------------------------------------------------------------- +Wed Mar 8 13:58:40 CET 2006 - uwedr + +- Bugfix: Images preview in filedialog works again. Seemed to be a QT + issue when multiple fileselections were allowed. + +------------------------------------------------------------------- +Mon Mar 6 15:02:57 CET 2006 - uwedr + +- Feature: Added export to Taskjuggler. xslt by Matt. + +------------------------------------------------------------------- +Wed Mar 1 22:29:47 CET 2006 - uwe + +- Bugfix: Canvas Size corrected when flag is toggled + +------------------------------------------------------------------- +Wed Mar 1 15:38:11 CET 2006 - uwedr + +- Version: 1.7.10 +- Feature: Include Images Horizontalls + +------------------------------------------------------------------- +Tue Feb 21 17:17:48 CET 2006 - uwedr + +- Feature: rudimentary import mmaps + +------------------------------------------------------------------- +Tue Feb 14 21:10:26 CET 2006 - uwe + +- Version 1.7.9 +- Feature: Import KDE bookmarks +- Feature: Own class xsltproc for doing xml transformations + +------------------------------------------------------------------- +Tue Jan 31 16:54:52 CET 2006 - uwedr + +- Version 1.7.8 +- Bugfix: Hide Include Images Horizontally (not implemented yet) +- Bugfix: Include Images Vertically was not read from saved file + +------------------------------------------------------------------- +Tue Jan 25 16:07:53 CET 2006 - uwedr + +- Version 1.7.7 +- Feature: Export to Open Office 2.x (Open Document) basically works +- Feature: Export to XHTML uses smaller icon for URLs now + +------------------------------------------------------------------- +Wed Jan 18 13:29:52 CET 2006 - uwedr + +- Feature: Multiple File selection while loading maps and images + +------------------------------------------------------------------- +Tue Jan 3 12:20:08 CET 2006 - uwe + +- Feature: Small optimization in zip/unzip functions + +------------------------------------------------------------------- +Mon Jan 2 21:03:05 CET 2006 - uwe + +- Feature: FATE support for URLs + +------------------------------------------------------------------- +Wed Dec 28 12:09:59 CET 2005 - uwe + +- Version 1.7.6 +- Feature: Added idAttr to BranchObj::saveToDir +- Bugfix: FloatObjects now use hideLinkIfUnselected, no more drawing + errors, if FO is selected (undefined link) +- Bugfix: FloatImages don't get lost during save after they have been + relinked to new parent +- Bugfix: Editing heading of mapcenter now also corrects position + +------------------------------------------------------------------- +Mon Oct 10 13:18:29 CEST 2005 - uwedr + +- Bugfix: Copy/Paste was currently not possible for images. Now + completly rewrote mechanism. Instead of invisible map now XML import + is used (Multiple clipboards should be not difficult now) + +------------------------------------------------------------------- +Mon Oct 3 10:33:09 CEST 2005 - uwe + +- Bugfix: Added small fix from Khaled Ahmed needed for display of + arabic languages + +------------------------------------------------------------------- +Mon Sep 12 21:39:38 CEST 2005 - uwedr + +- Version 1.7.5 +- Feature: Currently 15 levels of undo (GUI to set value still missing) +- Feature: Experimental LaTeX Export (without headers and opions so far) + +------------------------------------------------------------------- +Sun Sep 5 10:26:15 CEST 2005 - uwedr + +- Version 1.7.4 +- Feature: Link of a branch can be hidden, if object is not selected +- Bugfix: Zoomed map no longer "jumps around" when branch is selected + or moved. +- Bugfix: TextEditor now has grey background again, if it is empty +- Bugfix: BranchObj no longer need to connect to TextEditor, BranchObj + is no longer a QOBJECT + +------------------------------------------------------------------- +Thu Sep 1 12:26:24 CEST 2005 - uwedr + +- Bugfix: Some minor changes so that translations use arguments now + instead of several calls to tr() + +------------------------------------------------------------------- +Tue Aug 30 13:38:31 CEST 2005 - uwedr + +- Bugfix: Fixed pasting vymlinks: Pasting a branch to a target in + another map caused vym to go into an endless loop, if the vymlink of the + branch pointed to the new map. +- Bugfix: Invisible floatimages (which have a scrolled parent) no longer + can be selected + +------------------------------------------------------------------- +Fri Aug 19 09:12:49 CEST 2005 - uwedr + +- Feature: added debian subdirectory created by Steffen Joeris +- Feature: added license to new aboutwindow + +------------------------------------------------------------------- +Tue Aug 16 19:22:56 CEST 2005 - jhilmer + +- Bugfix: Fixed link handling in aboutdialog. + +------------------------------------------------------------------- +Tue Aug 16 12:25:09 CEST 2005 - uwedr + +- Feature: Added keyboard shortcut to reset zoom factor +- Bugfix: Added "..." to menu entries leading to another dialog +- Bugfix: The setting option "Delete Key" is working again +- Bugfix: A branch moved from left side to right had wrong orienation + +------------------------------------------------------------------- +Tue Aug 2 09:59:24 CEST 2005 - uwedr + +- Bugfix: Heading sizes now correct after moving e.g. mainbranch to + a branch + +------------------------------------------------------------------- +Mon Aug 1 22:40:29 CEST 2005 - jhilmer + +- Bugfix: Problems with closing of note editor when text was modified. +- Feature: Added subscript and superscript to note editor + +------------------------------------------------------------------- +Thu Jul 28 11:57:38 CEST 2005 + +- Version 1.7.3 +- Bugfix: Frames didn't become invisible if scrolled + +------------------------------------------------------------------- +Thu Jul 28 11:57:38 CEST 2005 + +- Version 1.7.2 +- Bugfix: if selection changed before undo, undo worked on wrong + branch +- included math.h again to enable compiling with gcc4 + +------------------------------------------------------------------- +Mi Jul 27 17:27:14 CEST 2005 + +- Bugfix: if selection changed before undo, undo worked on wrong branch + +------------------------------------------------------------------- +Mon Jul 25 22:22:21 CEST 2005 + +- Bugfix: changed MapEditor::undo and ::saveState to also save selection + +------------------------------------------------------------------- +Di Jul 19 16:42:31 CEST 2005 + +- Version: 1.7.1 +- Feature: Drag and Drop also for .vym and files (Jakob Hilmer) +- Feature: More speedup on moving/relinking branches + +------------------------------------------------------------------- + +Mi Jul 13 11:44:10 CEST 2005 + +- Drag and Drop also for URLs + +------------------------------------------------------------------- +Di Jul 12 20:56:09 CEST 2005 + +- Version: 1.7.0 + +------------------------------------------------------------------- +Mon Jul 4 21:13:42 CEST 2005 + +- Version: 1.6.9 +- Bugfix: TextEditor doesn't get minimized in KDE any longer (KDE-bug?) + +------------------------------------------------------------------- +Tue Jun 14 11:43:44 CEST 2005 + +- Feature: printer name is saved in vymrc now +- Feature: added image drag/drop (by Jakob Hilmer) +- Bugfix: Importing map into new map now has correct (empty) filename + +------------------------------------------------------------------- +2005-06-07 + +- Version: 1.6.8 +- Feature: Dramatic speedup in some operations + (e.g. move branch up/down) due to extended + undo engine +------------------------------------------------------------------- + 2005-05-27 + +- Version: 1.6.7 +- Feature:Changed default pdf-reader for Mac OSX +- Bugfix: xLinks stopped working in 1.6.6 +- Bugfix: drawing error when using modModeCopy +- Bugfix: replaced lrint by qRound for BSD port + +----------------------------------------------------------- + 2005-05-23 + +- Version 1.6.6 +- Feature: Exclusive standard flags + +----------------------------------------------------------- +2005-05-19 + +- Version: 1.6.5 +- Feature: removing a branch and keeping its childs +- Feature: removing childs of a branch +- Feature: insert branch and make selection its child +- Feature: restructured branch context menu + in a basic version (straight line) +- Feature: New shortcuts for use on Mac OS X +- Feature: Importing directories generates vymlinks now +- Bugfix: Changing linkstyle now automatically redraws all + links again +- Bugfix: Paste icon is disabled if clipboard is empty + +----------------------------------------------------------- +2005-04-15 + +- Version: 1.6.4 +- Feature: xLinks (connection between 2 branches) works + in a basic version (straight line) + +----------------------------------------------------------- +2005-03-30 + +- Version: 1.6.3 +- Bugfix: Saving of selection to a vym part (.vyp) +- Bugfix: Closing the noteeditor by closing its window now + also toggles the responding toolbar button. & + +----------------------------------------------------------- +2005-03-24 + +- Version: 1.6.2 +- Feature: Introduced Modifier modes: color, link, copy +- Feature: Linking branches is basically possible, though it can't be + edited/saved yet + +----------------------------------------------------------- +2005-01-30 + +- Version: 1.6.1 +- Feature: Optimized moving of branches: much faster especially + with huge subtrees +- Bugfix: Segfault when loading vym part +- Bugfix: ugly unitialized lines, when temporary drawn link + was moved from a temporary parent back to canvas + +----------------------------------------------------------- +2004-12-14 + +- Version: 1.6.0 +- Feature: Added saving of xhtml settings in map + +----------------------------------------------------------- +2004-12-13 + +- Version: 1.5.2 +- Feature: Added Import of maps with two modes: + add/replace +- Feature: Added export of part of maps +- Feature: Added joining of paragraphs in text editor +- Feature: Optimized undo: Only relevant parts are saved, which + dramatically improves e.g. moving branches up/down in most maps +- Bugfix: QTextEdit generates invalid XML code, which could lead to a + parse error, if font name contains a \& (bnc#62283) +- Bugfix: Wrong order of mainbranches in Export +- Bugfix: zip archive was not deleted before save, which could lead to + much bigger files, e.g. when working on older \vym maps or deleted + images +- Bugfix: Printing in Texteditor +- Bugfix: Wrong URLs in xhtml output +- Bugfix: Segfault fixed at Cursor left/right in empty map + +----------------------------------------------------------- +2004-10-01 + +- Version: 1.5.1 +- Feature: More options in xhtml export: external scripts + +----------------------------------------------------------- +2004-09-26 + +- Version: 1.5.0 +- Public release of all changes since 1.4.1 +- Feature: New function to replace paragraphs in note editor + by linebreaks, this makes pasted text much nicer +- Feature: New option to toggle exporting of of floatimages +- Feature: z-plane of floatimages can be set (manually only) +- Bugfix: Wrong ordering of branches, if mainbranch is exactly left of + center + +----------------------------------------------------------- +2004-09-24 + +- Version: 1.4.7 +- Feature: New Export to XHTML (by Thomas Schraitle) +- Bugfix: vymLink +- Bugfix: spaces and dots in filenames +- Bugfix: Error message if xsltproc is not installed + +----------------------------------------------------------- +2004-09-15 + +- Version: 1.4.6 +- Feature: New file format: notes are saved as part of the .xml file +- Feature: Note Editor supports Rich Text now. +- Feature: Parser now also nows {\tt standardflag} (all letters lowercase) + +----------------------------------------------------------- +2004-08-23 + +- Version: 1.4.5 +- Feature: Correct handling of font size in Heading + +----------------------------------------------------------- +2004-07-29 + +- Version: 1.4.4 +- Selecting with cursor now works between subtrees +- Bugfix: vymLink was set to temporary dir in 1.4.3 + +----------------------------------------------------------- +2004-07-19 + +- Version: 1.4.3 +- Optimisation: Reduced canvas objects by only creating objects for used + flags +- Better visualization of moving branch above/below target +- Find Window informs with dialog, if the search failed +- System Flags are clickable now +- Reworked CSS and XST stylsheets (comments, indent, browser + compatibility) +- vymLinks are shown in statusbar +- current directory is save +- Rewritten load/save to improve multimap handling and unzipped files +- Bugfix: vymLinks don't get deleted when Cancel is pressed +- Bugfix: Fixed a bunch of bugs in XSL for HTML export +- Bugfix: More toolbar buttons disabled, if action not possible +- Bugfix: Renaming .vymfile now works +- Bugfix: mapChanged set when toggling flags +- Bugfix: CTRL-N was used twice +- Bugfix: Del didn't work on floatimage + +----------------------------------------------------------- +- Version: 1.4.2 +- Bugfix: Float image could not be deleted + +----------------------------------------------------------- +2004-05-25 + +- Version: 1.4.1 +- Bugfix: Color of branch not saved +- Bugfix: wrong path at HTML export +- Bugfix: map is not save with special characters in path + +----------------------------------------------------------- +2004-05-17 + +- Version: 1.4.0 +- Ask for confirmation before opening + a map in multiple editors +- Save state of note editor (visible/minimized) +- Export to HTML +- Author and Comment is saved in map +- Stats are shown in Edit MapInfo +- Changes for OS X port (QCursor, QContextMenuEvent) +- Bugfix: Fonts from note editor are save now +- Bugfix: invisible image when parent is scrolled +- Bugfix: Segfault pressing "enter" for floatimage +- Bugfix: Images can't be outside of exported area + anymore. +- Bugfix: Filenames with blanks +- Bugfix: Old maplink is shown when editing maplink +- Bugfix: always show cursor while editing heading + +----------------------------------------------------------- +2004-04-16 + +- Version: 1.3.5 +- Export map to dir +- Export to any of QTs image formats +- Also right side of selection is always visible now. + +----------------------------------------------------------- +2004-04-07 + +- Version: 1.3.4 +- Load last maps in file menu +- save last image path for loading +- Also export standard flags to dir. + +----------------------------------------------------------- +2004-03-26 + +- Version: 1.3.3 +- Enabled
in headings as manual linebreak +- Heading can be copied to URL +- Bugfix: GIFs are automatically converted to PNG now + +----------------------------------------------------------- +2004-03-26 + +- Version: 1.3.2 +- Add and move branches above/below selection, Texteditor copy all, + +----------------------------------------------------------- +2004-03-25 + +- Version: 1.3.1 +- Export to directory, changed naming in .vym + +----------------------------------------------------------- +2004-03-23 + +- Version: 1.3.0 +- Bugfix: Check if map can be saved at all + +----------------------------------------------------------- +2004-03-22 + +- Version: 1.2.12 +- Select image format before saving image + +----------------------------------------------------------- +2004-03-18 + +- Version: 1.2.11 +- Selecting mainbranches by up/down +- Export ASCII (experimental) +- Each map can be saved individually at quit +- Bugfix: Opening VymLink crashes QT +- Bugfix: 50\% less objects on canvas +- Bugfix: Ignoring LANG, now always written as UTF8 + +----------------------------------------------------------- +2004-03-16 + +- Version: 1.2.10 +- Sort Mainbranches by angle to y-axis +- Import directory structure +- Bugfix: Set FrameType of MapCenter while loading map + +----------------------------------------------------------- +2004-03-12 + +- Version: 1.2.9 +- Jump to another vym map +- Mainbranches are alwas ordered clockwise + +----------------------------------------------------------- +2004-03-03 + +- Version: 1.2.8 +- Change frame types in context menu + +----------------------------------------------------------- +2004-02-25 + +- Version: 1.2.7 +- Copy / Paste and save Floatimages + +----------------------------------------------------------- +2004-02-24 + +- Version: 1.2.6 +- Closing vym in KDE now asks for save, too +- Context menu for branches +- Selection is saved in .vym file + +----------------------------------------------------------- +2004-02-18 + +- Version: 1.2.5 +- URLs to external links can be added +- All actions are deactived if not possible + +----------------------------------------------------------- +2004-02-16 + +- Version: 1.2.4 +- Images: Can be loaded, saved, relinked to other parents + +----------------------------------------------------------- +2004-01-27 + +- Version: 1.2.3 +- Zoom: Reset and finer steps shrinking/enlarging + +----------------------------------------------------------- +2004-01-27 + +- Version: 1.2.2 +- Editing of links (style and color) + +----------------------------------------------------------- +2004-01-27 + +- Version: 1.2.1 +- Bugfix: LineEdit when adding branch has correct position again. + +----------------------------------------------------------- +2004-01-23 + +- Version: 1.2.0 +- Scrolled parts are automatically unscrolled when selected and scrolled + again later. +- Bugfix: Save flag is updated when multiple maps are opened +- Bugfix: Moving of branches is faster and more accurat when adding to + mapcenter + +----------------------------------------------------------- +2003-12-04 + +- Version: 1.1.7 +- Bugfix: Remember filename of note in noteeditor + +----------------------------------------------------------- +2003-12-02 + +- Version: 1.1.6 +- Find Text also in Notes. + +----------------------------------------------------------- +2003-11-07 + +- Version: 1.1.5 +- Bugfix: Correct setting and positioning when relinking branches + +----------------------------------------------------------- +2003-11-03 + +- Version: 1.1.4 +- Scroll mode added (folding of subtrees). +- Bugfix: Wrong position of linedit in zoomed view + +----------------------------------------------------------- +2003-10-09 + +- Version: 1.1.3 +- Added clear button in find window, bugfixes + +----------------------------------------------------------- +2003-10-07 + +- Version: 1.1.2 +- Links can be colored with color of heading + +----------------------------------------------------------- +2003-09-26 + +- Version: 1.1.1 +- Improved visualization of linking to new branch + +----------------------------------------------------------- +2003-09-25 + +- Version: 1.1.0 +- Find Function +- Selection always stays in view + +----------------------------------------------------------- +2003-09-18 + +- Version: 1.0.1 +- Find function scrolls to result now +- Bugfix: Adding branch with midmouse +- Bugfix: multiple repositioning of map, when noteeditor was changed + (speedup) +- New Linestyles (still hardcoded) + +----------------------------------------------------------- +2003-09-16 + +- Version: 1.0.0 +- First public stable release + +----------------------------------------------------------- +- Version: 0.9.0 +- added quick color picker (CTRL + Left Mouse) ? + +----------------------------------------------------------- +- Version: 0.8.0 +- added automatic canvas resizer, removed manual resizing of canvas +- added settings option to paste text into new branch +- simplified code +- Added heart flag +- Choose and switch between fixed and variable width fonts +- note editor +- Fixed segfault caused by undo and a call of updateNoteFlag of note + editor +- Added settings menu to configure autoselect and autoedit mode +- autoedit and autoselect mode +- Fixed ugly display problem with QT Palette (Klaas Freitag) +- Reduced temporary directories from 4 to 1 +- Added wordwrap in printing of notes +- New toolbar buttons in texteditor +- Set background color +- Fixed bug: Flags in toolbar not updated when selecting map center + +----------------------------------------------------------- +- Version: 0.7.0 +- No more segfault, when an object is deleted while being edited +- Keep focus constant when zooming in/out +- Export as png graphic +- Keep Center of map where it is while zooming +- Added Standard Flags (Smiley, Hook, Stopsign, ...) +- MDI: Multi Document Interface enables working on several maps + simultanously +- Enabled creating a new map via argument on commandline +- Changed file extension from .mmap to .vym +- noteeditor changes color, if empty or nothing is selected +- Changes in NoteEditor window are recognized by main window, too, thus + preventing loosing data when quitting the program. + +----------------------------------------------------------- +- Version: 0.6.0 +- New rendering engine: Faster, no flickering + +----------------------------------------------------------- +- Version: 0.5.0 +- Changed printing to use maximum space on paper +- Note editor is hidden, too, when mapeditor is minimized +- New (compressed) file format + +----------------------------------------------------------- +- Version: 0.4.0 +- Size of map is saved +- Multi Line Headings +- Reworked Rendering Engine: Much faster now. +- Reworked Undo: Much faster now. +- Enabled moving of map center +- Multi-line headings + +----------------------------------------------------------- +- Version: 0.3.0 +- Introduced Undo +- Fixed some bugs + +----------------------------------------------------------- +- Version: 0.2.0 +- Moving view of map improved: +- New handling (acrobat reader style) +- New mousepointer +- Several tools to color a map + +----------------------------------------------------------- +- Version: 0.1.0 +- Inital version, basic map layout +- Data is stored in XML diff -r 49a910838042 -r e37153bea487 version.h --- a/version.h Sun Jan 30 12:59:03 2005 +0000 +++ b/version.h Thu Jul 17 09:27:20 2008 +0000 @@ -1,7 +1,16 @@ #ifndef VERSION_H #define VERSION_H -#define __VYM_VERSION__ "1.6.0" -#define __BUILD_DATE__ "January 4, 2005" +#include + +#define __VYM_NAME "VYM" +#define __VYM_VERSION "1.12.1" +#define __VYM_CODENAME "Maintenance Update" +//#define __VYM_CODENAME "Codename: development version" +#define __VYM_BUILD_DATE "2008-07-16" + + +bool checkVersion(const QString &); +bool checkVersion(const QString &, const QString &); #endif