BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
actionmanager.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/mainwindow/actionmanager.cpp
6 //! @brief Implements class ActionManager
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
16 #include "Base/Utils/Assert.h"
17 #include "Base/Utils/SysUtils.h"
27 #include "Views/JobView.h"
28 #include "Views/SampleView.h"
29 #include <QDir>
30 #include <QMenuBar>
31 #include <QSettings>
32 #include <QShortcut>
33 
35  : QObject(parent)
36  , m_mainWindow(parent)
37  , m_newAction(nullptr)
38  , m_openAction(nullptr)
39  , m_saveAction(nullptr)
40  , m_saveAsAction(nullptr)
41  , m_exitAction(nullptr)
42  , m_aboutAction(nullptr)
43  , m_menuBar(nullptr)
44  , m_fileMenu(nullptr)
45  , m_settingsMenu(nullptr)
46  , m_viewMenu(nullptr)
47  , m_recentProjectsMenu(nullptr)
48  , m_helpMenu(nullptr)
49  , m_importMenu(nullptr)
50  , m_runSimulationShortcut(nullptr)
51 {
52  createActions();
53  createMenus();
55 
58 }
59 
61 {
62  ProjectManager* projectManager = m_mainWindow->projectManager();
63  ASSERT(projectManager);
64 
65  // new project action
66  m_newAction = new QAction("&New Project", m_mainWindow);
67  m_newAction->setShortcuts(QKeySequence::New);
68  m_newAction->setStatusTip("Create a new project");
69  connect(m_newAction, &QAction::triggered, projectManager, &ProjectManager::newProject);
70 
71  // open project action
72  m_openAction = new QAction("&Open Project", m_mainWindow);
73  m_openAction->setShortcuts(QKeySequence::Open);
74  m_openAction->setStatusTip("Open an existing project");
75  connect(m_openAction, &QAction::triggered, projectManager,
76  [projectManager]() { projectManager->openProject(); });
77 
78  // save project action
79  m_saveAction = new QAction("&Save Project", m_mainWindow);
80  m_saveAction->setShortcuts(QKeySequence::Save);
81  m_saveAction->setStatusTip("Save project");
82  m_saveAction->setShortcutContext(Qt::ApplicationShortcut);
83  connect(m_saveAction, &QAction::triggered, projectManager,
84  [projectManager]() { projectManager->saveProject(); });
85 
86  // save-as project action
87  m_saveAsAction = new QAction("Save &As...", m_mainWindow);
88  m_saveAsAction->setShortcuts(QKeySequence::SaveAs);
89  m_saveAsAction->setStatusTip("Save project under different name");
90  connect(m_saveAsAction, &QAction::triggered, projectManager, &ProjectManager::saveProjectAs);
91 
92  // exit application action
93  m_exitAction = new QAction("E&xit Application", this);
94  m_exitAction->setShortcuts(QKeySequence::Quit);
95  m_exitAction->setStatusTip("Exit the application");
96  connect(m_exitAction, &QAction::triggered, m_mainWindow, &MainWindow::close);
97 
98  // about application action
99  m_aboutAction = new QAction("About &BornAgain", this);
100  m_aboutAction->setStatusTip("About the application");
101  connect(m_aboutAction, &QAction::triggered, this, &ActionManager::onAboutApplication);
102 }
103 
105 {
106  m_menuBar = new QMenuBar(0); // No parent (System menu bar on Mac OS X)
107 
109  m_mainWindow->setMenuBar(m_menuBar);
110 
111  // File Menu
112  m_fileMenu = m_menuBar->addMenu("&File");
113  m_fileMenu->addAction(m_newAction);
114  m_fileMenu->addAction(m_openAction);
115  connect(m_fileMenu, &QMenu::aboutToShow, this, &ActionManager::onAboutToShowFileMenu);
116 
117  m_recentProjectsMenu = m_fileMenu->addMenu("&Recent Projects");
118 
119  m_fileMenu->addSeparator();
120  m_fileMenu->addAction(m_saveAction);
121  m_fileMenu->addAction(m_saveAsAction);
122 
123  // Import submenu
124  m_fileMenu->addSeparator();
125  m_importMenu = m_fileMenu->addMenu("&Import");
126  m_importMenu->setToolTipsVisible(true);
127  QAction* action = m_importMenu->addAction("&Import from Python script (experimental)");
128  action->setToolTip("Import sample from Python script.\n The script should contain a function "
129  "returning a valid multi-layer.");
130 
131 #ifdef BORNAGAIN_PYTHON
132  connect(action, &QAction::triggered, this, &ActionManager::onImportFromPythonScript);
134  if (SysUtils::getenv("PYTHONHOME").empty())
135  action->setEnabled(false);
136 #endif // BORNAGAIN_PYTHON
137 
138  m_fileMenu->addSeparator();
139  m_fileMenu->addAction(m_exitAction);
140 
141  // Settings Menu
142  m_settingsMenu = new QMenu("&Settings", m_mainWindow);
143  onAboutToShowSettingsMenu(); // MacOS feature: action should exist already, otherwise menuBar
144  // will not add menu
145  connect(m_settingsMenu, &QMenu::aboutToShow, this, &ActionManager::onAboutToShowSettingsMenu);
146  m_menuBar->addMenu(m_settingsMenu);
147 
148  // View menu
149  m_viewMenu = new QMenu("&View", m_mainWindow);
150  onAboutToShowViewMenu(); // MacOS feature: action should exist already, otherwise menuBar will
151  // not add menu
152  connect(m_viewMenu, &QMenu::aboutToShow, this, &ActionManager::onAboutToShowViewMenu);
153  m_menuBar->addMenu(m_viewMenu);
154 
155  // Help Menu
156  m_helpMenu = m_menuBar->addMenu("&Help");
157  m_helpMenu->addAction(m_aboutAction);
158 
160 }
161 
163 {
164  m_runSimulationShortcut = new QShortcut(QKeySequence("Ctrl+r"), m_mainWindow);
165  m_runSimulationShortcut->setContext((Qt::ApplicationShortcut));
166  connect(m_runSimulationShortcut, &QShortcut::activated, m_mainWindow,
168 }
169 
171 {
172  m_recentProjectsMenu->clear();
173 
174  bool hasRecentProjects = false;
175  int orderNr = 1;
176  for (QString file : m_mainWindow->projectManager()->recentProjects()) {
177  hasRecentProjects = true;
178  QString actionText = GUI_StringUtils::withTildeHomePath(QDir::toNativeSeparators(file));
179  if (orderNr < 10)
180  actionText = QString("&%1 ").arg(orderNr) + actionText;
181  QAction* action = m_recentProjectsMenu->addAction(actionText);
182  action->setData(QVariant::fromValue(file));
183  connect(action, &QAction::triggered, m_mainWindow, &MainWindow::openRecentProject);
184  orderNr++;
185  }
186  m_recentProjectsMenu->setEnabled(hasRecentProjects);
187 
188  if (hasRecentProjects) {
189  m_recentProjectsMenu->addSeparator();
190  QAction* action = m_recentProjectsMenu->addAction("&Clear Menu");
191  connect(action, &QAction::triggered, m_mainWindow->projectManager(),
193  }
194 }
195 
197 {
198  m_settingsMenu->clear();
199  QSettings settings;
200 
201  settings.beginGroup(Constants::S_UPDATES);
202  QAction* action = m_settingsMenu->addAction("&Check for Updates");
203  action->setToolTip("Checks for updates available on GUI startup.");
204  action->setCheckable(true);
205  action->setChecked(settings.value(Constants::S_CHECKFORUPDATES, false).toBool());
206  connect(action, &QAction::toggled, this, &ActionManager::toggleCheckForUpdates);
207  settings.endGroup();
208 
209  settings.beginGroup(Constants::S_SESSIONMODELVIEW);
210  action = m_settingsMenu->addAction("&Model tech view");
211  action->setToolTip("Additional developer's view will appear in left control tab bar");
212  action->setCheckable(true);
213  action->setChecked(settings.value(Constants::S_VIEWISACTIVE, false).toBool());
214  connect(action, &QAction::toggled, this, &ActionManager::setSessionModelViewActive);
215  settings.endGroup();
216 
217  action = m_settingsMenu->addAction("&Enable autosave");
218  action->setToolTip("Project will be saved periodically in project's autosave directory.\n"
219  "When opening project, recover option will be suggested, if possible.");
220  action->setCheckable(true);
221  action->setChecked(m_mainWindow->projectManager()->isAutosaveEnabled());
222  connect(action, &QAction::toggled, m_mainWindow->projectManager(),
224 
225  m_settingsMenu->setToolTipsVisible(true);
226 }
227 
229 {
230  m_viewMenu->clear();
231 
232  auto view = m_mainWindow->currentView();
233  if (auto sampleView = dynamic_cast<SampleView*>(view); sampleView != nullptr)
234  sampleView->fillViewMenu(m_viewMenu);
235  if (auto jobView = dynamic_cast<JobView*>(view); jobView != nullptr)
236  jobView->fillViewMenu(m_viewMenu);
237 }
238 
240 {
243 }
244 
246 {
247  QSettings settings;
248  settings.beginGroup(Constants::S_SESSIONMODELVIEW);
249  settings.setValue(Constants::S_VIEWISACTIVE, status);
250  settings.endGroup();
252 }
253 
255 {
257  dialog.exec();
258 }
259 
261 {
262  // not every view support view menu entries -> hide it, if empty
264  m_viewMenu->menuAction()->setVisible(!m_viewMenu->actions().isEmpty());
265 }
266 
267 #ifdef BORNAGAIN_PYTHON
269 {
270  PyImportAssistant assistant(m_mainWindow);
271  assistant.exec();
272 }
273 #endif // BORNAGAIN_PYTHON
Defines the macro ASSERT.
#define ASSERT(condition)
Definition: Assert.h:31
Defines class DocksController.
Defines class ActionManager.
Defines class MainWindow.
Defines class ProjectManager.
Defines class JobView.
Implements class PyImportAssistant.
Defines class SampleView.
Defines various stuff in namespace Utils.
Implements class UpdateNotifier.
Defines class AboutApplicationDialog.
About BornAgain dialog.
ActionManager(MainWindow *parent)
MainWindow * m_mainWindow
Definition: actionmanager.h:46
void onCurrentViewChanged()
QMenu * m_viewMenu
Definition: actionmanager.h:58
void createGlobalShortcuts()
QAction * m_exitAction
Definition: actionmanager.h:52
QMenu * m_helpMenu
Definition: actionmanager.h:60
QAction * m_newAction
Definition: actionmanager.h:48
QMenu * m_settingsMenu
Definition: actionmanager.h:57
void onAboutToShowViewMenu()
QAction * m_saveAsAction
Definition: actionmanager.h:51
void onAboutToShowFileMenu()
void onAboutToShowSettingsMenu()
void onAboutApplication()
void createActions()
QMenu * m_importMenu
Definition: actionmanager.h:61
QMenu * m_fileMenu
Definition: actionmanager.h:56
void toggleCheckForUpdates(bool status)
QMenu * m_recentProjectsMenu
Definition: actionmanager.h:59
QAction * m_openAction
Definition: actionmanager.h:49
void setSessionModelViewActive(bool status)
QShortcut * m_runSimulationShortcut
Definition: actionmanager.h:63
void onImportFromPythonScript()
QAction * m_saveAction
Definition: actionmanager.h:50
QMenuBar * m_menuBar
Definition: actionmanager.h:55
QAction * m_aboutAction
Definition: actionmanager.h:53
static bool isMacHost()
Definition: hostosinfo.h:69
The JobView class is a main view to show list of jobs, job results and widgets for real time and fitt...
Definition: JobView.h:35
QWidget * currentView() const
Definition: mainwindow.cpp:189
UpdateNotifier * updateNotifier()
Definition: mainwindow.cpp:184
void onSessionModelViewActive(bool isActive)
Inserts/removes developers SessionModelView on the left tabbar.
Definition: mainwindow.cpp:225
void onRunSimulationShortcut()
Definition: mainwindow.cpp:215
void openRecentProject()
Definition: mainwindow.cpp:207
void currentViewChanged(ViewId newView)
ProjectManager * projectManager()
Definition: mainwindow.cpp:179
Handles activity related to opening/save projects.
bool saveProject(QString projectFileName="")
Processes save project request.
void clearRecentProjects()
Clears list of recent projects.
void setAutosaveEnabled(bool value)
void openProject(QString fileName="")
Opens existing project. If fileName is empty, will popup file selection dialog.
bool isAutosaveEnabled() const
void newProject()
Processes new project request (close old project, rise dialog for project name, create project).
bool saveProjectAs()
Processes 'save project as' request.
QStringList recentProjects()
Returns list of recent projects, validates if projects still exists on disk.
Assists in importing Python object to GUI models.
void setCheckUpdatesFlag(bool flag)
Defines Utils namespace.
Defines namespace Constants.
const char S_CHECKFORUPDATES[]
const char S_SESSIONMODELVIEW[]
const char S_VIEWISACTIVE[]
const char S_UPDATES[]
QString withTildeHomePath(const QString &path)
std::string getenv(const std::string &name)
Returns environment variable.
Definition: SysUtils.cpp:48
Defines functions from Utils namespace.