From 5ae95b88a94eee92e4581f96c96741db63a52055 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 13:11:56 +0100 Subject: [PATCH 01/18] Cloned GUI/View/Manager/ProjectManager -> GUI/Support/Data/Dirs --- GUI/Support/Data/Dirs.cpp | 451 ++++++++++++++++++++++++++++++++++++++ GUI/Support/Data/Dirs.h | 96 ++++++++ 2 files changed, 547 insertions(+) create mode 100644 GUI/Support/Data/Dirs.cpp create mode 100644 GUI/Support/Data/Dirs.h diff --git a/GUI/Support/Data/Dirs.cpp b/GUI/Support/Data/Dirs.cpp new file mode 100644 index 00000000000..ce26507323a --- /dev/null +++ b/GUI/Support/Data/Dirs.cpp @@ -0,0 +1,451 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Support/Data/Dirs.cpp +//! @brief Implements class ProjectManager. +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#include "GUI/View/Manager/ProjectManager.h" +#include "Base/Util/Assert.h" +#include "GUI/Model/Project/ProjectUtil.h" +#include "GUI/Support/Util/MessageService.h" +#include "GUI/View/Info/MessageBox.h" +#include "GUI/View/Layout/ApplicationSettings.h" +#include "GUI/View/Layout/mainwindow_constants.h" +#include "GUI/View/Manager/AutosaveController.h" +#include "GUI/View/Manager/NewProjectDialog.h" +#include "GUI/View/Manager/ProjectLoadProblemDialog.h" +#include "GUI/View/Tool/Globals.h" +#include <QApplication> +#include <QDateTime> +#include <QFileDialog> +#include <QMessageBox> +#include <QSettings> +#include <memory> + +namespace { + +const QString S_PROJECTMANAGER = "ProjectManager"; +const QString S_AUTOSAVE = "EnableAutosave"; +const QString S_DEFAULTPROJECTPATH = "DefaultProjectPath"; +const QString S_RECENTPROJECTS = "RecentProjects"; +const QString S_LASTUSEDIMPORTDIR = "LastUsedImportDir"; +const QString S_LASTUSEDIMPORFILTER1D = "LastUsedImportFilter1D"; +const QString S_LASTUSEDIMPORFILTER2D = "LastUsedImportFilter2D"; + +} // namespace + + +ProjectManager* ProjectManager::s_instance = nullptr; + +ProjectManager::ProjectManager(QObject* parent) + : QObject(parent) +{ + ASSERT(!s_instance); // it's a singleton + s_instance = this; +} + +ProjectManager::~ProjectManager() +{ + s_instance = nullptr; + gDoc.release(); +} + +ProjectManager* ProjectManager::instance() +{ + ASSERT(s_instance); + return s_instance; +} + +//! Reads settings of ProjectManager from global settings. + +void ProjectManager::readSettings() +{ + QSettings settings; + m_working_directory = QDir::homePath(); + if (settings.childGroups().contains(S_PROJECTMANAGER)) { + settings.beginGroup(S_PROJECTMANAGER); + + if (!settings.contains(S_AUTOSAVE)) + settings.setValue(S_AUTOSAVE, true); + + m_working_directory = settings.value(S_DEFAULTPROJECTPATH).toString(); + m_recent_projects = settings.value(S_RECENTPROJECTS).toStringList(); + + if (settings.contains(S_LASTUSEDIMPORTDIR)) + m_import_directory = settings.value(S_LASTUSEDIMPORTDIR, QString()).toString(); + + m_import_filter1D = settings.value(S_LASTUSEDIMPORFILTER1D, m_import_filter1D).toString(); + m_import_filter2D = settings.value(S_LASTUSEDIMPORFILTER2D, m_import_filter2D).toString(); + + setAutosaveEnabled(settings.value(S_AUTOSAVE).toBool()); + + settings.endGroup(); + } +} + +//! Saves settings of ProjectManager in global settings. + +void ProjectManager::writeSettings() +{ + QSettings settings; + settings.beginGroup(S_PROJECTMANAGER); + settings.setValue(S_DEFAULTPROJECTPATH, m_working_directory); + settings.setValue(S_RECENTPROJECTS, m_recent_projects); + + if (!m_import_directory.isEmpty()) + settings.setValue(S_LASTUSEDIMPORTDIR, m_import_directory); + settings.setValue(S_LASTUSEDIMPORFILTER1D, m_import_filter1D); + settings.setValue(S_LASTUSEDIMPORFILTER2D, m_import_filter2D); + + settings.endGroup(); +} + +//! Returns list of recent projects, validates if projects still exists on disk. + +QStringList ProjectManager::recentProjects() +{ + QStringList updatedList; + for (const QString& fname : m_recent_projects) + if (QFile fin(fname); fin.exists()) + updatedList.append(fname); + m_recent_projects = updatedList; + return m_recent_projects; +} + +//! Returns name of the current project directory. + +QString ProjectManager::projectDir() const +{ + if (gDoc) + return gDoc->validProjectDir(); + return ""; +} + +//! Returns directory name which was used by the user to import files. + +QString ProjectManager::userImportDir() const +{ + if (m_import_directory.isEmpty()) { + if (gDoc) + return gDoc->userExportDir(); + return ""; + } + return m_import_directory; +} //! Sets user import directory in system settings. + +void ProjectManager::setImportDir(const QString& dirname) +{ + m_import_directory = dirname; +} + +//! Sets user import directory in system settings. + +void ProjectManager::setImportDirFromFilePath(const QString& filePath) +{ + m_import_directory = QFileInfo(filePath).absolutePath(); +} + +void ProjectManager::setRecentlyUsedImportFilter1D(const QString& filter) +{ + m_import_filter1D = filter; +} + +void ProjectManager::setRecentlyUsedImportFilter2D(const QString& filter) +{ + m_import_filter2D = filter; +} + +bool ProjectManager::isAutosaveEnabled() const +{ + return static_cast<bool>(m_autosave); +} + +AutosaveController* ProjectManager::autosaveController() const +{ + return m_autosave.get(); +} + +void ProjectManager::setAutosaveEnabled(bool value) +{ + if (value) + m_autosave = std::make_unique<AutosaveController>(); + else + m_autosave.reset(); + + QSettings settings; + settings.setValue(S_PROJECTMANAGER + "/" + S_AUTOSAVE, value); +} + +//! Clears list of recent projects. + +void ProjectManager::clearRecentProjects() +{ + m_recent_projects.clear(); + emit recentListModified(); +} + +//! Processes new project request (close old project, rise dialog for project name, create project). + +ProjectDocument* ProjectManager::newProject() +{ + if (!closeCurrentProject()) + return nullptr; + createNewProject(); + emit documentOpenedOrClosed(true); + return gDoc.get(); +} + +//! Processes close current project request. Call save/discard/cancel dialog, if necessary. +//! Returns false if saving was canceled. + +bool ProjectManager::closeCurrentProject() +{ + if (!gDoc) + return true; + + if (gDoc->isModified()) { + QMessageBox msgBox; + msgBox.setText("The project has been modified."); + msgBox.setInformativeText("Do you want to save your changes?"); + msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Save); + + switch (msgBox.exec()) { + case QMessageBox::Save: + if (!saveProject()) + return false; + break; + case QMessageBox::Discard: + break; + case QMessageBox::Cancel: + return false; + default: + break; + } + } + + deleteCurrentProject(); + emit documentOpenedOrClosed(false); + return true; +} + +//! Processes save project request. + +bool ProjectManager::saveProject(QString projectPullPath) +{ + if (projectPullPath.isEmpty()) { + if (gDoc->hasValidNameAndPath()) + projectPullPath = gDoc->projectFullPath(); + else + projectPullPath = acquireProjectPullPath(); + } + + if (projectPullPath.isEmpty()) + return false; + + gDoc->setProjectName(GUI::Util::Project::projectName(projectPullPath)); + gDoc->setProjectDir(GUI::Util::Project::projectDir(projectPullPath)); + + try { + gDoc->saveProjectFileWithData(projectPullPath); + } catch (const std::exception& ex) { + QString message = QString("Failed to save project under '%1'. \n\n").arg(projectPullPath); + message.append("Exception was thrown.\n\n"); + message.append(ex.what()); + + QMessageBox::warning(GUI::Global::mainWindow, "Error while saving project", message); + return false; + } + addToRecentProjects(); + return true; +} + +//! Processes 'save project as' request. + +bool ProjectManager::saveProjectAs() +{ + QString projectFileName = acquireProjectPullPath(); + + if (projectFileName.isEmpty()) + return false; + + return saveProject(projectFileName); +} + +//! Opens existing project. If fname is empty, will popup file selection dialog. + +void ProjectManager::openProject(QString projectPullPath) +{ + if (!closeCurrentProject()) + return; + + if (projectPullPath.isEmpty()) { + const QString ext = QString(GUI::Util::Project::projectFileExtension); + projectPullPath = QFileDialog::getOpenFileName( + GUI::Global::mainWindow, "Open project file", workingDirectory(), + "BornAgain project Files (*" + ext + ")", nullptr, + appSettings->useNativeFileDialog() ? QFileDialog::Options() + : QFileDialog::DontUseNativeDialog); + if (projectPullPath.isEmpty()) + return; + } + + createNewProject(); + MessageService messageService; + const auto readResult = loadProject(projectPullPath, messageService); + + if (readResult == ProjectDocument::ReadResult::ok) + addToRecentProjects(); + else if (readResult == ProjectDocument::ReadResult::error) { + riseProjectLoadFailedDialog(messageService); + deleteCurrentProject(); + } else if (readResult == ProjectDocument::ReadResult::warning) { + riseProjectLoadProblemDialog(messageService); + addToRecentProjects(); + } + if (gDoc) + emit documentOpenedOrClosed(true); +} + +//! Calls dialog window to define project path and name. + +void ProjectManager::createNewProject() +{ + if (gDoc) + throw std::runtime_error("ProjectManager::createNewProject -> Project already exists"); + + gDoc.reset(new ProjectDocument); + + if (m_autosave) + m_autosave->setDocument(gDoc.get()); + + gDoc->setProjectName("Untitled"); + + connect(gDoc.get(), &ProjectDocument::modifiedStateChanged, this, + &ProjectManager::documentModified); +} + +void ProjectManager::deleteCurrentProject() +{ + emit aboutToCloseDocument(); + if (m_autosave) + m_autosave->removeAutosaveDir(); + gDoc.release(); +} + +//! Load project data from file name. If autosave info exists, opens dialog for project restore. + +ProjectDocument::ReadResult ProjectManager::loadProject(const QString& fullPathAndName, + MessageService& messageService) +{ + auto readResult = ProjectDocument::ReadResult::ok; + + const bool useAutosave = GUI::Util::Project::hasAutosavedData(fullPathAndName); + const QString autosaveFullPath = GUI::Util::Project::autosaveFullPath(fullPathAndName); + if (qApp) + QApplication::setOverrideCursor(Qt::WaitCursor); + if (useAutosave && restoreProjectDialog(fullPathAndName, autosaveFullPath)) { + readResult = gDoc->loadProjectFileWithData(autosaveFullPath, messageService); + gDoc->setProjectFullPath(fullPathAndName); + // restored project should be marked by '*' + gDoc->setModified(); + } else { + readResult = gDoc->loadProjectFileWithData(fullPathAndName, messageService); + } + if (qApp) + QApplication::restoreOverrideCursor(); + return readResult; +} + +//! Returns project file name from dialog. Returns empty string if dialog was canceled. + +QString ProjectManager::acquireProjectPullPath() +{ + NewProjectDialog dialog(GUI::Global::mainWindow, workingDirectory(), untitledProjectName()); + + if (dialog.exec() != QDialog::Accepted) + return ""; + + m_working_directory = dialog.getWorkingDirectory(); + + return dialog.getProjectFileName(); +} + +//! Add name of the current project to the name of recent projects + +void ProjectManager::addToRecentProjects() +{ + QString fname = gDoc->projectFullPath(); + m_recent_projects.removeAll(fname); + m_recent_projects.prepend(fname); + while (m_recent_projects.size() > GUI::Style::MAX_RECENT_PROJECTS) + m_recent_projects.removeLast(); + + emit recentListModified(); +} + +//! Returns default project path. +//! Will return 'Untitled' if the directory with such name doesn't exist in project +//! path. Otherwise will return Untitled1, Untitled2 etc. + +QString ProjectManager::untitledProjectName() +{ + QString result = "Untitled"; + QDir projectDir = workingDirectory() + "/" + result; + if (projectDir.exists()) { + for (size_t i = 1; i < 99; ++i) { + result = QString("Untitled") + QString::number(i); + projectDir.setPath(workingDirectory() + "/" + result); + if (!projectDir.exists()) + break; + } + } + return result; +} + +void ProjectManager::riseProjectLoadFailedDialog(const MessageService& messageService) +{ + QString message = QString("Failed to load the project '%1' \n\n").arg(gDoc->projectFullPath()); + + for (const auto& details : messageService.errors()) + message.append(details + "\n"); + + QMessageBox::warning(GUI::Global::mainWindow, "Error while opening project file", message); +} + +void ProjectManager::riseProjectLoadProblemDialog(const MessageService& messageService) +{ + auto* problemDialog = new ProjectLoadProblemDialog(messageService.warnings(true)); + problemDialog->show(); + problemDialog->raise(); +} + +//! Rises dialog if the project should be restored from autosave. Returns true, if yes. + +bool ProjectManager::restoreProjectDialog(const QString& projectFileName, + const QString autosaveName) +{ + const QString title("Recover project"); + const QString lmProject = + QFileInfo(projectFileName).lastModified().toString("hh:mm:ss, MMMM d, yyyy"); + const QString lmAutoSave = + QFileInfo(autosaveName).lastModified().toString("hh:mm:ss, MMMM d, yyyy"); + + QString message = QString("Project '%1' contains autosaved data.\n\n" + "Project saved at %2\nAutosave from %3") + .arg(GUI::Util::Project::projectName(projectFileName)) + .arg(lmProject) + .arg(lmAutoSave); + + return GUI::Message::question(GUI::Global::mainWindow, title, message, + "\nDo you want to restore from autosave?\n", + "Yes, please restore.", "No, keep loading original"); +} diff --git a/GUI/Support/Data/Dirs.h b/GUI/Support/Data/Dirs.h new file mode 100644 index 00000000000..cafc4739299 --- /dev/null +++ b/GUI/Support/Data/Dirs.h @@ -0,0 +1,96 @@ +// ************************************************************************************************ +// +// BornAgain: simulate and fit reflection and scattering +// +//! @file GUI/Support/Data/Dirs.h +//! @brief Defines class ProjectManager. +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) +// +// ************************************************************************************************ + +#ifndef BORNAGAIN_GUI_SUPPORT_DATA_DIRS_H +#define BORNAGAIN_GUI_SUPPORT_DATA_DIRS_H + +#include "GUI/Model/Project/ProjectDocument.h" + +class AutosaveController; + +//! Handles activity related to opening/save projects. + +class ProjectManager : public QObject { + Q_OBJECT +public: + ProjectManager(QObject* parent); + ~ProjectManager() override; + + static ProjectManager* instance(); + + void readSettings(); + void writeSettings(); + + QStringList recentProjects(); + QString projectDir() const; + QString userImportDir() const; + QString recentlyUsedImportFilter1D() const { return m_import_filter1D; } + QString recentlyUsedImportFilter2D() const { return m_import_filter2D; } + void setImportDir(const QString& dirname); + void setImportDirFromFilePath(const QString& filePath); + void setRecentlyUsedImportFilter1D(const QString& filter); + void setRecentlyUsedImportFilter2D(const QString& filter); + + bool isAutosaveEnabled() const; + AutosaveController* autosaveController() const; + +signals: + void aboutToCloseDocument(); + void documentOpenedOrClosed(bool opened); + void documentModified(); + void recentListModified(); + +public slots: + void setAutosaveEnabled(bool value); + void clearRecentProjects(); + ProjectDocument* newProject(); + bool closeCurrentProject(); + bool saveProject(QString projectPullPath = ""); + bool saveProjectAs(); + void openProject(QString projectPullPath = ""); + +private: + void createNewProject(); + void deleteCurrentProject(); + ProjectDocument::ReadResult loadProject(const QString& fullPathAndName, + MessageService& messageService); + QString acquireProjectPullPath(); + void addToRecentProjects(); + + QString workingDirectory() { return m_working_directory; } + QString untitledProjectName(); + + void riseProjectLoadFailedDialog(const MessageService& messageService); + void riseProjectLoadProblemDialog(const MessageService& messageService); + bool restoreProjectDialog(const QString& projectFileName, QString autosaveName); + + //!< Name of directory where project directory was created. + QString m_working_directory; + + //!< Name of directory from there user prefer to import files + QString m_import_directory; + + //! Recently used import filter for 1D files + QString m_import_filter1D; + + //! Recently used import filter for 2D files + QString m_import_filter2D; + + QStringList m_recent_projects; + std::unique_ptr<AutosaveController> m_autosave; + + static ProjectManager* s_instance; +}; + +#endif // BORNAGAIN_GUI_SUPPORT_DATA_DIRS_H -- GitLab From fcc543c69c1c4bd678a177bc9233d940fa75bdcd Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 13:33:39 +0100 Subject: [PATCH 02/18] src pair Dirs.* extracted from ProjectManager --- App/main.cpp | 6 + GUI/Support/Data/Dirs.cpp | 392 ++------------------------------------ GUI/Support/Data/Dirs.h | 57 ++---- 3 files changed, 38 insertions(+), 417 deletions(-) diff --git a/App/main.cpp b/App/main.cpp index c35b994c080..5505eab5b38 100644 --- a/App/main.cpp +++ b/App/main.cpp @@ -14,6 +14,7 @@ #include "App/AppOptions.h" #include "Base/Util/Assert.h" +#include "GUI/Support/Data/Dirs.h" #include "GUI/Support/Util/Path.h" #include "GUI/View/Layout/ApplicationSettings.h" #include "GUI/View/Main/MainWindow.h" @@ -28,6 +29,9 @@ #include <QtGlobal> #include <iostream> +// Global variables +BA_GUI_API_ std::unique_ptr<Dirs> gDirs; + void custom_terminate_handler() { try { @@ -74,6 +78,8 @@ int main(int argc, char* argv[]) if (!QDir().exists(dir)) QDir().mkpath(dir); + gDirs = std::make_unique<Dirs>(); + MainWindow win; GUI::Global::mainWindow = &win; diff --git a/GUI/Support/Data/Dirs.cpp b/GUI/Support/Data/Dirs.cpp index ce26507323a..44eb199b2aa 100644 --- a/GUI/Support/Data/Dirs.cpp +++ b/GUI/Support/Data/Dirs.cpp @@ -3,7 +3,7 @@ // BornAgain: simulate and fit reflection and scattering // //! @file GUI/Support/Data/Dirs.cpp -//! @brief Implements class ProjectManager. +//! @brief Implements class Dirs. //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) @@ -12,30 +12,16 @@ // // ************************************************************************************************ -#include "GUI/View/Manager/ProjectManager.h" +#include "GUI/Support/Data/Dirs.h" #include "Base/Util/Assert.h" -#include "GUI/Model/Project/ProjectUtil.h" -#include "GUI/Support/Util/MessageService.h" -#include "GUI/View/Info/MessageBox.h" -#include "GUI/View/Layout/ApplicationSettings.h" -#include "GUI/View/Layout/mainwindow_constants.h" -#include "GUI/View/Manager/AutosaveController.h" -#include "GUI/View/Manager/NewProjectDialog.h" -#include "GUI/View/Manager/ProjectLoadProblemDialog.h" -#include "GUI/View/Tool/Globals.h" -#include <QApplication> -#include <QDateTime> -#include <QFileDialog> -#include <QMessageBox> +#include <QDir> +#include <QFileInfo> #include <QSettings> -#include <memory> namespace { -const QString S_PROJECTMANAGER = "ProjectManager"; -const QString S_AUTOSAVE = "EnableAutosave"; +const QString S_DIRS = "Dirs"; const QString S_DEFAULTPROJECTPATH = "DefaultProjectPath"; -const QString S_RECENTPROJECTS = "RecentProjects"; const QString S_LASTUSEDIMPORTDIR = "LastUsedImportDir"; const QString S_LASTUSEDIMPORFILTER1D = "LastUsedImportFilter1D"; const QString S_LASTUSEDIMPORFILTER2D = "LastUsedImportFilter2D"; @@ -43,41 +29,26 @@ const QString S_LASTUSEDIMPORFILTER2D = "LastUsedImportFilter2D"; } // namespace -ProjectManager* ProjectManager::s_instance = nullptr; - -ProjectManager::ProjectManager(QObject* parent) - : QObject(parent) -{ - ASSERT(!s_instance); // it's a singleton - s_instance = this; -} - -ProjectManager::~ProjectManager() +Dirs::Dirs() { - s_instance = nullptr; - gDoc.release(); + readSettings(); } -ProjectManager* ProjectManager::instance() +Dirs::~Dirs() { - ASSERT(s_instance); - return s_instance; + writeSettings(); } -//! Reads settings of ProjectManager from global settings. +//! Reads settings of Dirs from global settings. -void ProjectManager::readSettings() +void Dirs::readSettings() { QSettings settings; m_working_directory = QDir::homePath(); - if (settings.childGroups().contains(S_PROJECTMANAGER)) { - settings.beginGroup(S_PROJECTMANAGER); - - if (!settings.contains(S_AUTOSAVE)) - settings.setValue(S_AUTOSAVE, true); + if (settings.childGroups().contains(S_DIRS)) { + settings.beginGroup(S_DIRS); m_working_directory = settings.value(S_DEFAULTPROJECTPATH).toString(); - m_recent_projects = settings.value(S_RECENTPROJECTS).toStringList(); if (settings.contains(S_LASTUSEDIMPORTDIR)) m_import_directory = settings.value(S_LASTUSEDIMPORTDIR, QString()).toString(); @@ -85,20 +56,17 @@ void ProjectManager::readSettings() m_import_filter1D = settings.value(S_LASTUSEDIMPORFILTER1D, m_import_filter1D).toString(); m_import_filter2D = settings.value(S_LASTUSEDIMPORFILTER2D, m_import_filter2D).toString(); - setAutosaveEnabled(settings.value(S_AUTOSAVE).toBool()); - settings.endGroup(); } } -//! Saves settings of ProjectManager in global settings. +//! Saves settings of Dirs in global settings. -void ProjectManager::writeSettings() +void Dirs::writeSettings() { QSettings settings; - settings.beginGroup(S_PROJECTMANAGER); + settings.beginGroup(S_DIRS); settings.setValue(S_DEFAULTPROJECTPATH, m_working_directory); - settings.setValue(S_RECENTPROJECTS, m_recent_projects); if (!m_import_directory.isEmpty()) settings.setValue(S_LASTUSEDIMPORTDIR, m_import_directory); @@ -108,344 +76,24 @@ void ProjectManager::writeSettings() settings.endGroup(); } -//! Returns list of recent projects, validates if projects still exists on disk. - -QStringList ProjectManager::recentProjects() -{ - QStringList updatedList; - for (const QString& fname : m_recent_projects) - if (QFile fin(fname); fin.exists()) - updatedList.append(fname); - m_recent_projects = updatedList; - return m_recent_projects; -} - -//! Returns name of the current project directory. - -QString ProjectManager::projectDir() const -{ - if (gDoc) - return gDoc->validProjectDir(); - return ""; -} - -//! Returns directory name which was used by the user to import files. - -QString ProjectManager::userImportDir() const -{ - if (m_import_directory.isEmpty()) { - if (gDoc) - return gDoc->userExportDir(); - return ""; - } - return m_import_directory; -} //! Sets user import directory in system settings. - -void ProjectManager::setImportDir(const QString& dirname) +void Dirs::setImportDir(const QString& dirname) { m_import_directory = dirname; } //! Sets user import directory in system settings. -void ProjectManager::setImportDirFromFilePath(const QString& filePath) +void Dirs::setImportDirFromFilePath(const QString& filePath) { m_import_directory = QFileInfo(filePath).absolutePath(); } -void ProjectManager::setRecentlyUsedImportFilter1D(const QString& filter) +void Dirs::setRecentlyUsedImportFilter1D(const QString& filter) { m_import_filter1D = filter; } -void ProjectManager::setRecentlyUsedImportFilter2D(const QString& filter) +void Dirs::setRecentlyUsedImportFilter2D(const QString& filter) { m_import_filter2D = filter; } - -bool ProjectManager::isAutosaveEnabled() const -{ - return static_cast<bool>(m_autosave); -} - -AutosaveController* ProjectManager::autosaveController() const -{ - return m_autosave.get(); -} - -void ProjectManager::setAutosaveEnabled(bool value) -{ - if (value) - m_autosave = std::make_unique<AutosaveController>(); - else - m_autosave.reset(); - - QSettings settings; - settings.setValue(S_PROJECTMANAGER + "/" + S_AUTOSAVE, value); -} - -//! Clears list of recent projects. - -void ProjectManager::clearRecentProjects() -{ - m_recent_projects.clear(); - emit recentListModified(); -} - -//! Processes new project request (close old project, rise dialog for project name, create project). - -ProjectDocument* ProjectManager::newProject() -{ - if (!closeCurrentProject()) - return nullptr; - createNewProject(); - emit documentOpenedOrClosed(true); - return gDoc.get(); -} - -//! Processes close current project request. Call save/discard/cancel dialog, if necessary. -//! Returns false if saving was canceled. - -bool ProjectManager::closeCurrentProject() -{ - if (!gDoc) - return true; - - if (gDoc->isModified()) { - QMessageBox msgBox; - msgBox.setText("The project has been modified."); - msgBox.setInformativeText("Do you want to save your changes?"); - msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - msgBox.setDefaultButton(QMessageBox::Save); - - switch (msgBox.exec()) { - case QMessageBox::Save: - if (!saveProject()) - return false; - break; - case QMessageBox::Discard: - break; - case QMessageBox::Cancel: - return false; - default: - break; - } - } - - deleteCurrentProject(); - emit documentOpenedOrClosed(false); - return true; -} - -//! Processes save project request. - -bool ProjectManager::saveProject(QString projectPullPath) -{ - if (projectPullPath.isEmpty()) { - if (gDoc->hasValidNameAndPath()) - projectPullPath = gDoc->projectFullPath(); - else - projectPullPath = acquireProjectPullPath(); - } - - if (projectPullPath.isEmpty()) - return false; - - gDoc->setProjectName(GUI::Util::Project::projectName(projectPullPath)); - gDoc->setProjectDir(GUI::Util::Project::projectDir(projectPullPath)); - - try { - gDoc->saveProjectFileWithData(projectPullPath); - } catch (const std::exception& ex) { - QString message = QString("Failed to save project under '%1'. \n\n").arg(projectPullPath); - message.append("Exception was thrown.\n\n"); - message.append(ex.what()); - - QMessageBox::warning(GUI::Global::mainWindow, "Error while saving project", message); - return false; - } - addToRecentProjects(); - return true; -} - -//! Processes 'save project as' request. - -bool ProjectManager::saveProjectAs() -{ - QString projectFileName = acquireProjectPullPath(); - - if (projectFileName.isEmpty()) - return false; - - return saveProject(projectFileName); -} - -//! Opens existing project. If fname is empty, will popup file selection dialog. - -void ProjectManager::openProject(QString projectPullPath) -{ - if (!closeCurrentProject()) - return; - - if (projectPullPath.isEmpty()) { - const QString ext = QString(GUI::Util::Project::projectFileExtension); - projectPullPath = QFileDialog::getOpenFileName( - GUI::Global::mainWindow, "Open project file", workingDirectory(), - "BornAgain project Files (*" + ext + ")", nullptr, - appSettings->useNativeFileDialog() ? QFileDialog::Options() - : QFileDialog::DontUseNativeDialog); - if (projectPullPath.isEmpty()) - return; - } - - createNewProject(); - MessageService messageService; - const auto readResult = loadProject(projectPullPath, messageService); - - if (readResult == ProjectDocument::ReadResult::ok) - addToRecentProjects(); - else if (readResult == ProjectDocument::ReadResult::error) { - riseProjectLoadFailedDialog(messageService); - deleteCurrentProject(); - } else if (readResult == ProjectDocument::ReadResult::warning) { - riseProjectLoadProblemDialog(messageService); - addToRecentProjects(); - } - if (gDoc) - emit documentOpenedOrClosed(true); -} - -//! Calls dialog window to define project path and name. - -void ProjectManager::createNewProject() -{ - if (gDoc) - throw std::runtime_error("ProjectManager::createNewProject -> Project already exists"); - - gDoc.reset(new ProjectDocument); - - if (m_autosave) - m_autosave->setDocument(gDoc.get()); - - gDoc->setProjectName("Untitled"); - - connect(gDoc.get(), &ProjectDocument::modifiedStateChanged, this, - &ProjectManager::documentModified); -} - -void ProjectManager::deleteCurrentProject() -{ - emit aboutToCloseDocument(); - if (m_autosave) - m_autosave->removeAutosaveDir(); - gDoc.release(); -} - -//! Load project data from file name. If autosave info exists, opens dialog for project restore. - -ProjectDocument::ReadResult ProjectManager::loadProject(const QString& fullPathAndName, - MessageService& messageService) -{ - auto readResult = ProjectDocument::ReadResult::ok; - - const bool useAutosave = GUI::Util::Project::hasAutosavedData(fullPathAndName); - const QString autosaveFullPath = GUI::Util::Project::autosaveFullPath(fullPathAndName); - if (qApp) - QApplication::setOverrideCursor(Qt::WaitCursor); - if (useAutosave && restoreProjectDialog(fullPathAndName, autosaveFullPath)) { - readResult = gDoc->loadProjectFileWithData(autosaveFullPath, messageService); - gDoc->setProjectFullPath(fullPathAndName); - // restored project should be marked by '*' - gDoc->setModified(); - } else { - readResult = gDoc->loadProjectFileWithData(fullPathAndName, messageService); - } - if (qApp) - QApplication::restoreOverrideCursor(); - return readResult; -} - -//! Returns project file name from dialog. Returns empty string if dialog was canceled. - -QString ProjectManager::acquireProjectPullPath() -{ - NewProjectDialog dialog(GUI::Global::mainWindow, workingDirectory(), untitledProjectName()); - - if (dialog.exec() != QDialog::Accepted) - return ""; - - m_working_directory = dialog.getWorkingDirectory(); - - return dialog.getProjectFileName(); -} - -//! Add name of the current project to the name of recent projects - -void ProjectManager::addToRecentProjects() -{ - QString fname = gDoc->projectFullPath(); - m_recent_projects.removeAll(fname); - m_recent_projects.prepend(fname); - while (m_recent_projects.size() > GUI::Style::MAX_RECENT_PROJECTS) - m_recent_projects.removeLast(); - - emit recentListModified(); -} - -//! Returns default project path. -//! Will return 'Untitled' if the directory with such name doesn't exist in project -//! path. Otherwise will return Untitled1, Untitled2 etc. - -QString ProjectManager::untitledProjectName() -{ - QString result = "Untitled"; - QDir projectDir = workingDirectory() + "/" + result; - if (projectDir.exists()) { - for (size_t i = 1; i < 99; ++i) { - result = QString("Untitled") + QString::number(i); - projectDir.setPath(workingDirectory() + "/" + result); - if (!projectDir.exists()) - break; - } - } - return result; -} - -void ProjectManager::riseProjectLoadFailedDialog(const MessageService& messageService) -{ - QString message = QString("Failed to load the project '%1' \n\n").arg(gDoc->projectFullPath()); - - for (const auto& details : messageService.errors()) - message.append(details + "\n"); - - QMessageBox::warning(GUI::Global::mainWindow, "Error while opening project file", message); -} - -void ProjectManager::riseProjectLoadProblemDialog(const MessageService& messageService) -{ - auto* problemDialog = new ProjectLoadProblemDialog(messageService.warnings(true)); - problemDialog->show(); - problemDialog->raise(); -} - -//! Rises dialog if the project should be restored from autosave. Returns true, if yes. - -bool ProjectManager::restoreProjectDialog(const QString& projectFileName, - const QString autosaveName) -{ - const QString title("Recover project"); - const QString lmProject = - QFileInfo(projectFileName).lastModified().toString("hh:mm:ss, MMMM d, yyyy"); - const QString lmAutoSave = - QFileInfo(autosaveName).lastModified().toString("hh:mm:ss, MMMM d, yyyy"); - - QString message = QString("Project '%1' contains autosaved data.\n\n" - "Project saved at %2\nAutosave from %3") - .arg(GUI::Util::Project::projectName(projectFileName)) - .arg(lmProject) - .arg(lmAutoSave); - - return GUI::Message::question(GUI::Global::mainWindow, title, message, - "\nDo you want to restore from autosave?\n", - "Yes, please restore.", "No, keep loading original"); -} diff --git a/GUI/Support/Data/Dirs.h b/GUI/Support/Data/Dirs.h index cafc4739299..884f11c2f90 100644 --- a/GUI/Support/Data/Dirs.h +++ b/GUI/Support/Data/Dirs.h @@ -3,7 +3,7 @@ // BornAgain: simulate and fit reflection and scattering // //! @file GUI/Support/Data/Dirs.h -//! @brief Defines class ProjectManager. +//! @brief Defines class Dirs. //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) @@ -15,26 +15,19 @@ #ifndef BORNAGAIN_GUI_SUPPORT_DATA_DIRS_H #define BORNAGAIN_GUI_SUPPORT_DATA_DIRS_H -#include "GUI/Model/Project/ProjectDocument.h" - -class AutosaveController; +#include "Wrap/WinDllMacros.h" +#include <QStringList> //! Handles activity related to opening/save projects. -class ProjectManager : public QObject { - Q_OBJECT +class Dirs { public: - ProjectManager(QObject* parent); - ~ProjectManager() override; + Dirs(); + ~Dirs(); - static ProjectManager* instance(); + static Dirs* instance(); - void readSettings(); - void writeSettings(); - QStringList recentProjects(); - QString projectDir() const; - QString userImportDir() const; QString recentlyUsedImportFilter1D() const { return m_import_filter1D; } QString recentlyUsedImportFilter2D() const { return m_import_filter2D; } void setImportDir(const QString& dirname); @@ -42,38 +35,11 @@ public: void setRecentlyUsedImportFilter1D(const QString& filter); void setRecentlyUsedImportFilter2D(const QString& filter); - bool isAutosaveEnabled() const; - AutosaveController* autosaveController() const; - -signals: - void aboutToCloseDocument(); - void documentOpenedOrClosed(bool opened); - void documentModified(); - void recentListModified(); - -public slots: - void setAutosaveEnabled(bool value); - void clearRecentProjects(); - ProjectDocument* newProject(); - bool closeCurrentProject(); - bool saveProject(QString projectPullPath = ""); - bool saveProjectAs(); - void openProject(QString projectPullPath = ""); - private: - void createNewProject(); - void deleteCurrentProject(); - ProjectDocument::ReadResult loadProject(const QString& fullPathAndName, - MessageService& messageService); - QString acquireProjectPullPath(); - void addToRecentProjects(); + void readSettings(); + void writeSettings(); QString workingDirectory() { return m_working_directory; } - QString untitledProjectName(); - - void riseProjectLoadFailedDialog(const MessageService& messageService); - void riseProjectLoadProblemDialog(const MessageService& messageService); - bool restoreProjectDialog(const QString& projectFileName, QString autosaveName); //!< Name of directory where project directory was created. QString m_working_directory; @@ -88,9 +54,10 @@ private: QString m_import_filter2D; QStringList m_recent_projects; - std::unique_ptr<AutosaveController> m_autosave; - static ProjectManager* s_instance; + static Dirs* s_instance; }; +BA_GUI_API_ extern std::unique_ptr<Dirs> gDirs; + #endif // BORNAGAIN_GUI_SUPPORT_DATA_DIRS_H -- GitLab From 32d05181397539f33b5e29beddddaae01b7e0b4e Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 14:21:57 +0100 Subject: [PATCH 03/18] ... --- App/main.cpp | 3 -- GUI/Support/Data/Dirs.cpp | 20 +++++++-- GUI/Support/Data/Dirs.h | 10 +---- GUI/View/Loader/DataLoader.cpp | 17 ++++---- GUI/View/Manager/ProjectManager.cpp | 58 +++----------------------- GUI/View/Manager/ProjectManager.h | 19 --------- GUI/View/Manager/PyImportAssistant.cpp | 6 +-- 7 files changed, 36 insertions(+), 97 deletions(-) diff --git a/App/main.cpp b/App/main.cpp index 5505eab5b38..0a7aabb5f72 100644 --- a/App/main.cpp +++ b/App/main.cpp @@ -29,9 +29,6 @@ #include <QtGlobal> #include <iostream> -// Global variables -BA_GUI_API_ std::unique_ptr<Dirs> gDirs; - void custom_terminate_handler() { try { diff --git a/GUI/Support/Data/Dirs.cpp b/GUI/Support/Data/Dirs.cpp index 44eb199b2aa..bcef548b9ce 100644 --- a/GUI/Support/Data/Dirs.cpp +++ b/GUI/Support/Data/Dirs.cpp @@ -28,6 +28,7 @@ const QString S_LASTUSEDIMPORFILTER2D = "LastUsedImportFilter2D"; } // namespace +BA_GUI_API_ std::unique_ptr<Dirs> gDirs; Dirs::Dirs() { @@ -44,12 +45,9 @@ Dirs::~Dirs() void Dirs::readSettings() { QSettings settings; - m_working_directory = QDir::homePath(); if (settings.childGroups().contains(S_DIRS)) { settings.beginGroup(S_DIRS); - m_working_directory = settings.value(S_DEFAULTPROJECTPATH).toString(); - if (settings.contains(S_LASTUSEDIMPORTDIR)) m_import_directory = settings.value(S_LASTUSEDIMPORTDIR, QString()).toString(); @@ -66,7 +64,6 @@ void Dirs::writeSettings() { QSettings settings; settings.beginGroup(S_DIRS); - settings.setValue(S_DEFAULTPROJECTPATH, m_working_directory); if (!m_import_directory.isEmpty()) settings.setValue(S_LASTUSEDIMPORTDIR, m_import_directory); @@ -76,6 +73,21 @@ void Dirs::writeSettings() settings.endGroup(); } +//! Returns directory name which was used by the user to import files. + +QString Dirs::userImportDir() const +{ + /* + if (m_import_directory.isEmpty()) { + if (gDoc) + return gDoc->userExportDir(); + return ""; + } + */ + return m_import_directory; +} //! Sets user import directory in system settings. + + void Dirs::setImportDir(const QString& dirname) { m_import_directory = dirname; diff --git a/GUI/Support/Data/Dirs.h b/GUI/Support/Data/Dirs.h index 884f11c2f90..fa03176c1ca 100644 --- a/GUI/Support/Data/Dirs.h +++ b/GUI/Support/Data/Dirs.h @@ -25,11 +25,10 @@ public: Dirs(); ~Dirs(); - static Dirs* instance(); - - + QString userImportDir() const; QString recentlyUsedImportFilter1D() const { return m_import_filter1D; } QString recentlyUsedImportFilter2D() const { return m_import_filter2D; } + void setImportDir(const QString& dirname); void setImportDirFromFilePath(const QString& filePath); void setRecentlyUsedImportFilter1D(const QString& filter); @@ -39,11 +38,6 @@ private: void readSettings(); void writeSettings(); - QString workingDirectory() { return m_working_directory; } - - //!< Name of directory where project directory was created. - QString m_working_directory; - //!< Name of directory from there user prefer to import files QString m_import_directory; diff --git a/GUI/View/Loader/DataLoader.cpp b/GUI/View/Loader/DataLoader.cpp index 95c64abb680..146e7c0f1cc 100644 --- a/GUI/View/Loader/DataLoader.cpp +++ b/GUI/View/Loader/DataLoader.cpp @@ -19,6 +19,7 @@ #include "Device/IO/ZipUtil.h" #include "GUI/Model/Data/DataItem.h" #include "GUI/Model/Device/DatafileItem.h" +#include "GUI/Support/Data/Dirs.h" #include "GUI/View/Info/MessageBox.h" #include "GUI/View/Layout/ApplicationSettings.h" #include "GUI/View/Loader/ImportDialogs.h" @@ -64,8 +65,8 @@ std::vector<DatafileItem*> RW::importData1D() static const QString filters = ::join_filterkeys(filters1D, ";;"); - QString selectedFilter = ProjectManager::instance()->recentlyUsedImportFilter1D(); - const QString dirname = ProjectManager::instance()->userImportDir(); + QString selectedFilter = gDirs->recentlyUsedImportFilter1D(); + const QString dirname = gDirs->userImportDir(); const QStringList fnames = QFileDialog::getOpenFileNames( Q_NULLPTR, "Open Intensity Files", dirname, filters, &selectedFilter, @@ -74,8 +75,8 @@ std::vector<DatafileItem*> RW::importData1D() if (fnames.isEmpty()) return {}; - ProjectManager::instance()->setImportDirFromFilePath(fnames[0]); - ProjectManager::instance()->setRecentlyUsedImportFilter1D(selectedFilter); + gDirs->setImportDirFromFilePath(fnames[0]); + gDirs->setRecentlyUsedImportFilter1D(selectedFilter); const IO::Filetype1D global_ftype = ::filterkey2type(filters1D, selectedFilter); @@ -125,8 +126,8 @@ std::vector<DatafileItem*> RW::importData2D() static const QString filters = ::join_filterkeys(filters2D, ";;"); - QString selectedFilter = ProjectManager::instance()->recentlyUsedImportFilter2D(); - const QString dirname = ProjectManager::instance()->userImportDir(); + QString selectedFilter = gDirs->recentlyUsedImportFilter2D(); + const QString dirname = gDirs->userImportDir(); const QStringList fnames = QFileDialog::getOpenFileNames( Q_NULLPTR, "Open Intensity Files", dirname, filters, &selectedFilter, @@ -135,8 +136,8 @@ std::vector<DatafileItem*> RW::importData2D() if (fnames.isEmpty()) return {}; - ProjectManager::instance()->setImportDirFromFilePath(fnames[0]); - ProjectManager::instance()->setRecentlyUsedImportFilter2D(selectedFilter); + gDirs->setImportDirFromFilePath(fnames[0]); + gDirs->setRecentlyUsedImportFilter2D(selectedFilter); const IO::Filetype2D global_ftype = ::filterkey2type(filters2D, selectedFilter); diff --git a/GUI/View/Manager/ProjectManager.cpp b/GUI/View/Manager/ProjectManager.cpp index 3e4506c2573..eef6eec561c 100644 --- a/GUI/View/Manager/ProjectManager.cpp +++ b/GUI/View/Manager/ProjectManager.cpp @@ -37,8 +37,6 @@ const QString S_AUTOSAVE = "EnableAutosave"; const QString S_DEFAULTPROJECTPATH = "DefaultProjectPath"; const QString S_RECENTPROJECTS = "RecentProjects"; const QString S_LASTUSEDIMPORTDIR = "LastUsedImportDir"; -const QString S_LASTUSEDIMPORFILTER1D = "LastUsedImportFilter1D"; -const QString S_LASTUSEDIMPORFILTER2D = "LastUsedImportFilter2D"; } // namespace @@ -73,18 +71,13 @@ void ProjectManager::readSettings() if (settings.childGroups().contains(S_PROJECTMANAGER)) { settings.beginGroup(S_PROJECTMANAGER); + m_working_directory = settings.value(S_DEFAULTPROJECTPATH).toString(); + if (!settings.contains(S_AUTOSAVE)) settings.setValue(S_AUTOSAVE, true); - m_working_directory = settings.value(S_DEFAULTPROJECTPATH).toString(); m_recent_projects = settings.value(S_RECENTPROJECTS).toStringList(); - if (settings.contains(S_LASTUSEDIMPORTDIR)) - m_import_directory = settings.value(S_LASTUSEDIMPORTDIR, QString()).toString(); - - m_import_filter1D = settings.value(S_LASTUSEDIMPORFILTER1D, m_import_filter1D).toString(); - m_import_filter2D = settings.value(S_LASTUSEDIMPORFILTER2D, m_import_filter2D).toString(); - setAutosaveEnabled(settings.value(S_AUTOSAVE).toBool()); settings.endGroup(); @@ -100,11 +93,6 @@ void ProjectManager::writeSettings() settings.setValue(S_DEFAULTPROJECTPATH, m_working_directory); settings.setValue(S_RECENTPROJECTS, m_recent_projects); - if (!m_import_directory.isEmpty()) - settings.setValue(S_LASTUSEDIMPORTDIR, m_import_directory); - settings.setValue(S_LASTUSEDIMPORFILTER1D, m_import_filter1D); - settings.setValue(S_LASTUSEDIMPORFILTER2D, m_import_filter2D); - settings.endGroup(); } @@ -129,40 +117,6 @@ QString ProjectManager::projectDir() const return ""; } -//! Returns directory name which was used by the user to import files. - -QString ProjectManager::userImportDir() const -{ - if (m_import_directory.isEmpty()) { - if (gDoc) - return gDoc->userExportDir(); - return ""; - } - return m_import_directory; -} //! Sets user import directory in system settings. - -void ProjectManager::setImportDir(const QString& dirname) -{ - m_import_directory = dirname; -} - -//! Sets user import directory in system settings. - -void ProjectManager::setImportDirFromFilePath(const QString& filePath) -{ - m_import_directory = QFileInfo(filePath).absolutePath(); -} - -void ProjectManager::setRecentlyUsedImportFilter1D(const QString& filter) -{ - m_import_filter1D = filter; -} - -void ProjectManager::setRecentlyUsedImportFilter2D(const QString& filter) -{ - m_import_filter2D = filter; -} - bool ProjectManager::isAutosaveEnabled() const { return static_cast<bool>(m_autosave); @@ -290,7 +244,7 @@ void ProjectManager::openProject(QString projectPullPath) if (projectPullPath.isEmpty()) { const QString ext = QString(GUI::Util::Project::projectFileExtension); projectPullPath = QFileDialog::getOpenFileName( - GUI::Global::mainWindow, "Open project file", workingDirectory(), + GUI::Global::mainWindow, "Open project file", m_working_directory, "BornAgain project Files (*" + ext + ")", nullptr, appSettings->useNativeFileDialog() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog); @@ -369,7 +323,7 @@ ProjectDocument::ReadResult ProjectManager::loadProject(const QString& fullPathA QString ProjectManager::acquireProjectPullPath() { - NewProjectDialog dialog(GUI::Global::mainWindow, workingDirectory(), untitledProjectName()); + NewProjectDialog dialog(GUI::Global::mainWindow, m_working_directory, untitledProjectName()); if (dialog.exec() != QDialog::Accepted) return ""; @@ -399,11 +353,11 @@ void ProjectManager::addToRecentProjects() QString ProjectManager::untitledProjectName() { QString result = "Untitled"; - QDir projectDir = workingDirectory() + "/" + result; + QDir projectDir = m_working_directory + "/" + result; if (projectDir.exists()) { for (size_t i = 1; i < 99; ++i) { result = QString("Untitled") + QString::number(i); - projectDir.setPath(workingDirectory() + "/" + result); + projectDir.setPath(m_working_directory + "/" + result); if (!projectDir.exists()) break; } diff --git a/GUI/View/Manager/ProjectManager.h b/GUI/View/Manager/ProjectManager.h index 4857dc137df..38a2a540c33 100644 --- a/GUI/View/Manager/ProjectManager.h +++ b/GUI/View/Manager/ProjectManager.h @@ -34,13 +34,6 @@ public: QStringList recentProjects(); QString projectDir() const; - QString userImportDir() const; - QString recentlyUsedImportFilter1D() const { return m_import_filter1D; } - QString recentlyUsedImportFilter2D() const { return m_import_filter2D; } - void setImportDir(const QString& dirname); - void setImportDirFromFilePath(const QString& filePath); - void setRecentlyUsedImportFilter1D(const QString& filter); - void setRecentlyUsedImportFilter2D(const QString& filter); bool isAutosaveEnabled() const; AutosaveController* autosaveController() const; @@ -68,25 +61,13 @@ private: QString acquireProjectPullPath(); void addToRecentProjects(); - QString workingDirectory() { return m_working_directory; } QString untitledProjectName(); void riseProjectLoadFailedDialog(const MessageService& messageService); void riseProjectLoadProblemDialog(const MessageService& messageService); bool restoreProjectDialog(const QString& projectFileName, QString autosaveName); - //!< Name of directory where project directory was created. QString m_working_directory; - - //!< Name of directory from there user prefer to import files - QString m_import_directory; - - //! Recently used import filter for 1D files - QString m_import_filter1D; - - //! Recently used import filter for 2D files - QString m_import_filter2D; - QStringList m_recent_projects; std::unique_ptr<AutosaveController> m_autosave; diff --git a/GUI/View/Manager/PyImportAssistant.cpp b/GUI/View/Manager/PyImportAssistant.cpp index bb321792d3a..05144ce83b6 100644 --- a/GUI/View/Manager/PyImportAssistant.cpp +++ b/GUI/View/Manager/PyImportAssistant.cpp @@ -21,13 +21,13 @@ #include "GUI/Model/FromCore/ItemizeSample.h" #include "GUI/Model/FromCore/ItemizeSimulation.h" #include "GUI/Model/Project/ProjectUtil.h" +#include "GUI/Support/Data/Dirs.h" #include "GUI/Support/Util/Path.h" #include "GUI/Support/Util/String.h" #include "GUI/View/Info/ComboSelectorDialog.h" #include "GUI/View/Info/DetailedMessageBox.h" #include "GUI/View/Info/MessageBox.h" #include "GUI/View/Layout/ApplicationSettings.h" -#include "GUI/View/Manager/ProjectManager.h" #include "GUI/View/Tool/Globals.h" #include "PyCore/Embed/PyInterpreter.h" // listOfFunctions #include "PyCore/Sample/ImportMultiLayer.h" // createMultiLayerFromPython @@ -69,7 +69,7 @@ QString getCandidate(const QStringList& funcNames) QString fnameToOpen() { - QString dirname = ProjectManager::instance()->userImportDir(); + QString dirname = gDirs->userImportDir(); QString result = QFileDialog::getOpenFileName( GUI::Global::mainWindow, "Open python script", dirname, "Python scripts (*.py)", nullptr, @@ -77,7 +77,7 @@ QString fnameToOpen() : QFileDialog::DontUseNativeDialog); if (!result.isEmpty()) - ProjectManager::instance()->setImportDir(GUI::Path::fileDir(result)); + gDirs->setImportDir(GUI::Path::fileDir(result)); return result; } -- GitLab From 7c0f2db3b511cd1781846e42c3bcce7fc8051131 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 14:30:14 +0100 Subject: [PATCH 04/18] Dirs -> public variables --- GUI/Support/Data/Dirs.cpp | 18 ++++-------------- GUI/Support/Data/Dirs.h | 13 +++---------- GUI/View/Loader/DataLoader.cpp | 12 ++++-------- 3 files changed, 11 insertions(+), 32 deletions(-) diff --git a/GUI/Support/Data/Dirs.cpp b/GUI/Support/Data/Dirs.cpp index bcef548b9ce..7748eacf4b7 100644 --- a/GUI/Support/Data/Dirs.cpp +++ b/GUI/Support/Data/Dirs.cpp @@ -51,8 +51,8 @@ void Dirs::readSettings() if (settings.contains(S_LASTUSEDIMPORTDIR)) m_import_directory = settings.value(S_LASTUSEDIMPORTDIR, QString()).toString(); - m_import_filter1D = settings.value(S_LASTUSEDIMPORFILTER1D, m_import_filter1D).toString(); - m_import_filter2D = settings.value(S_LASTUSEDIMPORFILTER2D, m_import_filter2D).toString(); + import_filter_1D = settings.value(S_LASTUSEDIMPORFILTER1D, import_filter_1D).toString(); + import_filter_2D = settings.value(S_LASTUSEDIMPORFILTER2D, import_filter_2D).toString(); settings.endGroup(); } @@ -67,8 +67,8 @@ void Dirs::writeSettings() if (!m_import_directory.isEmpty()) settings.setValue(S_LASTUSEDIMPORTDIR, m_import_directory); - settings.setValue(S_LASTUSEDIMPORFILTER1D, m_import_filter1D); - settings.setValue(S_LASTUSEDIMPORFILTER2D, m_import_filter2D); + settings.setValue(S_LASTUSEDIMPORFILTER1D, import_filter_1D); + settings.setValue(S_LASTUSEDIMPORFILTER2D, import_filter_2D); settings.endGroup(); } @@ -99,13 +99,3 @@ void Dirs::setImportDirFromFilePath(const QString& filePath) { m_import_directory = QFileInfo(filePath).absolutePath(); } - -void Dirs::setRecentlyUsedImportFilter1D(const QString& filter) -{ - m_import_filter1D = filter; -} - -void Dirs::setRecentlyUsedImportFilter2D(const QString& filter) -{ - m_import_filter2D = filter; -} diff --git a/GUI/Support/Data/Dirs.h b/GUI/Support/Data/Dirs.h index fa03176c1ca..cfeeed91983 100644 --- a/GUI/Support/Data/Dirs.h +++ b/GUI/Support/Data/Dirs.h @@ -25,14 +25,13 @@ public: Dirs(); ~Dirs(); + QString import_filter_1D; //!< Last used import filter for 1D files + QString import_filter_2D; //!< Last used import filter for 2D files + QString userImportDir() const; - QString recentlyUsedImportFilter1D() const { return m_import_filter1D; } - QString recentlyUsedImportFilter2D() const { return m_import_filter2D; } void setImportDir(const QString& dirname); void setImportDirFromFilePath(const QString& filePath); - void setRecentlyUsedImportFilter1D(const QString& filter); - void setRecentlyUsedImportFilter2D(const QString& filter); private: void readSettings(); @@ -41,12 +40,6 @@ private: //!< Name of directory from there user prefer to import files QString m_import_directory; - //! Recently used import filter for 1D files - QString m_import_filter1D; - - //! Recently used import filter for 2D files - QString m_import_filter2D; - QStringList m_recent_projects; static Dirs* s_instance; diff --git a/GUI/View/Loader/DataLoader.cpp b/GUI/View/Loader/DataLoader.cpp index 146e7c0f1cc..3a206f1bdbc 100644 --- a/GUI/View/Loader/DataLoader.cpp +++ b/GUI/View/Loader/DataLoader.cpp @@ -65,20 +65,18 @@ std::vector<DatafileItem*> RW::importData1D() static const QString filters = ::join_filterkeys(filters1D, ";;"); - QString selectedFilter = gDirs->recentlyUsedImportFilter1D(); const QString dirname = gDirs->userImportDir(); const QStringList fnames = QFileDialog::getOpenFileNames( - Q_NULLPTR, "Open Intensity Files", dirname, filters, &selectedFilter, + Q_NULLPTR, "Open Intensity Files", dirname, filters, &gDirs->import_filter_1D, appSettings->useNativeFileDialog() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog); if (fnames.isEmpty()) return {}; gDirs->setImportDirFromFilePath(fnames[0]); - gDirs->setRecentlyUsedImportFilter1D(selectedFilter); - const IO::Filetype1D global_ftype = ::filterkey2type(filters1D, selectedFilter); + const IO::Filetype1D global_ftype = ::filterkey2type(filters1D, gDirs->import_filter_1D); std::vector<DatafileItem*> result; for (const QString& fname : fnames) { @@ -126,20 +124,18 @@ std::vector<DatafileItem*> RW::importData2D() static const QString filters = ::join_filterkeys(filters2D, ";;"); - QString selectedFilter = gDirs->recentlyUsedImportFilter2D(); const QString dirname = gDirs->userImportDir(); const QStringList fnames = QFileDialog::getOpenFileNames( - Q_NULLPTR, "Open Intensity Files", dirname, filters, &selectedFilter, + Q_NULLPTR, "Open Intensity Files", dirname, filters, &gDirs->import_filter_2D, appSettings->useNativeFileDialog() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog); if (fnames.isEmpty()) return {}; gDirs->setImportDirFromFilePath(fnames[0]); - gDirs->setRecentlyUsedImportFilter2D(selectedFilter); - const IO::Filetype2D global_ftype = ::filterkey2type(filters2D, selectedFilter); + const IO::Filetype2D global_ftype = ::filterkey2type(filters2D, gDirs->import_filter_2D); std::vector<DatafileItem*> result; for (const QString& fname : fnames) { -- GitLab From 3059e3d53e251311b8977d5cc24df4fc36a776f5 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 14:31:06 +0100 Subject: [PATCH 05/18] rm duplicate member --- GUI/Support/Data/Dirs.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/GUI/Support/Data/Dirs.h b/GUI/Support/Data/Dirs.h index cfeeed91983..860f0072c0c 100644 --- a/GUI/Support/Data/Dirs.h +++ b/GUI/Support/Data/Dirs.h @@ -40,8 +40,6 @@ private: //!< Name of directory from there user prefer to import files QString m_import_directory; - QStringList m_recent_projects; - static Dirs* s_instance; }; -- GitLab From acdefa285b2cd000ba5111edb389bc62aa6a2299 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 14:33:25 +0100 Subject: [PATCH 06/18] rm unused --- GUI/Support/Data/Dirs.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/GUI/Support/Data/Dirs.h b/GUI/Support/Data/Dirs.h index 860f0072c0c..a7b8652f2fb 100644 --- a/GUI/Support/Data/Dirs.h +++ b/GUI/Support/Data/Dirs.h @@ -39,8 +39,6 @@ private: //!< Name of directory from there user prefer to import files QString m_import_directory; - - static Dirs* s_instance; }; BA_GUI_API_ extern std::unique_ptr<Dirs> gDirs; -- GitLab From 1e29efdabeeed1f00de5db3d285a9585bc80bf68 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 14:35:23 +0100 Subject: [PATCH 07/18] rm include --- GUI/View/Loader/DataLoader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/GUI/View/Loader/DataLoader.cpp b/GUI/View/Loader/DataLoader.cpp index 3a206f1bdbc..35bbf2cc1f5 100644 --- a/GUI/View/Loader/DataLoader.cpp +++ b/GUI/View/Loader/DataLoader.cpp @@ -23,7 +23,6 @@ #include "GUI/View/Info/MessageBox.h" #include "GUI/View/Layout/ApplicationSettings.h" #include "GUI/View/Loader/ImportDialogs.h" -#include "GUI/View/Manager/ProjectManager.h" #include <QFileDialog> #include <QFileInfo> -- GitLab From a8b989b1884966e45aade503ea61a364cd35f854 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 14:54:11 +0100 Subject: [PATCH 08/18] rm Houston --- GUI/View/Info/CautionSignWidget.cpp | 2 +- GUI/View/Realspace/RealspaceWidget.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GUI/View/Info/CautionSignWidget.cpp b/GUI/View/Info/CautionSignWidget.cpp index 612f6f5df9c..c857e0223ff 100644 --- a/GUI/View/Info/CautionSignWidget.cpp +++ b/GUI/View/Info/CautionSignWidget.cpp @@ -19,7 +19,7 @@ CautionSignWidget::CautionSignWidget(QWidget* parent) : QWidget(parent) , m_pixmap(":/images/warning@2x.png") - , m_caution_header("Houston, we have a problem.") + , m_caution_header("BornAgain warning") { setAttribute(Qt::WA_NoSystemBackground); setToolTip(m_caution_header + "\nClick to see details."); diff --git a/GUI/View/Realspace/RealspaceWidget.cpp b/GUI/View/Realspace/RealspaceWidget.cpp index 389aa0a6dc1..a97fad24f36 100644 --- a/GUI/View/Realspace/RealspaceWidget.cpp +++ b/GUI/View/Realspace/RealspaceWidget.cpp @@ -100,7 +100,7 @@ void RealspaceWidget::savePicture() message.append(nameToSave); message.append("' has failed with following error message\n\n"); message.append(QString::fromStdString(ex.what())); - QMessageBox::warning(nullptr, "Houston, we have a problem.", message); + QMessageBox::warning(nullptr, "Cannot save", message); } } -- GitLab From 16ea5979b9c161b4189ba27ba06947c3b4572c52 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 15:16:46 +0100 Subject: [PATCH 09/18] RealspaceWidget::savePicture simplify, standardize --- GUI/Support/Data/Dirs.cpp | 1 + GUI/Support/Data/Dirs.h | 1 + GUI/View/Realspace/RealspaceWidget.cpp | 34 +++++++++----------------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/GUI/Support/Data/Dirs.cpp b/GUI/Support/Data/Dirs.cpp index 7748eacf4b7..e980006076c 100644 --- a/GUI/Support/Data/Dirs.cpp +++ b/GUI/Support/Data/Dirs.cpp @@ -32,6 +32,7 @@ BA_GUI_API_ std::unique_ptr<Dirs> gDirs; Dirs::Dirs() { + artifacts_export_dir = QDir::homePath(); readSettings(); } diff --git a/GUI/Support/Data/Dirs.h b/GUI/Support/Data/Dirs.h index a7b8652f2fb..fdd60268f3f 100644 --- a/GUI/Support/Data/Dirs.h +++ b/GUI/Support/Data/Dirs.h @@ -28,6 +28,7 @@ public: QString import_filter_1D; //!< Last used import filter for 1D files QString import_filter_2D; //!< Last used import filter for 2D files + QString artifacts_export_dir; //!< Last used directory to save image, script, ... QString userImportDir() const; void setImportDir(const QString& dirname); diff --git a/GUI/View/Realspace/RealspaceWidget.cpp b/GUI/View/Realspace/RealspaceWidget.cpp index a97fad24f36..b3413ae1b6b 100644 --- a/GUI/View/Realspace/RealspaceWidget.cpp +++ b/GUI/View/Realspace/RealspaceWidget.cpp @@ -15,15 +15,15 @@ #include "GUI/View/Realspace/RealspaceWidget.h" #include "Base/Util/Assert.h" #include "GUI/Model/Material/MaterialItem.h" -#include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Model/Sample/SampleItem.h" +#include "GUI/Support/Data/Dirs.h" #include "GUI/View/Info/CautionSign.h" #include "GUI/View/Layout/ApplicationSettings.h" #include "GUI/View/Realspace/RealspaceBuilder.h" +#include "GUI/View/Widget/FileDialog.h" #include "Img3D/Model/Model.h" #include "Img3D/View/Canvas.h" #include <QApplication> -#include <QFileDialog> #include <QMessageBox> #include <QVBoxLayout> @@ -78,30 +78,20 @@ void RealspaceWidget::showEvent(QShowEvent*) void RealspaceWidget::savePicture() { - ASSERT(gDoc); - QString dirname = gDoc->userExportDir(); - QString defaultExtension = ".png"; - QString selectedFilter("*" + defaultExtension); - QString defaultName = dirname + "/untitled"; - QString fname = QFileDialog::getSaveFileName( - nullptr, "Save 3D real space view", defaultName, selectedFilter, nullptr, - appSettings->useNativeFileDialog() ? QFileDialog::Options() - : QFileDialog::DontUseNativeDialog); - QString nameToSave = fname.endsWith(defaultExtension) ? fname : fname + defaultExtension; - if (nameToSave.isEmpty()) + static const QString defaultExtension = ".png"; + QString fname = GUI::Dialog::fileSaveDialog("Save 3D real space view", + gDirs->artifacts_export_dir, + "*" + defaultExtension); + if (fname.isEmpty()) return; + if (!fname.endsWith(defaultExtension)) + fname += defaultExtension; QPixmap pixmap(this->size()); render(&pixmap, QPoint(), childrenRegion()); - try { - pixmap.save(nameToSave); - } catch (const std::exception& ex) { - QString message = "Attempt to save file with the name '"; - message.append(nameToSave); - message.append("' has failed with following error message\n\n"); - message.append(QString::fromStdString(ex.what())); - QMessageBox::warning(nullptr, "Cannot save", message); - } + bool ok = pixmap.save(fname); + if (!ok) + QMessageBox::warning(nullptr, "Cannot save", "Cannot save picture in file " + fname); } void RealspaceWidget::updateScene() -- GitLab From ba8e85b916eb4722ed0c5d8f6740ecffd3720603 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 15:20:51 +0100 Subject: [PATCH 10/18] Settings + r/w artifact_export_dir --- GUI/Support/Data/Dirs.cpp | 15 +++++++++------ GUI/Support/Data/Dirs.h | 2 +- GUI/View/Realspace/RealspaceWidget.cpp | 7 +++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/GUI/Support/Data/Dirs.cpp b/GUI/Support/Data/Dirs.cpp index e980006076c..3a9539a6c78 100644 --- a/GUI/Support/Data/Dirs.cpp +++ b/GUI/Support/Data/Dirs.cpp @@ -22,6 +22,7 @@ namespace { const QString S_DIRS = "Dirs"; const QString S_DEFAULTPROJECTPATH = "DefaultProjectPath"; +const QString S_ARTIFACTEXPORTDIR = "ArtifactExportDir"; const QString S_LASTUSEDIMPORTDIR = "LastUsedImportDir"; const QString S_LASTUSEDIMPORFILTER1D = "LastUsedImportFilter1D"; const QString S_LASTUSEDIMPORFILTER2D = "LastUsedImportFilter2D"; @@ -32,7 +33,7 @@ BA_GUI_API_ std::unique_ptr<Dirs> gDirs; Dirs::Dirs() { - artifacts_export_dir = QDir::homePath(); + artifact_export_dir = QDir::homePath(); readSettings(); } @@ -49,11 +50,13 @@ void Dirs::readSettings() if (settings.childGroups().contains(S_DIRS)) { settings.beginGroup(S_DIRS); + artifact_export_dir = + settings.value(S_LASTUSEDIMPORFILTER1D, artifact_export_dir).toString(); if (settings.contains(S_LASTUSEDIMPORTDIR)) - m_import_directory = settings.value(S_LASTUSEDIMPORTDIR, QString()).toString(); + m_import_directory = settings.value(S_LASTUSEDIMPORTDIR, "").toString(); - import_filter_1D = settings.value(S_LASTUSEDIMPORFILTER1D, import_filter_1D).toString(); - import_filter_2D = settings.value(S_LASTUSEDIMPORFILTER2D, import_filter_2D).toString(); + import_filter_1D = settings.value(S_LASTUSEDIMPORFILTER1D, "").toString(); + import_filter_2D = settings.value(S_LASTUSEDIMPORFILTER2D, "").toString(); settings.endGroup(); } @@ -66,8 +69,8 @@ void Dirs::writeSettings() QSettings settings; settings.beginGroup(S_DIRS); - if (!m_import_directory.isEmpty()) - settings.setValue(S_LASTUSEDIMPORTDIR, m_import_directory); + settings.setValue(S_ARTIFACTEXPORTDIR, artifact_export_dir); + settings.setValue(S_LASTUSEDIMPORTDIR, m_import_directory); settings.setValue(S_LASTUSEDIMPORFILTER1D, import_filter_1D); settings.setValue(S_LASTUSEDIMPORFILTER2D, import_filter_2D); diff --git a/GUI/Support/Data/Dirs.h b/GUI/Support/Data/Dirs.h index fdd60268f3f..98817ab4e9f 100644 --- a/GUI/Support/Data/Dirs.h +++ b/GUI/Support/Data/Dirs.h @@ -28,7 +28,7 @@ public: QString import_filter_1D; //!< Last used import filter for 1D files QString import_filter_2D; //!< Last used import filter for 2D files - QString artifacts_export_dir; //!< Last used directory to save image, script, ... + QString artifact_export_dir; //!< Last used directory to save image, script, ... QString userImportDir() const; void setImportDir(const QString& dirname); diff --git a/GUI/View/Realspace/RealspaceWidget.cpp b/GUI/View/Realspace/RealspaceWidget.cpp index b3413ae1b6b..e6011a1143a 100644 --- a/GUI/View/Realspace/RealspaceWidget.cpp +++ b/GUI/View/Realspace/RealspaceWidget.cpp @@ -79,13 +79,12 @@ void RealspaceWidget::showEvent(QShowEvent*) void RealspaceWidget::savePicture() { static const QString defaultExtension = ".png"; - QString fname = GUI::Dialog::fileSaveDialog("Save 3D real space view", - gDirs->artifacts_export_dir, - "*" + defaultExtension); + QString fname = GUI::Dialog::fileSaveDialog( + "Save 3D real space view", gDirs->artifact_export_dir, "*" + defaultExtension); if (fname.isEmpty()) return; if (!fname.endsWith(defaultExtension)) - fname += defaultExtension; + fname += defaultExtension; QPixmap pixmap(this->size()); render(&pixmap, QPoint(), childrenRegion()); -- GitLab From a3eadd80c4261504675932f12a723b93d9303a20 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 15:24:30 +0100 Subject: [PATCH 11/18] ProjectionsSaver std file dialog --- GUI/View/Loader/ProjectionsSaver.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/GUI/View/Loader/ProjectionsSaver.cpp b/GUI/View/Loader/ProjectionsSaver.cpp index 07dfa942252..f764acfa314 100644 --- a/GUI/View/Loader/ProjectionsSaver.cpp +++ b/GUI/View/Loader/ProjectionsSaver.cpp @@ -19,8 +19,10 @@ #include "GUI/Model/Data/Data2DItem.h" #include "GUI/Model/Mask/MasksSet.h" #include "GUI/Model/Project/ProjectDocument.h" +#include "GUI/Support/Data/Dirs.h" #include "GUI/View/Layout/ApplicationSettings.h" -#include <QFileDialog> +#include "GUI/View/Widget/FileDialog.h" +#include <QFile> #include <QString> #include <QTextStream> #include <QVector> @@ -149,14 +151,9 @@ void GUI::IO::saveProjections(const Data2DItem* data_item) { if (!data_item) return; - ASSERT(gDoc); - - QString defaultName = gDoc->userExportDir() + "/untitled.txt"; - QString fname = QFileDialog::getSaveFileName( - nullptr, "Save projections data", defaultName, "", nullptr, - appSettings->useNativeFileDialog() ? QFileDialog::Options() - : QFileDialog::DontUseNativeDialog); + QString fname = GUI::Dialog::fileSaveDialog( + "Save projections data", gDirs->artifact_export_dir, ""); if (fname.isEmpty()) return; -- GitLab From d8cf220728d7092ce38bcf79a69b123bd56ffc74 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 15:33:27 +0100 Subject: [PATCH 12/18] std dialog in SavePlotAssistant; rm ProjectDocument::userExportDir --- GUI/Model/Project/ProjectDocument.cpp | 9 -------- GUI/Model/Project/ProjectDocument.h | 1 - GUI/View/Canvas/MaskEditorCanvas.cpp | 4 +--- GUI/View/Canvas/SavePlotAssistant.cpp | 29 ++++++++++++-------------- GUI/View/Canvas/SavePlotAssistant.h | 2 +- GUI/View/Canvas/SpecularDataCanvas.cpp | 4 +--- 6 files changed, 16 insertions(+), 33 deletions(-) diff --git a/GUI/Model/Project/ProjectDocument.cpp b/GUI/Model/Project/ProjectDocument.cpp index d2d37622d56..e40c55fe12c 100644 --- a/GUI/Model/Project/ProjectDocument.cpp +++ b/GUI/Model/Project/ProjectDocument.cpp @@ -89,15 +89,6 @@ void ProjectDocument::setProjectDir(const QString& text) m_project_dir = text; } -//! Returns directory name suitable for saving plots. - -QString ProjectDocument::userExportDir() const -{ - if (QString dir = validProjectDir(); !dir.isEmpty()) - return dir; - return QStandardPaths::writableLocation(QStandardPaths::HomeLocation); -} - QString ProjectDocument::projectFullPath() const { if (!projectName().isEmpty()) diff --git a/GUI/Model/Project/ProjectDocument.h b/GUI/Model/Project/ProjectDocument.h index af3ef835041..3ceb64892ea 100644 --- a/GUI/Model/Project/ProjectDocument.h +++ b/GUI/Model/Project/ProjectDocument.h @@ -62,7 +62,6 @@ public: QString projectName() const { return m_project_name; } QString validProjectDir() const; - QString userExportDir() const; QString projectFullPath() const; bool hasValidNameAndPath() const; diff --git a/GUI/View/Canvas/MaskEditorCanvas.cpp b/GUI/View/Canvas/MaskEditorCanvas.cpp index a241c7c5fa1..1b465aa6b19 100644 --- a/GUI/View/Canvas/MaskEditorCanvas.cpp +++ b/GUI/View/Canvas/MaskEditorCanvas.cpp @@ -126,9 +126,7 @@ void MaskEditorCanvas::onPresentationChange(bool pixelized) void MaskEditorCanvas::onSavePlotRequest() { - ASSERT(gDoc); - QString dirname = gDoc->userExportDir(); - GUI::Plot::savePlot(dirname, m_scene->colorMap()->customPlot(), m_data_item->c_field()); + GUI::Plot::savePlot(m_scene->colorMap()->customPlot(), m_data_item->c_field()); } void MaskEditorCanvas::onPositionChanged(double x, double y) diff --git a/GUI/View/Canvas/SavePlotAssistant.cpp b/GUI/View/Canvas/SavePlotAssistant.cpp index b37c9f93fd0..7a38859fb87 100644 --- a/GUI/View/Canvas/SavePlotAssistant.cpp +++ b/GUI/View/Canvas/SavePlotAssistant.cpp @@ -15,9 +15,11 @@ #include "GUI/View/Canvas/SavePlotAssistant.h" #include "Base/Util/Assert.h" #include "Device/IO/IOFactory.h" +#include "GUI/Support/Data/Dirs.h" #include "GUI/View/Layout/ApplicationSettings.h" #include "GUI/View/Plotter/ColorMap.h" -#include <QFileDialog> +#include "GUI/View/Widget/FileDialog.h" +#include <QFile> #include <QMessageBox> #include <QVector> #include <qcustomplot.h> @@ -89,6 +91,7 @@ void saveToFile(const QString& fname, QCustomPlot* plot, const Datafield* output } } +/* //! Returns string contraining all defined filters in the format suitable for QFileDialog QString getFilterString() { @@ -126,29 +129,23 @@ QString composeFileName(const QString& fname, const QString& filterName) return fname; return fname + getExtensionFromFilterName(filterName); } - +*/ } // namespace -void GUI::Plot::savePlot(const QString& dirname, QCustomPlot* plot, const Datafield* output_data) +void GUI::Plot::savePlot(QCustomPlot* plot, const Datafield* output_data) { - static QString selectedFilter = "*.png"; - QString defaultName = dirname + "/untitled"; - QString fname = QFileDialog::getSaveFileName( - nullptr, "Save Plot", defaultName, getFilterString(), &selectedFilter, - appSettings->useNativeFileDialog() ? QFileDialog::Options() - : QFileDialog::DontUseNativeDialog); + static const QString defaultExtension = ".png"; + QString fname = GUI::Dialog::fileSaveDialog( + "Save Plot", gDirs->artifact_export_dir, "*" + defaultExtension); if (fname.isEmpty()) return; + if (!fname.endsWith(defaultExtension)) + fname += defaultExtension; - QString nameToSave = composeFileName(fname, selectedFilter); try { - ::saveToFile(nameToSave, plot, output_data); + ::saveToFile(fname, plot, output_data); } catch (const std::exception& ex) { - QString message = "Attempt to save file with the name '"; - message.append(nameToSave); - message.append("' has failed with following error message\n\n"); - message.append(QString::fromStdString(ex.what())); - QMessageBox::warning(nullptr, "Could not save", message); + QMessageBox::warning(nullptr, "Cannot save", "Cannot save picture in file " + fname); } } diff --git a/GUI/View/Canvas/SavePlotAssistant.h b/GUI/View/Canvas/SavePlotAssistant.h index 76d1914957b..476e34e3756 100644 --- a/GUI/View/Canvas/SavePlotAssistant.h +++ b/GUI/View/Canvas/SavePlotAssistant.h @@ -22,7 +22,7 @@ class QCustomPlot; namespace GUI::Plot { -void savePlot(const QString& dirname, QCustomPlot* plot, const Datafield* output_data); +void savePlot(QCustomPlot* plot, const Datafield* output_data); }; diff --git a/GUI/View/Canvas/SpecularDataCanvas.cpp b/GUI/View/Canvas/SpecularDataCanvas.cpp index 7bee5abc149..89fa9148e62 100644 --- a/GUI/View/Canvas/SpecularDataCanvas.cpp +++ b/GUI/View/Canvas/SpecularDataCanvas.cpp @@ -75,9 +75,7 @@ void SpecularDataCanvas::onResetViewAction() void SpecularDataCanvas::onSavePlotAction() { - ASSERT(gDoc); - QString dirname = gDoc->userExportDir(); - GUI::Plot::savePlot(dirname, m_plot_canvas->customPlot(), m_data_item->c_field()); + GUI::Plot::savePlot(m_plot_canvas->customPlot(), m_data_item->c_field()); } void SpecularDataCanvas::onMousePress(QMouseEvent* event) -- GitLab From 6f33bbf007d9c9dd71e29809ceb80ac7c37d5b1f Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 15:55:21 +0100 Subject: [PATCH 13/18] gDIrs + script|data_import_dir --- GUI/Support/Data/Dirs.cpp | 44 ++++++-------------------- GUI/Support/Data/Dirs.h | 11 ++----- GUI/View/Canvas/SavePlotAssistant.cpp | 4 +-- GUI/View/Loader/DataLoader.cpp | 14 +++----- GUI/View/Loader/ProjectionsSaver.cpp | 4 +-- GUI/View/Manager/PyImportAssistant.cpp | 8 ++--- GUI/View/Realspace/RealspaceWidget.cpp | 4 +-- 7 files changed, 24 insertions(+), 65 deletions(-) diff --git a/GUI/Support/Data/Dirs.cpp b/GUI/Support/Data/Dirs.cpp index 3a9539a6c78..ec29e3174c5 100644 --- a/GUI/Support/Data/Dirs.cpp +++ b/GUI/Support/Data/Dirs.cpp @@ -13,9 +13,7 @@ // ************************************************************************************************ #include "GUI/Support/Data/Dirs.h" -#include "Base/Util/Assert.h" #include <QDir> -#include <QFileInfo> #include <QSettings> namespace { @@ -23,7 +21,8 @@ namespace { const QString S_DIRS = "Dirs"; const QString S_DEFAULTPROJECTPATH = "DefaultProjectPath"; const QString S_ARTIFACTEXPORTDIR = "ArtifactExportDir"; -const QString S_LASTUSEDIMPORTDIR = "LastUsedImportDir"; +const QString S_DATAIMPORTDIR = "DataImportDir"; +const QString S_SCRIPTIMPORTDIR = "ScriptImportDir"; const QString S_LASTUSEDIMPORFILTER1D = "LastUsedImportFilter1D"; const QString S_LASTUSEDIMPORFILTER2D = "LastUsedImportFilter2D"; @@ -34,6 +33,8 @@ BA_GUI_API_ std::unique_ptr<Dirs> gDirs; Dirs::Dirs() { artifact_export_dir = QDir::homePath(); + data_import_dir = QDir::homePath(); + script_import_dir = QDir::homePath(); readSettings(); } @@ -50,10 +51,9 @@ void Dirs::readSettings() if (settings.childGroups().contains(S_DIRS)) { settings.beginGroup(S_DIRS); - artifact_export_dir = - settings.value(S_LASTUSEDIMPORFILTER1D, artifact_export_dir).toString(); - if (settings.contains(S_LASTUSEDIMPORTDIR)) - m_import_directory = settings.value(S_LASTUSEDIMPORTDIR, "").toString(); + artifact_export_dir = settings.value(S_ARTIFACTEXPORTDIR, artifact_export_dir).toString(); + data_import_dir = settings.value(S_DATAIMPORTDIR, data_import_dir).toString(); + script_import_dir = settings.value(S_SCRIPTIMPORTDIR, script_import_dir).toString(); import_filter_1D = settings.value(S_LASTUSEDIMPORFILTER1D, "").toString(); import_filter_2D = settings.value(S_LASTUSEDIMPORFILTER2D, "").toString(); @@ -70,36 +70,10 @@ void Dirs::writeSettings() settings.beginGroup(S_DIRS); settings.setValue(S_ARTIFACTEXPORTDIR, artifact_export_dir); - settings.setValue(S_LASTUSEDIMPORTDIR, m_import_directory); + settings.setValue(S_DATAIMPORTDIR, data_import_dir); + settings.setValue(S_SCRIPTIMPORTDIR, script_import_dir); settings.setValue(S_LASTUSEDIMPORFILTER1D, import_filter_1D); settings.setValue(S_LASTUSEDIMPORFILTER2D, import_filter_2D); settings.endGroup(); } - -//! Returns directory name which was used by the user to import files. - -QString Dirs::userImportDir() const -{ - /* - if (m_import_directory.isEmpty()) { - if (gDoc) - return gDoc->userExportDir(); - return ""; - } - */ - return m_import_directory; -} //! Sets user import directory in system settings. - - -void Dirs::setImportDir(const QString& dirname) -{ - m_import_directory = dirname; -} - -//! Sets user import directory in system settings. - -void Dirs::setImportDirFromFilePath(const QString& filePath) -{ - m_import_directory = QFileInfo(filePath).absolutePath(); -} diff --git a/GUI/Support/Data/Dirs.h b/GUI/Support/Data/Dirs.h index 98817ab4e9f..cf2e016d023 100644 --- a/GUI/Support/Data/Dirs.h +++ b/GUI/Support/Data/Dirs.h @@ -16,7 +16,7 @@ #define BORNAGAIN_GUI_SUPPORT_DATA_DIRS_H #include "Wrap/WinDllMacros.h" -#include <QStringList> +#include <QString> //! Handles activity related to opening/save projects. @@ -29,17 +29,12 @@ public: QString import_filter_2D; //!< Last used import filter for 2D files QString artifact_export_dir; //!< Last used directory to save image, script, ... - QString userImportDir() const; - - void setImportDir(const QString& dirname); - void setImportDirFromFilePath(const QString& filePath); + QString data_import_dir; //!< Last data were imported from this directory + QString script_import_dir; //!< Last script was imported from this directory private: void readSettings(); void writeSettings(); - - //!< Name of directory from there user prefer to import files - QString m_import_directory; }; BA_GUI_API_ extern std::unique_ptr<Dirs> gDirs; diff --git a/GUI/View/Canvas/SavePlotAssistant.cpp b/GUI/View/Canvas/SavePlotAssistant.cpp index 7a38859fb87..774b6a0e783 100644 --- a/GUI/View/Canvas/SavePlotAssistant.cpp +++ b/GUI/View/Canvas/SavePlotAssistant.cpp @@ -136,8 +136,8 @@ QString composeFileName(const QString& fname, const QString& filterName) void GUI::Plot::savePlot(QCustomPlot* plot, const Datafield* output_data) { static const QString defaultExtension = ".png"; - QString fname = GUI::Dialog::fileSaveDialog( - "Save Plot", gDirs->artifact_export_dir, "*" + defaultExtension); + QString fname = GUI::Dialog::fileSaveDialog("Save Plot", gDirs->artifact_export_dir, + "*" + defaultExtension); if (fname.isEmpty()) return; if (!fname.endsWith(defaultExtension)) diff --git a/GUI/View/Loader/DataLoader.cpp b/GUI/View/Loader/DataLoader.cpp index 35bbf2cc1f5..a9c75e1ed53 100644 --- a/GUI/View/Loader/DataLoader.cpp +++ b/GUI/View/Loader/DataLoader.cpp @@ -64,17 +64,14 @@ std::vector<DatafileItem*> RW::importData1D() static const QString filters = ::join_filterkeys(filters1D, ";;"); - const QString dirname = gDirs->userImportDir(); - const QStringList fnames = QFileDialog::getOpenFileNames( - Q_NULLPTR, "Open Intensity Files", dirname, filters, &gDirs->import_filter_1D, + Q_NULLPTR, "Open Intensity Files", gDirs->data_import_dir, filters, + &gDirs->import_filter_1D, appSettings->useNativeFileDialog() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog); if (fnames.isEmpty()) return {}; - gDirs->setImportDirFromFilePath(fnames[0]); - const IO::Filetype1D global_ftype = ::filterkey2type(filters1D, gDirs->import_filter_1D); std::vector<DatafileItem*> result; @@ -123,17 +120,14 @@ std::vector<DatafileItem*> RW::importData2D() static const QString filters = ::join_filterkeys(filters2D, ";;"); - const QString dirname = gDirs->userImportDir(); - const QStringList fnames = QFileDialog::getOpenFileNames( - Q_NULLPTR, "Open Intensity Files", dirname, filters, &gDirs->import_filter_2D, + Q_NULLPTR, "Open Intensity Files", gDirs->data_import_dir, filters, + &gDirs->import_filter_2D, appSettings->useNativeFileDialog() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog); if (fnames.isEmpty()) return {}; - gDirs->setImportDirFromFilePath(fnames[0]); - const IO::Filetype2D global_ftype = ::filterkey2type(filters2D, gDirs->import_filter_2D); std::vector<DatafileItem*> result; diff --git a/GUI/View/Loader/ProjectionsSaver.cpp b/GUI/View/Loader/ProjectionsSaver.cpp index f764acfa314..219987bd007 100644 --- a/GUI/View/Loader/ProjectionsSaver.cpp +++ b/GUI/View/Loader/ProjectionsSaver.cpp @@ -152,8 +152,8 @@ void GUI::IO::saveProjections(const Data2DItem* data_item) if (!data_item) return; - QString fname = GUI::Dialog::fileSaveDialog( - "Save projections data", gDirs->artifact_export_dir, ""); + QString fname = + GUI::Dialog::fileSaveDialog("Save projections data", gDirs->artifact_export_dir, ""); if (fname.isEmpty()) return; diff --git a/GUI/View/Manager/PyImportAssistant.cpp b/GUI/View/Manager/PyImportAssistant.cpp index 05144ce83b6..54ab7632b4d 100644 --- a/GUI/View/Manager/PyImportAssistant.cpp +++ b/GUI/View/Manager/PyImportAssistant.cpp @@ -69,16 +69,12 @@ QString getCandidate(const QStringList& funcNames) QString fnameToOpen() { - QString dirname = gDirs->userImportDir(); - QString result = QFileDialog::getOpenFileName( - GUI::Global::mainWindow, "Open python script", dirname, "Python scripts (*.py)", nullptr, + GUI::Global::mainWindow, "Open python script", gDirs->script_import_dir, + "Python scripts (*.py)", nullptr, appSettings->useNativeFileDialog() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog); - if (!result.isEmpty()) - gDirs->setImportDir(GUI::Path::fileDir(result)); - return result; } diff --git a/GUI/View/Realspace/RealspaceWidget.cpp b/GUI/View/Realspace/RealspaceWidget.cpp index e6011a1143a..f6e02bdcdbc 100644 --- a/GUI/View/Realspace/RealspaceWidget.cpp +++ b/GUI/View/Realspace/RealspaceWidget.cpp @@ -79,8 +79,8 @@ void RealspaceWidget::showEvent(QShowEvent*) void RealspaceWidget::savePicture() { static const QString defaultExtension = ".png"; - QString fname = GUI::Dialog::fileSaveDialog( - "Save 3D real space view", gDirs->artifact_export_dir, "*" + defaultExtension); + QString fname = GUI::Dialog::fileSaveDialog("Save 3D real space view", + gDirs->artifact_export_dir, "*" + defaultExtension); if (fname.isEmpty()) return; if (!fname.endsWith(defaultExtension)) -- GitLab From a8d48154ce8bcb6efe2da917279edcc42995b5ca Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 16:45:03 +0100 Subject: [PATCH 14/18] expand 'auto' --- GUI/Model/Job/JobsSet.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GUI/Model/Job/JobsSet.cpp b/GUI/Model/Job/JobsSet.cpp index d398071c616..a4726937137 100644 --- a/GUI/Model/Job/JobsSet.cpp +++ b/GUI/Model/Job/JobsSet.cpp @@ -88,7 +88,7 @@ void JobsSet::readFrom(QXmlStreamReader* r) void JobsSet::saveAllDatafields(const QString& projectDir) const { - for (const auto* job : *this) + for (const JobItem* job : *this) job->saveDatafields(projectDir); dataFilesCleaner.cleanOldFiles(projectDir, dataItems()); @@ -96,7 +96,7 @@ void JobsSet::saveAllDatafields(const QString& projectDir) const void JobsSet::loadAllDatafields(const QString& projectDir, MessageService* messageService) { - for (auto* job : *this) + for (JobItem* job : *this) job->loadDatafields(projectDir, messageService); dataFilesCleaner.recollectDataNames(dataItems()); -- GitLab From be74faaf14e7502f2a67012868668cec228aa73d Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 16:58:46 +0100 Subject: [PATCH 15/18] rm warnings mechanism from load datafiles --- GUI/Model/Data/DataItem.cpp | 40 ++++++++++++--------------- GUI/Model/Data/DataItem.h | 3 +- GUI/Model/Device/DatafileItem.cpp | 10 ++----- GUI/Model/Device/DatafileItem.h | 3 +- GUI/Model/Files/DatafilesSet.cpp | 4 +-- GUI/Model/Files/DatafilesSet.h | 3 +- GUI/Model/Job/JobItem.cpp | 33 ++-------------------- GUI/Model/Job/JobItem.h | 2 +- GUI/Model/Job/JobsSet.cpp | 4 +-- GUI/Model/Job/JobsSet.h | 3 +- GUI/Model/Project/ProjectDocument.cpp | 5 ++-- 11 files changed, 34 insertions(+), 76 deletions(-) diff --git a/GUI/Model/Data/DataItem.cpp b/GUI/Model/Data/DataItem.cpp index f22692525e0..5976cb1a050 100644 --- a/GUI/Model/Data/DataItem.cpp +++ b/GUI/Model/Data/DataItem.cpp @@ -19,7 +19,6 @@ #include "Device/IO/IOFactory.h" #include "GUI/Model/Axis/AmplitudeAxisItem.h" #include "GUI/Model/Axis/BasicAxisItem.h" -#include "GUI/Support/Util/MessageService.h" #include "GUI/Support/XML/UtilXML.h" #include <QFile> #include <utility> @@ -83,31 +82,26 @@ void DataItem::setFileName(const QString& filename) emit fnameChanged(filename); } -QString DataItem::loadDatafield(MessageService* messageService, const QString& projectDir, int rank) +void DataItem::loadDatafield(const QString& projectDir, int rank) { if (!QFile::exists(projectDir)) - return {}; - - ASSERT(messageService); + throw std::runtime_error("Cannot load datafield: project directory " + + projectDir.toStdString() + " does not exist"); const auto file = dataFullPath(projectDir); - try { - std::unique_ptr<Datafield> data; - if (rank == 1) - data = std::make_unique<Datafield>( - IO::readData1D(file.toStdString(), IO::Filetype1D::bornagain1D)); - else if (rank == 2) - data = std::make_unique<Datafield>( - IO::readData2D(file.toStdString(), IO::Filetype2D::bornagain2D)); - else - ASSERT_NEVER; - ASSERT(data); - setDatafield(*data); - m_last_saved = m_last_modified; - } catch (const std::exception& ex) { - messageService->addWarning(this, QString(ex.what())); - return ex.what(); - } - return {}; + + std::unique_ptr<Datafield> data; + if (rank == 1) + data = std::make_unique<Datafield>( + IO::readData1D(file.toStdString(), IO::Filetype1D::bornagain1D)); + else if (rank == 2) + data = std::make_unique<Datafield>( + IO::readData2D(file.toStdString(), IO::Filetype2D::bornagain2D)); + else + ASSERT_NEVER; + + ASSERT(data); + setDatafield(*data); + m_last_saved = m_last_modified; } void DataItem::saveDatafield(const QString& projectDir) const diff --git a/GUI/Model/Data/DataItem.h b/GUI/Model/Data/DataItem.h index d9d80557ebd..b0d8d97bfe3 100644 --- a/GUI/Model/Data/DataItem.h +++ b/GUI/Model/Data/DataItem.h @@ -24,7 +24,6 @@ class AmplitudeAxisItem; class BasicAxisItem; class Datafield; class Frame; -class MessageService; //! Abstract base class for Data2DItem and Data1DItem. //! Owns one simulated data set of type Datafield. @@ -59,7 +58,7 @@ public: QDateTime lastModified() const { return m_last_modified; } void setLastModified(const QDateTime& dtime); - QString loadDatafield(MessageService* messageService, const QString& projectDir, int rank); + void loadDatafield(const QString& projectDir, int rank); void saveDatafield(const QString& projectDir) const; // Number of bins in data diff --git a/GUI/Model/Device/DatafileItem.cpp b/GUI/Model/Device/DatafileItem.cpp index 36fa1f2f77e..4630ae4678b 100644 --- a/GUI/Model/Device/DatafileItem.cpp +++ b/GUI/Model/Device/DatafileItem.cpp @@ -201,14 +201,10 @@ void DatafileItem::saveDatafield(const QString& projectDir) const m_data_item->saveDatafield(projectDir); } -QString DatafileItem::loadDatafield(const QString& projectDir, MessageService* messageService) +void DatafileItem::loadDatafield(const QString& projectDir) { - if (m_data_item) { - QString dataError = m_data_item->loadDatafield(messageService, projectDir, rank()); - if (!dataError.isEmpty()) - return dataError; - } - return {}; + if (m_data_item) + m_data_item->loadDatafield(projectDir, rank()); } std::vector<int> DatafileItem::axdims() const diff --git a/GUI/Model/Device/DatafileItem.h b/GUI/Model/Device/DatafileItem.h index e2c4e8fed35..b54b5500466 100644 --- a/GUI/Model/Device/DatafileItem.h +++ b/GUI/Model/Device/DatafileItem.h @@ -24,7 +24,6 @@ class Data1DItem; class Data2DItem; class DataItem; class Datafield; -class MessageService; //! Provides access to experimental data, for display and fitting. @@ -59,7 +58,7 @@ public: void readFrom(QXmlStreamReader* r); void saveDatafield(const QString& projectDir) const; - QString loadDatafield(const QString& projectDir, MessageService* messageService); + void loadDatafield(const QString& projectDir); //... Other diff --git a/GUI/Model/Files/DatafilesSet.cpp b/GUI/Model/Files/DatafilesSet.cpp index 5dedd6ffe2b..18b7a3106b8 100644 --- a/GUI/Model/Files/DatafilesSet.cpp +++ b/GUI/Model/Files/DatafilesSet.cpp @@ -86,10 +86,10 @@ void DatafilesSet::writeDatafiles(const QString& projectDir) const dataFilesCleaner.cleanOldFiles(projectDir, dataItems()); } -void DatafilesSet::readDatafiles(const QString& projectDir, MessageService* messageService) +void DatafilesSet::readDatafiles(const QString& projectDir) { for (auto* dfi : *this) - dfi->loadDatafield(projectDir, messageService); + dfi->loadDatafield(projectDir); dataFilesCleaner.recollectDataNames(dataItems()); } diff --git a/GUI/Model/Files/DatafilesSet.h b/GUI/Model/Files/DatafilesSet.h index dc334989cad..ae012b6a3b9 100644 --- a/GUI/Model/Files/DatafilesSet.h +++ b/GUI/Model/Files/DatafilesSet.h @@ -21,7 +21,6 @@ #include <QXmlStreamWriter> class DataItem; -class MessageService; //! The DatafilesSet class is a model to store all imported DatafileItem's. class DatafilesSet : public SetWithModel<DatafileItem> { @@ -30,7 +29,7 @@ public: virtual ~DatafilesSet(); void readFrom(QXmlStreamReader* r); - void readDatafiles(const QString& projectDir, MessageService* messageService); + void readDatafiles(const QString& projectDir); void writeTo(QXmlStreamWriter* w) const; void writeDatafiles(const QString& projectDir) const; diff --git a/GUI/Model/Job/JobItem.cpp b/GUI/Model/Job/JobItem.cpp index 751988bdbe0..4036e21e0b7 100644 --- a/GUI/Model/Job/JobItem.cpp +++ b/GUI/Model/Job/JobItem.cpp @@ -371,40 +371,13 @@ void JobItem::saveDatafields(const QString& projectDir) const m_simulated_data_item->saveDatafield(projectDir); } -void JobItem::loadDatafields(const QString& projectDir, MessageService* messageService) +void JobItem::loadDatafields(const QString& projectDir) { - QString realError, simError, errorMessage; - if (m_dfile_item) - realError = m_dfile_item->loadDatafield(projectDir, messageService); + m_dfile_item->loadDatafield(projectDir); if (m_simulated_data_item) - simError = m_simulated_data_item->loadDatafield(messageService, projectDir, rank()); - - // Handling corrupted file on disk - if (!realError.isEmpty() || !simError.isEmpty()) { - errorMessage = QString("Load of the data from disk failed with:\n"); - - if (!realError.isEmpty() && simError.isEmpty()) - errorMessage += QString("'%1'").arg(realError); - else if (realError.isEmpty() && !simError.isEmpty()) - errorMessage += QString("'%1'").arg(simError); - else - errorMessage += QString("'%1',\n'%2'").arg(realError, simError); - } - - // Handling previous crash of GUI during job run - if (isRunning(batchInfo()->status())) { - if (errorMessage.isEmpty()) - errorMessage = "Possible GUI crash while job was running"; - else - errorMessage += "\n. Also possibly GUI crashed while job was running"; - } - - if (!errorMessage.isEmpty()) { - batchInfo()->setComments(errorMessage); - setFailed(); - } + m_simulated_data_item->loadDatafield(projectDir, rank()); } //! Updates the name of file to store intensity data. diff --git a/GUI/Model/Job/JobItem.h b/GUI/Model/Job/JobItem.h index 7a90adb39af..e4746f2549d 100644 --- a/GUI/Model/Job/JobItem.h +++ b/GUI/Model/Job/JobItem.h @@ -108,7 +108,7 @@ public: void readFrom(QXmlStreamReader* r); void saveDatafields(const QString& projectDir) const; - void loadDatafields(const QString& projectDir, MessageService* messageService); + void loadDatafields(const QString& projectDir); signals: void jobSelected(JobItem* item); diff --git a/GUI/Model/Job/JobsSet.cpp b/GUI/Model/Job/JobsSet.cpp index a4726937137..bff24ca4f7d 100644 --- a/GUI/Model/Job/JobsSet.cpp +++ b/GUI/Model/Job/JobsSet.cpp @@ -94,10 +94,10 @@ void JobsSet::saveAllDatafields(const QString& projectDir) const dataFilesCleaner.cleanOldFiles(projectDir, dataItems()); } -void JobsSet::loadAllDatafields(const QString& projectDir, MessageService* messageService) +void JobsSet::loadAllDatafields(const QString& projectDir) { for (JobItem* job : *this) - job->loadDatafields(projectDir, messageService); + job->loadDatafields(projectDir); dataFilesCleaner.recollectDataNames(dataItems()); } diff --git a/GUI/Model/Job/JobsSet.h b/GUI/Model/Job/JobsSet.h index 6ebec87b4e0..7eff8a0928b 100644 --- a/GUI/Model/Job/JobsSet.h +++ b/GUI/Model/Job/JobsSet.h @@ -24,7 +24,6 @@ class DataItem; class ISimulation; class JobItem; -class MessageService; class JobsSet : public QObject, public VectorWC<JobItem> { Q_OBJECT @@ -36,7 +35,7 @@ public: void readFrom(QXmlStreamReader* r); void saveAllDatafields(const QString& projectDir) const; - void loadAllDatafields(const QString& projectDir, MessageService* messageService); + void loadAllDatafields(const QString& projectDir); JobItem* createJobItem(); void addJobItem(JobItem* job_item); diff --git a/GUI/Model/Project/ProjectDocument.cpp b/GUI/Model/Project/ProjectDocument.cpp index e40c55fe12c..fc7bec1c11c 100644 --- a/GUI/Model/Project/ProjectDocument.cpp +++ b/GUI/Model/Project/ProjectDocument.cpp @@ -141,9 +141,8 @@ ProjectDocument::ReadResult ProjectDocument::loadProjectFileWithData(const QStri if (result == ReadResult::error) return result; - m_jobs->loadAllDatafields(GUI::Util::Project::projectDir(projectPullPath), &messageService); - m_datafiles->readDatafiles(GUI::Util::Project::projectDir(projectPullPath), - &messageService); + m_jobs->loadAllDatafields(GUI::Util::Project::projectDir(projectPullPath)); + m_datafiles->readDatafiles(GUI::Util::Project::projectDir(projectPullPath)); if (!messageService.warnings().empty()) result = ReadResult::warning; -- GitLab From fd71e7d96c134360b80f9ec1f73ea4b1675591b1 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 17:10:36 +0100 Subject: [PATCH 16/18] rm class ReadResult --- GUI/Model/Data/DataItem.cpp | 12 +- GUI/Model/Project/ProjectDocument.cpp | 158 ++++++++-------------- GUI/Model/Project/ProjectDocument.h | 8 +- GUI/View/Main/ActionManager.cpp | 1 + GUI/View/Main/MainWindow.cpp | 1 + GUI/View/Manager/ProjectManager.cpp | 41 +----- GUI/View/Manager/ProjectManager.h | 12 +- Tests/Unit/GUI/TestAutosaveController.cpp | 1 + 8 files changed, 83 insertions(+), 151 deletions(-) diff --git a/GUI/Model/Data/DataItem.cpp b/GUI/Model/Data/DataItem.cpp index 5976cb1a050..fabee74077b 100644 --- a/GUI/Model/Data/DataItem.cpp +++ b/GUI/Model/Data/DataItem.cpp @@ -86,18 +86,18 @@ void DataItem::loadDatafield(const QString& projectDir, int rank) { if (!QFile::exists(projectDir)) throw std::runtime_error("Cannot load datafield: project directory " - + projectDir.toStdString() + " does not exist"); + + projectDir.toStdString() + " does not exist"); const auto file = dataFullPath(projectDir); std::unique_ptr<Datafield> data; if (rank == 1) - data = std::make_unique<Datafield>( - IO::readData1D(file.toStdString(), IO::Filetype1D::bornagain1D)); + data = std::make_unique<Datafield>( + IO::readData1D(file.toStdString(), IO::Filetype1D::bornagain1D)); else if (rank == 2) - data = std::make_unique<Datafield>( - IO::readData2D(file.toStdString(), IO::Filetype2D::bornagain2D)); + data = std::make_unique<Datafield>( + IO::readData2D(file.toStdString(), IO::Filetype2D::bornagain2D)); else - ASSERT_NEVER; + ASSERT_NEVER; ASSERT(data); setDatafield(*data); diff --git a/GUI/Model/Project/ProjectDocument.cpp b/GUI/Model/Project/ProjectDocument.cpp index fc7bec1c11c..96a64f90d84 100644 --- a/GUI/Model/Project/ProjectDocument.cpp +++ b/GUI/Model/Project/ProjectDocument.cpp @@ -24,7 +24,6 @@ #include "GUI/Model/Sample/SamplesSet.h" #include "GUI/Support/Data/ID.h" #include "GUI/Support/Data/SimulationOptionsItem.h" -#include "GUI/Support/Util/MessageService.h" #include "GUI/Support/Util/Path.h" #include "GUI/Support/XML/DeserializationException.h" #include "GUI/Support/XML/UtilXML.h" @@ -123,35 +122,19 @@ void ProjectDocument::saveProjectFileWithData(const QString& projectPullPath) emit projectSaved(); } -ProjectDocument::ReadResult ProjectDocument::loadProjectFileWithData(const QString& projectPullPath, - MessageService& messageService) +void ProjectDocument::loadProjectFileWithData(const QString& projectPullPath) { setProjectFullPath(projectPullPath); QFile file(projectFullPath()); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - QString message = QString("Open file error '%1'").arg(file.errorString()); - messageService.addError(this, message); - return ReadResult::error; - } + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) + throw std::runtime_error("Cannot open project file " + projectPullPath.toStdString()); - try { - auto result = readProject(&file, messageService); - file.close(); - if (result == ReadResult::error) - return result; - - m_jobs->loadAllDatafields(GUI::Util::Project::projectDir(projectPullPath)); - m_datafiles->readDatafiles(GUI::Util::Project::projectDir(projectPullPath)); - - if (!messageService.warnings().empty()) - result = ReadResult::warning; - return result; - } catch (const std::exception& ex) { - QString message = QString("Exception thrown '%1'").arg(QString(ex.what())); - messageService.addError(this, message); - return ReadResult::error; - } + readProject(&file); + file.close(); + + m_jobs->loadAllDatafields(GUI::Util::Project::projectDir(projectPullPath)); + m_datafiles->readDatafiles(GUI::Util::Project::projectDir(projectPullPath)); } bool ProjectDocument::hasValidNameAndPath() const @@ -232,85 +215,64 @@ void ProjectDocument::writeProject(QIODevice* device) w.writeEndDocument(); } -ProjectDocument::ReadResult ProjectDocument::readProject(QIODevice* device, - MessageService& messageService) +void ProjectDocument::readProject(QIODevice* device) { - const int warningsBefore = messageService.warnings().size(); - QXmlStreamReader r(device); - try { - while (!r.atEnd()) { - r.readNext(); - if (r.isStartElement()) { - if (r.name() == Tag::BornAgain) { - const uint version = XML::readUIntAttribute(&r, XML::Attrib::version); - Q_UNUSED(version) - m_current_version = r.attributes().value(XML::Attrib::BA_Version).toString(); - - if (!GUI::Path::isVersionMatchMinimal(m_current_version, - minimal_supported_version)) { - QString message = QString("Cannot open document version '%1', " - "minimal supported version '%2'") - .arg(m_current_version) - .arg(minimal_supported_version); - messageService.addError(this, message); - return ReadResult::error; - } - - while (r.readNextStartElement()) { - QString tag = r.name().toString(); - - // simulation options - if (tag == Tag::SimulationOptions) { - m_options->readFrom(&r); - XML::gotoEndElementOfTag(&r, tag); - - // instruments - } else if (tag == Tag::InstrumentsSet) { - m_instruments->readFrom(&r); - XML::gotoEndElementOfTag(&r, tag); - - // samples - } else if (tag == Tag::SamplesSet) { - m_samples->readFrom(&r); - XML::gotoEndElementOfTag(&r, tag); - - // real model - } else if (tag == Tag::RealModel) { - // 'm_instruments' should be read before - m_datafiles->readFrom(&r); - XML::gotoEndElementOfTag(&r, tag); - - // job model - } else if (tag == Tag::JobsSet) { - m_jobs->readFrom(&r); - XML::gotoEndElementOfTag(&r, tag); - - // active view - } else if (tag == Tag::ActiveView) { - XML::readAttribute(&r, XML::Attrib::value, &m_last_view_active); - XML::gotoEndElementOfTag(&r, tag); - - } else - r.skipCurrentElement(); - } + while (!r.atEnd()) { + r.readNext(); + if (r.isStartElement()) { + if (r.name() == Tag::BornAgain) { + const uint version = XML::readUIntAttribute(&r, XML::Attrib::version); + Q_UNUSED(version) + m_current_version = r.attributes().value(XML::Attrib::BA_Version).toString(); + + if (!GUI::Path::isVersionMatchMinimal(m_current_version, minimal_supported_version)) + throw std::runtime_error(QString("Cannot open document version '%1', " + "minimal supported version is '%2'") + .arg(m_current_version) + .arg(minimal_supported_version) + .toStdString()); + + while (r.readNextStartElement()) { + QString tag = r.name().toString(); + + // simulation options + if (tag == Tag::SimulationOptions) { + m_options->readFrom(&r); + XML::gotoEndElementOfTag(&r, tag); + + // instruments + } else if (tag == Tag::InstrumentsSet) { + m_instruments->readFrom(&r); + XML::gotoEndElementOfTag(&r, tag); + + // samples + } else if (tag == Tag::SamplesSet) { + m_samples->readFrom(&r); + XML::gotoEndElementOfTag(&r, tag); + + // real model + } else if (tag == Tag::RealModel) { + // 'm_instruments' should be read before + m_datafiles->readFrom(&r); + XML::gotoEndElementOfTag(&r, tag); + + // job model + } else if (tag == Tag::JobsSet) { + m_jobs->readFrom(&r); + XML::gotoEndElementOfTag(&r, tag); + + // active view + } else if (tag == Tag::ActiveView) { + XML::readAttribute(&r, XML::Attrib::value, &m_last_view_active); + XML::gotoEndElementOfTag(&r, tag); + + } else + r.skipCurrentElement(); } } } - - } catch (DeserializationException& ex) { - r.raiseError(ex.text()); - } - - if (r.hasError()) { - QString message = QString("Format error '%1'").arg(r.errorString()); - messageService.addError(this, message); - return ReadResult::error; } - - // return "ReadResult::warning" only if warnings have been issued _in here_ - return warningsBefore != messageService.warnings().size() ? ReadResult::warning - : ReadResult::ok; } void ProjectDocument::setViewId(int id) diff --git a/GUI/Model/Project/ProjectDocument.h b/GUI/Model/Project/ProjectDocument.h index 3ceb64892ea..01327d0616b 100644 --- a/GUI/Model/Project/ProjectDocument.h +++ b/GUI/Model/Project/ProjectDocument.h @@ -21,7 +21,6 @@ class DatafilesSet; class InstrumentsSet; class JobsSet; -class MessageService; class ProjectDocument; class QIODevice; class SamplesSet; @@ -41,8 +40,6 @@ BA_GUI_API_ extern std::unique_ptr<ProjectDocument> gDoc; class ProjectDocument : public QObject { Q_OBJECT public: - enum class ReadResult { ok, warning, error }; - ProjectDocument(); ~ProjectDocument(); @@ -50,8 +47,7 @@ public: void setProjectName(const QString& text); void setProjectFullPath(const QString& fullPath); void saveProjectFileWithData(const QString& projectPullPath); - ReadResult loadProjectFileWithData(const QString& projectPullPath, - MessageService& messageService); + void loadProjectFileWithData(const QString& projectPullPath); void setModified(); void clearModified(); @@ -87,7 +83,7 @@ signals: private: void writeProject(QIODevice* device); - ReadResult readProject(QIODevice* device, MessageService& messageService); + void readProject(QIODevice* device); void onModelChanged(); diff --git a/GUI/View/Main/ActionManager.cpp b/GUI/View/Main/ActionManager.cpp index f8d736c3d5b..28bbe73fe50 100644 --- a/GUI/View/Main/ActionManager.cpp +++ b/GUI/View/Main/ActionManager.cpp @@ -15,6 +15,7 @@ #include "GUI/View/Main/ActionManager.h" #include "Base/Util/Assert.h" #include "Base/Util/SysUtil.h" +#include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Support/Util/Path.h" #include "GUI/View/Layout/ApplicationSettings.h" #include "GUI/View/Layout/mainwindow_constants.h" diff --git a/GUI/View/Main/MainWindow.cpp b/GUI/View/Main/MainWindow.cpp index 8417a6e8bac..cc94e303d01 100644 --- a/GUI/View/Main/MainWindow.cpp +++ b/GUI/View/Main/MainWindow.cpp @@ -14,6 +14,7 @@ #include "GUI/View/Main/MainWindow.h" #include "GUI/Model/Job/JobsSet.h" +#include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Support/Util/Path.h" #include "GUI/View/Layout/ApplicationSettings.h" #include "GUI/View/Layout/mainwindow_constants.h" diff --git a/GUI/View/Manager/ProjectManager.cpp b/GUI/View/Manager/ProjectManager.cpp index eef6eec561c..338fc2b81e7 100644 --- a/GUI/View/Manager/ProjectManager.cpp +++ b/GUI/View/Manager/ProjectManager.cpp @@ -14,6 +14,7 @@ #include "GUI/View/Manager/ProjectManager.h" #include "Base/Util/Assert.h" +#include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Model/Project/ProjectUtil.h" #include "GUI/Support/Util/MessageService.h" #include "GUI/View/Info/MessageBox.h" @@ -253,18 +254,7 @@ void ProjectManager::openProject(QString projectPullPath) } createNewProject(); - MessageService messageService; - const auto readResult = loadProject(projectPullPath, messageService); - - if (readResult == ProjectDocument::ReadResult::ok) - addToRecentProjects(); - else if (readResult == ProjectDocument::ReadResult::error) { - riseProjectLoadFailedDialog(messageService); - deleteCurrentProject(); - } else if (readResult == ProjectDocument::ReadResult::warning) { - riseProjectLoadProblemDialog(messageService); - addToRecentProjects(); - } + loadProject(projectPullPath); if (gDoc) emit documentOpenedOrClosed(true); } @@ -297,26 +287,22 @@ void ProjectManager::deleteCurrentProject() //! Load project data from file name. If autosave info exists, opens dialog for project restore. -ProjectDocument::ReadResult ProjectManager::loadProject(const QString& fullPathAndName, - MessageService& messageService) +void ProjectManager::loadProject(const QString& fullPathAndName) { - auto readResult = ProjectDocument::ReadResult::ok; - const bool useAutosave = GUI::Util::Project::hasAutosavedData(fullPathAndName); const QString autosaveFullPath = GUI::Util::Project::autosaveFullPath(fullPathAndName); if (qApp) QApplication::setOverrideCursor(Qt::WaitCursor); if (useAutosave && restoreProjectDialog(fullPathAndName, autosaveFullPath)) { - readResult = gDoc->loadProjectFileWithData(autosaveFullPath, messageService); + gDoc->loadProjectFileWithData(autosaveFullPath); gDoc->setProjectFullPath(fullPathAndName); // restored project should be marked by '*' gDoc->setModified(); } else { - readResult = gDoc->loadProjectFileWithData(fullPathAndName, messageService); + gDoc->loadProjectFileWithData(fullPathAndName); } if (qApp) QApplication::restoreOverrideCursor(); - return readResult; } //! Returns project file name from dialog. Returns empty string if dialog was canceled. @@ -365,23 +351,6 @@ QString ProjectManager::untitledProjectName() return result; } -void ProjectManager::riseProjectLoadFailedDialog(const MessageService& messageService) -{ - QString message = QString("Failed to load the project '%1' \n\n").arg(gDoc->projectFullPath()); - - for (const auto& details : messageService.errors()) - message.append(details + "\n"); - - QMessageBox::warning(GUI::Global::mainWindow, "Error while opening project file", message); -} - -void ProjectManager::riseProjectLoadProblemDialog(const MessageService& messageService) -{ - auto* problemDialog = new ProjectLoadProblemDialog(messageService.warnings(true)); - problemDialog->show(); - problemDialog->raise(); -} - //! Rises dialog if the project should be restored from autosave. Returns true, if yes. bool ProjectManager::restoreProjectDialog(const QString& projectFileName, diff --git a/GUI/View/Manager/ProjectManager.h b/GUI/View/Manager/ProjectManager.h index 38a2a540c33..8a1c1f15276 100644 --- a/GUI/View/Manager/ProjectManager.h +++ b/GUI/View/Manager/ProjectManager.h @@ -15,7 +15,11 @@ #ifndef BORNAGAIN_GUI_VIEW_MANAGER_PROJECTMANAGER_H #define BORNAGAIN_GUI_VIEW_MANAGER_PROJECTMANAGER_H -#include "GUI/Model/Project/ProjectDocument.h" +#include <QObject> +#include <QStringList> + +class AutosaveController; +class ProjectDocument; class AutosaveController; @@ -56,15 +60,13 @@ public slots: private: void createNewProject(); void deleteCurrentProject(); - ProjectDocument::ReadResult loadProject(const QString& fullPathAndName, - MessageService& messageService); + void loadProject(const QString& fullPathAndName); + QString acquireProjectPullPath(); void addToRecentProjects(); QString untitledProjectName(); - void riseProjectLoadFailedDialog(const MessageService& messageService); - void riseProjectLoadProblemDialog(const MessageService& messageService); bool restoreProjectDialog(const QString& projectFileName, QString autosaveName); QString m_working_directory; diff --git a/Tests/Unit/GUI/TestAutosaveController.cpp b/Tests/Unit/GUI/TestAutosaveController.cpp index e05dcef0247..f2405d61f9b 100644 --- a/Tests/Unit/GUI/TestAutosaveController.cpp +++ b/Tests/Unit/GUI/TestAutosaveController.cpp @@ -4,6 +4,7 @@ #include "GUI/Model/Device/DatafileItem.h" #include "GUI/Model/Device/InstrumentItems.h" #include "GUI/Model/Device/InstrumentsSet.h" +#include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Model/Project/ProjectUtil.h" #include "GUI/Support/Util/Path.h" #include "GUI/View/Manager/AutosaveController.h" -- GitLab From 229e994e62d08ffd4c6ba7ca0ba8074d96284dcc Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 17:12:58 +0100 Subject: [PATCH 17/18] rm MessageService --- GUI/Model/Job/JobItem.h | 1 - GUI/Model/Mask/MasksSet.cpp | 2 +- GUI/Model/Mask/MasksSet.h | 3 +- GUI/Support/Util/MessageService.cpp | 48 --------------------------- GUI/Support/Util/MessageService.h | 42 ----------------------- GUI/View/Manager/ProjectManager.cpp | 1 - Tests/Unit/GUI/TestMessageService.cpp | 37 --------------------- 7 files changed, 2 insertions(+), 132 deletions(-) delete mode 100644 GUI/Support/Util/MessageService.cpp delete mode 100644 GUI/Support/Util/MessageService.h delete mode 100644 Tests/Unit/GUI/TestMessageService.cpp diff --git a/GUI/Model/Job/JobItem.h b/GUI/Model/Job/JobItem.h index e4746f2549d..7de72d254d9 100644 --- a/GUI/Model/Job/JobItem.h +++ b/GUI/Model/Job/JobItem.h @@ -27,7 +27,6 @@ class DatafileItem; class FitSuiteItem; class InstrumentItem; class JobWorker; -class MessageService; class ParameterContainerItem; class ParameterTreeItems; class SampleItem; diff --git a/GUI/Model/Mask/MasksSet.cpp b/GUI/Model/Mask/MasksSet.cpp index 47117ddf3e3..74e4d93ffbb 100644 --- a/GUI/Model/Mask/MasksSet.cpp +++ b/GUI/Model/Mask/MasksSet.cpp @@ -70,7 +70,7 @@ void MasksSet::writeTo(QXmlStreamWriter* w) const } } -void MasksSet::readFrom(QXmlStreamReader* r, MessageService*) +void MasksSet::readFrom(QXmlStreamReader* r) { clear(); diff --git a/GUI/Model/Mask/MasksSet.h b/GUI/Model/Mask/MasksSet.h index 9b88835090b..90698e08293 100644 --- a/GUI/Model/Mask/MasksSet.h +++ b/GUI/Model/Mask/MasksSet.h @@ -20,7 +20,6 @@ #include <QModelIndex> #include <QXmlStreamWriter> -class MessageService; class RegionOfInterestItem; //! Container holding various masks as children @@ -35,7 +34,7 @@ public: RegionOfInterestItem* regionOfInterestItem() const; void writeTo(QXmlStreamWriter* w) const; - void readFrom(QXmlStreamReader* r, MessageService* messageService = nullptr); + void readFrom(QXmlStreamReader* r); void updateMaskNames(); diff --git a/GUI/Support/Util/MessageService.cpp b/GUI/Support/Util/MessageService.cpp deleted file mode 100644 index 472189d5b5f..00000000000 --- a/GUI/Support/Util/MessageService.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/Support/Util/MessageService.cpp -//! @brief Implements class MessageService. -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "GUI/Support/Util/MessageService.h" - -QStringList MessageService::descriptions(const Messages& messages, bool includeSenders) const -{ - QStringList result; - - for (const auto& message : messages) - if (includeSenders) - result.push_back(message.first + ": " + message.second); - else - result.push_back(message.second); - - return result; -} - -void MessageService::addError(QObject* sender, const QString& description) -{ - m_errors.append(qMakePair(sender->objectName(), description)); -} - -void MessageService::addWarning(QObject* sender, const QString& description) -{ - m_warnings.append(qMakePair(sender->objectName(), description)); -} - -QStringList MessageService::errors(bool includeSenders /*= false*/) const -{ - return descriptions(m_errors, includeSenders); -} - -QStringList MessageService::warnings(bool includeSenders /*= false*/) const -{ - return descriptions(m_warnings, includeSenders); -} diff --git a/GUI/Support/Util/MessageService.h b/GUI/Support/Util/MessageService.h deleted file mode 100644 index e4037266728..00000000000 --- a/GUI/Support/Util/MessageService.h +++ /dev/null @@ -1,42 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/Support/Util/MessageService.h -//! @brief Defines class MessageService. -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI_SUPPORT_UTIL_MESSAGESERVICE_H -#define BORNAGAIN_GUI_SUPPORT_UTIL_MESSAGESERVICE_H - -#include <QObject> -#include <QString> -#include <QVector> -#include <utility> - -//! The service to collect messages from different senders. - -class MessageService { -public: - void addError(QObject* sender, const QString& description); - void addWarning(QObject* sender, const QString& description); - - QStringList errors(bool includeSenders = false) const; - QStringList warnings(bool includeSenders = false) const; - -private: - using Messages = QVector<std::pair<QString, QString>>; // pair of sender & description - - QStringList descriptions(const Messages& messages, bool includeSenders) const; - - Messages m_warnings; - Messages m_errors; -}; - -#endif // BORNAGAIN_GUI_SUPPORT_UTIL_MESSAGESERVICE_H diff --git a/GUI/View/Manager/ProjectManager.cpp b/GUI/View/Manager/ProjectManager.cpp index 338fc2b81e7..73a93fa4a06 100644 --- a/GUI/View/Manager/ProjectManager.cpp +++ b/GUI/View/Manager/ProjectManager.cpp @@ -16,7 +16,6 @@ #include "Base/Util/Assert.h" #include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Model/Project/ProjectUtil.h" -#include "GUI/Support/Util/MessageService.h" #include "GUI/View/Info/MessageBox.h" #include "GUI/View/Layout/ApplicationSettings.h" #include "GUI/View/Layout/mainwindow_constants.h" diff --git a/Tests/Unit/GUI/TestMessageService.cpp b/Tests/Unit/GUI/TestMessageService.cpp deleted file mode 100644 index 0f95f9bcaf3..00000000000 --- a/Tests/Unit/GUI/TestMessageService.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "GUI/Support/Util/MessageService.h" - -#include "Tests/GTestWrapper/google_test.h" -#include <QObject> -#include <QString> - -class TestMessageService : public ::testing::Test { -public: - class Sender : public QObject { - public: - explicit Sender(const QString& name) { setObjectName(name); } - }; -}; - -TEST_F(TestMessageService, warningAndErrorCount) -{ - const QString senderName1("senderName1"); - const QString senderName2("senderName2"); - - const QString description1("description1"); - const QString description2("description2"); - const QString description3("description3"); - - MessageService svc; - Sender sender1(senderName1); - Sender sender2(senderName2); - - // sending messages - svc.addWarning(&sender1, description1); - svc.addWarning(&sender1, description2); - svc.addError(&sender1, description1); - svc.addError(&sender2, description2); - svc.addWarning(&sender1, description3); - - EXPECT_EQ(svc.warnings().size(), 3); - EXPECT_EQ(svc.errors().size(), 2); -} -- GitLab From 6111aad9cb15115d1f0da48da8ae5b11e111d426 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de> Date: Mon, 4 Mar 2024 17:19:57 +0100 Subject: [PATCH 18/18] rm DeserializationException --- GUI/Model/Device/DatafileItem.cpp | 1 - GUI/Model/Device/InstrumentXML.cpp | 1 - GUI/Model/Material/MaterialItem.cpp | 1 - GUI/Model/Project/ProjectDocument.cpp | 2 -- GUI/Support/Data/SimulationOptionsItem.cpp | 1 - GUI/Support/XML/DeserializationException.cpp | 36 -------------------- GUI/Support/XML/DeserializationException.h | 35 ------------------- GUI/Support/XML/UtilXML.cpp | 15 +++----- 8 files changed, 5 insertions(+), 87 deletions(-) delete mode 100644 GUI/Support/XML/DeserializationException.cpp delete mode 100644 GUI/Support/XML/DeserializationException.h diff --git a/GUI/Model/Device/DatafileItem.cpp b/GUI/Model/Device/DatafileItem.cpp index 4630ae4678b..4d44a31f967 100644 --- a/GUI/Model/Device/DatafileItem.cpp +++ b/GUI/Model/Device/DatafileItem.cpp @@ -22,7 +22,6 @@ #include "GUI/Model/Data/Data2DItem.h" #include "GUI/Support/Util/Path.h" #include "GUI/Support/XML/Backup.h" -#include "GUI/Support/XML/DeserializationException.h" #include "GUI/Support/XML/UtilXML.h" namespace { diff --git a/GUI/Model/Device/InstrumentXML.cpp b/GUI/Model/Device/InstrumentXML.cpp index 318f52484cc..93e6c3e2c04 100644 --- a/GUI/Model/Device/InstrumentXML.cpp +++ b/GUI/Model/Device/InstrumentXML.cpp @@ -17,7 +17,6 @@ #include "GUI/Model/Descriptor/PolyItem.h" #include "GUI/Model/Device/InstrumentItems.h" #include "GUI/Model/Device/InstrumentsCatalog.h" -#include "GUI/Support/XML/DeserializationException.h" #include "GUI/Support/XML/UtilXML.h" #include <QFile> diff --git a/GUI/Model/Material/MaterialItem.cpp b/GUI/Model/Material/MaterialItem.cpp index 7adcef85a10..a5996d227a5 100644 --- a/GUI/Model/Material/MaterialItem.cpp +++ b/GUI/Model/Material/MaterialItem.cpp @@ -14,7 +14,6 @@ #include "GUI/Model/Material/MaterialItem.h" #include "Base/Util/Assert.h" -#include "GUI/Support/XML/DeserializationException.h" #include "GUI/Support/XML/UtilXML.h" #include "Sample/Material/MaterialFactoryFuncs.h" #include <QUuid> diff --git a/GUI/Model/Project/ProjectDocument.cpp b/GUI/Model/Project/ProjectDocument.cpp index 96a64f90d84..dacaab1b9b0 100644 --- a/GUI/Model/Project/ProjectDocument.cpp +++ b/GUI/Model/Project/ProjectDocument.cpp @@ -25,10 +25,8 @@ #include "GUI/Support/Data/ID.h" #include "GUI/Support/Data/SimulationOptionsItem.h" #include "GUI/Support/Util/Path.h" -#include "GUI/Support/XML/DeserializationException.h" #include "GUI/Support/XML/UtilXML.h" #include <QFile> -#include <QStandardPaths> BA_GUI_API_ std::unique_ptr<ProjectDocument> gDoc; diff --git a/GUI/Support/Data/SimulationOptionsItem.cpp b/GUI/Support/Data/SimulationOptionsItem.cpp index d6db12507e9..daca3268262 100644 --- a/GUI/Support/Data/SimulationOptionsItem.cpp +++ b/GUI/Support/Data/SimulationOptionsItem.cpp @@ -13,7 +13,6 @@ // ************************************************************************************************ #include "GUI/Support/Data/SimulationOptionsItem.h" -#include "GUI/Support/XML/DeserializationException.h" #include "GUI/Support/XML/UtilXML.h" #include <thread> diff --git a/GUI/Support/XML/DeserializationException.cpp b/GUI/Support/XML/DeserializationException.cpp deleted file mode 100644 index 90b31d01a7d..00000000000 --- a/GUI/Support/XML/DeserializationException.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/Support/XML/DeserializationException.cpp -//! @brief Implements class DeserializationException. -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2021 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "GUI/Support/XML/DeserializationException.h" -#include <utility> - -DeserializationException::DeserializationException(QString t) - : m_text(std::move(t)) -{ -} - -DeserializationException DeserializationException::tooOld() -{ - return DeserializationException("The found file is too old."); -} - -DeserializationException DeserializationException::tooNew() -{ - return DeserializationException("The found file is too new."); -} - -DeserializationException DeserializationException::streamError() -{ - return DeserializationException("The data seems to be corrupted."); -} diff --git a/GUI/Support/XML/DeserializationException.h b/GUI/Support/XML/DeserializationException.h deleted file mode 100644 index 6daed29978e..00000000000 --- a/GUI/Support/XML/DeserializationException.h +++ /dev/null @@ -1,35 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/Support/XML/DeserializationException.h -//! @brief Defines class DeserializationException. -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2021 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI_SUPPORT_XML_DESERIALIZATIONEXCEPTION_H -#define BORNAGAIN_GUI_SUPPORT_XML_DESERIALIZATIONEXCEPTION_H - -#include <QString> - -class DeserializationException { -private: - DeserializationException(QString t); - -public: - static DeserializationException tooOld(); - static DeserializationException tooNew(); - static DeserializationException streamError(); - - QString text() const { return m_text; } - -private: - QString m_text; -}; - -#endif // BORNAGAIN_GUI_SUPPORT_XML_DESERIALIZATIONEXCEPTION_H diff --git a/GUI/Support/XML/UtilXML.cpp b/GUI/Support/XML/UtilXML.cpp index 41c0bdbbdfb..140cafc5a92 100644 --- a/GUI/Support/XML/UtilXML.cpp +++ b/GUI/Support/XML/UtilXML.cpp @@ -14,7 +14,6 @@ #include "GUI/Support/XML/UtilXML.h" #include "Base/Util/Assert.h" -#include "GUI/Support/XML/DeserializationException.h" #include <QColor> #include <QUuid> @@ -23,20 +22,16 @@ namespace { void assertCurrentTag(QXmlStreamReader* reader, const QString& expectedTag) { - if (reader->name() != expectedTag) { -#ifdef _DEBUG - // to simplify debugging: what is the current tag - QString foundTag = reader->name().toString(); - Q_UNUSED(foundTag); -#endif - throw DeserializationException::streamError(); - } + if (reader->name() != expectedTag) + throw std::runtime_error("Found tag '" + reader->name().toString().toStdString() + + "' instead of expected expected tag '" + + expectedTag.toStdString() + "'"); } void assertCurrentToken(QXmlStreamReader* reader, QXmlStreamReader::TokenType token) { if (reader->tokenType() != token) - throw DeserializationException::streamError(); + throw std::runtime_error("Found unexpected token type"); } } // namespace -- GitLab