ImpMainWindow.cpp 25.7 KB
Newer Older
1
2
3
4
/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
5
 * (c) 2001-2018 Univ. Grenoble Alpes, CNRS, TIMC-IMAG UMR 5525 (GMCAO)
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

// -- Application Imp stuff
#include "ImpMainWindow.h"

// -- Core stuff
#include <Application.h>
#include <ExtensionManager.h>
#include <MedicalImageViewer.h>
Jean-Loup HABERBUSCH's avatar
Jean-Loup HABERBUSCH committed
33
#include <ActionViewer.h>
34
35
36
#include <SettingsDialog.h>
#include <Component.h>
#include <Action.h>
37
38
#include <Core.h> // for getActionDirectories()
#include <Explorer.h>
39
#include <FrameExplorer.h>
40
#include <PropertyExplorer.h>
41
42
#include <Property.h>
#include <PropertyObject.h>
43
#include <Log.h>
44

45
using namespace camitk;
46
47
48
49
50
51
52
53
54
55
56

// -- QT stuff
#include <QAction>
#include <QFileDialog>
#include <QPixmap>
#include <QWhatsThis>
#include <QMenu>
#include <QToolBar>
#include <QMenuBar>
#include <QStatusBar>
#include <QDockWidget>
57
#include <QTranslator>
58
59

// ------------- constructor -----------------
60
ImpMainWindow::ImpMainWindow() : MainWindow("imp") {
61
62
63
    // set the specific actions state machine icon
    setWindowIcon(QPixmap(":/applicationIcon"));

64
65
66
67
68
69
70
71
72
73
74
    // init all other GUI
    initActions();
    initMenuBar();
    initToolBar();

    // initialize architecture
    updateActionStates();
    updateOpenDirectoryMenu();

    // now add the different viewers
    setCentralViewer(MedicalImageViewer::getInstance());
75
    addDockViewer(Qt::LeftDockWidgetArea, Explorer::getInstance());
76
    addDockViewer(Qt::LeftDockWidgetArea, FrameExplorer::getInstance());
77
    addDockViewer(Qt::LeftDockWidgetArea, PropertyExplorer::getInstance());
78
    addDockViewer(Qt::RightDockWidgetArea, ActionViewer::getInstance());
79
80
81
82

    //Merge Explorer and FrameExplorer viewers in one layout
    QDockWidget* dockWidgetExplorer = dockWidgetMap.value(Explorer::getInstance(), NULL);
    QDockWidget* dockWidgetFrameExplorer = dockWidgetMap.value(FrameExplorer::getInstance(), NULL);
83
    if (dockWidgetExplorer && dockWidgetFrameExplorer) {
84
85
        tabifyDockWidget(dockWidgetExplorer, dockWidgetFrameExplorer);
        dockWidgetExplorer->raise();
86
87
    }

88
    showDockViewer(ActionViewer::getInstance(), false);
89
    ActionViewer::getInstance()->setSearchPanelVisible(true);
90
91
92
    showStatusBar(true);
}

93
// ------------- destructor -----------------
94
95
96
97
98
99
100
101
102
103
104
ImpMainWindow::~ImpMainWindow() {
}

// ------------- aboutToShow -----------------
void ImpMainWindow::aboutToShow() {
    MainWindow::aboutToShow(); // calls init settings

    // now that initSettings was called, populate the recent document menu
    updateRecentDocumentsMenu();

    // check autoload for files and load if needed
105
106
    if (Application::getPropertyObject()->getPropertyValue("Auto Load Last Opened Component").toBool() && Application::getRecentDocuments().size() > 0) {
        Application::open(Application::getRecentDocuments().last().absoluteFilePath());
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    }
}

// ------------- refresh -----------------
void ImpMainWindow::refresh() {
    MainWindow::refresh();

    // update Data directory menu
    updateOpenDirectoryMenu();
    // update all the action states
    updateActionStates();
    // update menu
    updateRecentDocumentsMenu();
}

// ------------- addDockViewer -----------------
123
void ImpMainWindow::addDockViewer(Qt::DockWidgetArea dockingArea, Viewer* theViewer) {
124
125
126
127
128
129
    MainWindow::addDockViewer(dockingArea, theViewer);
    // update the menu
    updateViewMenu();
}

// ------------- setCentralViewer -----------------
130
void ImpMainWindow::setCentralViewer(Viewer* theViewer) {
131
132
133
134
135
136
137
    MainWindow::setCentralViewer(theViewer);
    // update the menu
    updateViewMenu();
}

// ------------- initActions -----------------
void ImpMainWindow::initActions() {
138
    //-- Check for action applications
139
    ActionExtension* applicationActionExtension = NULL;
140
    QListIterator<ActionExtension*> it(ExtensionManager::getActionExtensionsList());
141
142
    while (it.hasNext() && applicationActionExtension == NULL) {
        ActionExtension* current = it.next();
143
        if (current->getName() == "Application Level Actions") {
144
            applicationActionExtension = current;
145
        }
146
    }
147
    if (applicationActionExtension == NULL) {
148
        CAMITK_ERROR(tr("Application error: the \"Application Level Actions\" extension is required by this application but could not be found\nIn any of the following extension directories:\n - %1\nPlease check your CamiTK configuration and/or installation using \"camitk-config --config\"").arg(Core::getActionDirectories().join("\n - ")))
149
150
        exit(EXIT_FAILURE);
    }
151

152
153
    //--- actions of the File menu
    // get the CamiTK actions
154
    fileOpen = Application::getAction("Open")->getQAction();
155
156
157
158
159
160
161
    fileClose = Application::getAction("Close")->getQAction();
    fileCloseAll = Application::getAction("Close All")->getQAction();
    fileSave = Application::getAction("Save")->getQAction();
    fileSaveAs = Application::getAction("Save As")->getQAction();
    fileSaveAll = Application::getAction("Save All")->getQAction();
    fileQuit = Application::getAction("Quit")->getQAction();

162
163
164
    recentDocumentSeparator = new QAction(tr("Recent Documents"), this);
    recentDocumentSeparator->setSeparator(true);
    recentDocumentSeparator->setVisible(false);
165

166
167
168
169
    for (int i = 0; i < Application::getMaxRecentDocuments(); i++) {
        recentDocumentActions.append(new QAction(this));
        recentDocumentActions.last()->setVisible(false);
        connect(recentDocumentActions.last(), SIGNAL(triggered()), this, SLOT(openRecentDocuments()));
170
171
172
173
174
175
    }

    //--- actions of the Edit menu
    editClearSelection = Application::getAction("Clear Selection")->getQAction();

    // settings
176
177
178
179
180
    editApplicationSettings = new QAction(tr("&Preferences..."), this);
    editApplicationSettings->setShortcut(tr("Ctrl+P"));
    editApplicationSettings->setStatusTip(tr("Edit the preferences"));
    editApplicationSettings->setWhatsThis(tr("Preferences\n\nEdit the settings and preferences of imp"));
    connect(editApplicationSettings, SIGNAL(triggered()), this, SLOT(editSettings()));
181

182
    // save history as SCXML
183
    saveHistory = new QAction(tr("&Save History"), this);
184
185
186
    saveHistory->setStatusTip(tr("Save the history of actions processed as an SCXML file."));
    saveHistory->setWhatsThis(tr("Save the history of actions processed as an SCXML file."));
    connect(saveHistory, SIGNAL(triggered()), this, SLOT(saveHistoryAsSCXML()));
187
188

    //--- actions of the View menu
189
190
191
192
193
194
    viewMenuBar = new QAction(tr("Menu bar"), this);
    viewMenuBar->setCheckable(true);
    viewMenuBar->setChecked(true);
    viewMenuBar->setStatusTip(tr("Hide/show the menu bar (Ctrl-M to show again)."));
    viewMenuBar->setWhatsThis(tr("Hide/show the menu bar (Ctrl-M to show again)."));
    viewMenuBar->setShortcut(tr("Ctrl+M"));
195
196
    // global shortcut, NOTE: the action should also be added as an ImpMainWindow action, otherwise the shortcut will not work when
    // the menu bar is hidden! (see initMenuBar() method)
197
198
    viewMenuBar->setShortcutContext(Qt::ApplicationShortcut);
    connect(viewMenuBar, SIGNAL(triggered(bool)), this, SLOT(showMenuBar(bool)));
199
200
201
202
203
204
    // NOTE: viewMenuBar can be used to hide the menu bar, if the menu bar is not visible,
    // since Qt4, it does not receive any event (and thus there is no way to set the menu
    // visible again! Which is quite annoying).
    // To prevent this, the viewMenuBar action has to be added to the QMainWindow as well
    // This should be done everytime the shortcut context is set
    // to Qt::ApplicationShortcut using setShortcutContext(Qt::ApplicationShortcut);
205
    this->addAction(viewMenuBar);
206

207
208
209
210
211
212
    viewStatusBar = new QAction(tr("Status bar"), this);
    viewStatusBar->setCheckable(true);
    viewStatusBar->setChecked(true);
    viewStatusBar->setStatusTip(tr("Hide/show the status bar."));
    viewStatusBar->setWhatsThis(tr("Hide/show the status bar."));
    connect(viewStatusBar, SIGNAL(toggled(bool)), this, SLOT(showStatusBar(bool)));
213

214
215
    viewResetWindows = new QAction(tr("Reset Windows"), this);
    viewResetWindows->setStatusTip(tr("Reset all windows in the initial state"));
216
    connect(viewResetWindows, SIGNAL(triggered()), this, SLOT(resetWindows()));
217
218

    //--- actions of the Help menu
219
220
    helpAboutApp = Application::getAction("About...")->getQAction();
    helpShowConsole = Application::getAction("Toggle Log Console")->getQAction();
221
    changeLanguage = Application::getAction("Change Language")->getQAction();
222
223
224
225
226
227
228

}

//**************************************************************************

void ImpMainWindow::initMenuBar() {
    // -- file
229
230
    fileMenu = new QMenu(tr("&File"));
    fileMenu->addAction(fileOpen);
231

232
233
234
235
    fileOpenDataDirectoryMenu = new QMenu(tr("Open &Data Directory..."));
    fileOpenDataDirectoryMenu->setIcon(QPixmap(":/fileOpen"));
    fileOpenDataDirectoryMenu->setEnabled(false);
    fileMenu->addMenu(fileOpenDataDirectoryMenu);
236

237
238
    fileMenu->addAction(fileClose);
    fileMenu->addAction(fileCloseAll);
239
    fileMenu->addSeparator();
240
241
242
    fileMenu->addAction(fileSave);
    fileMenu->addAction(fileSaveAs);
    fileMenu->addAction(fileSaveAll);
243
244
    fileMenu->addSeparator();
    fileMenu->addAction(saveHistory);
245
    fileMenu->addAction(recentDocumentSeparator);
246

247
248
    foreach (QAction* recentAction, recentDocumentActions) {
        fileMenu->addAction(recentAction);
249
250
251
252
    }

    fileMenu->addSeparator();
    fileMenu->addSeparator();
253
    fileMenu->addAction(fileQuit);
254

255
256

    // -- edit
257
258
    QMenu* editMenu = new QMenu(tr("&Edit"));
    editMenu->addAction(editClearSelection);
259
    editMenu->addSeparator();
260
    editMenu->addAction(editApplicationSettings);
261

262
263

    // -- View menu
264
    viewMenu = new QMenu(tr("&View"));
265
266

    // -- help
267
268
269
270
271
272
    QMenu* helpMenu = new QMenu(tr("&Help"));
    QAction* whatsThisAction = QWhatsThis::createAction(this);
    whatsThisAction->setStatusTip(tr("What's This and Viewer Keyboard Shortcuts."));
    whatsThisAction->setWhatsThis(tr("What's This and Viewer Keyboard Shortcuts."));
    helpMenu->addAction(whatsThisAction);
    this->addAction(whatsThisAction);
273
    helpMenu->addSeparator();
274
    helpMenu->addAction(helpShowConsole);
275
276
    helpMenu->addSeparator();
    helpMenu->addAction(changeLanguage);
277
    helpMenu->addSeparator();
278
    helpMenu->addAction(helpAboutApp);
279
280

    // -- action
281
    actionMenu = new QMenu(tr("&Actions"));
282
283

    // -- add everything in the menu bar
284
285
286
287
    menuBar()->addMenu(fileMenu);
    menuBar()->addMenu(editMenu);
    menuBar()->addMenu(viewMenu);
    menuBar()->addMenu(actionMenu);
288
    menuBar()->addSeparator();
289
    menuBar()->addMenu(helpMenu);
290
291
292
293
294

}

//--------------------------initToolBar-------------------------------
void ImpMainWindow::initToolBar() {
295
    mainToolbar = addToolBar("Main Toolbar");
296
    // ensure object name is set for saving the state
297
    mainToolbar->setObjectName("ImpMainWindow Main Toolbar");
298
299
300
    mainToolbar->addAction(fileOpen);
    mainToolbar->addAction(fileSave);
    mainToolbar->addAction(QWhatsThis::createAction(this));
301
302
303
304
305
}

// ------------------------ updateActionStates ----------------------------
void ImpMainWindow::updateActionStates() {
    unsigned int nrOfSelectedItems = Application::getSelectedComponents().size();
306
    bool selectedIsTopLevel = (nrOfSelectedItems > 0 && Application::getSelectedComponents().last()->isTopLevel());
307
308
309
    unsigned int nrOfComponents = Application::getTopLevelComponents().size();

    //-- update file menu
310
311
312
313
314
    fileCloseAll->setEnabled(nrOfComponents > 0);
    fileSaveAll->setEnabled(nrOfComponents > 0);
    fileSave->setEnabled(selectedIsTopLevel && Application::getSelectedComponents().first()->getTopLevelComponent()->getModified());    // save available only if needed
    fileSaveAs->setEnabled(nrOfSelectedItems > 0);     // no need to be top level to be saved as in a compatible format
    fileClose->setEnabled(selectedIsTopLevel);
315

316
    //-- update edit menu
317
    editClearSelection->setEnabled(nrOfSelectedItems > 0);
318
319
320

    //-- update the action menu
    actionMenu->clear();
321
    actionMenu->setEnabled(false);
322

323
    if (nrOfSelectedItems > 0) {
324
        // use the selection to populate the menu
325
        Component* comp = Application::getSelectedComponents().last();
326
327

        if (comp) {
328
            QMenu* compActionsMenu = comp->getActionMenu();
329
330
331

            if (compActionsMenu) {
                actionMenu->addActions(compActionsMenu->actions());
332
                actionMenu->setEnabled(true);
333
334
            }
        }
335
336
    }
    else {
337
338
        // add all generic actions
        ActionList allActions = Application::getActions(NULL);
339
        foreach (Action* action, allActions) {
340
            actionMenu->addAction(action->getQAction());
341
            actionMenu->setEnabled(true);
342
343
344
345
        }
    }

    // update the application window title
346
    if (nrOfSelectedItems > 0) {
347
        setWindowSubtitle(Application::getSelectedComponents().last()->getFileName() + ((Application::getSelectedComponents().last()->getTopLevelComponent()->getModified()) ? "*" : ""));
348
349
    }
    else {
350
        setWindowSubtitle("");
351
    }
352
353
354
}

// ------------- showToolbar -----------------
355
356
void ImpMainWindow::showToolbar(bool b) {
    mainToolbar->setVisible(b);
357
358
359
}

// ------------- showMenuBar -----------------
360
void ImpMainWindow::showMenuBar(bool b) {
361
    if (!b) {
362
363
364
365
366
367
368
369
370
371
372
373
        // warn the user first
        CAMITK_WARNING(tr("Hide menu: the menu is going to be hidden. There is only one way to make it reappear: you need to press CTRL+M again."))
        viewMenuBar->blockSignals(true);
        viewMenuBar->setChecked(true);
        viewMenuBar->blockSignals(false);
    }
    else {
        menuBar()->setVisible(b);
        viewMenuBar->blockSignals(true);
        viewMenuBar->setChecked(b);
        viewMenuBar->blockSignals(false);
        showStatusBar(b);
374
375
376
377
378
379
380
381
382
383
    }
}

// ------------- showStatusBar -----------------
void ImpMainWindow::showStatusBar(bool b) {
    MainWindow::showStatusBar(b);
}

// ------------------------ resetWindows ----------------------------
void ImpMainWindow::resetWindows() {
384
    for (QMap<Viewer*, QDockWidget*>::iterator it = dockWidgetMap.begin(); it != dockWidgetMap.end(); it++) {
385
        if (it.value()->widget() == Explorer::getInstance()->getWidget(NULL)) {
386
387
388
            removeDockWidget(it.value());
            addDockWidget(Qt::LeftDockWidgetArea, it.value());
            it.value()->show();
389
        }
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
        else
            if (it.value()->widget() == FrameExplorer::getInstance()->getWidget(NULL)) {
                removeDockWidget(it.value());
                addDockWidget(Qt::LeftDockWidgetArea, it.value());
                it.value()->show();
            }
            else
                if (it.value()->widget() == PropertyExplorer::getInstance()->getWidget()) {
                    removeDockWidget(it.value());
                    addDockWidget(Qt::LeftDockWidgetArea, it.value());
                    it.value()->show();
                }
                else
                    if (it.value()->widget() == ActionViewer::getInstance()->getWidget()) {
                        removeDockWidget(it.value());
                        addDockWidget(Qt::RightDockWidgetArea, it.value());
                        it.value()->show();
                    }
408
    }
409
410
411
    //Merge Explorer and FrameExplorer viewers in one layout
    QDockWidget* dockWidgetExplorer = dockWidgetMap.value(Explorer::getInstance(), NULL);
    QDockWidget* dockWidgetFrameExplorer = dockWidgetMap.value(FrameExplorer::getInstance(), NULL);
412
    if (dockWidgetExplorer && dockWidgetFrameExplorer) {
413
414
        tabifyDockWidget(dockWidgetExplorer, dockWidgetFrameExplorer);
        dockWidgetExplorer->raise();
415
    }
416
417
418
419
420
421

    showStatusBar(true);
    showMenuBar(true);
    showToolbar(true);

    // reset geometry to default
422
423
    resize(1024, 768);
    move(0, 0);
424
425
426
427
428
429
}

// ------------------------ updateDataDirectoryMenu ----------------------------
void ImpMainWindow::updateOpenDirectoryMenu() {
    unsigned int nrOfDataDirectoryManager = 0;

430
    disconnect(fileOpenDataDirectoryMenu, SIGNAL(triggered(QAction*)), this, SLOT(openDirectory(QAction*)));
431
    fileOpenDataDirectoryMenu->clear();
432
    fileOpenDataDirectoryMenu->setEnabled(false);
433

434
    foreach (QString name, ExtensionManager::getDataDirectoryExtNames()) {
435
        nrOfDataDirectoryManager++;
436
437
438
        QAction* openDirectory = new QAction(name, this);
        openDirectory->setStatusTip(tr(QString("Opens data directory for " + name).toStdString().c_str()));
        openDirectory->setWhatsThis(tr(QString("Opens data directory for " + name).toStdString().c_str()));
439

440
        fileOpenDataDirectoryMenu->addAction(openDirectory);
441
442
    }

443
444
445
    if (nrOfDataDirectoryManager > 0) {
        fileOpenDataDirectoryMenu->setEnabled(true);
        connect(fileOpenDataDirectoryMenu, SIGNAL(triggered(QAction*)), this, SLOT(openDirectory(QAction*)));
446
447
448
449
    }
}

// ------------- openDataDirectory -----------------
450
451
void ImpMainWindow::openDirectory(QAction* emitter) {
    QString pluginName = emitter->text().replace("&", "");
452

453
    statusBar()->showMessage(tr(QString("Opening " + pluginName + " directory...").toStdString().c_str()));
454
455

    // Open more than one file
456
    QString dir = QFileDialog::getExistingDirectory(this, tr(QString("Choose a " + pluginName + " directory ").toStdString().c_str()), Application::getLastUsedDirectory().absolutePath());
457

458
    if (!dir.isEmpty()) {
459
        // set waiting cursor
460
        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
461

462
        // instantiate a Component to represent the data contained in the directory
463
        Component* comp = Application::openDirectory(dir, pluginName);
464

465
466
        if (!comp) {
            statusBar()->showMessage(tr("Error loading directory:") + dir);
467
468
        }
        else {
469
            // TODO add to recent document and manage directories as recent documents
470
            statusBar()->showMessage(tr(QString("Directory " + dir + " successfully loaded").toStdString().c_str()));
471
472
473
474
475
476
477
478
479
480
481
482
483

            // refresh all
            refresh();
        }

        // restore the normal cursor
        QApplication::restoreOverrideCursor();
        getProgressBar()->setValue(0.0);
    }
}

// ------------- updateViewMenu -----------------
void ImpMainWindow::updateViewMenu() {
484
485
486
487
    // From Qt documentation:
    // "Removes all the menu's actions. Actions owned by the menu and not shown in any other widget are deleted"
    // I.e., the central viewer toggle action are own by viewMenu (they are created and used here), they will
    // therefore be no memory leak
488
489
490
    viewMenu->clear();

    // insert viewers menu
491
    foreach (Viewer* v, viewers) {
492
        QMenu* viewerMenu = v->getMenu();
493

494
495
        if (viewerMenu) {
            viewMenu->addMenu(viewerMenu);
496
        }
497
498
    }

499
500
501
    // change the central viewer if there is more than one viewer in the central area
    if (qobject_cast<QStackedWidget*>(centralWidget())->count() > 1) {
        viewMenu->addSeparator()->setText(tr("Toggle Central Viewers"));
502
503
//         for(Viewer *v : viewers) {
//             int i = 0;
504
505
506
//             // beware that getWidget(..) requires a parent and as the widget was setup inside centralWidget()
//             // it was reparented to centralWidget() → use getWidget(centralWidget()) and not getWidget(this)
//             // in order not to modify the central widget parenting
507
508
509
510
511
//             while (i<qobject_cast<QStackedWidget*>(centralWidget())->count() && qobject_cast<QStackedWidget*>(centralWidget())->widget(i)!=v->getWidget(centralWidget()))
//                 i++;
//             if (i<qobject_cast<QStackedWidget*>(centralWidget())->count()) {
//                 viewMenu->addAction(v->objectName());
//             }
512
//         }
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
        
        // add a toggle action
        for (int i = 0; i < qobject_cast<QStackedWidget*>(centralWidget())->count(); i++) {
            QWidget* cWidget = qobject_cast<QStackedWidget*>(centralWidget())->widget(i);
            // get the viewer associated with the widget in the central area
            // Beware that getWidget(..) requires a parent and as the widget was setup inside centralWidget()
            // it was reparented to centralWidget() → use getWidget(centralWidget()) and not getWidget(this)
            // in order not to modify the central widget parenting
            auto it = std::find_if(viewers.begin(), viewers.end(), [&](Viewer * v) {
                return v->getWidget(centralWidget()) == cWidget;
            });
            Viewer* cViewer = (*it);
            // viewerAction is own by viewMenu, viewMenu->clear() will delete it
            QAction *viewerAction = viewMenu->addAction(cViewer->objectName());
            viewerAction->setCheckable(true);
            viewerAction->setChecked(cViewer == centralViewer);
            QString tipString = "Hide/show the " + cViewer->objectName() + " central viewer";
            viewerAction->setStatusTip(tr(tipString.toStdString().c_str()));
            viewerAction->setWhatsThis(tr(tipString.toStdString().c_str()));
            // add the toggle action slot using C++11 lambda so that everything is contained inside viewMenu
            connect(viewerAction, &QAction::toggled, [=](bool) {
                    setCentralViewer(cViewer);
            });
        }
537
538
    }

539
    // insert viewers on/off actions
540
    viewMenu->addSeparator()->setText(tr("Toggle Viewers"));
541
542
    viewMenu->addAction(viewResetWindows);

543
544
    for (QMap<Viewer*, QDockWidget*>::iterator it = dockWidgetMap.begin(); it != dockWidgetMap.end(); it++) {
        viewMenu->addAction(it.value()->toggleViewAction());
545
    }
546
547

    // insert generic on/off actions
548
549
550
551
    viewMenu->addSeparator()->setText(tr("Other Toggle"));
    viewMenu->addAction(viewMenuBar);
    viewMenu->addAction(viewStatusBar);
    viewMenu->addAction(mainToolbar->toggleViewAction());
552
553
554
555
}

// ------------------------------ slotEditSettings -------------------------------
void ImpMainWindow::editSettings() {
556
    statusBar()->showMessage(tr("Edit application preferences..."));
557
558
559
560
    // ask the ImpMainWindowDoc to show the settings

    // create the dialog
    SettingsDialog settingsDialog;
561

562
563
    // show the properties of the CamiTK application
    settingsDialog.editSettings(dynamic_cast<Application*>(qApp)->getPropertyObject());
564

565
    // edit all viewers that have properties
566
    foreach (Viewer* v, viewers) {
567
        QObject* viewerProp = v->getPropertyObject();
568

569
570
        if (viewerProp) {
            settingsDialog.editSettings(viewerProp);
571
        }
572
573
574
    }

    // execute the dialog
575
    if (settingsDialog.exec() == QDialog::Accepted) {
576
577
578
579
580
581
582
583
584
        // update recent docs
        updateRecentDocumentsMenu();
    }

    // check if there are anything to change in the data directory menu (for data directory manager)
    updateOpenDirectoryMenu();
}

// ------------- setApplicationConsole -----------------
585
void ImpMainWindow::redirectToConsole(bool visible) {
586
    MainWindow::redirectToConsole(visible);
587
    helpShowConsole->setEnabled(visible);
588
589
590
591
592
}


// ------------------------------ slotRecentDocuments -------------------------------
void ImpMainWindow::openRecentDocuments() {
593
    QAction* action = qobject_cast<QAction*> (sender());
594

595
    if (action) {
596
        // check if this recent document still exists!
597
        if (QFileInfo(action->data().toString()).exists()) {
598
599
600
            Action* openFileAction = Application::getAction("Open File");
            openFileAction->setProperty("File Name", action->data().toString()); // avoid opening a dialog, as the file path is already know
            openFileAction->applyAndRegister();
601
        }
602
        else {
603
            CAMITK_WARNING(tr("Open Recent Documents: document \"%1\" does not exist anymore.").arg(action->data().toString()))
604
        }
605
    }
606

607
608
609
610
}

// ------------------------------ updateRecentDocumentsMenu -------------------------------
void ImpMainWindow::updateRecentDocumentsMenu() {
611
    const QList<QFileInfo>& recentDocuments = Application::getRecentDocuments();
612
    recentDocumentSeparator->setVisible(recentDocuments.size() > 0);
613
614
615

    int id = 0;

616
617
618
619
620
621
622
    for (int i = recentDocuments.size() - 1; i >= 0 && id < Application::getMaxRecentDocuments(); i--, id++) {
        QString text = tr("&%1 %2").arg(id + 1).arg(recentDocuments[i].fileName());
        recentDocumentActions[id]->setText(text);
        recentDocumentActions[id]->setData(recentDocuments[i].absoluteFilePath());
        recentDocumentActions[id]->setStatusTip(recentDocuments[i].absoluteFilePath());
        recentDocumentActions[id]->setWhatsThis(recentDocuments[i].absoluteFilePath());
        recentDocumentActions[id]->setVisible(true);
623
624
    }

625
626
    for (; id < recentDocumentActions.size(); id++) {
        recentDocumentActions[id]->setVisible(false);
627
628
629
    }
}

630
// ------------------------------ saveHistoryAsSCXML -------------------------------
631
void ImpMainWindow::saveHistoryAsSCXML() {
632
633
634
    Application::saveHistoryAsSXML();
}

635
636
637
638