diff -r 9eb7767c2dfa -r 608f976aa7bb mapeditor.cpp --- a/mapeditor.cpp Sun Jan 30 12:58:47 2005 +0000 +++ b/mapeditor.cpp Tue Jun 06 14:58:11 2006 +0000 @@ -4,61 +4,63 @@ #include #include #include -#include +#include #include -#include +#include #include -#include +#include #include #include #include #include -#include +#include #include +#include +#include +#include +#include +//Added by qt3to4: +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include +#include #include #include "version.h" +#include "api.h" +#include "editxlinkdialog.h" +#include "exports.h" +#include "extrainfodialog.h" +#include "file.h" +#include "linkablemapobj.h" +#include "mainwindow.h" +#include "misc.h" +#include "settings.h" +#include "texteditor.h" +#include "warningdialog.h" #include "xml.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" + extern TextEditor *textEditor; extern int statusbarTime; extern Main *mainWindow; +extern QString tmpVymDir; +extern QString clipboardDir; +extern bool clipboardEmpty; extern FlagRowObj *systemFlagsDefault; extern FlagRowObj *standardFlagsDefault; -extern MapEditor *clipboardME; + +extern Q3PtrList actionListBranches; extern QAction *actionFileSave; extern QAction *actionEditUndo; @@ -69,24 +71,28 @@ extern QAction *actionEditMoveDown; extern QAction *actionEditToggleScroll; extern QAction *actionEditOpenURL; +extern QAction *actionEditOpenURLTab; extern QAction *actionEditURL; extern QAction *actionEditHeading2URL; extern QAction *actionEditBugzilla2URL; +extern QAction *actionEditFATE2URL; extern QAction *actionEditOpenVymLink; extern QAction *actionEditVymLink; extern QAction *actionEditDeleteVymLink; +extern QAction *actionEditToggleHideExport; extern QAction *actionEditHeading; extern QAction *actionEditDelete; extern QAction *actionEditAddBranch; extern QAction *actionEditAddBranchAbove; extern QAction *actionEditAddBranchBelow; +extern QAction *actionEditRemoveBranchHere; +extern QAction *actionEditRemoveChilds; 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; @@ -95,11 +101,19 @@ extern QAction *actionFormatBackColor; extern QAction *actionFormatLinkColor; -extern QActionGroup *actionGroupFormatFrameTypes; +extern Q3ActionGroup* actionGroupModModes; +extern QAction* actionModModeColor; +extern QAction* actionModModeLink; +extern QAction* actionModModeCopy; + +extern Q3ActionGroup *actionGroupFormatFrameTypes; extern QAction *actionFormatFrameNone; extern QAction *actionFormatFrameRectangle; -extern QActionGroup *actionGroupFormatLinkStyles; +extern Q3ActionGroup *actionGroupFormatLinkStyles; +extern QAction *actionFormatIncludeImagesVer; +extern QAction *actionFormatIncludeImagesHor; +extern QAction *actionFormatHideLinkUnselected; extern QAction *actionFormatLinkStyleLine; extern QAction *actionFormatLinkStyleParabel; extern QAction *actionFormatLinkStylePolyLine; @@ -111,213 +125,98 @@ 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 QAction *actionSettingsUseFlagGroups; + +extern Q3PopupMenu *branchContextMenu; +extern Q3PopupMenu *branchLinksContextMenu; +extern Q3PopupMenu *branchLinksContextMenuDup; +extern Q3PopupMenu *floatimageContextMenu; +extern Q3PopupMenu *saveImageFormatMenu; +extern Q3PopupMenu *exportImageFormatMenu; +extern Q3PopupMenu *canvasContextMenu; extern Settings settings; +extern QString iconPath; +extern QDir vymBaseDir; + +int MapEditor::mapNum=0; // make instance /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// MapEditor::MapEditor( - QWidget* parent, bool interactive, const char* name, WFlags f) : - QCanvasView(parent,name,f) + QWidget* parent, bool interactive, const char* name, Qt::WFlags f) : + Q3CanvasView(parent,name,f), urlOperator(0), imageBuffer(0) { //cout << "Constructor ME "<setAcceptDrops(true); + + mapCanvas = new Q3Canvas(1000,800); mapCanvas->setAdvancePeriod(30); + mapCanvas->setBackgroundColor (Qt::white); 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); - - } - + // Always show scroll bars (automatic would flicker sometimes) + setVScrollBarMode ( Q3ScrollView::AlwaysOn ); + setHScrollBarMode ( Q3ScrollView::AlwaysOn ); + mapCenter = new MapCenterObj(mapCanvas); mapCenter->setVisibility (true); mapCenter->setMapEditor (this); - mapCenter->setHeading (tr("New Map")); + mapCenter->setHeading (tr("New Map","Heading of mapcenter in new map")); + mapCenter->move(mapCanvas->width()/2-mapCenter->width()/2,mapCanvas->height()/2-mapCenter->height()/2); printer=NULL; lineedit = new QLineEdit(this, "lineedit" ); - connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEditNoSave() ) ); + connect( lineedit, SIGNAL( returnPressed() ), SLOT( finishedLineEdit() ) ); lineedit->hide(); - actColor=black; setColor (actColor); - deflinkcolor=QColor (0,0,255); + actColor=Qt::black; setColor (actColor); + defLinkColor=QColor (0,0,255); + defXLinkColor=QColor (180,180,180); 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 ); + handOpenCursor=QCursor ( QPixmap(iconPath+"cursorhandopen16.png") ); // set hot spot to tip of picker - pickColorCursor=QCursor ( cursorcolorpicker_xpm, 1,15 ); + pickColorCursor=QCursor ( QPixmap (iconPath+"cursorcolorpicker16.png"), 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 ); + handOpenCursor=QCursor (QPixmap(iconPath+"cursorhandopen16.png")); // set hot spot to tip of picker - pickColorCursor=QCursor ( cursorcolorpicker_xpm, 5,27 ); + pickColorCursor=QCursor ( QPixmap(iconPath+"cursorcolorpicker.png"), 5,27 ); #endif - pickingColor=false; + drawingLink=false; + copyingObj=false; editingBO=NULL; selection=NULL; selectionLast=NULL; movingObj=NULL; + defXLinkWidth=1; + defXLinkColor=QColor (230,230,230); + mapChanged=false; mapDefault=true; mapUnsaved=false; - undoSelection=NULL; zipped=true; filePath=""; - fileName="unnamed"; + fileName=tr("unnamed"); mapName=""; + undosTotal=settings.readNumEntry("/vym/mapeditor/undoLevels",50); + undosAvail=0; + undoNum=0; + // Initialize find routine itFind=NULL; EOFind=false; @@ -325,7 +224,11 @@ printFrame=true; printFooter=true; - blockreposition=false; + blockReposition=false; + blockSaveState=false; + + hidemode=HideNone; + isInteractive=interactive; if (isInteractive) // Create temporary files @@ -334,13 +237,22 @@ // Initially set movingCentre updateViewCenter(); + // For testing purposes create history window + historyWindow = new ShowTextDialog (this); + historyWindow->setCaption (fileName); + mapCenter->reposition(); // for positioning heading } MapEditor::~MapEditor() { + if (imageBuffer) delete imageBuffer; + if (urlOperator) { + urlOperator->stop(); + delete urlOperator; + } + //cout <<"Destructor MapEditor\n"; - if (isInteractive) delTmpDirs(); // Save Settings //settings.writeEntry( "/vym/mapeditor/editmode/autoselect", ); @@ -362,7 +274,7 @@ return mapCenter; } -QCanvas* MapEditor::getCanvas() +Q3Canvas* MapEditor::getCanvas() { return mapCanvas; } @@ -420,6 +332,7 @@ { mapCenter->moveAllBy(dx,dy); mapCenter->reposition(); +// mapCenter->positionBBox(); // To move float // scroll the view (in order to not move map on screen) scrollBy (dx,dy); @@ -427,45 +340,44 @@ } } -bool MapEditor::blockReposition() +bool MapEditor::isRepositionBlocked() { - return blockreposition; + return blockReposition; +} + +QString MapEditor::getName (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); + QDir d; + d.mkdir (tmpMapDir,true); } -void MapEditor::delTmpDirs() +QString MapEditor::saveToDir(const QString &tmpdir, const QString &prefix, bool writeflags, const QPoint &offset, LinkableMapObj *saveSelection) { - //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 + // 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. // Needed for XML export - // completeMap if false, only vympart will be written, without - // mapcenter // Save Header QString ls; @@ -490,14 +402,16 @@ if (linkcolorhint==HeadingColor) colhint=attribut("linkColorHint","HeadingColor"); - QString mapAttr=attribut("version",__VYM_VERSION__); - if (savemode==CompleteMap) + QString mapAttr=attribut("version",__VYM_VERSION); + if (!saveSelection) mapAttr+= attribut("author",mapCenter->getAuthor()) + attribut("comment",mapCenter->getComment()) + attribut("date",mapCenter->getDate()) + attribut("backgroundColor", mapCanvas->backgroundColor().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,21 +419,29 @@ // Find the used flags while traversing the tree standardFlagsDefault->resetUsedCounter(); + // Reset the counters before saving + FloatImageObj (mapCanvas).resetSaveCounter(); + // Build xml recursivly - if (savemode==CompleteMap) + if (!saveSelection) s+=mapCenter->saveToDir(tmpdir,prefix,writeflags,offset); else { - if ( undoSelection && - typeid(*undoSelection) == typeid(BranchObj) ) - s+=((BranchObj*)(undoSelection))->saveToDir(tmpdir,prefix,offset); + if ( typeid(*saveSelection) == typeid(BranchObj) ) + s+=((BranchObj*)(saveSelection))->saveToDir(tmpdir,prefix,offset); + else if ( typeid(*saveSelection) == typeid(FloatImageObj) ) + s+=((FloatImageObj*)(saveSelection))->saveToDir(tmpdir,prefix,offset); + + else if (selection && typeid(*selection)==typeid(BranchObj)) + // This is used if selected branch is saved from mainwindow + s+=((BranchObj*)selection)->saveToDir(tmpdir,prefix,offset); } // Save local settings s+=settings.getXMLData (destPath); // Save selection - if (selection) + if (selection && !saveSelection ) s+=valueElement("select",selection->getSelectString()); decIndent(); @@ -527,37 +449,240 @@ if (writeflags) standardFlagsDefault->saveToDir (tmpdir+"/flags/","",writeflags); - return s; } -void MapEditor::saveState() +void MapEditor::saveState(const QString &comment) { - saveState (CompleteMap,NULL); + // Save complete map + saveState (CompleteMap,"",NULL,"",NULL, comment); } -void MapEditor::saveState(const SaveMode &mode, LinkableMapObj *part) +void MapEditor::saveState(LinkableMapObj *undoSel, const QString &comment) { - // 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) ) ) + // save the given part of the map + saveState (PartOfMap,"",undoSel,"",NULL, comment); +} + +void MapEditor::saveState(const QString &uc, const QString &rc, const QString &comment) +{ + // selection does not change during action, + // so just save commands for undo and redo + LinkableMapObj *unsel; + if (selection) + unsel=selection; + else + unsel=NULL; + saveState (UndoCommand,uc,unsel,rc,unsel, comment); +} + +void MapEditor::saveState(const QString & uncom, LinkableMapObj *unsel, const QString &comment) +{ + saveState (UndoCommand,uncom,unsel,"FIXME-redoCom",NULL, comment); +} + +void MapEditor::saveState(const SaveMode &savemode, const QString &undoCom, LinkableMapObj *undoSel, const QString &redoCom, LinkableMapObj *redoSel, const QString &comment) +{ + // Main saveState + + if (blockSaveState) return; + + /* TODO remove after testing + cout << "ME::saveState() begin\n"<append (comment); + + setChanged(); + + // Find out current undo directory + if (undosAvailundosTotal) undoNum=1; + + QString backupXML; + QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(undoNum)); + QString bakMapPath=QDir::convertSeparators(bakMapDir+"/map.xml"); + + // Create bakMapDir if not available + QDir d(bakMapDir); + if (!d.exists()) + makeSubDirs (bakMapDir); + + // Save current selection + QString redoSelection=""; + if (redoSel) + redoSelection=redoSel->getSelectString(); + + // Save the object, which should be undone + QString undoSelection=""; + if (undoSel) + undoSelection=undoSel->getSelectString(); + + // Save depending on how much needs to be saved + QString undoCommand=""; + if (savemode==UndoCommand) { - // Writing a vympart only is useful for BranchObj - undoSelection=part; - backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),PartOfMap); - } else + undoCommand=undoCom; + backupXML=""; + } + else if (savemode==PartOfMap && undoSel) { - undoSelection=NULL; - backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),CompleteMap); + undoCommand="undoPart (\""+ undoSelection+"\",\""+bakMapPath+"\")"; + backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),undoSel); + } else + { + undoCommand="undoMap (\""+bakMapPath+"\")"; + backupXML=saveToDir (bakMapDir,mapName+"-",false, QPoint (),NULL); + undoSelection=""; + } + if (!backupXML.isEmpty()) + // Write XML Data to disk + saveStringToDisk (QString(bakMapPath),backupXML); + + SimpleSettings set; + set.setEntry (QString("undoCommand"),undoCommand); + set.setEntry (QString("undoSelection"),undoSelection); + set.setEntry (QString("redoCommand"),redoCom); + set.setEntry (QString("redoSelection"),redoSelection); + set.setEntry (QString("comment"),comment); + set.writeSettings(QString(bakMapDir+"/commands")); + + /* TODO remove after testing + cout << " into="<< bakMapDir<findObjBySelect (s); + if (dst) + { + if (typeid(*dst) == typeid(BranchObj) ) + { + // Get number in parent + x=api.parInt (ok,1); + if (ok) + ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),x); + } else if (typeid(*dst) == typeid(MapCenterObj) ) + { + ((BranchObj*)selection)->moveBranchTo ((BranchObj*)(dst),-1); + // Get coordinates of mainbranch + x=api.parInt (ok,2); + if (ok) + { + y=api.parInt (ok,3); + if (ok) ((BranchObj*)selection)->move (x,y); + } + } + } + } + } + } else if (com=="setHeading") + { + if (api.checkParamCount(1)) + { + s=api.parString (ok,0); + if (ok) setHeading (s); + } + } else if (com=="setURL") + { + if (api.checkParamCount(1)) + { + s=api.parString (ok,0); + if (ok) setURL(s); + } + } else if (com=="setVymLink") + { + if (api.checkParamCount(1)) + { + s=api.parString (ok,0); + if (ok) setVymLink(s); + } + } + // Internal commands, used for undo etc. + else if (com==QString("undoMap")) + { + if (api.checkParamCount(1)) + undoXML("",api.parString (ok,0)); + } else if (com==QString("undoPart")) + { + if (api.checkParamCount(2)) + { + s=api.parString (ok,0); + t=api.parString (ok,1); + undoXML(s,t); + } + } else if (com=="select") + if (api.checkParamCount(1)) + { + s=api.parString(ok,0); + if (ok) select (s); + } + else + { + api.setError ("Unknown command in: "+atom); + cout << "ME::parse api should have error now...\n"; + } + + // Any errors? + if (api.error()) + { + qWarning("MapEditor::parseAtom: Error!"); + qWarning(api.errorDesc()); } } -void MapEditor::finishedLineEditNoSave() + +void MapEditor::finishedLineEdit() { // This is called by finishedLineEdit or any MapEditor method, // which wants to assure, that lineedits finish, before e.g. a branch is @@ -569,6 +694,7 @@ if (editingBO!=NULL) { + saveState("setHeading (\""+editingBO->getHeading()+"\")",editingBO, QString("Set heading of %1 to \"%2\"").arg(getName(editingBO)).arg(lineedit->text()) ); editingBO->setHeading(lineedit->text() ); editingBO=NULL; lineedit->releaseKeyboard(); @@ -580,6 +706,14 @@ } } +void MapEditor::toggleHistoryWindow() +{ + if (historyWindow->isVisible()) + historyWindow->hide(); + else + historyWindow->show(); +} + bool MapEditor::isDefault() { @@ -609,7 +743,7 @@ void MapEditor::closeMap() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); // Unselect before disabling the toolbar actions if (selection) selection->unselect(); @@ -627,20 +761,31 @@ 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) ); + if (fname.isEmpty() || fname=="") + { + filePath=""; + fileName=""; + destPath=""; + } else + { + filePath=fname; // becomes absolute path + fileName=fname; // gets stripped of path + destPath=destname; // needed for vymlinks + + // 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) ); + + // Adjust history window + historyWindow->setCaption (fileName); + } } QString MapEditor::getFilePath() @@ -663,12 +808,12 @@ return destPath; } -int MapEditor::load (QString &fname, const LoadMode &lmode) +ErrorCode MapEditor::load (QString fname, LoadMode lmode) { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - int returnCode=0; + if (lineedit) finishedLineEdit(); + + ErrorCode err=success; if (lmode==NewMap) { @@ -679,8 +824,7 @@ // (map state is set later at end of load...) } else { - setChanged(); - saveState(PartOfMap,selection); + saveState(selection,"Load map"); } @@ -693,19 +837,22 @@ { QMessageBox::critical( 0, tr( "Critical Parse Error" ), tr("Couldn't open map " +fname)+"."); - returnCode=1; + err=aborted; } else { - blockreposition=true; + blockReposition=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.setInputFile (file.name()); handler.setLoadMode (lmode); + blockSaveState=true; bool ok = reader.parse( source ); - blockreposition=false; + blockReposition=false; + blockSaveState=false; file.close(); if ( ok ) { @@ -727,16 +874,19 @@ } } updateActions(); - return returnCode; + return err; } int MapEditor::save (const SaveMode &savemode) { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); int returnCode=0; + // The SaveMode UndoCommand is not supported here + if (savemode==UndoCommand) return 1; + // Create mapName and fileDir makeSubDirs (fileDir); QString fname; @@ -748,32 +898,14 @@ 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); + QString saveFile; + if (savemode==CompleteMap || selection==NULL) + saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),NULL); + else + saveFile=saveToDir (fileDir,mapName+"-",true,QPoint(),selection); + + if (!saveStringToDisk(fileDir+fname,saveFile)) 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) { @@ -798,12 +930,13 @@ void MapEditor::print() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); if ( !printer ) { printer = new QPrinter; printer->setColorMode (QPrinter::Color); + printer->setPrinterName (settings.readEntry("/vym/mainwindow/printerName",printer->printerName())); } QRect totalBBox=mapCenter->getTotalBBox(); @@ -840,50 +973,56 @@ // e.g. (0,50,700,700) is upper part on A4 // see also /usr/lib/qt3/doc/html/coordsys.html - QPaintDeviceMetrics metrics (printer); + Q3PaintDeviceMetrics 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; + QRect mapRect=totalBBox; + Q3CanvasRectangle *frame=NULL; + Q3CanvasText *footerFN=NULL; + Q3CanvasText *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)); + mapRect.setRect (totalBBox.x()-10, totalBBox.y()-10, + totalBBox.width()+20, totalBBox.height()+20); + frame=new Q3CanvasRectangle (mapRect,mapCanvas); + frame->setBrush (QColor(Qt::white)); + frame->setPen (QColor(Qt::black)); frame->setZ(0); frame->show(); } + /* TODO remove after testing + QCanvasLine *l=new QCanvasLine (mapCanvas); + l->setPoints (0,0,mapRect.width(),mapRect.height()); + l->setPen (QPen(QColor(black), 1)); + l->setZ (200); + l->show(); + */ + if (printFooter) { // Print footer below map QFont font; font.setPointSize(10); - footerFN=new QCanvasText (mapCanvas); + footerFN=new Q3CanvasText (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=new Q3CanvasText (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()); + pp.setWindow (mapRect.x(), mapRect.y(), mapRect.width(), mapRect.height()+20); } else { pp.setWindow (mapRect); @@ -915,6 +1054,9 @@ selection=oldselection; selection->select(); } + + // Save settings in vymrc + settings.writeEntry("/vym/mainwindow/printerName",printer->printerName()); } } @@ -947,86 +1089,84 @@ return pix; } +void MapEditor::setHideTmpMode (HideTmpMode mode) +{ + hidemode=mode; + mapCenter->setHideTmp (hidemode); + mapCenter->reposition(); + adjustCanvasSize(); + canvas()->update(); +} + +HideTmpMode MapEditor::getHideTmpMode() +{ + return hidemode; +} + void MapEditor::exportImage(QString fn) { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - + if (lineedit) finishedLineEdit(); + + setExportMode (true); QPixmap pix (getPixmap()); pix.save(fn, "PNG"); + setExportMode (false); +} + +void MapEditor::setExportMode (bool b) +{ + // should be called before and after exports + // depending on the settings + if (b && settings.value("/vym/export/useHideExport","yes")=="yes") + setHideTmpMode (HideExport); + else + setHideTmpMode (HideNone); } void MapEditor::exportImage(QString fn, int item) { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - + if (lineedit) finishedLineEdit(); + + setExportMode (true); QPixmap pix (getPixmap()); pix.save(fn, exportImageFormatMenu->text(item) ); + setExportMode (false); } -void MapEditor::exportASCII() +void MapEditor::exportOOPresentation(const QString &fn, const QString &cf) { - // 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 ) + ExportOO ex; + ex.setFile (fn); + ex.setMapCenter(mapCenter); + if (ex.setConfigFile(cf)) { - 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(); + setExportMode (true); + ex.exportPresentation(); + setExportMode (false); } } + void MapEditor::exportXML(const QString &dir) { + // 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,mapCenter->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; } @@ -1038,6 +1178,8 @@ // Now write image, too exportImage (dir+"/images/"+mapName+".png"); + + setExportMode (false); } void MapEditor::clear() @@ -1051,240 +1193,264 @@ mapCenter->clear(); } +void MapEditor::copy() +{ + // Finish open lineEdits + if (lineedit) finishedLineEdit(); + + if (selection) + { + // write to directory + QString clipfile="part"; + QString saveFile=saveToDir (fileDir,clipfile+"-",true,QPoint(),selection); + QFile file; + + file.setName ( clipboardDir + "/"+clipfile+".xml"); + if ( !file.open( QIODevice::WriteOnly ) ) + { + // This should neverever happen + QMessageBox::critical (0,tr("Critical Export Error"),tr("MapEditor::exportXML couldn't open %1").arg(file.name())); + return; + } + + // Write it finally, and write in UTF8, no matter what + QTextStream ts( &file ); + ts.setEncoding (QTextStream::UnicodeUTF8); + ts << saveFile; + file.close(); + + clipboardEmpty=false; + updateActions(); + } +} + +void MapEditor::redo() +{ + // Finish open lineEdits + if (lineedit) finishedLineEdit(); + + blockSaveState=true; + + // Find out current undo directory + QString bakMapDir=QDir::convertSeparators (QString(tmpMapDir+"/undo-%1").arg(undoNum)); + + // Restore variables + QString undoCommand; + QString undoSelection; + QString redoCommand; + QString redoSelection; + SimpleSettings set; + set.readSettings(QString(bakMapDir+"/commands")); + undoCommand=set.readEntry ("undoCommand"); + undoSelection=set.readEntry ("undoSelection"); + redoCommand=set.readEntry ("redoCommand"); + redoSelection=set.readEntry ("redoSelection"); + + // select object before redo + if (!redoSelection.isEmpty()) + select (redoSelection); + +/* TODO remove testing + cout << "ME::redo() begin\n"; + cout << " undosTotal="<reposition(); + + //if (!redoSelection.isEmpty()) + // select (redoSelection); + + undosAvail--; + if (undosAvail<1) + // Undo not longer available now + actionEditUndo->setEnabled (false); + else + undoNum--; if (undoNum<1) undoNum=undosTotal; + + blockSaveState=false; +/* TODO remove testing + cout << "ME::redo() end\n"; + cout << " undosAvail="<reposition(); + + //if (!redoSelection.isEmpty()) + // select (redoSelection); + + undosAvail--; + if (undosAvail<1) + // Undo not longer available now + actionEditUndo->setEnabled (false); + else + undoNum--; if (undoNum<1) undoNum=undosTotal; + + blockSaveState=false; +/* TODO remove testing + cout << "ME::undo() end\n"; + cout << " undosAvail="<unselect(); - selection=NULL; - } - + // We need to parse saved XML data mapBuilderHandler handler; - QXmlInputSource source; - source.setData(backupXML); + 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) + if (undoSel.isEmpty()) { - selection=undoSelection; - selection->select(); - handler.setLoadMode (ImportReplace); - + unselect(); + mapCenter->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 ); + tr( handler.errorProtocol() )+" in "+bakMapDir ); } - // 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" + tr("Temporary directory %1 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.") ); + "Sorry for any inconveniences.").arg(bakMapDir) ); makeTmpDirs(); } } -void MapEditor::copy() +void MapEditor::pasteNoSave() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - if (selection) - { - if (typeid(*selection) == typeid(BranchObj) ) - { - 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(); - } - } - 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(); - } - } - } -} - -LinkableMapObj* MapEditor::pasteNoSave() -{ - return pasteAtNoSave (-1); -} - -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; + if (lineedit) finishedLineEdit(); + + load (clipboardDir+"/part.xml",ImportAdd); } 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(); - } - } + copy(); + deleteSelection(); } void MapEditor::paste() { - setChanged(); - saveState(PartOfMap,selection); - pasteNoSave(); - mapCenter->reposition(); - adjustCanvasSize(); + if (selection && (typeid(*selection) == typeid(BranchObj) || + typeid(*selection) == typeid(MapCenterObj))) + { + saveState(selection,QString("Paste to %1").arg( getName(selection))); + pasteNoSave(); + mapCenter->reposition(); + adjustCanvasSize(); + } } void MapEditor::cut() { - setChanged(); - saveState(PartOfMap,selection->getParObj()); + saveState(selection->getParObj(),QString("Cut %1").arg(getName(selection))); copy(); cutNoSave(); mapCenter->reposition(); adjustCanvasSize(); } +void MapEditor::move(const int &x, const int &y) +{ + // TODO no saveState, because this is only internal at undo so far + if (selection) selection->move(x,y); + if (typeid(*selection) == typeid(FloatImageObj)) + ((FloatImageObj*)selection)->setRelPos(); +} + void MapEditor::moveBranchUp() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); BranchObj* bo; BranchObj* par; if (typeid(*selection) == typeid(BranchObj) ) { - setChanged(); - saveState(PartOfMap,selection->getParObj()); - bo=(BranchObj*)(selection); + bo=(BranchObj*)selection; + if (!bo->canMoveBranchUp()) return; par=(BranchObj*)(bo->getParObj()); selection->unselect(); selection=par->moveBranchUp (bo); selection->select(); + saveState("moveBranchDown ()",bo,QString("Move up %1").arg(getName(bo))); mapCenter->reposition(); ensureSelectionVisible(); } @@ -1293,19 +1459,19 @@ void MapEditor::moveBranchDown() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); BranchObj* bo; BranchObj* par; if (typeid(*selection) == typeid(BranchObj) ) { - setChanged(); - saveState(PartOfMap,selection->getParObj()); - bo=(BranchObj*)(selection); + bo=(BranchObj*)selection; + if (!bo->canMoveBranchDown()) return; par=(BranchObj*)(bo->getParObj()); selection->unselect(); selection=par->moveBranchDown(bo); selection->select(); + saveState("moveBranchUp ()",bo,QString("Move down %1").arg(getName(bo))); mapCenter->reposition(); ensureSelectionVisible(); } @@ -1314,46 +1480,82 @@ void MapEditor::editHeading() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); if (selection && (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj) ) ) { - setChanged(); - saveState(PartOfMap,selection); + editingBO=(BranchObj*)selection; ensureSelectionVisible(); - BranchObj *bo=(BranchObj*)(selection); - editingBO=(BranchObj*)(selection); - QPoint p = worldMatrix().map(QPoint (bo->x(),bo->y())); + QPoint p = worldMatrix().map(QPoint (editingBO->x(),editingBO->y())); lineedit->setGeometry(p.x()-contentsX(),p.y()-contentsY(),200,25); - QString s=bo->getHeading(); + QString s=editingBO->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) +void MapEditor::setHeading(const QString &s) { - // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - + // Internal function, no saveState needed if (selection && (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj) ) ) { - setChanged(); - saveState(PartOfMap,selection); - - BranchObj* bo1 = (BranchObj*) (selection); + ((BranchObj*)selection)->setHeading(s); + mapCenter->reposition(); + adjustCanvasSize(); + ensureSelectionVisible(); + } +} + +void MapEditor::setURL (const QString &s) +{ + // Internal function, no saveState needed + if (selection && + (typeid(*selection) == typeid(BranchObj) || + typeid(*selection) == typeid(MapCenterObj) ) ) + { + ((BranchObj*)selection)->setURL(s); + mapCenter->reposition(); + adjustCanvasSize(); + ensureSelectionVisible(); + } +} + +void MapEditor::setVymLink (const QString &s) +{ + // Internal function, no saveState needed + if (selection && + (typeid(*selection) == typeid(BranchObj) || + typeid(*selection) == typeid(MapCenterObj) ) ) + { + ((BranchObj*)selection)->setVymLink(s); + mapCenter->reposition(); + adjustCanvasSize(); + ensureSelectionVisible(); + } +} + +void MapEditor::addNewBranch(int pos) +{ + // Finish open lineEdits + if (lineedit) finishedLineEdit(); + + if (selection && + (typeid(*selection) == typeid(BranchObj) || + typeid(*selection) == typeid(MapCenterObj) ) ) + { + BranchObj* bo1 = (BranchObj*) selection; + saveState(selection, QString("Add new branch to %1").arg(getName(bo1))); //TODO undoCommand + bool wasScrolled=false; BranchObj *newbo=NULL; if (pos==0) @@ -1391,7 +1593,7 @@ selection->select(); if (actionSettingsPasteNewHeading->isOn() ) { - BranchObj *bo2= (BranchObj*)(selection); + BranchObj *bo2= (BranchObj*)selection; bo2->setHeading(""); } if (actionSettingsAutoedit->isOn() ) @@ -1407,18 +1609,74 @@ } } + +void MapEditor::addNewBranchHere() +{ + // Finish open lineEdits + if (lineedit) finishedLineEdit(); + + if (selection && + (typeid(*selection) == typeid(BranchObj) ) ) + { + BranchObj* bo1 = (BranchObj*) selection; + saveState(selection, QString("Add new branch here").arg(getName(bo1))); + + bool wasScrolled=false; + BranchObj *newbo=NULL; + BranchObj *parbo=(BranchObj*)(selection->getParObj()); + if (parbo) + { + // add below selection + newbo=parbo->insertBranch(bo1->getNum()+1); + } + + LinkableMapObj *oldselection=selection; + ((BranchObj*)selection)->moveBranchTo (newbo,-1); + + 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(); + } + } + } +} + void MapEditor::deleteSelection() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); if (selection && typeid(*selection) ==typeid(BranchObj) ) { - setChanged(); - saveState(PartOfMap,selection->getParObj()); BranchObj* bo=dynamic_cast (selection); BranchObj* par=(BranchObj*)(bo->getParObj()); bo->unselect(); + if (selection->getDepth()>1) + // Normal branch, save parent with childs + saveState(par,QString("Delete %1").arg(getName(bo))); + else + // Mainbranch, save whole map + // TODO Better would be to insert mainbranch again at pos + // But undoCommand is missing right now + saveState(QString("Delete %1").arg(getName(bo))); selection=NULL; par->removeBranch(bo); selection=par; @@ -1429,10 +1687,9 @@ } if (selection && typeid(*selection) ==typeid(FloatImageObj) ) { - setChanged(); - saveState(PartOfMap,selection->getParObj()); FloatImageObj* fio=dynamic_cast (selection); BranchObj* par=(BranchObj*)(fio->getParObj()); + saveState(par, QString("Delete %1").arg(getName(fio))); fio->unselect(); selection=NULL; par->removeFloatImage(fio); @@ -1449,56 +1706,6 @@ 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) @@ -1519,6 +1726,37 @@ } } +bool MapEditor::select (const QString &s) +{ + LinkableMapObj *lmo=mapCenter->findObjBySelect(s); + + // Finally select the found object + if (lmo) + { + if (selection) unselect(); + selection=lmo; + selection->select(); + adjustCanvasSize(); + ensureSelectionVisible(); + return true; + } + return false; +} + +void MapEditor::select (LinkableMapObj *lmo) +{ + if (lmo && selection != lmo) + { + // select the MapObj + if (selection) selection->unselect(); + selection=lmo; + selection->select(); + + adjustCanvasSize(); + } + +} + void MapEditor::selectNextBranch() { // Increase number of branch @@ -1583,7 +1821,7 @@ b=select (s); if (b) { - if ( ((BranchObj*)(selection))->countBranches()>0) + if ( ((BranchObj*)selection)->countBranches()>0) s+=",bo:0"; else break; @@ -1662,8 +1900,8 @@ { b=select (s); if (b) - if ( ((BranchObj*)(selection))->countBranches()>0) - s+=",bo:"+ QString ("%1").arg( ((BranchObj*)(selection))->countBranches()-1 ); + if ( ((BranchObj*)selection)->countBranches()>0) + s+=",bo:"+ QString ("%1").arg( ((BranchObj*)selection)->countBranches()-1 ); else break; else @@ -1681,7 +1919,7 @@ void MapEditor::selectUpperBranch() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); if (selection) { @@ -1701,7 +1939,7 @@ void MapEditor::selectLowerBranch() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); if (selection) { @@ -1722,7 +1960,7 @@ void MapEditor::selectLeftBranch() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); BranchObj* bo; BranchObj* par; @@ -1730,7 +1968,7 @@ { if (typeid(*selection) == typeid(MapCenterObj)) { - par= (BranchObj*) (selection); + par= (BranchObj*) selection; bo=par->getLastSelectedBranch(); if (bo) { @@ -1766,7 +2004,7 @@ { if (typeid(*selection) == typeid(BranchObj) ) { - bo=((BranchObj*)(selection))->getLastSelectedBranch(); + bo=((BranchObj*)selection)->getLastSelectedBranch(); if (bo) { selection->unselect(); @@ -1784,7 +2022,7 @@ void MapEditor::selectRightBranch() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); BranchObj* bo; BranchObj* par; @@ -1793,7 +2031,7 @@ { if (typeid(*selection) == typeid(MapCenterObj)) { - par= (BranchObj*) (selection); + par= (BranchObj*) selection; bo=par->getLastSelectedBranch(); if (bo) { @@ -1826,7 +2064,7 @@ { if (typeid(*selection) == typeid(BranchObj) ) { - bo=((BranchObj*)(selection))->getLastSelectedBranch(); + bo=((BranchObj*)selection)->getLastSelectedBranch(); if (bo) { selection->unselect(); @@ -1844,7 +2082,7 @@ void MapEditor::selectFirstBranch() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); BranchObj *bo1; BranchObj *bo2; @@ -1852,7 +2090,7 @@ if (selection) { if (typeid(*selection) == typeid(BranchObj)) { - bo1= (BranchObj*) (selection); + bo1= (BranchObj*) selection; par=(BranchObj*)(bo1->getParObj()); bo2=par->getFirstBranch(); if (bo2) { @@ -1869,7 +2107,7 @@ void MapEditor::selectLastBranch() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); BranchObj *bo1; BranchObj *bo2; @@ -1877,7 +2115,7 @@ if (selection) { if (typeid(*selection) == typeid(BranchObj)) { - bo1= (BranchObj*) (selection); + bo1= (BranchObj*) selection; par=(BranchObj*)(bo1->getParObj()); bo2=par->getLastBranch(); if (bo2) { @@ -1899,12 +2137,12 @@ void MapEditor::selectBackgroundColor() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); QColor col = QColorDialog::getColor( mapCanvas->backgroundColor(), this ); if ( !col.isValid() ) return; setBackgroundColor( col ); - setChanged(); + saveState(QString("Set background color of map to %1").arg(col.name())); } void MapEditor::setBackgroundColor(QColor c) @@ -1919,7 +2157,7 @@ if (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj)) { - BranchObj *bo=(BranchObj*)(selection); + BranchObj *bo=(BranchObj*)selection; actColor=bo->getColor(); } } @@ -1933,10 +2171,9 @@ if (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj)) { - setChanged(); - saveState(PartOfMap,selection); - BranchObj *bo=(BranchObj*)(selection); - bo->setColor(actColor, false); // color links, color childs + BranchObj *bo=(BranchObj*)selection; + saveState(selection, QString("Set color of %1 to %2").arg(getName(bo)).arg(actColor.name())); //TODO undoCommand + bo->setColor(actColor); // color branch } } } @@ -1948,10 +2185,9 @@ 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 + BranchObj *bo=(BranchObj*)selection; + saveState(selection, QString ("Set color of %1 and childs to %2").arg(getName(bo)).arg(actColor.name())); //TODO undoCommand + bo->setColorChilds(actColor); // color links, color childs } } } @@ -1961,9 +2197,15 @@ { if (selection) { - setChanged(); - saveState(PartOfMap,selection); - ((BranchObj*)(selection))->toggleStandardFlag (f); + BranchObj *bo=(BranchObj*)selection; + QString s; + if (bo->isSetStandardFlag(f)) + s="Unset"; + else + s="Set"; + saveState(selection, QString("%1 standard flag \"%2\" of %3").arg(s).arg(f).arg(getName(bo)));// TODO undoCommand + bo->toggleStandardFlag (f,actionSettingsUseFlagGroups->isOn()); + adjustCanvasSize(); } } @@ -1995,7 +2237,7 @@ { if (selection!=itFind) { - if (selection) ((BranchObj*)(selection))->unselect(); + if (selection) ((BranchObj*)selection)->unselect(); selection=itFind; selection->select(); adjustCanvasSize(); @@ -2010,7 +2252,7 @@ // Searching in Heading if (searching && itFind->getHeading().contains (s,cs) ) { - if (selection) ((BranchObj*)(selection))->unselect(); + if (selection) ((BranchObj*)selection)->unselect(); selection=itFind; selection->select(); adjustCanvasSize(); @@ -2027,7 +2269,7 @@ if (!searching) { adjustCanvasSize(); - return (BranchObj*)(selection); + return (BranchObj*)selection; } else return NULL; } @@ -2038,62 +2280,44 @@ EOFind=false; } -void MapEditor::openURL() -{ - if (selection ) - { - if (typeid(*selection) == typeid(BranchObj) || - typeid(*selection) == typeid(MapCenterObj)) - { - QString url=((BranchObj*)(selection))->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::editURL() { if (selection && (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj)) ) { bool ok; + BranchObj *bo=(BranchObj*)selection; 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); + saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+text+"\")", QString("Set URL of %1 to %21").arg(getName(bo)).arg(text)); + bo->setURL (text); updateActions(); - setChanged(); } } } +QString MapEditor::getURL() +{ + if (selection && (typeid(*selection) == typeid(BranchObj) || + typeid(*selection) == typeid(MapCenterObj)) ) + return ((BranchObj*)selection)->getURL(); + else + return ""; +} + void MapEditor::editHeading2URL() { if (selection && (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj)) ) { - BranchObj *b=(BranchObj*)(selection); - b->setURL (b->getHeading()); + BranchObj *bo=(BranchObj*)selection; + saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+bo->getHeading()+"\")",QString("Copy heading of %1 to URL").arg(getName(bo))); + bo->setURL (bo->getHeading()); updateActions(); - setChanged(); } } @@ -2102,10 +2326,24 @@ if (selection && (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj)) ) { - BranchObj *b=(BranchObj*)(selection); - b->setURL ("http://bugzilla.suse.de/show_bug.cgi?id="+b->getHeading()); + BranchObj *bo=(BranchObj*)selection; + QString url= "https://bugzilla.novell.com/show_bug.cgi?id="+bo->getHeading(); + saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+url+"\")",QString("Use heading of %1 as link to Novell Bugzilla").arg(getName(bo))); + bo->setURL (url); updateActions(); - setChanged(); + } +} + +void MapEditor::editFATE2URL() +{ + if (selection && (typeid(*selection) == typeid(BranchObj) || + typeid(*selection) == typeid(MapCenterObj)) ) + { + BranchObj *bo=(BranchObj*)selection; + QString url= "http://keeper.suse.de:8080/webfate/match/id?value=ID"+bo->getHeading(); + saveState("setURL (\""+bo->getURL()+"\")","setURL (\""+url+"\")",QString("Use heading of %1 as link to FATE").arg(getName(bo))); + bo->setURL (url); + updateActions(); } } @@ -2114,21 +2352,24 @@ if (selection && (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj)) ) { - QFileDialog *fd=new QFileDialog( this,tr("VYM - Link to another map")); + BranchObj *bo=(BranchObj*)selection; + Q3FileDialog *fd=new Q3FileDialog( this,__VYM " - " +tr("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() ); + fd->setCaption(__VYM " - " +tr("Link to another map")); + if (! bo->getVymLink().isEmpty() ) + fd->setSelection( bo->getVymLink() ); fd->show(); QString fn; if ( fd->exec() == QDialog::Accepted ) - ((BranchObj*)(selection))->setVymLink (fd->selectedFile() ); - updateActions(); - mapCenter->reposition(); - adjustCanvasSize(); - canvas()->update(); - setChanged(); + { + saveState("setVymLink (\""+bo->getVymLink()+"\")","setVymLink (\""+fd->selectedFile()+"\")",QString("Set vymlink of %1 to %2").arg(getName(bo)).arg(fd->selectedFile())); + bo->setVymLink (fd->selectedFile() ); + updateActions(); + mapCenter->reposition(); + adjustCanvasSize(); + canvas()->update(); + } } } @@ -2137,12 +2378,41 @@ if (selection && (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj)) ) { - ((BranchObj*)(selection))->setVymLink ("" ); + BranchObj *bo=(BranchObj*)selection; + saveState("setVymLink (\""+bo->getVymLink()+"\")","setVymLink (\"\")",QString("Unset vymlink of %1").arg(getName(bo))); + bo->setVymLink ("" ); updateActions(); mapCenter->reposition(); adjustCanvasSize(); canvas()->update(); - setChanged(); + } +} + +void MapEditor::toggleHideExport() +{ + if (selection && (typeid(*selection) == typeid(BranchObj) || + typeid(*selection) == typeid(MapCenterObj)) || + (typeid(*selection)==typeid(FloatImageObj)) + ) + { + OrnamentedObj *oo=(OrnamentedObj*)selection; + QString s; + if (oo->hideInExport()) + { + oo->setHideInExport(false); + s="Unset"; + } + else + { + oo->setHideInExport(true); + s="Set"; + } + saveState(QString ("%1 hide export flag of %2").arg(s).arg(getName(selection))); //TODO undoCommand + actionEditToggleHideExport->setOn (oo->hideInExport()); + updateActions(); + mapCenter->reposition(); + adjustCanvasSize(); + canvas()->update(); } } @@ -2151,12 +2421,41 @@ if (selection && (typeid(*selection) == typeid(BranchObj) || typeid(*selection) == typeid(MapCenterObj)) ) { - return ((BranchObj*)(selection))->getVymLink(); + return ((BranchObj*)selection)->getVymLink(); } return ""; } +void MapEditor::removeBranchKeepChilds() +{ + if (selection && (typeid(*selection) == typeid(BranchObj) )) + { + BranchObj* bo=(BranchObj*)selection; + BranchObj* par=(BranchObj*)(bo->getParObj()); + QString s=QString("Remove %1 and keep its childs").arg(getName(bo)); + if (bo->getDepth()==1) + saveState(s); + else + saveState(selection->getParObj(),s); // TODO undoCommand + QString sel=selection->getSelectString(); + unselect(); + par->removeBranchHere(bo); + mapCenter->reposition(); + select (sel); + } +} + +void MapEditor::removeChilds() +{ + if (selection && (typeid(*selection) == typeid(BranchObj) )) + { + saveState(selection->getParObj(), QString("Remove childs of branch %1").arg(getName(selection))); + ((BranchObj*)selection)->removeChilds(); + mapCenter->reposition(); + } +} + void MapEditor::editMapInfo() { ExtraInfoDialog dia; @@ -2167,14 +2466,15 @@ // Calc some stats QString stats; int i=0; - QCanvasItemList l=canvas()->allItems(); - for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) + Q3CanvasItemList l=canvas()->allItems(); + for (Q3CanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) i++; stats+=QString ("%1 items on canvas\n").arg (i,6); uint b=0; uint f=0; uint n=0; + uint xl=0; BranchObj *bo; bo=mapCenter->first(); while (bo) @@ -2182,9 +2482,11 @@ if (!bo->getNote().isEmpty() ) n++; f+= bo->countFloatImages(); b++; + xl+=bo->countXLinks(); bo=bo->next(); } 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,14 +2494,15 @@ // Finally show dialog if (dia.exec() == QDialog::Accepted) { + saveState("Edit info about map"); //TODO undoCommand mapCenter->setAuthor (dia.getAuthor() ); mapCenter->setComment (dia.getComment() ); - setChanged(); } } void MapEditor::updateActions() { + QAction *a; if (getLinkColorHint()==HeadingColor) actionFormatLinkColorHint->setOn(true); else @@ -2226,7 +2529,7 @@ QPixmap pix( 16, 16 ); pix.fill( mapCanvas->backgroundColor() ); actionFormatBackColor->setIconSet( pix ); - pix.fill( deflinkcolor ); + pix.fill( defLinkColor ); actionFormatLinkColor->setIconSet( pix ); actionEditUndo->setEnabled( mapChanged ); @@ -2237,17 +2540,54 @@ if ( (typeid(*selection) == typeid(BranchObj)) || (typeid(*selection) == typeid(MapCenterObj)) ) { + BranchObj *bo=(BranchObj*)selection; + // Take care of links + if (bo->countXLinks()==0) + { + branchLinksContextMenu->clear(); + branchLinksContextMenu->insertItem ("No xLink available"); + branchLinksContextMenuDup->clear(); + branchLinksContextMenuDup->insertItem ("No xLink available"); + + } else + { + BranchObj *bot; + QString s; + branchLinksContextMenu->clear(); + branchLinksContextMenuDup->clear(); + for (int i=0; i<=bo->countXLinks();i++) + { + bot=bo->XLinkTargetAt(i); + if (bot) + { + s=bot->getHeading(); + if (s.length()>25) + s=s.left(25)+"..."; + branchLinksContextMenu->insertItem (s); + branchLinksContextMenuDup->insertItem (s); + } + } + } + standardFlagsDefault->setEnabled (true); - if ( ((BranchObj*)(selection))->getURL().isEmpty() ) + actionEditToggleScroll->setEnabled (true); + if ( bo->isScrolled() ) + actionEditToggleScroll->setOn(true); + else + actionEditToggleScroll->setOn(false); + + if ( bo->getURL().isEmpty() ) + { actionEditOpenURL->setEnabled (false); + actionEditOpenURLTab->setEnabled (false); + } else + { actionEditOpenURL->setEnabled (true); - actionEditURL->setEnabled (true); - actionEditHeading2URL->setEnabled (true); - actionEditBugzilla2URL->setEnabled (true); - - if ( ((BranchObj*)(selection))->getVymLink().isEmpty() ) + actionEditOpenURLTab->setEnabled (true); + } + if ( bo->getVymLink().isEmpty() ) { actionEditOpenVymLink->setEnabled (false); actionEditDeleteVymLink->setEnabled (false); @@ -2256,28 +2596,29 @@ actionEditOpenVymLink->setEnabled (true); actionEditDeleteVymLink->setEnabled (true); } - actionEditVymLink->setEnabled (true); + + if (bo->canMoveBranchUp()) + actionEditMoveUp->setEnabled (true); + else + actionEditMoveUp->setEnabled (false); + if (bo->canMoveBranchDown()) + actionEditMoveDown->setEnabled (true); + else + actionEditMoveDown->setEnabled (false); + + + actionEditToggleHideExport->setEnabled (true); + actionEditToggleHideExport->setOn (bo->hideInExport() ); actionEditCopy->setEnabled (true); actionEditCut->setEnabled (true); - actionEditPaste->setEnabled (true); - actionEditMoveUp->setEnabled (true); - actionEditMoveDown->setEnabled (true); - actionEditToggleScroll->setEnabled (true); - actionEditHeading->setEnabled (true); + if (!clipboardEmpty) + actionEditPaste->setEnabled (true); + else + actionEditPaste->setEnabled (false); + for (a=actionListBranches.first();a;a=actionListBranches.next()) + a->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: @@ -2289,40 +2630,35 @@ default: break; } + actionFormatIncludeImagesVer->setOn + ( ((BranchObj*)selection)->getIncludeImagesVer()); + actionFormatIncludeImagesHor->setOn + ( ((BranchObj*)selection)->getIncludeImagesHor()); + actionFormatHideLinkUnselected->setOn + (selection->getHideLinkUnselected()); } if ( (typeid(*selection) == typeid(FloatImageObj)) ) { + FloatObj *fo=(FloatImageObj*)selection; standardFlagsDefault->setEnabled (false); actionEditOpenURL->setEnabled (false); - actionEditURL->setEnabled (false); - actionEditHeading2URL->setEnabled (false); - actionEditBugzilla2URL->setEnabled (false); actionEditOpenVymLink->setEnabled (false); - actionEditVymLink->setEnabled (false); actionEditDeleteVymLink->setEnabled (false); + actionEditToggleHideExport->setEnabled (true); + actionEditToggleHideExport->setOn (fo->hideInExport() ); + actionEditCopy->setEnabled (true); actionEditCut->setEnabled (true); - actionEditPaste->setEnabled (false); //FIXME - actionEditMoveUp->setEnabled (false); - actionEditMoveDown->setEnabled (false); - actionEditToggleScroll->setEnabled (false); - actionEditHeading->setEnabled (false); + actionEditPaste->setEnabled (false); + for (a=actionListBranches.first();a;a=actionListBranches.next()) + a->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); + actionFormatHideLinkUnselected->setOn + ( selection->getHideLinkUnselected()); + actionEditMoveUp->setEnabled (false); + actionEditMoveDown->setEnabled (false); } } else @@ -2332,36 +2668,34 @@ actionEditCopy->setEnabled (false); actionEditCut->setEnabled (false); actionEditPaste->setEnabled (false); - actionEditMoveUp->setEnabled (false); - actionEditMoveDown->setEnabled (false); - actionEditToggleScroll->setEnabled (false); + for (a=actionListBranches.first();a;a=actionListBranches.next()) + a->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); + actionEditMoveUp->setEnabled (false); + actionEditMoveDown->setEnabled (false); + actionEditToggleHideExport->setEnabled (false); } } +void MapEditor::updateNoteFlag() +{ + if (selection) + if ( (typeid(*selection) == typeid(BranchObj)) || + (typeid(*selection) == typeid(MapCenterObj)) ) + ((BranchObj*)selection)->updateNoteFlag(); +} + void MapEditor::setLinkStyle (LinkStyle ls) { linkstyle=ls; + saveState("Set link style"); // TODO undoCommand BranchObj *bo; bo=mapCenter->first(); bo=bo->next(); @@ -2370,8 +2704,7 @@ bo->setLinkStyle(bo->getDefLinkStyle()); bo=bo->next(); } - //setChanged(); - //saveState(); + mapCenter->reposition(); } LinkStyle MapEditor::getLinkStyle () @@ -2381,7 +2714,7 @@ void MapEditor::setLinkColor(QColor c) { - deflinkcolor=c; + defLinkColor=c; updateActions(); } @@ -2425,29 +2758,54 @@ QColor MapEditor::getDefLinkColor() { - return deflinkcolor; + return defLinkColor; +} + +void MapEditor::setDefXLinkColor(QColor col) +{ + defXLinkColor=col; +} + +QColor MapEditor::getDefXLinkColor() +{ + return defXLinkColor; +} + +void MapEditor::setDefXLinkWidth (int w) +{ + defXLinkWidth=w; +} + +int MapEditor::getDefXLinkWidth() +{ + return defXLinkWidth; } void MapEditor::selectLinkColor() { // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); - - QColor col = QColorDialog::getColor( deflinkcolor, this ); + if (lineedit) finishedLineEdit(); + + QColor col = QColorDialog::getColor( defLinkColor, this ); if ( !col.isValid() ) return; setLinkColor( col ); - setChanged(); + saveState(QString("Set link color to %1").arg(col.name())); //TODO undoCommand + } void MapEditor::toggleScroll() { if (selection && (typeid(*selection) == typeid(BranchObj)) ) { - BranchObj *bo=((BranchObj*)(selection)); + BranchObj *bo=((BranchObj*)selection); if (bo->countBranches()==0) return; if (bo->getDepth()==0) return; - setChanged(); - saveState(PartOfMap,selection); + QString s; + if (bo->isScrolled()) + s="Unscroll"; + else + s="Scroll"; + saveState(selection, QString ("%1 %2").arg(s).arg(getName(bo))); bo->toggleScroll(); adjustCanvasSize(); canvas()->update(); @@ -2471,33 +2829,42 @@ (typeid(*selection) == typeid(BranchObj)) || (typeid(*selection) == typeid(MapCenterObj)) ) { - BranchObj *bo=((BranchObj*)(selection)); - - QFileDialog *fd=new QFileDialog( this,tr("vym - load image")); + BranchObj *bo=((BranchObj*)selection); + + 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(__VYM " - " +tr("Load image")); fd->setDir (lastImageDir); fd->show(); QString fn; if ( fd->exec() == QDialog::Accepted ) { - setChanged(); - saveState(PartOfMap,selection); - QString fn=fd->selectedFile(); + saveState(selection, QString("Add floatimage to %1").arg(getName(selection))); lastImageDir=fn.left(fn.findRev ("/")); - bo->addFloatImage(); - // FIXME check if load was successful - bo->getLastFloatImage()->load(fn); - bo->getLastFloatImage()->setOriginalFilename(fn); + QStringList flist = fd->selectedFiles(); + QStringList::Iterator it = flist.begin(); + while( it != flist.end() ) + { + fn = *it; + bo->addFloatImage(); + // TODO check if load was successful + bo->getLastFloatImage()->load(*it); + bo->getLastFloatImage()->setOriginalFilename(fn); + ++it; + } + mapCenter->reposition(); adjustCanvasSize(); canvas()->update(); } + delete (p); + delete (fd); } } @@ -2506,10 +2873,10 @@ if (selection && (typeid(*selection) == typeid(FloatImageObj)) ) { - FloatImageObj *fio=((FloatImageObj*)(selection)); + FloatImageObj *fio=((FloatImageObj*)selection); const char* fmt = saveImageFormatMenu->text(item); - QFileDialog *fd=new QFileDialog( this, tr("vym - save image as") + fmt); + Q3FileDialog *fd=new Q3FileDialog( this, tr("vym - save image as") + fmt); fd->addFilter ("PNG (*.png)"); fd->addFilter ("BMP (*.bmp)"); fd->addFilter ("XBM (*.xbm)"); @@ -2518,8 +2885,8 @@ 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->setCaption(__VYM " - " +tr("Save image as %1").arg(fmt)); + fd->setMode( Q3FileDialog::AnyFile ); fd->setSelection (fio->getOriginalFilename()); fd->show(); @@ -2528,10 +2895,9 @@ { if (QFile (fd->selectedFile()).exists() ) { - QMessageBox mb( "VYM", - tr("The file ") + fd->selectedFile() + - tr(" exists already. " - "Do you want to overwrite it?"), + QMessageBox mb( __VYM, + tr("The file %1 exists already.\n" + "Do you want to overwrite it?").arg(fd->selectedFile()), QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, QMessageBox::Cancel | QMessageBox::Escape, @@ -2555,17 +2921,6 @@ } } -void MapEditor::toggleFloatExport() -{ - if (selection && - (typeid(*selection) == typeid(FloatImageObj))|| - (typeid(*selection) == typeid(FloatObj)) ) - { - FloatImageObj *fio=((FloatImageObj*)(selection)); - fio->setFloatExport (actionEditToggleFloatExport->isOn() ); - } -} - void MapEditor::setFrame(const FrameType &t) { if (selection && @@ -2578,6 +2933,33 @@ } } +void MapEditor::setIncludeImagesVer(bool b) +{ + if (selection && + (typeid(*selection) == typeid(BranchObj)) || + (typeid(*selection) == typeid(MapCenterObj)) ) + ((BranchObj*)selection)->setIncludeImagesVer(b); + mapCenter->reposition(); +} + +void MapEditor::setIncludeImagesHor(bool b) +{ + if (selection && + (typeid(*selection) == typeid(BranchObj)) || + (typeid(*selection) == typeid(MapCenterObj)) ) + ((BranchObj*)selection)->setIncludeImagesHor(b); + mapCenter->reposition(); +} + +void MapEditor::setHideLinkUnselected (bool b) +{ + if (selection && + (typeid(*selection) == typeid(BranchObj)) || + (typeid(*selection) == typeid(MapCenterObj)) || + (typeid(*selection) == typeid(FloatImageObj)) ) + selection->setHideLinkUnselected(b); +} + void MapEditor::importDir(BranchObj *dst, QDir d) { if (selection && @@ -2588,41 +2970,42 @@ // 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 ) + QFileInfoList list = d.entryInfoList(); + QFileInfo fi; + + for (int i = 0; i < list.size(); ++i) { - if (fi->fileName() != "." && fi->fileName() != ".." ) + fi=list.at(i); + if (fi.fileName() != "." && fi.fileName() != ".." ) { dst->addBranch(); bo=dst->getLastBranch(); - bo->setHeading (fi->fileName() ); - bo->setColor (QColor("blue"),false); + 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")); + 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 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 ) + 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"),false); - ++itfile; + bo->setHeading (fi.fileName() ); + bo->setColor (QColor("black")); + if (fi.fileName().right(4) == ".vym" ) + bo->setVymLink (fi.filePath()); } } } @@ -2633,16 +3016,16 @@ (typeid(*selection) == typeid(BranchObj)) || (typeid(*selection) == typeid(MapCenterObj)) ) { - QFileDialog *fd=new QFileDialog( this,tr("VYM - Choose directory structur to import")); - fd->setMode (QFileDialog::DirectoryOnly); + Q3FileDialog *fd=new Q3FileDialog( this,__VYM " - " +tr("Choose directory structure to import")); + fd->setMode (Q3FileDialog::DirectoryOnly); fd->addFilter (QString (tr("vym map") + " (*.vym)")); - fd->setCaption(tr("VYM - Choose directory structur to import")); + fd->setCaption(__VYM " - " +tr("Choose directory structure to import")); fd->show(); QString fn; if ( fd->exec() == QDialog::Accepted ) { - BranchObj *bo=((BranchObj*)(selection)); + BranchObj *bo=((BranchObj*)selection); importDir (bo,QDir(fd->selectedFile()) ); mapCenter->reposition(); adjustCanvasSize(); @@ -2651,20 +3034,119 @@ } } +void MapEditor::followXLink(int i) +{ + if (selection && + (typeid(*selection) == typeid(BranchObj)) || + (typeid(*selection) == typeid(MapCenterObj)) ) + { + BranchObj *bo=((BranchObj*)selection)->XLinkTargetAt(i); + if (bo) + { + selection->unselect(); + selection=bo; + selection->select(); + ensureSelectionVisible(); + } + } +} + +void MapEditor::editXLink(int i) +{ + if (selection && + (typeid(*selection) == typeid(BranchObj)) || + (typeid(*selection) == typeid(MapCenterObj)) ) + { + XLinkObj *xlo=((BranchObj*)selection)->XLinkAt(i); + if (xlo) + { + EditXLinkDialog dia; + dia.setXLink (xlo); + dia.setSelection(selection); + if (dia.exec() == QDialog::Accepted) + { + if (dia.useSettingsGlobal() ) + { + setDefXLinkColor (xlo->getColor() ); + setDefXLinkWidth (xlo->getWidth() ); + } + if (dia.deleteXLink()) + ((BranchObj*)selection)->deleteXLinkAt(i); + saveState("Edit xLink"); //TODO undoCommand + } + } + } +} + void MapEditor::testFunction() { cout << "MapEditor::testFunction() called\n"; + + mapCenter->positionBBox(); + return; + + WarningDialog dia; + dia.setCancelButton (true); + dia.setText("This is a longer \nWarning"); + dia.setCaption("Warning: Flux problem"); + dia.setShowAgainName("/vym/warnings/mapeditor"); + if (dia.exec()==QDialog::Accepted) + cout << "accepted!\n"; + else + cout << "canceled!\n"; + return; + + QString ub=vymBaseDir.path()+"/scripts/update-bookmarks"; + Q3Process *proc = new Q3Process( this ); + proc->addArgument(ub); + + if ( !proc->start() ) + { + QMessageBox::warning(0, + tr("Warning"), + tr("Couldn't find script %1\nto notifiy Browsers of changed bookmarks.").arg(ub)); + } + + +/* + if (hidemode==HideNone) + { + setHideTmpMode (HideExport); + mapCenter->calcBBoxSizeWithChilds(); + QRect totalBBox=mapCenter->getTotalBBox(); + QRect mapRect=totalBBox; + QCanvasRectangle *frame=NULL; + + cout << " map has =("<setBrush (QColor(white)); + frame->setPen (QColor(black)); + frame->setZ(0); + frame->show(); + } + else + { + setHideTmpMode (HideNone); + } + cout <<" hidemode="< (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() ); + if (selection) + { + 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() ); + } } @@ -2719,78 +3201,129 @@ updateActions(); canvasContextMenu->popup(e->globalPos() ); } + e->accept(); } void MapEditor::contentsMousePressEvent(QMouseEvent* e) { + // Ignore right clicks, these will go to context menus + if (e->button() == Qt::RightButton ) + { + e->ignore(); + return; + } + // Finish open lineEdits - if (lineedit) finishedLineEditNoSave(); + if (lineedit) finishedLineEdit(); 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) + e->accept(); + + //Take care of clickdesystem flags _or_ modifier modes + // + if (lmo && (typeid(*lmo)==typeid(BranchObj) || + typeid(*lmo)==typeid(MapCenterObj) )) { - pickingColor=true; - setCursor (pickColorCursor); - return; + QString foname=((BranchObj*)lmo)->getSystemFlagName(p); + if (!foname.isEmpty()) + { + // systemFlag clicked + select (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(); + return; + } + } + // No system flag clicked, take care of modmodes + + // Special case: CTRL is pressed + if (e->state() & Qt::ControlModifier) + { + if (actionModModeColor->isOn()) + { + pickingColor=true; + setCursor (pickColorCursor); + return; + } + if (actionModModeLink->isOn()) + { + BranchObj *bo_begin=NULL; + if (lmo) + bo_begin=(BranchObj*)(lmo); + else + if (selection && + ((typeid(*selection) == typeid(BranchObj)) || + (typeid(*selection) == typeid(MapCenterObj))) ) + bo_begin=(BranchObj*)selection; + if (bo_begin) + { + drawingLink=true; + linkingObj_src=bo_begin; + tmpXLink=new XLinkObj (mapCanvas); + tmpXLink->setBegin (bo_begin); + tmpXLink->setEnd (p); + tmpXLink->setColor(defXLinkColor); + tmpXLink->setWidth(defXLinkWidth); + tmpXLink->updateXLink(); + tmpXLink->setVisibility (true); + return; + } + } } - if (lmo) - { // MapObj was found - if (selection != lmo) + { + select (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()) - { - // 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() ); + movingObj_orgPos.setX (lmo->x() ); + movingObj_orgPos.setY (lmo->y() ); + + // 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 (actionModModeCopy->isOn() && + e->state() & Qt::ControlModifier) + { + if (typeid(*selection)==typeid(BranchObj) ) + { + copyingObj=true; + mapCenter->addBranch ((BranchObj*)selection); + unselect(); + selection=mapCenter->getLastBranch(); + selection->select(); + mapCenter->reposition(); + } + } + movingObj=selection; } 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(); } else { // No MapObj found, we are on the Canvas itself // Left Button move Pos of CanvasView - if (e->button() == QMouseEvent::LeftButton ) + if (e->button() == Qt::LeftButton ) { movingObj=NULL; // move Content not Obj movingObj_start=e->globalPos(); @@ -2803,14 +3336,19 @@ void MapEditor::contentsMouseMoveEvent(QMouseEvent* e) { + QPoint p = inverseWorldMatrix().map(e->pos()); + // Move the selected MapObj if ( selection && movingObj) { - QPoint p = inverseWorldMatrix().map(e->pos()); + // To avoid jumping of the CanvasView, only + // ensureSelectionVisible, if not tmp linked + if (!selection->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; @@ -2822,21 +3360,17 @@ if (typeid(*selection) == typeid(FloatImageObj)) { - setChanged(); - saveState(); - FloatObj *fo=(FloatObj*)(selection); - if (fo->getLinkStyle()==StyleUndef) - { - fo->setLinkStyle(fo->getDefLinkStyle()); - fo->setLinkColor(fo->getParObj()->getLinkColor()); - } + FloatObj *fo=(FloatObj*)selection; + saveState( + "move "+qpointToString(movingObj_orgPos),fo->getSelectString() , + QString("Move %1").arg(getName(selection))); fo->move (p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); fo->setRelPos(); fo->reposition(); // 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->state() & Qt::ShiftModifier) && lmo && ( (typeid(*lmo)==typeid(BranchObj)) || (typeid(*lmo)==typeid(MapCenterObj)) ) && ( lmo != fo->getParObj()) @@ -2844,6 +3378,7 @@ { if (typeid(*fo) == typeid(FloatImageObj)) { + saveState(QString("Relink %1 to %2").arg(getName(fo)).arg(getName(lmo) ) ); FloatImageObj *fio=(FloatImageObj*)(fo); ((BranchObj*)(lmo))->addFloatImage (fio); fio->unselect(); @@ -2854,18 +3389,13 @@ selection=(LinkableMapObj*)(fio); selection->select(); movingObj=(MapObj*)(fio); - // setLinkStyle calls updateLink, only set it once - if (fio->getLinkStyle()!=fio->getDefLinkStyle() ) - fio->setLinkStyle (fio->getDefLinkStyle()); - } - // TODO if (typeid(*selection) == typeid(FloatTextObj)) } } else // selection != a FloatObj { if (lmosel->getDepth()==0) { - if (e->state() == (LeftButton | !ShiftButton)) + if (e->state() == Qt::LeftButton && e->modifiers()==Qt::ShiftModifier) // If mapCenter is moved, move all the rest by default, too. mapCenter->moveAll(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); else @@ -2875,8 +3405,6 @@ if (lmosel->getDepth()==1) { // depth==1, mainbranch - setChanged(); - saveState(PartOfMap,lmosel); lmosel->move(p.x() -movingObj_start.x(), p.y()-movingObj_start.y() ); } else { @@ -2884,36 +3412,31 @@ if (lmosel->getOrientation() == OrientLeftOfCenter) // 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(); + //ensureSelectionVisible(); if (lmo && (lmo!=selection) && (typeid(*lmo) == typeid(BranchObj) || (typeid(*lmo) == typeid(MapCenterObj) ) ) ) { - if (e->state() & QMouseEvent::ControlButton) + if (e->state() & Qt::ControlModifier) { // Special case: CTRL to link below lmo lmosel->setParObjTmp (lmo,p,+1); } - else if (e->state() & QMouseEvent::ShiftButton) + else if (e->state() & 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(); } } // depth>0 @@ -2923,8 +3446,15 @@ return; } // selection && moving_obj + // Draw a link from one branch to another + if (drawingLink) + { + tmpXLink->setEnd (p); + tmpXLink->updateXLink(); + } + // Move CanvasView - if (!movingObj && !pickingColor) + if (!movingObj && !pickingColor &&!drawingLink) { QPoint p=e->globalPos(); movingVec.setX(-p.x() + movingObj_start.x() ); @@ -2944,37 +3474,62 @@ 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) { - if (e->state() & QMouseEvent::ShiftButton) + if (e->state() & Qt::ShiftModifier) { - ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),false); - ((BranchObj*)(selection))->setLinkColor (); + ((BranchObj*)selection)->setColor (((BranchObj*)(dst))->getColor()); + ((BranchObj*)selection)->setLinkColor (); } else { - ((BranchObj*)(selection))->setColor (((BranchObj*)(dst))->getColor(),true); - ((BranchObj*)(selection))->setLinkColor (); + ((BranchObj*)selection)->setColorChilds (((BranchObj*)(dst))->getColor()); + ((BranchObj*)selection)->setLinkColor (); } } return; } + + // Have we been drawing a link? + if (drawingLink) + { + drawingLink=false; + // Check if we are over another branch + dst=mapCenter->findMapObj(inverseWorldMatrix().map(e->pos() ), NULL); + if (dst && selection) + { + tmpXLink->setEnd ( ((BranchObj*)(dst)) ); + tmpXLink->updateXLink(); + tmpXLink->activate(); + saveState(QString("Activate xLink from %1 to %2").arg(getName(tmpXLink->getBegin())).arg(getName(tmpXLink->getEnd())) ); //TODO undoCommand + } else + { + delete(tmpXLink); + tmpXLink=NULL; + } + return; + } + // Have we been moving something? if ( selection && movingObj ) { + // Moved FloatObj? Maybe we need to reposition + if(typeid(*selection)==typeid (FloatImageObj)) + { + selection->getParObj()->requestReposition(); + mapCenter->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))) - { + ((LinkableMapObj*)selection) ); + + 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) ) @@ -2983,40 +3538,43 @@ QPoint savePos=QPoint (selection->x(),selection->y() ); // Reset the temporary drawn link to the original one - ((LinkableMapObj*)(selection))->unsetParObjTmp(); - + ((LinkableMapObj*)selection)->unsetParObjTmp(); + + + copyingObj=false; if (dst ) - { - setChanged(); - saveState(); + { + BranchObj* bs=((BranchObj*)selection); + QString undoCom="linkBranchToPos (\""+ + (bs->getParObj())->getSelectString()+ + "\","+ + QString("%1").arg(bs->getNum())+ + ","+ + QString ("%1,%2").arg(movingObj_orgPos.x()).arg(movingObj_orgPos.y())+ + ")"; // 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) + if (e->state() & Qt::ShiftModifier) { - selection=pasteAtNoSave (((BranchObj*)(dst))->getNum()); - if (selection) selection->select(); - } - else if (e->state() & QMouseEvent::ControlButton) + bs->moveBranchTo ( (BranchObj*)(dst->getParObj()), ((BranchObj*)(dst))->getNum()); + } else + if (e->state() & Qt::ControlModifier) + { + bs->moveBranchTo ( (BranchObj*)(dst->getParObj()), ((BranchObj*)(dst))->getNum()+1); + } else { - selection=pasteAtNoSave (((BranchObj*)(dst))->getNum()+1); - if (selection) selection->select(); - } - else - { - selection=pasteNoSave(); - selection->select(); + bs->moveBranchTo ((BranchObj*)(dst),-1); if (dst->getDepth()==0) - ((BranchObj*)(selection))->move (savePos); - } - } + bs->move (savePos); + } + saveState (undoCom,bs->getSelectString(),QString("Relink %1 to %2").arg(getName(bs)).arg(getName(dst)) ); + } else + if (selection->getDepth()==1) + // If we have moved mainbranch only save endposition + saveState("move "+qpointToString(movingObj_orgPos), selection->getSelectString(), QString("Move %1 to %2").arg(getName(selection)).arg(qpointToString(movingObj_orgPos))); + // Draw the original link, before selection was moved around mapCenter->reposition(); } @@ -3025,17 +3583,17 @@ canvas()->update(); movingObj=NULL; } 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 (lineedit) finishedLineEdit(); - if (e->button() == QMouseEvent::LeftButton ) + if (e->button() == Qt::LeftButton ) { QPoint p = inverseWorldMatrix().map(e->pos()); LinkableMapObj *lmo=mapCenter->findMapObj(p, NULL); @@ -3044,8 +3602,6 @@ if (selection) selection->unselect(); selection=lmo; selection->select(); - setChanged(); - saveState(PartOfMap,selection); editHeading(); } } @@ -3053,10 +3609,239 @@ void MapEditor::resizeEvent (QResizeEvent* e) { - QCanvasView::resizeEvent( e ); - - QString s=""; - if (!fileName.isEmpty()) s=fileName; + Q3CanvasView::resizeEvent( e ); adjustCanvasSize(); } +void MapEditor::contentsDragEnterEvent(QDragEnterEvent *event) +{ + +// for (unsigned int i=0;event->format(i);i++) // Debug mime type +// cerr << event->format(i) << endl; + + if (selection && + (typeid(*selection) == typeid(BranchObj)) || + (typeid(*selection) == typeid(MapCenterObj))) { + + // If QImageDrag can decode mime type + if (Q3ImageDrag::canDecode(event)) { + event->accept(); + return; + } + + // If image are dragged from firefox + if (event->provides("application/x-moz-file-promise-url") && + event->provides("application/x-moz-nativeimage")) { + event->accept(true); + return; + } + + // If QUriDrag can decode mime type + if (Q3UriDrag::canDecode(event)) { + event->accept(); + return; + } + + // If Uri are dragged from firefox + if (event->provides("_NETSCAPE_URL")){ + event->accept(); + return; + } + + // If QTextDrag can decode mime type + if (Q3TextDrag::canDecode(event)) { + event->accept(); + return; + } + + } + event->ignore(); +} + +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; iprovides("image/png")) + { + QPixmap pix; + if (Q3ImageDrag::decode(event, pix)) + { + addFloatImage(pix); + event->accept(); + update=true; + } else + event->ignore(); + + } else if (event->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; + } + + if (uris.count()>0) + { + QStringList files; + QStringList urls; + QString s; + BranchObj *bo; + for (const char* u=uris.first(); u; u=uris.next()) + { + bo=((BranchObj*)selection)->addBranch(); + if (bo) + { + s=Q3UriDrag::uriToLocalFile(u); + if (!s.isEmpty()) + { + QString file = QDir::convertSeparators(s); + heading = QFileInfo(file).baseName(); + files.append(file); + if (file.endsWith(".vym", false)) + bo->setVymLink(file); + else + bo->setURL(u); + } else + { + urls.append (u); + bo->setURL(u); + } + + if (!heading.isEmpty()) + bo->setHeading(heading); + else + bo->setHeading(u); + } + } + update=true; + } + + if (update) + { + //FIXME saveState has to be called earlier for each of the drops... + saveState("Drop Event"); //TODO undo Command + mapCenter->reposition(); + adjustCanvasSize(); + canvas()->update(); + } + } +} + +void MapEditor::addFloatImage(const QPixmap &img) +{ + if (selection && + (typeid(*selection) == typeid(BranchObj)) || + (typeid(*selection) == typeid(MapCenterObj)) ) + { + BranchObj *bo=((BranchObj*)selection); + saveState(selection,QString("Add floatimage to %1").arg(getName(bo))); + //QString fn=fd->selectedFile(); + //lastImageDir=fn.left(fn.findRev ("/")); + bo->addFloatImage(); + // FIXME check if load was successful + bo->getLastFloatImage()->load(img); + //bo->getLastFloatImage()->setOriginalFilename(fn); + mapCenter->reposition(); + adjustCanvasSize(); + canvas()->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()); + addFloatImage(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(); +}