diff -r 000000000000 -r 7a96bd401351 mainwindow.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mainwindow.cpp Sun Jan 30 12:58:47 2005 +0000 @@ -0,0 +1,2213 @@ +#include "mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#include "version.h" + +#include "icons/filenew.xpm" +#include "icons/fileopen.xpm" +#include "icons/filesave.xpm" +#include "icons/fileprint.xpm" +#include "icons/editundo.xpm" +//#include "icons/editredo.xpm" // TODO +#include "icons/editcopy.xpm" +#include "icons/editcut.xpm" +#include "icons/editpaste.xpm" +#include "icons/editmoveup.xpm" +#include "icons/editmovedown.xpm" +#include "icons/formatcoloritem.xpm" +#include "icons/formatcolorbranch.xpm" +#include "icons/formatcolorpicker.xpm" +#include "icons/viewzoomreset.xpm" +#include "icons/viewzoomin.xpm" +#include "icons/viewzoomout.xpm" +#include "icons/vym-48x48.xpm" +#include "icons/flag-note.xpm" +#include "icons/flag-url.xpm" +#include "icons/flag-vymlink.xpm" +#include "icons/flag-scrolled-right.xpm" + +#include "flagrowobj.h" +#include "texteditor.h" +#include "mapeditor.h" +#include "exporthtmldialog.h" +#include "exportxhtmldialog.h" +#include "showtextdialog.h" +#include "process.h" +#include "settings.h" +#include "options.h" + +extern TextEditor *textEditor; +extern Main *mainWindow; +extern int statusbarTime; +extern MapEditor *clipboardME; +extern FlagRowObj* standardFlagsDefault; + +extern QAction* actionFileSave; +extern QAction* actionFilePrint; +extern QAction* actionEditUndo; +extern QAction *actionEditCopy; +extern QAction *actionEditCut; +extern QAction *actionEditPaste; +extern QAction *actionEditMoveUp; +extern QAction *actionEditMoveDown; +extern QAction *actionEditToggleScroll; +extern QAction* actionEditOpenURL; +extern QAction* actionEditURL; +extern QAction* actionEditHeading2URL; +extern QAction* actionEditBugzilla2URL; +extern QAction *actionEditOpenVymLink; +extern QAction *actionEditVymLink; +extern QAction *actionEditDeleteVymLink; +extern QAction *actionEditMapInfo; +extern QAction *actionEditHeading; +extern QAction *actionEditDelete; +extern QAction *actionEditAddBranch; +extern QAction *actionEditAddBranchAbove; +extern QAction *actionEditAddBranchBelow; +extern QAction *actionEditImportAdd; +extern QAction *actionEditImportReplace; +extern QAction *actionEditSaveBranch; +extern QAction *actionEditSelectFirst; +extern QAction *actionEditSelectLast; +extern QAction *actionEditLoadImage; +extern QAction *actionEditToggleFloatExport; + +extern QAction* actionFormatColor; +extern QAction* actionFormatPickColor; +extern QAction* actionFormatColorBranch; +extern QAction* actionFormatColorSubtree; +extern QAction* actionFormatLinkColorHint; +extern QAction* actionFormatBackColor; +extern QAction* actionFormatLinkColor; + +extern QActionGroup *actionGroupFormatFrameTypes; +extern QAction *actionFormatFrameNone; +extern QAction *actionFormatFrameRectangle; + +extern QActionGroup *actionGroupFormatLinkStyles; +extern QAction *actionFormatLinkStyleLine; +extern QAction *actionFormatLinkStyleParabel; +extern QAction *actionFormatLinkStylePolyLine; +extern QAction *actionFormatLinkStylePolyParabel; + +extern QAction *actionViewToggleNoteEditor; + +extern QAction* actionSettingsAutoedit; +extern QAction* actionSettingsAutoselectHeading; +extern QAction* actionSettingsAutoselectHeading; +extern QAction* actionSettingsAutoselectText; +extern QAction* actionSettingsPasteNewHeading; +extern QAction* actionSettingsUseDelKey; + +extern QPopupMenu* branchContextMenu; +extern QPopupMenu* floatimageContextMenu; +extern QPopupMenu* saveImageFormatMenu; +extern QPopupMenu* canvasContextMenu; +extern QPopupMenu* lastMapsMenu; +extern QPopupMenu* exportMenu; +extern QPopupMenu* exportImageFormatMenu; + + +extern Settings settings; +extern Options options; + +#if defined(Q_OS_LINUX) +extern void qt_wait_for_window_manager( QWidget* w ); +#endif + +Main::Main(QWidget* parent, const char* name, WFlags f) : + QMainWindow(parent,name,f) +{ + mainWindow=this; + + setCaption ("VYM - View Your Mind"); + + // Load window settings + resize (settings.readNumEntry( "/vym/mainwindow/geometry/width", 800), + settings.readNumEntry( "/vym/mainwindow/geometry/height",600)); + move (settings.readNumEntry( "/vym/mainwindow/geometry/posX", 100), + settings.readNumEntry( "/vym/mainwindow/geometry/posY", 100)); + + + // Initialize some settings, which are platform dependant + QString p,s; + + // application to open URLs + p="/vym/mainwindow/readerURL"; + #if defined(Q_OS_LINUX) + s=settings.readEntry (p,"konqueror"); + #else + #if defined(Q_OS_MACX) + s=settings.readEntry (p,"/Applications/Safari.app/Contents/MacOS/Safari"); + #else + s=settings.readEntry (p,"mozilla"); + #endif + #endif + settings.writeEntry( p,s); + + // application to open PDFs + p="/vym/mainwindow/readerPDF"; + #if defined(Q_OS_LINUX) + s=settings.readEntry (p,"acroread"); + #else + #if defined(Q_OS_MACX) + s=settings.readEntry (p,"/Applications/Safari.app/Contents/MacOS/Safari"); + #else + s=settings.readEntry (p,"acroread"); + #endif + #endif + settings.writeEntry( p,s); + + + maxLastMaps=9; + + // Create tab widget which holds the maps + tabWidget= new QTabWidget (this); + connect( tabWidget, SIGNAL( currentChanged( QWidget * ) ), + this, SLOT( editorChanged( QWidget * ) ) ); + + setCentralWidget(tabWidget); + + setupFileActions(); + setupEditActions(); + setupFormatActions(); + setupViewActions(); + setupFlagActions(); + setupSettingsActions(); + setupContextMenus(); + if (settings.readBoolEntry( "/vym/mainwindow/showTestMenu",false)) setupTestActions(); + setupHelpActions(); + + // After menu is created, we can enable some actions + actionFilePrint->setEnabled (true); + + statusBar(); + + // Create the default map into first tab +// fileNew(); +// tabWidget->addTab (new MapEditor(tabWidget,true), "unnamed"); +// currentMapEditor()->show(); + + // Initialize Find window + findWindow=new FindWindow(NULL,"findwindow"); + connect (findWindow, SIGNAL( findButton(QString) ), + this, SLOT(editFind(QString) ) ); + connect (findWindow, SIGNAL( somethingChanged() ), + this, SLOT(editFindChanged() ) ); + + updateGeometry(); +} + +Main::~Main() +{ + // Save Settings + settings.writeEntry( "/vym/mainwindow/geometry/width", width() ); + settings.writeEntry( "/vym/mainwindow/geometry/height", height() ); + settings.writeEntry( "/vym/mainwindow/geometry/posX", pos().x() ); + settings.writeEntry( "/vym/mainwindow/geometry/posY", pos().y() ); + + settings.writeEntry( "/vym/version/version", __VYM_VERSION__ ); + settings.writeEntry( "/vym/version/builddate", __BUILD_DATE__ ); + + settings.writeEntry( "/vym/mapeditor/editmode/autoselectheading",actionSettingsAutoselectHeading->isOn() ); + settings.writeEntry( "/vym/mapeditor/editmode/autoselecttext",actionSettingsAutoselectText->isOn() ); + settings.writeEntry( "/vym/mapeditor/editmode/pastenewheading",actionSettingsPasteNewHeading->isOn() ); + settings.writeEntry( "/vym/mapeditor/editmode/autoedit",actionSettingsAutoedit->isOn() ); + settings.writeEntry( "/vym/mapeditor/editmode/useDelKey",actionSettingsUseDelKey->isOn() ); + + QString s; + int maps=lastMaps.count(); + settings.writeEntry( "/vym/lastMaps/number",maps ); + for (int i=1;i<=maps;i++) + { + QStringList::Iterator it = lastMaps.at(i-1); + s=QString("/vym/lastMaps/map-%1").arg(i); + if (!s.isEmpty() && i<=maxLastMaps) + settings.writeEntry (s, *it); + } + + + // To make the texteditor save its settings, call the destructor + delete (textEditor); +} + +void Main::loadCmdLine() +{ + /* TODO draw some kind of splashscreen while loading... + if (qApp->argc()>1) + { + } + */ + + QStringList flist=options.getFileList(); + QStringList::Iterator it=flist.begin(); + + while (it !=flist.end() ) + { + fileLoad (*it, NewMap); + *it++; + } +} + + +void Main::statusMessage(const QString &s) +{ + statusBar()->message (s); +} + +void Main::closeEvent (QCloseEvent* ) +{ + fileExitVYM(); +} + +// File Actions +void Main::setupFileActions() +{ + QToolBar *tb = new QToolBar( this ); + tb->setLabel( "File Actions" ); + QPopupMenu *menu = new QPopupMenu( this ); + menuBar()->insertItem( tr( "&File" ), menu ); + + // Keycodes: /usr/lib64/qt3/include/qnamespace.h + + QAction *a; + a = new QAction( tr( "New map" ), QPixmap( filenew_xpm ), tr( "&New..." ), CTRL + Key_N, this, "fileNew" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) ); + a->addTo( tb ); + a->addTo( menu ); + + a = new QAction( tr( "Open" ), QPixmap( fileopen_xpm), tr( "&Open..." ), CTRL + Key_O, this, "fileOpen" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileLoad() ) ); + a->addTo( tb ); + a->addTo( menu ); + + lastMapsMenu = new QPopupMenu (this); + + menu->insertItem (tr("Open Recent"),lastMapsMenu ); + menu->insertSeparator(); + + a = new QAction( tr( "Save" ), QPixmap( filesave_xpm ), tr( "&Save..." ), CTRL + Key_S, this, "fileSave" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileSave() ) ); + a->addTo( tb ); + a->addTo( menu ); + actionFileSave=a; + + a = new QAction( tr( "Save &As" ), QPixmap(), tr( "Save &As..." ), 0, this, "fileSaveAs" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileSaveAs() ) ); + a->addTo( menu ); + + menu->insertSeparator(); + + a = new QAction( tr( "Import directory structure (experimental)" ), QPixmap(), tr( "Import Dir" ), 0, this, "export" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileImportDir() ) ); + a->addTo( menu ); + + exportMenu = new QPopupMenu (this); + menu->insertItem (tr("Export"),exportMenu ); + + menu->insertSeparator(); + + + a = new QAction( tr( "Print" ), QPixmap( fileprint_xpm ), tr( "&Print..." ), CTRL + Key_P, this, "filePrint" ); + connect( a, SIGNAL( activated() ), this, SLOT( filePrint() ) ); + a->addTo( tb ); + a->addTo( menu ); + actionFilePrint=a; + + a = new QAction( tr( "Close Map" ), QPixmap(), tr( "&Close Map" ), ALT + Key_C, this, "fileCloseMap" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileCloseMap() ) ); + a->addTo( menu ); + + a = new QAction( tr( "Exit VYM" ), QPixmap(), tr( "E&xit VYM" ), CTRL + Key_Q, this, "fileExitVYM" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileExitVYM() ) ); + a->addTo( menu ); +} + + +//Edit Actions +void Main::setupEditActions() +{ + QToolBar *tb = new QToolBar( this ); + tb->setLabel( "Edit Actions" ); + QPopupMenu *menu = new QPopupMenu( this ); + menuBar()->insertItem( tr( "&Edit" ), menu ); + + QAction *a; + a = new QAction( tr( "Undo" ), QPixmap( editundo_xpm ), tr( "&Undo" ), CTRL + Key_Z, this, "editUndo" ); + connect( a, SIGNAL( activated() ), this, SLOT( editUndo() ) ); + a->setEnabled (false); + a->addTo( tb ); + a->addTo( menu ); + actionEditUndo=a; + /* + a = new QAction( tr( "Redo" ), QPixmap( editredo_xpm ), tr( "&Redo" ), CTRL + Key_Y, this, "editRedo" ); + connect( a, SIGNAL( activated() ), this, SLOT( editRedo() ) ); + a->addTo( tb ); + a->addTo( menu ); + */ + menu->insertSeparator(); + a = new QAction( tr( "Copy" ), QPixmap( editcopy_xpm ), tr( "&Copy" ), CTRL + Key_C, this, "editCopy" ); + connect( a, SIGNAL( activated() ), this, SLOT( editCopy() ) ); + a->setEnabled (false); + a->addTo( tb ); + a->addTo( menu ); + actionEditCopy=a; + a = new QAction( tr( "Cut" ), QPixmap( editcut_xpm ), tr( "Cu&t" ), CTRL + Key_X, this, "editCut" ); + connect( a, SIGNAL( activated() ), this, SLOT( editCut() ) ); + a->setEnabled (false); + a->addTo( tb ); + a->addTo( menu ); + actionEditCut=a; + a = new QAction( tr( "Paste" ), QPixmap( editpaste_xpm ), tr( "&Paste" ), CTRL + Key_V, this, "editPaste" ); + connect( a, SIGNAL( activated() ), this, SLOT( editPaste() ) ); + a->setEnabled (false); + a->addTo( tb ); + a->addTo( menu ); + actionEditPaste=a; + a = new QAction( tr( "Move branch up" ), QPixmap( editmoveup_xpm ), tr( "Move up" ), Key_PageUp, this, "editMoveUp" ); + connect( a, SIGNAL( activated() ), this, SLOT( editMoveUp() ) ); + a->setEnabled (false); + a->addTo( tb ); + a->addTo( menu ); + actionEditMoveUp=a; + a = new QAction( tr( "Move branch down" ), QPixmap( editmovedown_xpm ), tr( "Move down" ), Key_PageDown, this, "editMoveDown" ); + connect( a, SIGNAL( activated() ), this, SLOT( editMoveDown() ) ); + a->setEnabled (false); + a->addTo( tb ); + a->addTo( menu ); + actionEditMoveDown=a; + + a = new QAction( tr( "Scroll branch" ), QPixmap(flag_scrolled_right_xpm), tr( "Scroll branch" ), Key_ScrollLock, this, "scroll" ); + connect( a, SIGNAL( activated() ), this, SLOT( editToggleScroll() ) ); + a->setEnabled (false); + a->addTo( tb ); + a->addTo( menu ); + actionEditToggleScroll=a; + + a = new QAction( tr( "Unscroll all" ), QPixmap(), tr( "Unscroll all scrolled branches" ), 0, this, "scroll" ); + connect( a, SIGNAL( activated() ), this, SLOT( editUnScrollAll() ) ); + a->addTo( menu ); + + menu->insertSeparator(); + + a = new QAction( tr( "Find" ), QPixmap(), tr( "Find" ), CTRL + Key_F, this, "find" ); + connect( a, SIGNAL( activated() ), this, SLOT( editOpenFindWindow() ) ); + a->addTo( menu ); + + menu->insertSeparator(); + + a = new QAction( tr( "Open URL" ), QPixmap(flag_url_xpm), tr( "Open URL" ), CTRL + Key_U, this, "url" ); + connect( a, SIGNAL( activated() ), this, SLOT( editOpenURL() ) ); + a->addTo( menu ); + a->addTo( tb ); + a->setEnabled (false); + actionEditOpenURL=a; + + a = new QAction( tr( "Edit URL" ), QPixmap(), tr( "Edit URL" ), SHIFT + CTRL + Key_U, this, "url" ); + connect( a, SIGNAL( activated() ), this, SLOT( editURL() ) ); + a->addTo( menu ); + a->setEnabled (false); + actionEditURL=a; + + a = new QAction( tr( "Use heading of selected branch as URL" ), QPixmap(), tr( "Use heading for URL" ), 0, this, "heading2url" ); + connect( a, SIGNAL( activated() ), this, SLOT( editHeading2URL() ) ); + a->addTo( menu ); + a->setEnabled (false); + actionEditHeading2URL=a; + + a = new QAction( tr( "Create URL to Bugzilla" ), QPixmap(), tr( "Create URL to Bugzilla" ), 0, this, "bugzilla2url" ); + connect( a, SIGNAL( activated() ), this, SLOT( editBugzilla2URL() ) ); + a->setEnabled (false); + actionEditBugzilla2URL=a; + + menu->insertSeparator(); + + a = new QAction( tr( "Jump to another vym map, if needed load it first" ), QPixmap(flag_vymlink_xpm), tr( "Jump to map" ), 0, this, "jumpMap" ); + connect( a, SIGNAL( activated() ), this, SLOT( editOpenVymLink() ) ); + a->addTo( menu ); + a->addTo( tb ); + a->setEnabled (false); + actionEditOpenVymLink=a; + + a = new QAction( tr( "Edit link to another vym map" ), QPixmap(), tr( "Edit vym link" ), 0, this, "editLinkMap" ); + connect( a, SIGNAL( activated() ), this, SLOT( editVymLink() ) ); + a->addTo( menu ); + a->setEnabled (false); + actionEditVymLink=a; + + a = new QAction( tr( "Delete link to another vym map" ), QPixmap(), tr( "Delete vym link" ), 0, this, "deleteLinkMap" ); + connect( a, SIGNAL( activated() ), this, SLOT( editDeleteVymLink() ) ); + a->addTo( menu ); + a->setEnabled (false); + actionEditDeleteVymLink=a; + + menu->insertSeparator(); + + a = new QAction( tr( "Edit Map Info" ), QPixmap(), tr( "Edit Map Info" ), 0, this, "editMapInfo" ); + connect( a, SIGNAL( activated() ), this, SLOT( editMapInfo() ) ); + a->addTo( menu ); + a->setEnabled (true); + actionEditMapInfo=a; + + menu->insertSeparator(); + + // Shortcuts to modify heading: + a = new QAction( tr( "edit Heading" ),tr( "Edit heading" ), Key_Enter, this, "editHeading" ); + connect( a, SIGNAL( activated() ), this, SLOT( editHeading() ) ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditHeading=a; + a = new QAction( tr( "edit Heading" ),tr( "Edit heading" ), Key_Return, this, "editHeading" ); + connect( a, SIGNAL( activated() ), this, SLOT( editHeading() ) ); + //a->addTo ( menu ); + + // Shortcut to delete selection + a = new QAction( tr( "Delete Selection" ),tr( "Delete Selection" ), Key_Delete, this, "deleteBranch" ); + connect( a, SIGNAL( activated() ), this, SLOT( editDeleteSelection() ) ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditDelete=a; + + // Shortcut to add branch + #if defined (Q_OS_MACX) + a = new QAction( tr( "Add a branch as child of selection" ),tr( "Add branch as child" ), CTRL + Key_I, this, "newBranch" ); + #else + a = new QAction( tr( "Add a branch as child of selection" ),tr( "Add branch as child" ), Key_Insert, this, "newBranch" ); + #endif + connect( a, SIGNAL( activated() ), this, SLOT( editNewBranch() ) ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditAddBranch=a; + + // Add branch above + a = new QAction( tr( "Add a branch above selection" ),tr( "Add branch above" ), SHIFT+Key_Insert, this, "newBranch" ); + connect( a, SIGNAL( activated() ), this, SLOT( editNewBranchAbove() ) ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditAddBranchAbove=a; + + // Add branch below + a = new QAction( tr( "Add a branch below selection" ),tr( "Add branch below" ), CTRL +Key_Insert, this, "newBranch" ); + connect( a, SIGNAL( activated() ), this, SLOT( editNewBranchBelow() ) ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditAddBranchBelow=a; + + // Import at selection (adding to selection) + a = new QAction( tr( "Add map at selection" ),tr( "Import (add)" ), 0, this, "importAdd" ); + connect( a, SIGNAL( activated() ), this, SLOT( editImportAdd() ) ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditImportAdd=a; + + // Import at selection (replacing selection) + a = new QAction( tr( "Replace selection with map" ),tr( "Import (replace)" ), 0, this, "importReplace" ); + connect( a, SIGNAL( activated() ), this, SLOT( editImportReplace() ) ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditImportReplace=a; + + // Save selection + a = new QAction( tr( "Save selction" ),tr( "Save selection" ), 0, this, "saveSelection" ); + connect( a, SIGNAL( activated() ), this, SLOT( editSaveBranch() ) ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditSaveBranch=a; + + // Shortcuts for navigating with cursor: + a = new QAction( tr( "Select upper branch" ),tr( "Select upper branch" ), Key_Up, this, "upperBranch" ); + connect( a, SIGNAL( activated() ), this, SLOT( editUpperBranch() ) ); + a = new QAction( tr( "Select lower branch" ),tr( "Select lower branch" ), Key_Down, this, "lowerBranch" ); + connect( a, SIGNAL( activated() ), this, SLOT( editLowerBranch() ) ); + a = new QAction( tr( "Select left branch" ),tr( "Select left branch" ), Key_Left, this, "upperBranch" ); + connect( a, SIGNAL( activated() ), this, SLOT( editLeftBranch() ) ); + a = new QAction( tr( "Select right branch" ),tr( "Select child branch" ), Key_Right, this, "rightBranch" ); + connect( a, SIGNAL( activated() ), this, SLOT( editRightBranch() ) ); + a = new QAction( tr( "Select first branch" ),tr( "Select first branch" ), Key_Home, this, "firstBranch" ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditSelectFirst=a; + connect( a, SIGNAL( activated() ), this, SLOT( editFirstBranch() ) ); + a = new QAction( tr( "Select last branch" ),tr( "Select last branch" ), Key_End, this, "lastBranch" ); + connect( a, SIGNAL( activated() ), this, SLOT( editLastBranch() ) ); + a->setEnabled (false); + a->addTo ( menu ); + actionEditSelectLast=a; + + a = new QAction( tr( "Add Image" ),tr( "Add Image" ), 0, this, "loadImage" ); + connect( a, SIGNAL( activated() ), this, SLOT( editLoadImage() ) ); + actionEditLoadImage=a; +} + +// Format Actions +void Main::setupFormatActions() +{ + QPopupMenu *menu = new QPopupMenu( this ); + menuBar()->insertItem( tr( "&Format" ), menu ); + + QToolBar *tb = new QToolBar( this ); + QAction *a; + QPixmap pix( 16,16); + pix.fill (black); + actionFormatColor= new QAction( tr( "Set Color" ), pix, tr( "Set &Color" ), 0, this, "formatColor" ); + connect( actionFormatColor, SIGNAL( activated() ), this, SLOT( formatSelectColor() ) ); + actionFormatColor->addTo( tb ); + actionFormatColor->addTo( menu ); + a= new QAction( tr( "Pick color\nHint: You can pick a color from another branch and color using CTRL+Left Button" ), QPixmap(formatcolorpicker_xpm), tr( "Pic&k color" ), CTRL + Key_K, this, "pickColor" ); + connect( a, SIGNAL( activated() ), this, SLOT( formatPickColor() ) ); + a->setEnabled (false); + a->addTo( tb ); + a->addTo( menu ); + actionFormatPickColor=a; + a= new QAction( tr( "Color branch" ), QPixmap(formatcoloritem_xpm), tr( "Color &branch" ), CTRL + Key_I, this, "colorItem" ); + connect( a, SIGNAL( activated() ), this, SLOT( formatColorItem() ) ); + a->setEnabled (false); + a->addTo( tb ); + a->addTo( menu ); + actionFormatColorBranch=a; + a= new QAction( tr( "Color Subtree" ), QPixmap(formatcolorbranch_xpm), tr( "Color sub&tree" ), CTRL + Key_T, this, "colorBranch" ); + connect( a, SIGNAL( activated() ), this, SLOT( formatColorBranch() ) ); + a->setEnabled (false); + a->addTo( menu ); + a->addTo( tb ); + actionFormatColorSubtree=a; + + menu->insertSeparator(); + actionGroupFormatLinkStyles=new QActionGroup ( this, "formatLinkStyles"); + actionGroupFormatLinkStyles->setExclusive (true); + a= new QAction( tr( "Line" ), QPixmap(), tr( "Linkstyle Line" ), 0, actionGroupFormatLinkStyles, "formatLinkStyleLine" ); + a->setToggleAction(true); + connect( a, SIGNAL( activated() ), this, SLOT( formatLinkStyleLine() ) ); + actionFormatLinkStyleLine=a; + a= new QAction( tr( "Line" ), QPixmap(), tr( "Linkstyle Parabel" ), 0, actionGroupFormatLinkStyles, "formatLinkStyleLine" ); + a->setToggleAction(true); + connect( a, SIGNAL( activated() ), this, SLOT( formatLinkStyleParabel() ) ); + actionFormatLinkStyleParabel=a; + a= new QAction( tr( "PolyLine" ), QPixmap(), tr( "Linkstyle Thick Line" ), 0, actionGroupFormatLinkStyles, "formatLinkStyleLine" ); + a->setToggleAction(true); + connect( a, SIGNAL( activated() ), this, SLOT( formatLinkStylePolyLine() ) ); + actionFormatLinkStylePolyLine=a; + a= new QAction( tr( "PolyParabel" ), QPixmap(), tr( "Linkstyle Thick Parabel" ), 0, actionGroupFormatLinkStyles, "formatLinkStylePolyParabel" ); + a->setToggleAction(true); + connect( a, SIGNAL( activated() ), this, SLOT( formatLinkStylePolyParabel() ) ); + actionFormatLinkStylePolyParabel=a; + actionGroupFormatLinkStyles->addTo (menu); + + actionGroupFormatFrameTypes=new QActionGroup ( this, "formatFrameTypes"); + actionGroupFormatFrameTypes->setExclusive (true); + a = new QAction( tr( "No Frame" ),tr( "No Frame" ), 0, actionGroupFormatFrameTypes, "frameNone" ); + a->setToggleAction(true); + connect( a, SIGNAL( activated() ), this, SLOT( formatFrameNone() ) ); + actionFormatFrameNone=a; + a = new QAction( tr( "Rectangle" ),tr( "Rectangle" ), 0, actionGroupFormatFrameTypes, "frameRectangle" ); + a->setToggleAction(true); + connect( a, SIGNAL( activated() ), this, SLOT( formatFrameRectangle() ) ); + actionFormatFrameRectangle=a; + + menu->insertSeparator(); + a= new QAction( tr( "Use same color for links and headings" ), QPixmap(), tr( "&Use color of heading for link" ), 0, this, "formatLinkColorHint" ); + a->setToggleAction(true); + connect( a, SIGNAL( activated() ), this, SLOT( formatToggleLinkColorHint() ) ); + a->addTo( menu ); + actionFormatLinkColorHint=a; + pix.fill (white); + actionFormatLinkColor= new QAction( tr( "Set Link Color" ), pix, tr( "Set &Link Color" ), 0, this, "formatLinkColor" ); + connect( actionFormatLinkColor, SIGNAL( activated() ), this, SLOT( formatSelectLinkColor() ) ); + actionFormatLinkColor->addTo( menu ); + actionFormatBackColor= new QAction( tr( "Set Background Color" ), pix, tr( "Set &Background Color" ), 0, this, "formatBackColor" ); + connect( actionFormatBackColor, SIGNAL( activated() ), this, SLOT( formatSelectBackColor() ) ); + actionFormatBackColor->addTo( menu ); +} + +// View Actions +void Main::setupViewActions() +{ + QToolBar *tb = new QToolBar( this ); + tb->setLabel( "View Actions" ); + QPopupMenu *menu = new QPopupMenu( this ); + menuBar()->insertItem( tr( "&View" ), menu ); + + QAction *a; + a = new QAction( tr( "Zoom reset" ), QPixmap(viewzoomreset_xpm), tr( "reset Zoom" ), 0, this, "zoomReset" ); + connect( a, SIGNAL( activated() ), this, SLOT(viewZoomReset() ) ); + a->addTo( tb ); + a->addTo( menu ); + a = new QAction( tr( "Zoom in" ), QPixmap(viewzoomin_xpm), tr( "Zoom in" ), CTRL + Key_Plus, this, "zoomIn" ); + connect( a, SIGNAL( activated() ), this, SLOT(viewZoomIn() ) ); + a->addTo( tb ); + a->addTo( menu ); + a = new QAction( tr( "Zoom out" ), QPixmap(viewzoomout_xpm), tr( "Zoom out" ), CTRL + Key_Minus, this, "zoomOut" ); + connect( a, SIGNAL( activated() ), this, SLOT( viewZoomOut() ) ); + a->addTo( tb ); + a->addTo( menu ); + a = new QAction( tr( "Toggle Note Editor" ), QPixmap(flag_note_xpm), tr( "Toggle Note Editor" ), CTRL + Key_E , this, "noteEditor" ); + connect( a, SIGNAL( activated() ), this, SLOT(windowToggleNoteEditor() ) ); + a->setToggleAction(true); + if (textEditor->showWithMain()) + a->setOn(true); + else + a->setOn(false); + a->addTo( tb ); + a->addTo( menu ); + actionViewToggleNoteEditor=a; + a = new QAction( tr( "&Next Window" ), QPixmap(), tr( "Next Window" ), ALT + Key_N , this, "nextWindow" ); + connect( a, SIGNAL( activated() ), this, SLOT(windowNextEditor() ) ); + a->addTo( menu ); + a = new QAction( tr( "&Previous Window" ), QPixmap(), tr( "Previous Window" ), ALT + Key_P , this, "previousWindow" ); + connect( a, SIGNAL( activated() ), this, SLOT(windowPreviousEditor() ) ); + a->addTo( menu ); +} + +// Flag Actions +void Main::setupFlagActions() +{ + standardFlagsDefault->makeToolbar(this, "Standard Flags"); +} + +// Settings Actions +void Main::setupSettingsActions() +{ + QPopupMenu *menu = new QPopupMenu( this ); + menuBar()->insertItem( tr( "&Settings" ), menu ); + + QAction *a; + + + a = new QAction( tr( "Set application to open pdf files" ), QPixmap(), tr( "Set application to open pdf files" ), 0, this, "setPDF" ); + connect( a, SIGNAL( activated() ), this, SLOT( settingsPDF() ) ); + a->addTo( menu ); + + a = new QAction( tr( "Set application to open an URL" ), QPixmap(), tr( "Set application to open an URL" ), 0, this, "setURL" ); + connect( a, SIGNAL( activated() ), this, SLOT( settingsURL() ) ); + a->addTo( menu ); + + menu->insertSeparator(); + a = new QAction( tr( "Edit branch after adding it" ), QPixmap(), tr( "Edit branch after adding it" ), 0, this, "autoedit" ); + a->setToggleAction(true); + a->setOn ( settings.readBoolEntry ("/vym/mapeditor/editmode/autoedit",true) ); + a->addTo( menu ); + actionSettingsAutoedit=a; + + a= new QAction( tr( "Select branch after adding it" ), QPixmap(), tr( "Select branch after adding it" ), 0, this, "autoselectheading" ); + a->setToggleAction(true); + a->setOn ( settings.readBoolEntry ("/vym/mapeditor/editmode/autoselect",false) ); + a->addTo( menu ); + actionSettingsAutoselectHeading=a; + + a= new QAction( tr( "Select heading before editing" ), QPixmap(), tr( "Select existing heading" ), 0, this, "autoselectexistingtext" ); + a->setToggleAction(true); + a->setOn ( settings.readBoolEntry ("/vym/mapeditor/editmode/autoselectexistingtext",true) ); + a->addTo( menu ); + actionSettingsAutoselectText=a; + + a= new QAction( tr( "Enable pasting into new branch" ), QPixmap(), tr( "Enable pasting into new branch" ), 0, this, "pastenewheading" ); + a->setToggleAction(true); + a->setOn ( settings.readBoolEntry ("/vym/mapeditor/editmode/newheadingisempty",true) ); + a->addTo( menu ); + actionSettingsPasteNewHeading=a; + + a= new QAction( tr( "Enable Delete key for deleting branches" ), QPixmap(), tr( "Enable Delete key" ), 0, this, "delkey" ); + a->setToggleAction(true); + a->setOn ( settings.readBoolEntry ("/vym/mapeditor/editmode/useDelKey",false) ); + a->addTo( menu ); + actionSettingsUseDelKey=a; +} + +// Test Actions +void Main::setupTestActions() +{ + QPopupMenu *menu = new QPopupMenu( this ); + menuBar()->insertItem( tr( "&Test" ), menu ); + + QAction *a; + a = new QAction( tr( "Test Flag" ), QPixmap(), tr( "test flag" ), 0, this, "flag" ); + connect( a, SIGNAL( activated() ), this, SLOT( testFunction() ) ); + a->addTo( menu ); + + a = new QAction( tr( "Show Clipboard" ), QPixmap(), tr( "Show clipboard" ), 0, this, "clipboard" ); + connect( a, SIGNAL( activated() ), this, SLOT( testShowClipboard() ) ); + a->addTo( menu ); +} + +// Help Actions +void Main::setupHelpActions() +{ + QPopupMenu *menu = new QPopupMenu( this ); + menuBar()->insertItem( tr( "&Help" ), menu ); + + QAction *a; + a = new QAction( tr( "Open VYM Documentation (pdf)" ), QPixmap(), tr( "Open VYM Documentation (pdf) " ), 0, this, "about" ); + connect( a, SIGNAL( activated() ), this, SLOT( helpDoc() ) ); + a->addTo( menu ); + + a = new QAction( tr( "Information about VYM" ), QPixmap(), tr( "About VYM" ), 0, this, "about" ); + connect( a, SIGNAL( activated() ), this, SLOT( helpAbout() ) ); + a->addTo( menu ); + + a = new QAction( tr( "Information about QT toolkit" ), QPixmap(), tr( "About QT" ), 0, this, "about" ); + connect( a, SIGNAL( activated() ), this, SLOT( helpAboutQT() ) ); + a->addTo( menu ); +} + +// Context Menus +void Main::setupContextMenus() +{ + QAction*a; + + // Context Menu for branch or mapcenter + branchContextMenu =new QPopupMenu (this); + actionEditAddBranch->addTo ( branchContextMenu ); + actionEditAddBranchAbove->addTo ( branchContextMenu ); + actionEditAddBranchBelow->addTo ( branchContextMenu ); + actionEditSaveBranch->addTo( branchContextMenu ); + branchContextMenu->insertSeparator(); + actionEditImportAdd->addTo ( branchContextMenu ); + actionEditImportReplace->addTo ( branchContextMenu ); + branchContextMenu->insertSeparator(); + actionEditOpenURL->addTo ( branchContextMenu ); + actionEditURL->addTo ( branchContextMenu ); + actionEditHeading2URL->addTo ( branchContextMenu ); + if (settings.readBoolEntry( "/vym/mainwindow/showTestMenu",false)) + actionEditBugzilla2URL->addTo( branchContextMenu ); + branchContextMenu->insertSeparator(); + actionEditOpenVymLink->addTo ( branchContextMenu ); + actionEditVymLink->addTo ( branchContextMenu ); + actionEditDeleteVymLink->addTo ( branchContextMenu ); + branchContextMenu->insertSeparator(); + actionEditLoadImage->addTo( branchContextMenu ); + branchContextMenu->insertSeparator(); + actionEditCopy->addTo( branchContextMenu ); + actionEditCut->addTo( branchContextMenu ); + actionEditPaste->addTo( branchContextMenu ); + branchContextMenu->insertSeparator(); + actionGroupFormatFrameTypes->addTo( branchContextMenu ); + + // Context menu for floatimage + floatimageContextMenu =new QPopupMenu (this); + saveImageFormatMenu=new QPopupMenu (this); + exportImageFormatMenu=new QPopupMenu (this); + + QStrList fmt = QImage::outputFormats(); + for (const char* f = fmt.first(); f; f = fmt.next()) + { + saveImageFormatMenu->insertItem( f ); + exportImageFormatMenu->insertItem( f ); + } + connect( saveImageFormatMenu, SIGNAL( activated(int) ), this, SLOT( editSaveImage(int ) ) ); + connect( exportImageFormatMenu, SIGNAL( activated(int) ), this, SLOT( fileExportImage(int ) ) ); + floatimageContextMenu->insertItem( tr("Save image"),saveImageFormatMenu ); + + floatimageContextMenu->insertSeparator(); + actionEditCopy->addTo( floatimageContextMenu ); + actionEditCut->addTo( floatimageContextMenu ); + + floatimageContextMenu->insertSeparator(); + a = new QAction( tr( "Use for Export" ), QPixmap(), tr( "Use for Export"), 0, this, "useForExport" ); + a->setToggleAction(true); + connect( a, SIGNAL( activated() ), this, SLOT( editToggleFloatExport() ) ); + a->addTo( floatimageContextMenu); + actionEditToggleFloatExport=a; + + + + // Context menu for exports + exportMenu->insertItem ( tr("Export map as image"),exportImageFormatMenu); + + a = new QAction( tr( "Export as ASCII (still experimental)" ), QPixmap(), tr( "Export (ASCII)" ), 0, this, "exportASCII" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileExportASCII() ) ); + a->addTo( exportMenu ); + + a = new QAction( tr( "Export XML" ), QPixmap(), tr( "Export XML" ), 0, this, "exportXML" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileExportXML() ) ); + a->addTo( exportMenu ); + + if (settings.readBoolEntry( "/vym/mainwindow/showTestMenu",false)) + { + a = new QAction( tr( "Export HTML" ), QPixmap(), tr( "Export HTML" ), 0, this, "exportHTML" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileExportHTML() ) ); + a->addTo( exportMenu ); + } + + a = new QAction( tr( "Export XHTML" ), QPixmap(), tr( "Export XHTML" ), ALT + Key_X, this, "exportXHTML" ); + connect( a, SIGNAL( activated() ), this, SLOT( fileExportXHTML() ) ); + a->addTo( exportMenu ); + + + // Context menu for canvas + canvasContextMenu =new QPopupMenu (this); + actionEditMapInfo->addTo( canvasContextMenu ); + canvasContextMenu->insertSeparator(); + actionGroupFormatLinkStyles->addTo( canvasContextMenu ); + canvasContextMenu->insertSeparator(); + actionFormatLinkColorHint->addTo( canvasContextMenu ); + actionFormatLinkColor->addTo( canvasContextMenu ); + actionFormatBackColor->addTo( canvasContextMenu ); + + // Menu for last opened files + // Read settings initially + QString s; + int j=settings.readNumEntry( "/vym/lastMaps/number",0); + for (int i=1;i<=j;i++) + { + s=settings.readEntry(QString("/vym/lastMaps/map-%1").arg(i),""); + if (!s.isEmpty() && j<=maxLastMaps) + lastMaps.append(s); + } + setupLastMapsMenu(); + connect( lastMapsMenu, SIGNAL( activated(int) ), this, SLOT( fileLoadLast(int ) ) ); +} + +void Main::setupLastMapsMenu() +{ + // Remove double entries + QStringList::Iterator it=lastMaps.begin(); + QStringList::Iterator jt; + while (it!=lastMaps.end() ) + { + jt=it; + ++jt; + while (jt!=lastMaps.end() ) + { + if (*it == *jt) + jt=lastMaps.remove(jt); + else + jt++; + } + it++; + } + + // Limit length of list to maxLastMaps + while ((int)(lastMaps.count()) > maxLastMaps) lastMaps.pop_back(); + + // build Menu from lastMaps string list + lastMapsMenu->clear(); + for (it = lastMaps.begin(); it != lastMaps.end(); ++it ) + lastMapsMenu->insertItem (*it ); + +} + +void Main::hideEvent (QHideEvent * ) +{ + if (!textEditor->isMinimized() ) textEditor->hide(); +} + +void Main::showEvent (QShowEvent * ) +{ + if (textEditor->showWithMain()) textEditor->show(); +} + +bool Main::reallyWriteDirectory(const QString &dir) +{ + QStringList eList = QDir(dir).entryList(); + if (eList.first() ==".") eList.pop_front(); // remove "." + if (eList.first() =="..") eList.pop_front(); // remove "." + if (!eList.isEmpty()) + { + QMessageBox mb( "VYM", + tr("The directory ") + dir + + tr(" is not empty. Do you risk to overwrite its contents?"), + QMessageBox::Warning, + QMessageBox::Yes , + QMessageBox::Cancel | QMessageBox::Default, + QMessageBox::QMessageBox::NoButton ); + + mb.setButtonText( QMessageBox::Yes, tr("Overwrite") ); + mb.setButtonText( QMessageBox::No, tr("Cancel")); + switch( mb.exec() ) + { + case QMessageBox::Yes: + // save + return true; + case QMessageBox::Cancel: + // do nothing + return false; + } + } + return true; +} + +QString Main::browseDirectory (const QString &caption) +{ + QFileDialog fd(this,caption); + fd.setMode (QFileDialog::DirectoryOnly); + fd.setCaption("VYM - "+caption); + fd.show(); + + if ( fd.exec() == QDialog::Accepted ) + return fd.selectedFile(); + else + return ""; +} + +MapEditor* Main::currentMapEditor() const +{ + if ( tabWidget->currentPage() && + tabWidget->currentPage()->inherits( "MapEditor" ) ) + return (MapEditor*)tabWidget->currentPage(); + return NULL; +} + +//TODO not used now, maybe use this for overview window later +void Main::newView() +{ + // Open a new view... have it delete when closed. + Main *m = new Main(0, 0, WDestructiveClose); + qApp->setMainWidget(m); + m->show(); + qApp->setMainWidget(0); +} + +void Main::editorChanged(QWidget *) +{ + // Unselect all possibly selected objects + // (Important to update note editor) + int i; + MapEditor *me; + for (i=0;i<=tabWidget->count() -1;i++) + { + + me=(MapEditor*)tabWidget->page(i); + me->unselect(); + } + currentMapEditor()->reselect(); + + // Update actions to in menus and toolbars according to editor + currentMapEditor()->updateActions(); +} + +void Main::fileNew() +{ + QString fn="unnamed"; + MapEditor* medit = new MapEditor (tabWidget, true); + tabWidget->addTab (medit,fn); + tabWidget->showPage(medit); + medit->viewport()->setFocus(); + medit->select("mc:"); +} + +void Main::fileLoad(QString fn, const LoadMode &lmode) +{ + // Error codes + enum errorCode {success,aborted}; + errorCode err=success; + + // fn is usually the archive, mapfile the file after uncompressing + QString mapfile; + + // Make fn absolute (needed for unzip) + fn=QDir (fn).absPath(); + + MapEditor *me; + + if (lmode==NewMap) + { + // Check, if map is already loaded + int i=0; + while (i<=tabWidget->count() -1) + { + me=(MapEditor*)tabWidget->page(i); + if (me->getFilePath() == fn) + { + // Already there, ask for confirmation + QMessageBox mb( "VYM", + tr("The map ") + fn + tr ("\n is already opened." + "Opening the same map in multiple editors may lead \n" + "to confusion when finishing working with vym." + "Do you want to"), + QMessageBox::Warning, + QMessageBox::Yes | QMessageBox::Default, + QMessageBox::Cancel | QMessageBox::Escape, + QMessageBox::QMessageBox::NoButton); + mb.setButtonText( QMessageBox::Yes, tr("Open anyway") ); + mb.setButtonText( QMessageBox::Cancel, tr("Cancel")); + switch( mb.exec() ) + { + case QMessageBox::Yes: + // load anyway + i=tabWidget->count(); + break; + case QMessageBox::Cancel: + // do nothing + return; + break; + } + } + i++; + } + } + + + // Try to load map + if ( !fn.isEmpty() ) + { + me = currentMapEditor(); + int tabIndex=tabWidget->currentPageIndex(); + // Check first, if mapeditor exists + // If it is not default AND we want a new map, + // create a new mapeditor in a new tab + if ( lmode==NewMap && (!me || !me->isDefault() ) ) + { + me = new MapEditor (tabWidget,true); + tabWidget->addTab (me,fn); + tabIndex=tabWidget->indexOf (me); + tabWidget->setCurrentPage (tabIndex); + } + + // Check, if file exists (important for creating new files + // from command line + if (!QFile(fn).exists() ) + { + QMessageBox mb( "VYM", + tr("The map") + fn + + tr(" does not exist.\n Do you want to create a new one?"), + QMessageBox::Question, + QMessageBox::Yes , + QMessageBox::Cancel | QMessageBox::Default, + QMessageBox::QMessageBox::NoButton ); + + mb.setButtonText( QMessageBox::Yes, tr("Create")); + mb.setButtonText( QMessageBox::No, tr("Cancel")); + switch( mb.exec() ) + { + case QMessageBox::Yes: + // Create new map + currentMapEditor()->setFilePath(fn); + tabWidget->setTabLabel (currentMapEditor(), + currentMapEditor()->getFileName() ); + statusBar()->message( "Created " + fn , statusbarTime ); + return; + + case QMessageBox::Cancel: + // don't create new map + statusBar()->message( "Loading " + fn + " failed!", statusbarTime ); + fileCloseMap(); + return; + } + } + + + //tabWidget->currentPage() won't be NULL here, because of above... + tabWidget->showPage(me); + me->viewport()->setFocus(); + + // Create temporary directory for packing + char tmpdir1[]="/tmp/vym-XXXXXX"; + QString tmpMapDir=mkdtemp(tmpdir1); + + // Try to unzip file + Process *zipProc=new Process (); + zipProc->clearArguments(); + zipProc->setWorkingDirectory (QDir(tmpMapDir)); + zipProc->addArgument ("unzip"); + zipProc->addArgument (fn ); + zipProc->addArgument ("-d"); + zipProc->addArgument (tmpMapDir); + + if (!zipProc->start() ) + { + QMessageBox::critical( 0, tr( "Critical Load Error" ), + tr("Couldn't start unzip to decompress data.")); + err=aborted; + + } else + { + zipProc->waitFinished(); + if (!zipProc->normalExit() ) + { + QMessageBox::critical( 0, tr( "Critical Load Error" ), + tr("unzip didn't exit normally") + + zipProc->getErrout() ); + err=aborted; + } else + { + if (zipProc->exitStatus()>0) + { + if (zipProc->exitStatus()==9) + { + // no zipped file, but maybe .xml or old version? Try again. + mapfile=fn; + me->setZipped(false); + } + else + { + QMessageBox::critical( 0, tr( "Critical Load Error" ), + QString("unzip exit code: %1").arg(zipProc->exitStatus() ) + + zipProc->getErrout() ); + err=aborted; + } + } else + { // Uncompressing was successfull, + // load from uncompressed temporary directory + + me->setZipped(true); + + + // Look for mapname.xml + mapfile= fn.left(fn.findRev(".",-1,true)); + mapfile=mapfile.section( '/', -1 ); + QFile file( tmpMapDir + "/" + mapfile + ".xml"); + if (!file.exists() ) + { + // mapname.xml does not exist, well, + // maybe some renamed the mapname.vym file... + // Try to find any .xml in the toplevel + // directory of the .vym file + QStringList flist=QDir (tmpMapDir).entryList("*.xml"); + if (flist.count()==1) + { + // Only one entry, take this one + mapfile=tmpMapDir + "/"+flist.first(); + } else + { + for ( QStringList::Iterator it = flist.begin(); it != flist.end(); ++it ) + *it=tmpMapDir + "/" + *it; + // FIXME + // Multiple entries, load all (but only the first one into this ME) + //mainWindow->fileLoadFromTmp (flist); + //returnCode=1; // Silently forget this attempt to load + qWarning ("MainWindow::load (fn) multimap found..."); + } + + if (flist.isEmpty() ) + { + QMessageBox::critical( 0, tr( "Critical Load Error" ), + tr("Couldn't find a map (*.xml) in .vym archive.\n")); + err=aborted; + } + } //file doesn't exist + else + mapfile=file.name(); + } // Uncompressing successfull + } + } + + // Finally load map into mapEditor + me->setFilePath (mapfile,fn); + if (me->load(mapfile,lmode)) + err=aborted; + + // Delete tmpDir + system ( "rm -rf "+tmpMapDir); + + // Check for errors + if (err==success) + { + if (lmode==NewMap) + { + me->setFilePath (fn); + tabWidget->changeTab(tabWidget->page(tabIndex), me->getFileName()); + lastMaps.prepend(me->getFilePath() ); + setupLastMapsMenu(); + actionFilePrint->setEnabled (true); + } + statusBar()->message( "Loaded " + fn, statusbarTime ); + return; + } else + { + if (lmode==NewMap) + fileCloseMap(); + } + + + } + statusBar()->message( "Could not load " + fn, statusbarTime ); +} + + +void Main::fileLoad(const LoadMode &lmode) +{ + QFileDialog *fd=new QFileDialog( this); + if (!lastFileDir.isEmpty()) + fd->setDir (lastFileDir); + fd->addFilter ("XML (*.xml)"); + fd->addFilter ("VYM map (*.vym *.vyp)"); + switch (lmode) + { + case NewMap: + fd->setCaption(tr("Load vym map")); + break; + case ImportAdd: + fd->setCaption(tr("Import: Add vym map to selection")); + break; + case ImportReplace: + fd->setCaption(tr("Import: Replace selection with vym map")); + break; + } + fd->show(); + + QString fn; + if ( fd->exec() == QDialog::Accepted ) + { + lastFileDir=fd->dirPath(); + fn = fd->selectedFile(); + fileLoad(fn, lmode); + } +} + +void Main::fileLoad() +{ + fileLoad (NewMap); +} + +void Main::fileLoadLast(int i) +{ + fileLoad(*lastMaps.at(lastMapsMenu->indexOf (i) ),NewMap); +} + +void Main::fileSave(const SaveMode &savemode) +{ + // tmp dir for zipping + QString tmpMapDir; + + // Error codes + enum errorCode {success,aborted}; + errorCode err=success; + + QString safeFilePath; + + bool saveZipped=currentMapEditor()->saveZipped(); + + if (currentMapEditor()) + { + QString fn=currentMapEditor()->getFilePath(); + // filename=unnamed, filepath="" in constructor... + if ( !fn.isEmpty() ) + { + // We have a filepath, go on saving + // First remove existing file, we + // don't want to add to old zip archives + QFile f(fn); + if (f.exists() ) + if (!f.remove()) + QMessageBox::warning( 0, tr( "Save Error" ), + fn+ tr("\ncould not be removed before saving")); + + // Look, if we should zip the data: + if (!saveZipped) + { + QMessageBox mb( "VYM", + tr("The map ") + fn + + tr ("\ndid not use the compressed " + "vym file format.\nWriting it uncompressed will also write images \n" + "and flags and thus may overwrite files in the " + "given directory\n\nDo you want to write the map"), + QMessageBox::Warning, + QMessageBox::Yes | QMessageBox::Default, + QMessageBox::No , + QMessageBox::Cancel | QMessageBox::Escape); + mb.setButtonText( QMessageBox::Yes, tr("compressed (vym default)") ); + mb.setButtonText( QMessageBox::No, tr("uncompressed") ); + mb.setButtonText( QMessageBox::Cancel, tr("Cancel")); + switch( mb.exec() ) + { + case QMessageBox::Yes: + // save compressed (default file format) + saveZipped=true; + break; + case QMessageBox::No: + // save uncompressed + saveZipped=false; + break; + case QMessageBox::Cancel: + // do nothing + return; + break; + } + } + + if (saveZipped) + { + char tmpdir1[]="/tmp/vym-XXXXXX"; + tmpMapDir=mkdtemp(tmpdir1); + + safeFilePath=currentMapEditor()->getFilePath(); + currentMapEditor()->setFilePath (tmpMapDir+"/"+ + currentMapEditor()->getMapName()+ ".xml", + safeFilePath); + currentMapEditor()->save (savemode); + currentMapEditor()->setFilePath (safeFilePath); + + // zip the temporary directory + Process *zipProc=new Process (); + zipProc->clearArguments(); + zipProc->setWorkingDirectory (QDir(tmpMapDir)); + zipProc->addArgument ("zip"); + zipProc->addArgument ("-r"); + zipProc->addArgument (fn); + zipProc->addArgument ("."); + + if (!zipProc->start() ) + { + // zip could not be started + QMessageBox::critical( 0, tr( "Critical Save Error" ), + tr("Couldn't start zip to compress data.")); + err=aborted; + } else + { + // zip could be started + zipProc->waitFinished(); + if (!zipProc->normalExit() ) + { + QMessageBox::critical( 0, tr( "Critical Save Error" ), + tr("zip didn't exit normally")+ + "\n" + zipProc->getErrout()); + err=aborted; + } else + { + if (zipProc->exitStatus()>0) + { + QMessageBox::critical( 0, tr( "Critical Save Error" ), + QString("zip exit code: %1").arg(zipProc->exitStatus() )+ + "\n" + zipProc->getErrout() ); + err=aborted; + } + } + } // zip could be started + } // save zipped + else + { + // Save unzipped. + safeFilePath=currentMapEditor()->getFilePath(); + currentMapEditor()->setFilePath (fn, safeFilePath); + currentMapEditor()->save (savemode); + currentMapEditor()->setFilePath (safeFilePath); + } // save zipped + } // filepath available + else + { + // We have no filepath yet, + // call fileSaveAs() now, this will call fileSave() + // again. + fileSaveAs(savemode); + } + } + + if (currentMapEditor()->saveZipped()) + { + // Delete tmpDir + system ( "rm -rf "+ tmpMapDir ); + } + + if (err==success) + statusBar()->message( + tr("Saved")+" " + currentMapEditor()->getFilePath(), + statusbarTime ); + else + statusBar()->message( + tr("Couldn't save")+" " + currentMapEditor()->getFilePath(), + statusbarTime ); +} + +void Main::fileSave() +{ + fileSave (CompleteMap); +} + +void Main::fileSaveAs(const SaveMode& savemode) +{ + QString tmpMapDir; + QString fn; + + if (currentMapEditor()) + { + if (savemode==CompleteMap) + fn = QFileDialog::getSaveFileName( QString::null, "VYM map (*.vym)", this ); + else + fn = QFileDialog::getSaveFileName( QString::null, "VYM part of map (*.vyp)", this ); + if ( !fn.isEmpty() ) + { + // Check for existing file + if (QFile (fn).exists()) + { + QMessageBox mb( "VYM", + tr("The file ") + fn + tr ("\nexists already. Do you want to"), + QMessageBox::Warning, + QMessageBox::Yes | QMessageBox::Default, + QMessageBox::Cancel | QMessageBox::Escape, + QMessageBox::QMessageBox::NoButton); + mb.setButtonText( QMessageBox::Yes, tr("Overwrite") ); + mb.setButtonText( QMessageBox::Cancel, tr("Cancel")); + switch( mb.exec() ) + { + case QMessageBox::Yes: + // save + break; + case QMessageBox::Cancel: + // do nothing + return; + break; + } + } else + { + // New file, add extension to filename, if missing + // This is always .vym or .vyp, depending on savemode + if (savemode==CompleteMap) + { + if (!fn.contains (".vym") && !fn.contains (".xml")) + fn +=".vym"; + } else + { + if (!fn.contains (".vyp") && !fn.contains (".xml")) + fn +=".vyp"; + } + } + + + + + // Save now + currentMapEditor()->setFilePath(fn); + fileSave(savemode); + + // Set name of tab + tabWidget->setTabLabel (currentMapEditor(), + currentMapEditor()->getFileName() ); + return; + } + } +} + +void Main::fileSaveAs() +{ + fileSaveAs (CompleteMap); +} + +void Main::fileImportDir() +{ + if (currentMapEditor()) + currentMapEditor()->importDir(); +} + +void Main::fileExportXML() +{ + if (currentMapEditor()) + { + QString dir=browseDirectory(tr("Export XML to directory")); + if (dir !="" && reallyWriteDirectory(dir) ) + currentMapEditor()->exportXML(dir); + } +} + +void Main::fileExportHTML() +{ + if (currentMapEditor()) + { + ExportHTMLDialog dia(this); + + if (dia.exec()==QDialog::Accepted) + { + QString dir=dia.getDir(); + if (reallyWriteDirectory(dir) ) + { + currentMapEditor()->exportXML (dia.getDir() ); + dia.doExport(currentMapEditor()->getMapName() ); + } + } + } +} + +void Main::fileExportXHTML() +{ + QString dir; + if (currentMapEditor()) + { + ExportXHTMLDialog dia(this); + dia.setFilePath (currentMapEditor()->getFilePath() ); + dia.setMapName (currentMapEditor()->getMapName() ); + dia.readSettings(); + + if (dia.exec()==QDialog::Accepted) + { + QString dir=dia.getDir(); + // Check, if warnings should be used before overwriting + // the output directory + bool ok; + if (dia.warnings()) + ok=reallyWriteDirectory(dir); + else + ok=true; + + if (ok) + { + currentMapEditor()->exportXML (dia.getDir() ); + dia.doExport(currentMapEditor()->getMapName() ); + if (dia.hasChanged()) + currentMapEditor()->setChanged(); + } + } + } +} + +void Main::fileExportImage(int item) +{ + if (currentMapEditor()) + { + QString fn = QFileDialog::getSaveFileName( QString::null, "Image (*.bmp *.jpg *.pbm *.pgm *.png *.ppm *xbm *.xpm)", + this ); + if ( !fn.isEmpty() ) + { + currentMapEditor()->exportImage(fn,item); + } else { + statusBar()->message( tr("Couldn't save") + fn, statusbarTime ); + } + } +} + +void Main::fileExportASCII() +{ + if (currentMapEditor()) + currentMapEditor()->exportASCII(); +} + +void Main::fileCloseMap() +{ + if (currentMapEditor()) + { + if (currentMapEditor()->hasChanged()) + { + QMessageBox mb( "VYM", + tr("The map ") + currentMapEditor()->getFileName() + + tr(" has been modified but not saved yet. Do you want to"), + QMessageBox::Warning, + QMessageBox::Yes | QMessageBox::Default, + QMessageBox::No, + QMessageBox::Cancel | QMessageBox::Escape ); + mb.setButtonText( QMessageBox::Yes, tr("Save modified map before closing it") ); + mb.setButtonText( QMessageBox::No, tr("Discard changes")); + switch( mb.exec() ) + { + case QMessageBox::Yes: + // save and close + fileSave(CompleteMap); + break; + case QMessageBox::No: + // close without saving + break; + case QMessageBox::Cancel: + // do nothing + return; + } + } + currentMapEditor()->closeMap(); + tabWidget->removePage(currentMapEditor()); + if (tabWidget->count()==0) + actionFilePrint->setEnabled (false); + } +} + +void Main::filePrint() +{ + if (currentMapEditor()) + currentMapEditor()->print(); +} + +void Main::fileExitVYM() +{ + // Check if one or more editors have changed + MapEditor *me; + int i; + for (i=0;i<=tabWidget->count() -1;i++) + { + + me=(MapEditor*)tabWidget->page(i); + + // If something changed, ask what to do + if (me->isUnsaved()) + { + tabWidget->setCurrentPage(i); + QMessageBox mb( "VYM", + tr("This map is not saved yet. Do you want to"), + QMessageBox::Warning, + QMessageBox::Yes | QMessageBox::Default, + QMessageBox::No, + QMessageBox::Cancel | QMessageBox::Escape ); + mb.setButtonText( QMessageBox::Yes, tr("Save map") ); + mb.setButtonText( QMessageBox::No, tr("Discard changes") ); + mb.show(); + // Call undocumented function: setActiveWindow is only + // possible, if widget is visible. This depends on + // windowmanager... +#if defined(Q_OS_LINUX) + qt_wait_for_window_manager( this); +#endif + mb.setActiveWindow(); + switch( mb.exec() ) { + case QMessageBox::Yes: + // save (the changed editors) and exit + fileSave(CompleteMap); + break; + case QMessageBox::No: + // exit without saving + break; + case QMessageBox::Cancel: + // don't save and don't exit + return; + } + } + } // loop over all MEs + qApp->quit(); +} + +void Main::editUndo() +{ + if (currentMapEditor()) + currentMapEditor()->undo(); +} + +void Main::editRedo() // TODO +{ +} + +void Main::editCopy() +{ + if (currentMapEditor()) + currentMapEditor()->copy(); +} + +void Main::editPaste() +{ + if (currentMapEditor()) + currentMapEditor()->paste(); +} + +void Main::editCut() +{ + if (currentMapEditor()) + currentMapEditor()->cut(); +} + +void Main::editOpenFindWindow() +{ + findWindow->popup(); + findWindow->raise(); + + // Call undocumented function: setActiveWindow is only + // possible, if widget is visible. This depends on + // windowmanager... +#if defined(Q_OS_LINUX) + qt_wait_for_window_manager( this); +#endif + findWindow->setActiveWindow(); +} + +void Main::editFind(QString s) +{ + bool cs=false; + BranchObj *bo=currentMapEditor()->findText(s, cs); + if (bo) + { + statusBar()->message( "Found: " + bo->getHeading(), statusbarTime ); + } else + { + QMessageBox::information( findWindow, tr( "VYM -Information:" ), + tr("No matches found for ")+ + "'"+s+"'"); + } +} + +void Main::editFindChanged() +{ // Notify editor, to abort the current find process + currentMapEditor()->findReset(); +} + +void Main::editOpenURL() +{ + if (currentMapEditor()) + currentMapEditor()->openURL(); +} + +void Main::editURL() +{ + if (currentMapEditor()) + currentMapEditor()->editURL(); +} + +void Main::editHeading2URL() +{ + if (currentMapEditor()) + currentMapEditor()->editHeading2URL(); +} + +void Main::editBugzilla2URL() +{ + if (currentMapEditor()) + currentMapEditor()->editBugzilla2URL(); +} + +void Main::editOpenVymLink() +{ + // Get current path to map + QString currentVymLink; + if (currentMapEditor()) + { + currentVymLink=currentMapEditor()->getVymLink(); + // compare path with already loaded maps + int index=-1; + int i; + MapEditor *me; + for (i=0;i<=tabWidget->count() -1;i++) + { + me=(MapEditor*)tabWidget->page(i); + if (currentVymLink==me->getFilePath() ) + { + index=i; + break; + } + } + if (index<0) + // Load map + { + if (!QFile(currentVymLink).exists() ) + QMessageBox::critical( 0, tr( "Critical Error" ), + tr("Couldn't open map " +currentVymLink)+"."); + else + { + fileLoad (currentVymLink, NewMap); + tabWidget->setCurrentPage (tabWidget->count()-1); + } + } else + // Go to tab containing the map + tabWidget->setCurrentPage (index); + } +} + +void Main::editVymLink() +{ + if (currentMapEditor()) + currentMapEditor()->editVymLink(); +} + +void Main::editDeleteVymLink() +{ + if (currentMapEditor()) + currentMapEditor()->deleteVymLink(); +} + +void Main::editMapInfo() +{ + if (currentMapEditor()) + currentMapEditor()->editMapInfo(); +} + +void Main::editMoveUp() +{ + if (currentMapEditor()) + currentMapEditor()->moveBranchUp(); +} + +void Main::editMoveDown() +{ + if (currentMapEditor()) + currentMapEditor()->moveBranchDown(); +} + +void Main::editToggleScroll() +{ + if (currentMapEditor()) + { + currentMapEditor()->toggleScroll(); + } +} + +void Main::editUnScrollAll() +{ + if (currentMapEditor()) + { + currentMapEditor()->unScrollAll(); + } +} + +void Main::editHeading() +{ + if (currentMapEditor()) + currentMapEditor()->editHeading(); +} + +void Main::editNewBranch() +{ + if (currentMapEditor()) + currentMapEditor()->addNewBranch(0); +} + +void Main::editNewBranchAbove() +{ + if (currentMapEditor()) + currentMapEditor()->addNewBranch(-1); +} + +void Main::editNewBranchBelow() +{ + if (currentMapEditor()) + currentMapEditor()->addNewBranch(1); +} + +void Main::editImportAdd() +{ + fileLoad (ImportAdd); +} + +void Main::editImportReplace() +{ + fileLoad (ImportReplace); +} + +void Main::editSaveBranch() +{ + fileSaveAs (PartOfMap); +} + +void Main::editDeleteSelection() +{ + if (currentMapEditor()) + currentMapEditor()->deleteSelection(); +} + +void Main::editUpperBranch() +{ + if (currentMapEditor()) + currentMapEditor()->selectUpperBranch(); +} + +void Main::editLowerBranch() +{ + if (currentMapEditor()) + currentMapEditor()->selectLowerBranch(); +} + +void Main::editLeftBranch() +{ + if (currentMapEditor()) + currentMapEditor()->selectLeftBranch(); +} + +void Main::editRightBranch() +{ + if (currentMapEditor()) + currentMapEditor()->selectRightBranch(); +} + +void Main::editFirstBranch() +{ + if (currentMapEditor()) + currentMapEditor()->selectFirstBranch(); +} + +void Main::editLastBranch() +{ + if (currentMapEditor()) + currentMapEditor()->selectLastBranch(); +} + +void Main::editLoadImage() +{ + if (currentMapEditor()) + currentMapEditor()->loadFloatImage(); +} + +void Main::editSaveImage(int item) +{ + if (currentMapEditor()) + currentMapEditor()->saveFloatImage(item); +} + +void Main::editToggleFloatExport() +{ + if (currentMapEditor()) + currentMapEditor()->toggleFloatExport(); +} + +void Main::formatSelectColor() +{ + if (currentMapEditor()) + { + QColor col = QColorDialog::getColor( currentMapEditor()->color(), this ); + if ( !col.isValid() ) return; + currentMapEditor()->setColor( col ); + colorChanged( col ); + } +} + +void Main::formatPickColor() +{ + if (currentMapEditor()) + colorChanged( currentMapEditor()->pickColor() ); +} + +void Main::colorChanged(QColor c) +{ + QPixmap pix( 16, 16 ); + pix.fill( c ); + actionFormatColor->setIconSet( pix ); +} + +void Main::formatColorItem() +{ + if (currentMapEditor()) + currentMapEditor()->colorItem(); +} + +void Main::formatColorBranch() +{ + if (currentMapEditor()) + currentMapEditor()->colorBranch(); +} + +void Main::formatLinkStyleLine() +{ + if (currentMapEditor()) + currentMapEditor()->setLinkStyle(StyleLine); +} + +void Main::formatLinkStyleParabel() +{ + if (currentMapEditor()) + currentMapEditor()->setLinkStyle(StyleParabel); +} + +void Main::formatLinkStylePolyLine() +{ + if (currentMapEditor()) + currentMapEditor()->setLinkStyle(StylePolyLine); +} + +void Main::formatLinkStylePolyParabel() +{ + if (currentMapEditor()) + currentMapEditor()->setLinkStyle(StylePolyParabel); +} + +void Main::formatSelectBackColor() +{ + if (currentMapEditor()) + currentMapEditor()->selectBackgroundColor(); +} + +void Main::formatSelectLinkColor() +{ + if (currentMapEditor()) + currentMapEditor()->selectLinkColor(); +} + +void Main::formatToggleLinkColorHint() +{ + currentMapEditor()->toggleLinkColorHint(); +} + +void Main::formatFrameNone() +{ + if (currentMapEditor()) + currentMapEditor()->setFrame(NoFrame); +} + +void Main::formatFrameRectangle() +{ + if (currentMapEditor()) + currentMapEditor()->setFrame(Rectangle); +} + +void Main::viewZoomReset() +{ + if (currentMapEditor()) + { + QWMatrix m; + m.reset(); + currentMapEditor()->setWorldMatrix( m ); + currentMapEditor()->setViewCenter(); + currentMapEditor()->adjustCanvasSize(); + } +} + +void Main::viewZoomIn() +{ + if (currentMapEditor()) + { + QWMatrix m = currentMapEditor()->worldMatrix(); + m.scale( 1.25, 1.25 ); + currentMapEditor()->setWorldMatrix( m ); + currentMapEditor()->setViewCenter(); + currentMapEditor()->adjustCanvasSize(); + } +} + +void Main::viewZoomOut() +{ + if (currentMapEditor()) + { + QWMatrix m = currentMapEditor()->worldMatrix(); + m.scale( 0.8, 0.8 ); + currentMapEditor()->setWorldMatrix( m ); + currentMapEditor()->setViewCenter(); + currentMapEditor()->adjustCanvasSize(); + } +} +bool Main::settingsPDF() +{ + // Default browser is set in constructor + bool ok; + QString text = QInputDialog::getText( + "VYM", tr("Enter path for pdf reader:"), QLineEdit::Normal, + settings.readEntry("/vym/mainwindow/readerPDF"), &ok, this ); + if (ok) + settings.writeEntry ("/vym/mainwindow/readerPDF",text); + return ok; +} + + +bool Main::settingsURL() +{ + // Default browser is set in constructor + bool ok; + QString text = QInputDialog::getText( + "VYM", tr("Enter path for application to open an URL:"), QLineEdit::Normal, + settings.readEntry("/vym/mainwindow/readerURL") + , &ok, this ); + if (ok) + settings.writeEntry ("/vym/mainwindow/readerURL",text); + return ok; +} + +void Main::windowToggleNoteEditor() +{ + if (textEditor->showWithMain() ) + windowHideNoteEditor(); + else + windowShowNoteEditor(); +} + +void Main::windowShowNoteEditor() +{ + textEditor->setShowWithMain(true); + textEditor->show(); + actionViewToggleNoteEditor->setOn (true); +} + +void Main::windowHideNoteEditor() +{ + textEditor->setShowWithMain(false); + textEditor->hide(); + actionViewToggleNoteEditor->setOn (false); +} + +void Main::windowNextEditor() +{ + if (tabWidget->currentPageIndex() < tabWidget->count()) + tabWidget->setCurrentPage (tabWidget->currentPageIndex() +1); +} + +void Main::windowPreviousEditor() +{ + if (tabWidget->currentPageIndex() >0) + tabWidget->setCurrentPage (tabWidget->currentPageIndex() -1); +} + +void Main::standardFlagChanged() +{ + currentMapEditor()->toggleStandardFlag(sender()->name()); +} + +void Main::testFunction() +{ + //textEditor->stackUnder(this); + currentMapEditor()->testFunction(); +} + +void Main::testShowClipboard() +{ + clipboardME->show(); +} + +void Main::helpDoc() +{ + QString docpath; + // default path in SUSE LINUX + docpath="/usr/share/doc/packages/vym/doc/vym.pdf"; + + if (!QFile (docpath).exists() ) + { + // relative path for easy testing in tarball + docpath="doc/vym.pdf"; + if (!QFile (docpath).exists() ) + { + // relative path for testing while still writing vym.tex + docpath="doc/tex/vym.pdf"; + if (!QFile (docpath).exists() ) + { + QMessageBox::critical(0, + tr("Critcal error"), + tr("Couldn't find the documentation\n" + "vym.pdf in various places.")); + return; + } + } + } + + Process *pdfProc = new Process(); + pdfProc->clearArguments(); + pdfProc->addArgument( settings.readEntry("/vym/mainwindow/readerPDF")); + pdfProc->addArgument( docpath); + + if ( !pdfProc->start() ) + { + // error handling + QMessageBox::critical(0, + tr("Critcal error"), + tr("Couldn't find a viewer to read vym.pdf.\n" + "Please use Settings->")+tr("Set application to open pdf files")); + return; + } +} + + +void Main::helpAbout() +{ + static QMessageBox* about = new QMessageBox( "VYM", + "

VYM - View Your Mind

" + "

A tool to put the things you have got in your mind into a map.

" + "
    " + "
  • (c) by Uwe Drechsel (vym@InSilmaril.de)
  • " + "
  • vym is released under the GPL (Gnu General Public License)" + ", with one exception (see the file \"LICENSE\"which " + "comes with vym). This exception is needed to build vym with QT libraries for proprietary operating systems.
  • " + "
  • Project homepage " + "http:/www.InSilmaril.de/vym
  • " + "
  • Credits " + "
      " + "
    • Thomas Schraitle for the stylesheet used for XHTML-export
    • " + "
    • Clemens Kraus for stylesheets and script used for HTML-export " + "(www.clemens-kraus.de)
    • " + "
    • Alexander Johannesen for providing stylesheets from his xsiteable project " + "(www.shelter.nu/xsiteable/xsiteable.html).
    • " + "
    • Ken Wimer and Olaf Hering for Mac support
    • " + "
    " + "
  • " + "
  • Version " __VYM_VERSION__ "
  • " + "
  • Build date " __BUILD_DATE__"
  • " + "
", QMessageBox::Information, 1, 0, 0, this, 0, FALSE ); + about->setButtonText( 1, "Dismiss" ); + about->setMinimumSize(QSize(300,300)); + about->setIconPixmap (QPixmap(vym_logo_xpm)); + about->show(); +} + +void Main::helpAboutQT() +{ + QMessageBox::aboutQt( this, "Qt Application Example" ); +} +