File indexing completed on 2024-05-12 16:23:34

0001 /***************************************************************************
0002  *   Copyright (C) 2005-2017 by Linuxstopmotion contributors;              *
0003  *   see the AUTHORS file for details.                                     *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "mainwindowgui.h"
0021 
0022 #include "logger.h"
0023 #include "src/presentation/frontends/qtfrontend/framebar/framebar.h"
0024 #include "src/presentation/frontends/qtfrontend/frameview.h"
0025 #include "src/presentation/frontends/qtfrontend/flexiblespinbox.h"
0026 #include "src/application/camerahandler.h"
0027 #include "src/application/editmenuhandler.h"
0028 #include "src/application/runanimationhandler.h"
0029 #include "src/application/modelhandler.h"
0030 #include "src/application/languagehandler.h"
0031 #include "src/application/soundhandler.h"
0032 #include "src/presentation/frontends/qtfrontend/framepreferencesmenu.h"
0033 #include "src/presentation/frontends/qtfrontend/preferencesmenu.h"
0034 #include "src/domain/domainfacade.h"
0035 #include "src/foundation/preferencestool.h"
0036 #include "src/technical/video/videoencoder.h"
0037 #include "src/presentation/frontends/qtfrontend/toolsmenu.h"
0038 #include "src/presentation/frontends/qtfrontend/helpwindow.h"
0039 #include "src/presentation/frontends/qtfrontend/aboutdialog.h"
0040 #include "src/presentation/frontends/qtfrontend/editobserver.h"
0041 
0042 #include "graphics/icons/windowicon.xpm"
0043 #include "graphics/icons/configureicon.xpm"
0044 #include "graphics/icons/undoicon.xpm"
0045 #include "graphics/icons/redoicon.xpm"
0046 #include "graphics/icons/cuticon.xpm"
0047 #include "graphics/icons/copyicon.xpm"
0048 #include "graphics/icons/pasteicon.xpm"
0049 #include "graphics/icons/filenewicon.xpm"
0050 #include "graphics/icons/fileopenicon.xpm"
0051 #include "graphics/icons/filesaveicon.xpm"
0052 #include "graphics/icons/filesaveasicon.xpm"
0053 #include "graphics/icons/quiticon.xpm"
0054 #include "graphics/icons/whatsthisicon.xpm"
0055 #include "graphics/icons/close.xpm"
0056 #include "graphics/icons/videoexport.xpm"
0057 #include "graphics/icons/languages.xpm"
0058 
0059 #include <QShortcut>
0060 #include <QPixmap>
0061 #include <QFileDialog>
0062 #include <QMessageBox>
0063 #include <QMimeData>
0064 #include <QWhatsThis>
0065 #include <QFileSystemWatcher>
0066 #include <QClipboard>
0067 
0068 #include <assert.h>
0069 #include <string.h>
0070 #include <unistd.h>
0071 #include <cstdlib>
0072 #include <sstream>
0073 #include <string>
0074 
0075 using namespace std;
0076 using namespace Qt;
0077 
0078 MainWindowGUI::MainWindowGUI(QApplication *stApp)
0079     : stApp(stApp), centerWidget(0), centerWidgetLayout(0), bottomWidget(0),
0080       bottomWidgetLayout(0), workArea(0), workAreaLayout(0),
0081       frameBar(0), frameView(0), gotoMenuWidget(0), gotoMenuWidgetLayout(0),
0082       fileWatcher(0), editObserver(0),
0083       newAct(0), openAct(0), mostRecentAct(0), secondMostRecentAct(0),
0084       thirdMostRecentAct(0), saveAct(0), saveAsAct(0), videoAct(0), cinerellaAct(0),
0085       quitAct(0), undoAct(0), redoAct(0), cutAct(0), copyAct(0), pasteAct(0),
0086       gotoFrameAct(0), configureAct(0), whatsthisAct(0), aboutAct(0),
0087       helpAct(0),
0088       fileMenu(0), exportMenu(0), mostRecentMenu(0), editMenu(0),
0089       settingsMenu(0), languagesMenu(0), helpMenu(0), toolsMenu(0),
0090       framePreferencesMenu(0), preferencesMenu(0),
0091       gotoMenuCloseButton(0), numberDisplay(0), gotoSpinner(0),
0092       gotoFrameLabel(0),
0093       modelHandler(0), soundHandler(0), cameraHandler(0), editMenuHandler(0),
0094       languageHandler(0), runAnimationHandler(0),
0095       lastVisitedDir(getenv("PWD")) {
0096 
0097     centerWidget = new QWidget;
0098     centerWidget->setObjectName("CenterWidget");
0099     centerWidgetLayout = new QVBoxLayout;
0100     centerWidgetLayout->setSpacing(5);
0101     centerWidgetLayout->setContentsMargins(0, 0, 0, 0);
0102 
0103     frameBar = new FrameBar;
0104     centerWidgetLayout->addWidget(frameBar);
0105 }
0106 
0107 
0108 void MainWindowGUI::ConstructUI() {
0109     createHandlers(stApp);
0110     createAccelerators();
0111     bottomWidget = new QWidget;
0112     bottomWidget->setObjectName("BottomWidget");
0113     centerWidgetLayout->addWidget(bottomWidget);
0114     bottomWidgetLayout = new QVBoxLayout;
0115     bottomWidgetLayout->setSpacing(0);
0116     bottomWidgetLayout->setContentsMargins(0, 0, 0, 0);
0117     makePreferencesMenu(bottomWidgetLayout);
0118     //Initializes and sets up the workarea consisting of the toolsmenu and the frameview.
0119     workArea = new QWidget;
0120     workArea->setObjectName("WorkArea");
0121     bottomWidgetLayout->addWidget(workArea);
0122     bottomWidget->setLayout(bottomWidgetLayout);
0123     workAreaLayout = new QHBoxLayout;
0124     workAreaLayout->setObjectName("WorkAreaLayout");
0125     workAreaLayout->setSpacing(5);
0126     workAreaLayout->setContentsMargins(0, 0, 0, 0);
0127     makeToolsMenu(workAreaLayout);
0128     makeViews(workAreaLayout);
0129     workArea->setLayout(workAreaLayout);
0130     connect(runAnimationHandler, SIGNAL(playFrame(int,int)), frameView,
0131             SLOT(updatePlayFrame(int,int)));
0132     connect(frameBar, SIGNAL(newActiveFrame(int,int)), runAnimationHandler,
0133             SLOT(stopAnimation()));
0134     makeGotoMenu(centerWidgetLayout);
0135     centerWidget->setLayout(centerWidgetLayout);
0136     setCentralWidget(centerWidget);
0137     makeStatusBar();
0138     //Initializes and sets up the menu system.
0139     createActions();
0140     createMenus();
0141     //These slots will activate/deactivate menu options based on the changes in the model.
0142     connect(frameBar, SIGNAL(modelSizeChanged(int)), this,
0143             SLOT(modelSizeChanged(int)));
0144     connect(frameBar, SIGNAL(newActiveFrame(int, int)), this,
0145             SLOT(updateNewActiveFrame(int, int)));
0146     // update paste menu item depending on what's on the clipboard
0147     connect(QApplication::clipboard(), SIGNAL(dataChanged()), this,
0148             SLOT(updatePasteEnabled()));
0149     setupDirectoryMonitoring();
0150     //Mainwindow preferences.
0151     setWindowIcon(QPixmap(windowicon));
0152     setContentsMargins(5, 0, 5, 0);
0153     setAcceptDrops(true);
0154     statusBar()->showMessage(tr("Ready to rumble ;-)"), 2000);
0155     statusBar()->setSizeGripEnabled(false);
0156 
0157     retranslateStrings();
0158 
0159     DomainFacade* facade = DomainFacade::getFacade();
0160     setTitle(facade->canUndo());
0161     facade->setUndoRedoObserver(this);
0162 }
0163 
0164 
0165 MainWindowGUI::~MainWindowGUI() {
0166     delete editObserver;
0167 }
0168 
0169 
0170 void MainWindowGUI::createHandlers(QApplication *stApp) {
0171     languageHandler = new LanguageHandler( this, stApp );
0172     connect( languageHandler, SIGNAL(languageChanged()), this, SLOT(retranslateStrings()) );
0173 
0174     runAnimationHandler = new RunAnimationHandler(this, statusBar(), frameBar);
0175     connect(runAnimationHandler, SIGNAL(stopped(int, int, int)),
0176             frameBar, SLOT(setSelection(int, int, int)));
0177 
0178     modelHandler = new ModelHandler( this, this->statusBar(), frameBar, &lastVisitedDir );
0179     connect( modelHandler, SIGNAL(modelChanged()), this, SLOT(activateMenuOptions()) );
0180 
0181     cameraHandler = new CameraHandler( this, this->statusBar(), modelHandler );
0182 
0183     editMenuHandler = new EditMenuHandler( this, this->statusBar(), frameBar );
0184     connect( editMenuHandler, SIGNAL(addFrames(const QStringList &)),
0185             modelHandler, SLOT(addFrames(const QStringList &)) );
0186     connect(editMenuHandler, SIGNAL(removeFrames()),
0187             modelHandler, SLOT(removeFrames()));
0188     connect(editMenuHandler, SIGNAL(undoOrRedo()),
0189             this, SLOT(activateMenuOptions()));
0190 
0191     soundHandler = new SoundHandler( this, this->statusBar(), frameBar,
0192             this->lastVisitedDir.toLocal8Bit() );
0193 }
0194 
0195 
0196 void MainWindowGUI::setupDirectoryMonitoring() {
0197     fileWatcher = new QFileSystemWatcher(this);
0198     editObserver = new EditObserver(fileWatcher);
0199     connect(fileWatcher, SIGNAL(fileChanged(const QString&)),
0200             frameBar, SLOT(fileChanged(const QString&)));
0201     connect(fileWatcher, SIGNAL(fileChanged(const QString&)),
0202             frameView, SLOT(fileChanged(const QString&)));
0203     DomainFacade::getFacade()->attach(editObserver);
0204 }
0205 
0206 
0207 void MainWindowGUI::createAccelerators()
0208 {
0209     QShortcut *nextFrameAccel = new QShortcut(QKeySequence(Qt::Key_L), this);
0210     connect(nextFrameAccel, SIGNAL(activated()), frameBar, SLOT(selectNextFrame()));
0211     QShortcut *nextFrameAccel2 = new QShortcut(QKeySequence(Qt::Key_Right), this);
0212     connect(nextFrameAccel2, SIGNAL(activated()), frameBar, SLOT(selectNextFrame()));
0213     QShortcut *nextFrameSelectionAccel = new QShortcut(
0214             QKeySequence(Qt::ShiftModifier | Qt::Key_L), this);
0215     connect(nextFrameSelectionAccel, SIGNAL(activated()),
0216             frameBar, SLOT(moveSelectionToNextFrame()));
0217     QShortcut *nextFrameSelectionAccel2 = new QShortcut(
0218             QKeySequence(Qt::ShiftModifier | Qt::Key_Right), this);
0219     connect(nextFrameSelectionAccel2, SIGNAL(activated()),
0220             frameBar, SLOT(moveSelectionToNextFrame()));
0221 
0222     QShortcut *previousFrameAccel = new QShortcut(QKeySequence(Qt::Key_J), this);
0223     connect(previousFrameAccel, SIGNAL(activated()), frameBar, SLOT(selectPreviousFrame()));
0224     QShortcut *previousFrameAccel2 = new QShortcut(QKeySequence(Qt::Key_Left), this );
0225     connect(previousFrameAccel2, SIGNAL(activated()), frameBar, SLOT(selectPreviousFrame()));
0226     QShortcut *previousFrameSelectionAccel = new QShortcut(
0227             QKeySequence(Qt::ShiftModifier | Qt::Key_J), this);
0228     connect(previousFrameSelectionAccel, SIGNAL(activated()),
0229             frameBar, SLOT(moveSelectionToPreviousFrame()));
0230     QShortcut *previousFrameSelectionAccel2 = new QShortcut(
0231             QKeySequence(Qt::ShiftModifier | Qt::Key_Left), this);
0232     connect(previousFrameSelectionAccel2, SIGNAL(activated()),
0233             frameBar, SLOT(moveSelectionToPreviousFrame()));
0234 
0235     QShortcut *nextSceneAccel = new QShortcut(QKeySequence(Qt::Key_O), this);
0236     connect(nextSceneAccel, SIGNAL(activated()), frameBar, SLOT(selectNextScene()));
0237 
0238     QShortcut *prevSceneAccel = new QShortcut(QKeySequence(Qt::Key_I), this);
0239     connect(prevSceneAccel, SIGNAL(activated()), frameBar, SLOT(selectPreviousScene()));
0240 
0241     QShortcut *toggleCameraAccel = new QShortcut(QKeySequence(Qt::Key_C), this);
0242     connect(toggleCameraAccel, SIGNAL(activated()), cameraHandler, SLOT(toggleCamera()));
0243 
0244     QShortcut *captureAccel = new QShortcut(QKeySequence(Qt::Key_Space), this);
0245     connect(captureAccel, SIGNAL(activated()), cameraHandler, SLOT(captureFrame()));
0246 
0247     QShortcut *addFrameAccel = new QShortcut(QKeySequence(Qt::Key_F), this);
0248     connect(addFrameAccel, SIGNAL(activated()), modelHandler, SLOT(chooseFrame()));
0249 
0250     QShortcut *newSceneAccel = new QShortcut(QKeySequence(Qt::ControlModifier | Qt::Key_E), this);
0251     connect(newSceneAccel, SIGNAL(activated()), modelHandler, SLOT(newScene()));
0252 
0253     QShortcut *removeFramesAccel = new QShortcut(QKeySequence(Qt::Key_Delete), this);
0254     connect(removeFramesAccel, SIGNAL(activated()), modelHandler, SLOT(removeFrames()));
0255 
0256     QShortcut *removeSceneAccel = new QShortcut(QKeySequence(Qt::ShiftModifier | Qt::Key_Delete), this);
0257     connect(removeSceneAccel, SIGNAL(activated()), modelHandler, SLOT(removeScene()));
0258 }
0259 
0260 
0261 void MainWindowGUI::createActions()
0262 {
0263     //File menu
0264     newAct = new QAction(this);
0265     newAct->setIcon(QPixmap(filenewicon));
0266     newAct->setShortcut(QKeySequence(ControlModifier | Key_N));
0267     connect(newAct, SIGNAL(triggered()), this, SLOT(newProject()));
0268 
0269     openAct = new QAction(this);
0270     openAct->setIcon(QPixmap(fileopenicon));
0271     openAct->setShortcut(QKeySequence(ControlModifier | Key_O));
0272     connect(openAct, SIGNAL(triggered()), this, SLOT(openProject()));
0273 
0274     mostRecentAct = new QAction(this);
0275     mostRecentAct->setIcon(QPixmap(windowicon));
0276     connect(mostRecentAct, SIGNAL(triggered()), this, SLOT(openMostRecent()));
0277 
0278     secondMostRecentAct = new QAction(this);
0279     secondMostRecentAct->setIcon(QPixmap(windowicon));
0280     connect(secondMostRecentAct, SIGNAL(triggered()), this, SLOT(openSecondMostRecent()));
0281 
0282     thirdMostRecentAct = new QAction(this);
0283     thirdMostRecentAct->setIcon(QPixmap(windowicon));
0284     connect(thirdMostRecentAct, SIGNAL(triggered()), this, SLOT(openThirdMostRecent()));
0285 
0286     saveAct = new QAction(this);
0287     saveAct->setIcon(QPixmap(filesaveasicon));
0288     saveAct->setShortcut(QKeySequence(ControlModifier | Key_S));
0289     connect(saveAct, SIGNAL(triggered()), this, SLOT(saveProject()));
0290 
0291     saveAsAct = new QAction(this);
0292     saveAsAct->setIcon(QPixmap(filesaveicon));
0293     saveAsAct->setShortcut(QKeySequence(ControlModifier | ShiftModifier | Key_S));
0294     connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveProjectAs()));
0295 
0296     videoAct = new QAction(this);
0297     videoAct->setShortcut(QKeySequence(ControlModifier | AltModifier | Key_V));
0298     videoAct->setIcon(QPixmap(videoexport));
0299     connect(videoAct, SIGNAL(triggered()), this, SLOT(exportToVideo()));
0300 
0301     cinerellaAct = new QAction(this);
0302     cinerellaAct->setShortcut(QKeySequence(ControlModifier | AltModifier | Key_C));
0303     cinerellaAct->setEnabled(false);
0304     connect(cinerellaAct, SIGNAL(triggered()), this, SLOT(exportToCinerella()));
0305 
0306     quitAct = new QAction(this);
0307     quitAct->setIcon(QPixmap(quiticon));
0308     quitAct->setShortcut(QKeySequence(ControlModifier | Key_Q));
0309     connect(quitAct, SIGNAL(triggered()), stApp, SLOT(quit()));
0310 
0311     //Edit menu
0312     undoAct = new QAction(this);
0313     undoAct->setIcon(QPixmap(undoicon));
0314     undoAct->setShortcut(QKeySequence(ControlModifier | Key_Z));
0315     connect(undoAct, SIGNAL(triggered()), editMenuHandler, SLOT(undo()));
0316 
0317     redoAct = new QAction(this);
0318     redoAct->setIcon(QPixmap(redoicon));
0319     redoAct->setShortcut(QKeySequence(ControlModifier | ShiftModifier | Key_Z));
0320     connect(redoAct, SIGNAL(triggered()), editMenuHandler, SLOT(redo()));
0321 
0322     cutAct = new QAction(this);
0323     cutAct->setIcon(QPixmap(cuticon));
0324     cutAct->setShortcut(QKeySequence(ControlModifier | Key_X));
0325     connect(cutAct, SIGNAL(triggered()), editMenuHandler, SLOT(cut()));
0326 
0327     copyAct = new QAction(this);
0328     copyAct->setIcon(QPixmap(copyicon));
0329     copyAct->setShortcut(QKeySequence(ControlModifier | Key_C));
0330     connect(copyAct, SIGNAL(triggered()), editMenuHandler, SLOT(copy()));
0331 
0332     pasteAct = new QAction(this);
0333     pasteAct->setIcon(QPixmap(pasteicon));
0334     pasteAct->setShortcut(QKeySequence(ControlModifier | Key_V));
0335     connect(pasteAct, SIGNAL(triggered()), editMenuHandler, SLOT(paste()));
0336 
0337     gotoFrameAct = new QAction(this);
0338     gotoFrameAct->setShortcut(QKeySequence(ControlModifier | Key_G));
0339     connect(gotoFrameAct, SIGNAL(triggered()), gotoMenuWidget, SLOT(show()));
0340 
0341     configureAct = new QAction(this);
0342     configureAct->setIcon(QPixmap(configureicon));
0343     configureAct->setShortcut(QKeySequence(ControlModifier | Key_P));
0344     connect(configureAct, SIGNAL(triggered()), this, SLOT(showPreferencesMenu()));
0345 
0346     //Help menu
0347     whatsthisAct = new QAction(this);
0348     whatsthisAct->setIcon(QPixmap(whatsthisicon));
0349     whatsthisAct->setShortcut(QKeySequence(ShiftModifier | Key_F1));
0350     connect(whatsthisAct, SIGNAL(triggered()), this, SLOT(whatsThis()));
0351 
0352     helpAct = new QAction(this);
0353     helpAct->setShortcut(QKeySequence(Key_F1));
0354     connect(helpAct, SIGNAL(triggered()), this, SLOT(showHelpDialog()));
0355 
0356     aboutAct = new QAction(this);
0357     aboutAct->setIcon(QPixmap(windowicon));
0358     connect(aboutAct, SIGNAL(triggered()), this, SLOT(showAboutDialog()));
0359 }
0360 
0361 
0362 void MainWindowGUI::createMenus()
0363 {
0364     fileMenu = menuBar()->addMenu(tr("&File"));
0365     exportMenu = fileMenu->addMenu(tr("&Export"));
0366     mostRecentMenu = fileMenu->addMenu(tr("Open &Recent"));
0367 
0368     editMenu = menuBar()->addMenu(tr("&Edit"));
0369     editMenu->addAction(undoAct);
0370     editMenu->addAction(redoAct);
0371     editMenu->addSeparator();
0372     editMenu->addAction(cutAct);
0373     editMenu->addAction(copyAct);
0374     editMenu->addAction(pasteAct);
0375     editMenu->addSeparator();
0376     editMenu->addAction(gotoFrameAct);
0377 
0378     undoAct->setEnabled(false);
0379     redoAct->setEnabled(false);
0380     cutAct->setEnabled(false);
0381     copyAct->setEnabled(false);
0382     updatePasteEnabled();
0383     gotoFrameAct->setEnabled(false);
0384 
0385     settingsMenu = menuBar()->addMenu(tr("&Settings"));
0386     languagesMenu = languageHandler->createLanguagesMenu(settingsMenu);
0387 
0388     helpMenu = menuBar()->addMenu(tr("&Help"));
0389     helpMenu->addAction(whatsthisAct);
0390     helpMenu->addAction(helpAct);
0391     helpMenu->addSeparator();
0392     helpMenu->addAction(aboutAct);
0393 }
0394 
0395 
0396 void MainWindowGUI::makeToolsMenu(QHBoxLayout *layout)
0397 {
0398     toolsMenu = new ToolsMenu(runAnimationHandler, modelHandler, cameraHandler,
0399             frameBar);
0400     layout->addWidget(toolsMenu);
0401 
0402     connect(frameBar, SIGNAL(modelSizeChanged(int)),
0403             toolsMenu, SLOT(fixNavigationButtons(int)));
0404     connect(cameraHandler, SIGNAL(cameraStateChanged(bool)),
0405             toolsMenu, SLOT(cameraOn(bool)));
0406 }
0407 
0408 
0409 void MainWindowGUI::makePreferencesMenu(QVBoxLayout *layout)
0410 {
0411     framePreferencesMenu = new FramePreferencesMenu(0, soundHandler, frameBar);
0412     layout->addWidget(framePreferencesMenu);
0413     frameBar->setPreferencesMenu(framePreferencesMenu);
0414     framePreferencesMenu->hide();
0415 
0416     preferencesMenu = new PreferencesMenu(this);
0417     preferencesMenu->hide();
0418 }
0419 
0420 
0421 void MainWindowGUI::makeGotoMenu(QVBoxLayout *layout)
0422 {
0423     gotoMenuWidget = new QWidget;
0424     gotoMenuWidgetLayout = new QHBoxLayout;
0425     gotoMenuWidgetLayout->setSpacing(5);
0426     gotoMenuWidgetLayout->setContentsMargins(0, 0, 0, 0);
0427 
0428     gotoFrameLabel = new QLabel;
0429 
0430     gotoSpinner = new FlexibleSpinBox;
0431     gotoSpinner->setMaximumWidth(60);
0432     gotoSpinner->setRange(1, 1);
0433 
0434     connect(frameBar, SIGNAL(newActiveFrame(int,int)), gotoSpinner, SLOT(setValue(int)));
0435     connect(frameBar, SIGNAL(modelSizeChanged(int)),
0436             gotoSpinner, SLOT(setMaximumValue(int)));
0437     connect(frameBar, SIGNAL(newMaximumValue(int)), gotoSpinner, SLOT(setMaximumValue(int)));
0438     connect(gotoSpinner, SIGNAL(spinBoxTriggered(int)), editMenuHandler, SLOT(gotoFrame(int)));
0439     connect(gotoSpinner, SIGNAL(spinBoxCanceled()),editMenuHandler, SLOT(closeGotoMenu()));
0440 
0441     gotoMenuCloseButton = new QPushButton;
0442     gotoMenuCloseButton->setIcon(QPixmap(closeicon));
0443     gotoMenuCloseButton->setFlat(true);
0444     gotoMenuCloseButton->setMinimumSize(16, 16);
0445     gotoMenuCloseButton->setMaximumSize(16, 16);
0446     connect(gotoMenuCloseButton, SIGNAL(clicked()), gotoMenuWidget, SLOT(hide()));
0447 
0448     gotoMenuWidgetLayout->addWidget(gotoFrameLabel);
0449     gotoMenuWidgetLayout->addWidget(gotoSpinner);
0450     gotoMenuWidgetLayout->addStretch();
0451     gotoMenuWidgetLayout->addWidget(gotoMenuCloseButton);
0452     gotoMenuWidget->setLayout(gotoMenuWidgetLayout);
0453 
0454     layout->addWidget(gotoMenuWidget);
0455     gotoMenuWidget->hide();
0456     editMenuHandler->setGotoMenu(gotoMenuWidget);
0457 }
0458 
0459 
0460 void MainWindowGUI::makeStatusBar()
0461 {
0462     numberDisplay = new QLabel;
0463     numberDisplay->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
0464     numberDisplay->setContentsMargins(0, 0, 0, 0);
0465     connect(frameBar, SIGNAL(newActiveFrame(const QString &)), numberDisplay, SLOT(setText(const QString &)));
0466     this->statusBar()->addPermanentWidget(numberDisplay);
0467 }
0468 
0469 
0470 void MainWindowGUI::makeViews(QHBoxLayout *layout)
0471 {
0472     frameView = new FrameView;
0473     frameView->setObjectName("FrameView");
0474     frameView->setMinimumSize(400, 300);
0475     frameView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0476     layout->addWidget(frameView);
0477 
0478     connect( frameView, SIGNAL(cameraReady()), cameraHandler, SLOT(switchToVideoView()));
0479     connect(cameraHandler, SIGNAL(capturedFrame()), this, SLOT(activateMenuOptions()));
0480 
0481     cameraHandler->setFrameView(frameView);
0482     connect(frameBar, SIGNAL(newActiveFrame(int,int)),
0483             frameView, SLOT(updateNewActiveFrame(int,int)));
0484     connect(stApp, SIGNAL(aboutToQuit()), frameView, SLOT(off()));
0485 }
0486 
0487 
0488 void MainWindowGUI::retranslateStrings()
0489 {
0490     Logger::get().logDebug("Retranslating strings");
0491 
0492     //The actions caption texts
0493     newAct->setText(tr("&New"));
0494     openAct->setText(tr("&Open"));
0495     saveAct->setText(tr("&Save"));
0496     saveAsAct->setText(tr("Save &As"));
0497     videoAct->setText(tr("Video"));
0498     cinerellaAct->setText(tr("Cinelerra"));
0499     quitAct->setText(tr("&Quit"));
0500     undoAct->setText(tr("&Undo"));
0501     redoAct->setText(tr("Re&do"));
0502     cutAct->setText(tr("Cu&t"));
0503     copyAct->setText(tr("&Copy"));
0504     pasteAct->setText(tr("&Paste"));
0505     gotoFrameAct->setText(tr("&Go to frame"));
0506     configureAct->setText(tr("&Configure Stopmotion"));
0507     whatsthisAct->setText(tr("What's &This"));
0508     helpAct->setText(tr("&Help"));
0509     aboutAct->setText(tr("&About"));
0510 
0511     //Other widgets
0512     numberDisplay->setText(tr("Frame number: ") +
0513             QString("%1").arg(frameBar->getActiveFrame() + 1));
0514     gotoFrameLabel->setText(tr("Go to frame:"));
0515 
0516     //Tooltip and whatsthis texts
0517     retranslateHelpText();
0518 
0519     //The menus
0520     menuBar()->clear();
0521     menuBar()->addMenu(fileMenu);
0522 
0523     fileMenu->clear();
0524     fileMenu->setTitle(tr("&File"));
0525     fileMenu->addAction(newAct);
0526     fileMenu->addAction(openAct);
0527     fileMenu->addMenu(mostRecentMenu);
0528 
0529     createMostRecentMenu();
0530 
0531     fileMenu->addSeparator();
0532     fileMenu->addAction(saveAct);
0533     fileMenu->addAction(saveAsAct);
0534     fileMenu->addMenu(exportMenu);
0535 
0536     exportMenu->clear();
0537     exportMenu->setTitle(tr("&Export"));
0538     exportMenu->addAction(videoAct);
0539     exportMenu->addAction(cinerellaAct);
0540 
0541     fileMenu->addSeparator();
0542     fileMenu->addAction(quitAct);
0543 
0544     menuBar()->addMenu(editMenu);
0545     menuBar()->addMenu(settingsMenu);
0546 
0547     settingsMenu->clear();
0548     settingsMenu->setTitle(tr("&Settings"));
0549     languagesMenu->setIcon(QPixmap(languages));
0550     settingsMenu->addMenu(languagesMenu);
0551     settingsMenu->addAction(configureAct);
0552 
0553     editMenu->setTitle(tr("&Edit"));
0554 
0555     helpMenu->setTitle(tr("&Help"));
0556     menuBar()->addMenu(helpMenu);
0557 
0558     //The submenus
0559     toolsMenu->retranslateStrings();
0560     framePreferencesMenu->retranslateStrings();
0561     preferencesMenu->retranslateStrings();
0562 }
0563 
0564 
0565 void MainWindowGUI::retranslateHelpText()
0566 {
0567     QString infoText;
0568 
0569     //File menu
0570     infoText =
0571             tr("<h4>New</h4> "
0572             "<p>Creates a <em>new</em> project.</p>");
0573     newAct->setWhatsThis(infoText);
0574     //The prepend part is a trick to keep the accelerator in the tooltip
0575     infoText =
0576             newAct->toolTip().prepend(tr("New project"));
0577     newAct->setToolTip(infoText);
0578 
0579     infoText =
0580             tr("<h4>Open</h4> "
0581             "<p><em>Opens</em> a Stopmotion project file.</p>");
0582     openAct->setWhatsThis(infoText);
0583     infoText =
0584             openAct->toolTip().prepend(tr("Open project"));
0585     openAct->setToolTip(infoText);
0586 
0587     infoText =
0588             tr("<h4>Save</h4> "
0589             "<p><em>Saves</em> the current animation as a Stopmotion "
0590             "project file. <BR>If this project has been saved before it will "
0591             "automatically be saved to the previously selected file.</p>");
0592     saveAct->setWhatsThis(infoText);
0593     infoText =
0594             saveAct->toolTip().prepend(tr("Save project"));
0595     saveAct->setToolTip(infoText);
0596 
0597     infoText =
0598             tr("<h4>Save As</h4> "
0599             "<p><em>Saves</em> the current animation as a Stopmotion "
0600             "project file.</p>");
0601     saveAsAct->setWhatsThis(infoText);
0602     infoText =
0603             saveAsAct->toolTip().prepend(tr("Save project As"));
0604     saveAsAct->setToolTip(infoText);
0605 
0606     infoText =
0607             tr("<h4>Video</h4> "
0608             "<p>Exports the current project as <em>video</em>.</p>"
0609             "You will be given a wizard to guide you.");
0610     videoAct->setWhatsThis(infoText);
0611     videoAct->setToolTip(infoText);
0612 
0613     infoText =
0614             tr("<h4>Cinerella</h4> "
0615             "<p>Exports the current animation as a <em>Cinerella</em> project.</p>"
0616             "You will be given a wizard to guide you.");
0617     cinerellaAct->setWhatsThis(infoText);
0618     cinerellaAct->setToolTip(infoText);
0619 
0620     infoText =
0621             tr("<h4>Quit</h4> "
0622             "<p><em>Quits</em> the program.</p>");
0623     quitAct->setWhatsThis(infoText);
0624     infoText =
0625             quitAct->toolTip().prepend(tr("Quit"));
0626     quitAct->setToolTip(infoText);
0627 
0628 
0629     //Edit menu
0630     infoText =
0631             tr("<h4>Undo</h4> "
0632             "<p><em>Undoes</em> your last operation. You can press undo "
0633             "several time to undo earlier operations.</p>");
0634     undoAct->setWhatsThis(infoText);
0635     infoText =
0636             undoAct->toolTip().prepend(tr("Undo"));
0637     undoAct->setToolTip(infoText);
0638 
0639     infoText =
0640             tr("<h4>Redo</h4> "
0641             "<p><em>Redoes</em> your last operation. You can press redo "
0642             "several times to redo several operations.</p>");
0643     redoAct->setWhatsThis(infoText);
0644     infoText =
0645             redoAct->toolTip().prepend(tr("Redo"));
0646     redoAct->setToolTip(infoText);
0647 
0648     infoText =
0649             tr("<h4>Cut</h4> "
0650             "<p><em>Cuts</em> the selected frames out of the animation and adds them "
0651             "to the clipboard so that you can paste them in somewhere else.</p>");
0652     cutAct->setWhatsThis(infoText);
0653     infoText =
0654             cutAct->toolTip().prepend(tr("Cut"));
0655     cutAct->setToolTip(infoText);
0656 
0657     infoText =
0658             tr("<h4>Copy</h4> "
0659             "<p><em>Copies</em> the selected frames to the clipboard. You can "
0660             "then paste them in another place.</p>");
0661     copyAct->setWhatsThis(infoText);
0662     infoText =
0663             copyAct->toolTip().prepend(tr("Copy"));
0664     copyAct->setToolTip(infoText);
0665 
0666     infoText =
0667             tr("<h4>Paste</h4> "
0668             "<p><em>Pastes</em> the frames which are currently in the clipboard "
0669             "into the selected location.</p> <p>You can copy/cut images from another "
0670             "programs and then use this option to paste them into this animation.</p>");
0671     pasteAct->setWhatsThis(infoText);
0672     infoText =
0673             pasteAct->toolTip().prepend(tr("Paste"));
0674     pasteAct->setToolTip(infoText);
0675 
0676     infoText =
0677             tr("<h4>Go to frame</h4> "
0678             "<p>This will bring up a popup-menu at the bottom where you can choose "
0679             "a frame you want to <em>go to</em>.</p>");
0680     gotoFrameAct->setWhatsThis(infoText);
0681     infoText =
0682             gotoFrameAct->toolTip().prepend(tr("Go to frame"));
0683     gotoFrameAct->setToolTip(infoText);
0684 
0685     infoText =
0686             tr("<h4>Configure Stopmotion</h4> "
0687             "<p>This will open a window where you can <em>configure</em> "
0688             "Stopmotion with various input and output devices.</p>");
0689     configureAct->setWhatsThis(infoText);
0690     infoText =
0691             configureAct->toolTip().prepend(tr("Configure Stopmotion"));
0692     configureAct->setToolTip(infoText);
0693 
0694 
0695     //Help menu
0696     infoText =
0697         tr("<h4>What's This</h4> "
0698         "<p>This will give you a WhatsThis mouse cursor which can be used to "
0699         "bring up helpful information like this.</p>");
0700     whatsthisAct->setWhatsThis(infoText);
0701     infoText =
0702             whatsthisAct->toolTip().prepend(tr("What's This"));
0703     whatsthisAct->setToolTip(infoText);
0704 
0705     infoText =
0706             tr("<h4>Help</h4> "
0707             "<p>This button will bring up a dialog with the Stopmotion manual</p>");
0708     helpAct->setWhatsThis(infoText);
0709     infoText =
0710             aboutAct->toolTip().prepend(tr("Help"));
0711     helpAct->setToolTip(infoText);
0712 
0713     infoText =
0714             tr("<h4>About</h4> "
0715             "<p>This will display a small information box where you can read "
0716             "general information as well as the names of the developers "
0717             "behind this excellent piece of software.</p>");
0718     aboutAct->setWhatsThis(infoText);
0719     infoText =
0720             aboutAct->toolTip().prepend(tr("About"));
0721     aboutAct->setToolTip(infoText);
0722 
0723 
0724     //Other widgets
0725     infoText =
0726             tr("<h4>Frame number</h4><p>This area displays the number "
0727             "of the currently selected frame</p>");
0728     numberDisplay->setToolTip(infoText );
0729     numberDisplay->setWhatsThis(infoText );
0730 
0731     //Various menues
0732     infoText =
0733             tr("<h4>FrameView</h4><p> In this area you can see the "
0734             "selected frame. You can also play "
0735             "animations in this window by pressing the "
0736             "<b>Play</b> button.</p>");
0737     frameView->setWhatsThis(infoText );
0738 
0739     infoText =
0740             tr("<h4>Go to frame menu</h4> "
0741             "<p>Here you can specify a framenumber and the program will jump "
0742             "to the specified frame</p> ");
0743     gotoMenuWidget->setWhatsThis(infoText );
0744 
0745     infoText =
0746             tr("<h4>Frame preferences menu</h4> "
0747             "<p>In this menu you can set preferences for the "
0748             "selected frame/frames, such as <b>subtitles</b>, "
0749             "<b>sound effects</b>, etc.</p>");
0750     framePreferencesMenu->setWhatsThis(infoText );
0751 
0752     infoText =
0753             tr("<h4>Tool menu</h4> "
0754             "<p>This is the tool menu where most of the buttons and widgets "
0755             "you will need when working on stop motion animations are located.</p>");
0756     toolsMenu->setWhatsThis(infoText );
0757 
0758     infoText =
0759             tr("<h4>FrameBar</h4> "
0760             "<p>In this area you can see the frames and scenes "
0761             "in the animations and build the animation "
0762             "by moving the them around.</p><p>You can "
0763             "switch to the next and the previous frame "
0764             "using the <b>arrow buttons</b> or <b>x</b> "
0765             "and <b>z</b></p> ");
0766     frameBar->setWhatsThis(infoText );
0767 }
0768 
0769 MainWindowGUI::SaveDialogResult MainWindowGUI::saveIfNecessary() {
0770     bool b = DomainFacade::getFacade()->isUnsavedChanges();
0771     if (b) {
0772         int save = QMessageBox::question(this, tr("Unsaved changes"),
0773                 tr("There are unsaved changes. Do you want to save?"),
0774                 tr("&Save"), tr("Do&n't save"), tr("Abort"), 0, 2);
0775         if (save == 2) {
0776             return saveDialogCancel;
0777         } else if (save == 0) {
0778             if (saveProject())
0779                 return saveDialogSave;
0780             // User requested a save but cancelled the "Save As" dialog.
0781             // This counts as a cancel.
0782             return saveDialogCancel;
0783         }
0784     }
0785     return saveDialogDiscard;
0786 }
0787 
0788 void MainWindowGUI::newProject() {
0789     if (saveDialogCancel != saveIfNecessary()) {
0790         DomainFacade::getFacade()->newProject();
0791         // It would be better if this was a signal emission, but it seems that
0792         // connect(this, ...) is problematic for some reason.
0793         frameView->workspaceCleared();
0794         saveAct->setEnabled(false);
0795         setTitle(false);
0796         DomainFacade::getFacade()->clearHistory();
0797         modelSizeChanged(0);
0798         toolsMenu->fixNavigationButtons(0);
0799     }
0800 }
0801 
0802 void MainWindowGUI::openProject() {
0803     if (saveDialogCancel != saveIfNecessary()) {
0804         QString file = QFileDialog::
0805             getOpenFileName(this,
0806                     tr("Choose project file"),
0807                     lastVisitedDir,
0808                     "Stopmotion (*.sto)");
0809         if ( !file.isNull() ) {
0810             doOpenProject( file.toLocal8Bit().constData() );
0811         }
0812     }
0813 }
0814 
0815 void MainWindowGUI::updateNewActiveFrame(int, int frame) {
0816     if (frame < 0) {
0817         cutAct->setEnabled(false);
0818         copyAct->setEnabled(false);
0819     } else {
0820         cutAct->setEnabled(true);
0821         copyAct->setEnabled(true);
0822     }
0823 }
0824 
0825 void MainWindowGUI::updatePasteEnabled() {
0826     const QMimeData *mimeData = QApplication::clipboard()->mimeData();
0827     pasteAct->setEnabled(mimeData->hasUrls());
0828 }
0829 
0830 void MainWindowGUI::doOpenProject(const char* projectFile) {
0831     assert(projectFile != NULL);
0832     DomainFacade::getFacade()->openProject(projectFile);
0833     frameView->workspaceCleared();
0834     saveAsAct->setEnabled(true);
0835     saveAct->setEnabled(false);
0836     setTitle(false);
0837     updateMostRecentMenu();
0838     int size = DomainFacade::getFacade()->getModelSize();
0839     if (size > 0) {
0840         activateMenuOptions();
0841         modelSizeChanged(size);
0842         toolsMenu->fixNavigationButtons(size);
0843     }
0844 }
0845 
0846 void MainWindowGUI::openProject( const char * projectFile ) {
0847     if (saveDialogCancel != saveIfNecessary()) {
0848         doOpenProject(projectFile);
0849     }
0850 }
0851 
0852 void MainWindowGUI::openMostRecent() {
0853     Preference prop("mostRecent", "");
0854     openProject(prop.get());
0855 }
0856 
0857 
0858 void MainWindowGUI::openSecondMostRecent()
0859 {
0860     Preference prop("secondMostRecent", "");
0861     openProject(prop.get());
0862 }
0863 
0864 
0865 void MainWindowGUI::openThirdMostRecent()
0866 {
0867     Preference prop("thirdMostRecent", "");
0868     openProject(prop.get());
0869 }
0870 
0871 
0872 bool MainWindowGUI::saveProjectAs() {
0873     QString file = QFileDialog::getSaveFileName(this,
0874             tr("Save As"), lastVisitedDir, "Stopmotion (*.sto)");
0875     if ( file.isNull() )
0876         return false;
0877     DomainFacade::getFacade()->saveProject(file.toLocal8Bit());
0878     saveAct->setEnabled(false);
0879     setTitle(false);
0880     updateMostRecentMenu();
0881     return true;
0882 }
0883 
0884 
0885 bool MainWindowGUI::saveProject() {
0886     const char *file = DomainFacade::getFacade()->getProjectFile();
0887     if (file) {
0888         DomainFacade::getFacade()->saveProject(file);
0889         return true;
0890     }
0891     return saveProjectAs();
0892 }
0893 
0894 
0895 void MainWindowGUI::exportToVideo()
0896 {
0897     PreferencesTool *prefs = PreferencesTool::get();
0898     int active = prefs->getPreference("activeEncoder", -1);
0899     if ( active == -1 ) {
0900         int ret = QMessageBox::warning(this,
0901             tr("Warning"),
0902             tr("Cannot find any registered encoder to be used for\n"
0903                "video export. This can be set in the preferences\n"
0904                "menu. Export to video will not be possible until you\n"
0905                "have set an encoder to use. Do you want to set it now?"),
0906             tr("&Yes"), tr("&No"), // button 0, button 1, ...
0907             QString(), 0, 1 );
0908         if (ret == 0) {
0909             showPreferencesMenu();
0910         }
0911     }
0912     else {
0913         bool isCanceled = false;
0914         std::stringstream key;
0915         std::string k;
0916         VideoEncoder enc;
0917 
0918         key << "startEncoder" << active;
0919         k = key.str();
0920         Preference start(k.c_str(), "");
0921         enc.setStartCommand(start.get());
0922 
0923         key.str("");
0924         key << "stopEncoder" << active;
0925         k = key.str();
0926         Preference stop(k.c_str(), "");
0927         enc.setStopCommand(stop.get());
0928 
0929         key.str("");
0930         key << "outputFile" << active;
0931         k = key.str();
0932         Preference output(k.c_str());
0933         if (output.get() && *output.get()) {
0934             enc.setOutputFile(output.get());
0935         } else {
0936             QString file = QFileDialog::
0937                 getSaveFileName(this,
0938                         tr("Export to video file"),
0939                         lastVisitedDir);
0940             if ( file.isEmpty() ) {
0941                 isCanceled = true;
0942             } else {
0943                 enc.setOutputFile( file.toLocal8Bit().constData() );
0944             }
0945         }
0946 
0947         if ( enc.isValid() && isCanceled == false ) {
0948             DomainFacade::getFacade()->exportToVideo(&enc,
0949                     frameView->getPlaybackSpeed());
0950         }
0951         else if (!isCanceled){
0952             int ret = QMessageBox::warning(this,
0953                     tr("Warning"),
0954                     tr("The registered encoder is not valid. Do you want\n"
0955                     "to check your settings in the preferences menu?"),
0956                     tr("&Yes"), tr("&No"), // button 0, button 1, ...
0957                     QString(), 0, 1 );
0958             if (ret == 0) {
0959                 showPreferencesMenu();
0960             }
0961         }
0962     }
0963 }
0964 
0965 
0966 void MainWindowGUI::exportToCinerella()
0967 {
0968     QString file = QFileDialog::
0969         getSaveFileName(this,
0970                 tr("Export to file"), lastVisitedDir, "Cinerella (*.XXX)");
0971 
0972     if ( !file.isNull() ) {
0973         DomainFacade::getFacade()->exportToCinerella( file.toLocal8Bit().constData() );
0974     }
0975 }
0976 
0977 
0978 void MainWindowGUI::whatsThis()
0979 {
0980     QWhatsThis::enterWhatsThisMode();
0981 }
0982 
0983 
0984 void MainWindowGUI::dragEnterEvent ( QDragEnterEvent * event)
0985 {
0986     Logger::get().logDebug("Drag entering application");
0987     if ( event->mimeData()->hasUrls() ) {
0988         event->accept();
0989     }
0990     else {
0991         event->ignore();
0992     }
0993 }
0994 
0995 
0996 void MainWindowGUI::dropEvent(QDropEvent *event)
0997 {
0998     Logger::get().logDebug("Drop inside the application");
0999     if ( event->mimeData()->hasUrls() ) {
1000         QStringList fileNames;
1001         QList<QUrl> urls = event->mimeData()->urls();
1002         int numFrames = urls.size();
1003         for (int i = 0; i < numFrames; ++i) {
1004             fileNames.append(urls[i].toLocalFile());
1005             modelHandler->addFrames(fileNames);
1006         }
1007 
1008     }
1009 }
1010 
1011 
1012 /**
1013  * @todo change so that CTRL+A instead of just A selects all the frames.
1014  */
1015 void MainWindowGUI::keyPressEvent( QKeyEvent *k )
1016 {
1017     switch ( k->key() )
1018     {
1019         case Key_Shift:
1020         {
1021             frameBar->setSelecting(true);
1022             break;
1023         }
1024         case Key_A:
1025         {
1026             DomainFacade* facade = DomainFacade::getFacade();
1027             int scene = frameBar->getActiveScene();
1028             if(0 <= scene) {
1029                 int sceneSize = facade->getSceneSize(scene);
1030                 if( sceneSize > 1) {
1031                     frameBar->updateNewActiveFrame(scene, 0);
1032                     frameBar->setSelection(sceneSize - 1);
1033                 }
1034             }
1035             break;
1036         }
1037         default:
1038         {
1039             k->ignore();
1040             break;
1041         }
1042     }
1043 }
1044 
1045 void MainWindowGUI::updateCanUndo(bool newCanUndo) {
1046     undoAct->setEnabled(newCanUndo);
1047     saveAct->setEnabled(newCanUndo);
1048     setTitle(newCanUndo);
1049 }
1050 
1051 void MainWindowGUI::updateCanRedo(bool newCanRedo) {
1052     redoAct->setEnabled(newCanRedo);
1053 }
1054 
1055 void MainWindowGUI::keyReleaseEvent ( QKeyEvent * k )
1056 {
1057     switch ( k->key() )
1058     {
1059         case Key_Shift:
1060         {
1061             frameBar->setSelecting(false);
1062             break;
1063         }
1064     }
1065 }
1066 
1067 
1068 void MainWindowGUI::setTitle(bool modified) {
1069     std::string title;
1070     if (modified)
1071         title = "* ";
1072     const char* name = DomainFacade::getFacade()->getProjectFile();
1073     if (name) {
1074         const char* lastDot = strrchr(name, '.');
1075         const char* lastSlash = strrchr(name, '/');
1076         title.append(lastSlash? lastSlash + 1 : name,
1077                 lastDot? lastDot : name + strlen(name));
1078     } else {
1079         title.append("Stopmotion");
1080     }
1081     setWindowTitle(title.c_str());
1082 }
1083 
1084 
1085 void MainWindowGUI::showAboutDialog()
1086 {
1087     AboutDialog *aboutDialog = new AboutDialog(this);
1088     aboutDialog->show();
1089 }
1090 
1091 
1092 void MainWindowGUI::showHelpDialog()
1093 {
1094     HelpWindow *help = new HelpWindow(this);
1095     help->move(40, 40);
1096     help->show();
1097 }
1098 
1099 
1100 
1101 void MainWindowGUI::showPreferencesMenu()
1102 {
1103     preferencesMenu->display();
1104 }
1105 
1106 
1107 void MainWindowGUI::mousePressEvent( QMouseEvent * )
1108 {
1109     gotoMenuWidget->hide();
1110 }
1111 
1112 
1113 void MainWindowGUI::modelSizeChanged( int modelSize ) {
1114     if (modelSize == 0) {
1115         gotoFrameAct->setEnabled(false);
1116     } else {
1117         gotoFrameAct->setEnabled(true);
1118         saveAsAct->setEnabled(true);
1119     }
1120 }
1121 
1122 
1123 void MainWindowGUI::activateMenuOptions() {
1124     DomainFacade* facade = DomainFacade::getFacade();
1125     bool canUndo = facade->canUndo();
1126     undoAct->setEnabled(canUndo);
1127     redoAct->setEnabled(facade->canRedo());
1128     setTitle(canUndo);
1129 }
1130 
1131 void MainWindowGUI::createMostRecentMenu() {
1132     mostRecentMenu->clear();
1133     mostRecentMenu->setTitle(tr("Open &Recent"));
1134     Preference first("mostRecent", "");
1135     if (first.get() && access(first.get(), R_OK) == 0) {
1136         mostRecentAct->setVisible(true);
1137         mostRecentAct->setText(QString::fromLocal8Bit(first.get()));
1138     } else {
1139         mostRecentAct->setVisible(false);
1140     }
1141     Preference second("secondMostRecent", "");
1142     if (second.get() && access(second.get(), R_OK) == 0) {
1143         secondMostRecentAct->setVisible(true);
1144         secondMostRecentAct->setText(QString::fromLocal8Bit(second.get()));
1145     } else {
1146         secondMostRecentAct->setVisible(false);
1147     }
1148     Preference third("thirdMostRecent", "");
1149     if (third.get() && access(third.get(), R_OK) == 0) {
1150         thirdMostRecentAct->setVisible(true);
1151         thirdMostRecentAct->setText(QString::fromLocal8Bit(third.get()));
1152     } else {
1153         thirdMostRecentAct->setVisible(false);
1154     }
1155     mostRecentMenu->addAction(mostRecentAct);
1156     mostRecentMenu->addAction(secondMostRecentAct);
1157     mostRecentMenu->addAction(thirdMostRecentAct);
1158 }
1159 
1160 void MainWindowGUI::updateMostRecentMenu() {
1161     DomainFacade::getFacade()->setMostRecentProject();
1162     createMostRecentMenu();
1163 }