From bf19b4fcc354412bf15fc1903fb69891e311a8d7 Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Wed, 13 Mar 2024 10:31:57 +0100 Subject: [PATCH 1/2] merge Globals.h into AppConfig --- App/main.cpp | 3 +-- GUI/View/Layout/AppConfig.h | 2 ++ GUI/View/Manager/ProjectManager.cpp | 9 ++++----- GUI/View/Manager/PyImportAssistant.cpp | 16 +++++++--------- GUI/View/Tool/Globals.h | 26 -------------------------- GUI/View/Views/SimulationView.cpp | 4 ++-- 6 files changed, 16 insertions(+), 44 deletions(-) delete mode 100644 GUI/View/Tool/Globals.h diff --git a/App/main.cpp b/App/main.cpp index f017b48da80..4445f715426 100644 --- a/App/main.cpp +++ b/App/main.cpp @@ -18,7 +18,6 @@ #include "GUI/Support/Util/Path.h" #include "GUI/View/Layout/AppConfig.h" #include "GUI/View/Main/MainWindow.h" -#include "GUI/View/Tool/Globals.h" #include "config_build.h" #include <QApplication> #include <QDir> @@ -73,7 +72,7 @@ int main(int argc, char* argv[]) gDoc = std::make_unique<ProjectDocument>(); MainWindow win; - GUI::Global::mainWindow = &win; + gApp->mainWindow = &win; if (options.find("geometry")) win.resize(options.mainWindowSize()); diff --git a/GUI/View/Layout/AppConfig.h b/GUI/View/Layout/AppConfig.h index a5a930ea6e1..4afcf3ff3d7 100644 --- a/GUI/View/Layout/AppConfig.h +++ b/GUI/View/Layout/AppConfig.h @@ -26,6 +26,8 @@ public: bool useNativeFileDialog() const; + class QWidget* mainWindow; //!< Pointer to _the_ MainWindow + QString import_filter_1D; //!< Last used import filter for 1D files QString import_filter_2D; //!< Last used import filter for 2D files diff --git a/GUI/View/Manager/ProjectManager.cpp b/GUI/View/Manager/ProjectManager.cpp index 418f92f95ff..7f2ca3e6b9d 100644 --- a/GUI/View/Manager/ProjectManager.cpp +++ b/GUI/View/Manager/ProjectManager.cpp @@ -20,7 +20,6 @@ #include "GUI/View/Info/MessageBox.h" #include "GUI/View/Layout/AppConfig.h" #include "GUI/View/Manager/NewProjectDialog.h" -#include "GUI/View/Tool/Globals.h" #include <QApplication> #include <QDateTime> #include <QFileDialog> @@ -174,7 +173,7 @@ bool ProjectManager::saveProject(QString projectPullPath) message.append("Exception was thrown.\n\n"); message.append(ex.what()); - QMessageBox::warning(GUI::Global::mainWindow, "Error while saving project", message); + QMessageBox::warning(gApp->mainWindow, "Error while saving project", message); return false; } addToRecentProjects(); @@ -200,7 +199,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", m_working_directory, + gApp->mainWindow, "Open project file", m_working_directory, "BornAgain project Files (*" + ext + ")", nullptr, gApp->useNativeFileDialog() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog); @@ -247,7 +246,7 @@ void ProjectManager::loadProject(const QString& fullPathAndName) QString ProjectManager::acquireProjectPullPath() { - NewProjectDialog dialog(GUI::Global::mainWindow, m_working_directory, untitledProjectName()); + NewProjectDialog dialog(gApp->mainWindow, m_working_directory, untitledProjectName()); if (dialog.exec() != QDialog::Accepted) return ""; @@ -306,7 +305,7 @@ bool ProjectManager::restoreProjectDialog(const QString& projectFileName, .arg(lmProject) .arg(lmAutoSave); - return GUI::Message::question(GUI::Global::mainWindow, title, message, + return GUI::Message::question(gApp->mainWindow, title, message, "\nDo you want to restore from autosave?\n", "Yes, please restore.", "No, keep loading original"); } diff --git a/GUI/View/Manager/PyImportAssistant.cpp b/GUI/View/Manager/PyImportAssistant.cpp index 2143a44edd0..4576c0683ed 100644 --- a/GUI/View/Manager/PyImportAssistant.cpp +++ b/GUI/View/Manager/PyImportAssistant.cpp @@ -27,7 +27,6 @@ #include "GUI/View/Info/DetailedMessageBox.h" #include "GUI/View/Info/MessageBox.h" #include "GUI/View/Layout/AppConfig.h" -#include "GUI/View/Tool/Globals.h" #include "PyCore/Embed/PyInterpreter.h" // listOfFunctions #include "PyCore/Sample/ImportMultiLayer.h" // createMultiLayerFromPython #include "Sample/Multilayer/MultiLayer.h" @@ -69,8 +68,8 @@ QString getCandidate(const QStringList& funcNames) QString fnameToOpen() { QString result = QFileDialog::getOpenFileName( - GUI::Global::mainWindow, "Open python script", gApp->script_import_dir, - "Python scripts (*.py)", nullptr, + gApp->mainWindow, "Open python script", gApp->script_import_dir, "Python scripts (*.py)", + nullptr, gApp->useNativeFileDialog() ? QFileDialog::Options() : QFileDialog::DontUseNativeDialog); return result; @@ -88,7 +87,7 @@ QString readFile(const QString& fname) const QString message = "Cannot read the file. \n\nPyImportAssistant::readFile -> Error: Can' t open the file '" + fname + "' for reading."; - GUI::Message::warning(GUI::Global::mainWindow, "File read failure.", message); + GUI::Message::warning(gApp->mainWindow, "File read failure.", message); return {}; } @@ -115,7 +114,7 @@ QString selectPySampleFunction(const QStringList& funcNames) if (funcNames.empty()) { QString message("Python code doesn't contain any functions.\n\n"); - GUI::Message::warning(GUI::Global::mainWindow, "Python failure", message); + GUI::Message::warning(gApp->mainWindow, "Python failure", message); } else { ComboSelectorDialog dialog; dialog.addItems(funcNames, getCandidate(funcNames)); @@ -144,7 +143,7 @@ QString getPySampleFunctionName(const QString& snippet) if (funcs_res.empty()) { QString message("Exception thrown while acquiring functions from Python code.\n\n"); - DetailedMessageBox(GUI::Global::mainWindow, "Python failure", message, "").exec(); + DetailedMessageBox(gApp->mainWindow, "Python failure", message, "").exec(); return ""; } @@ -159,14 +158,13 @@ SampleItem* itemizeSample(const MultiLayer& sample) QString message("Seems that import was successful.\n\n" "Check SampleView for new sample and material editor for new materials."); - GUI::Message::information(GUI::Global::mainWindow, "Python import", message); + GUI::Message::information(gApp->mainWindow, "Python import", message); return newItem; } catch (const std::exception& ex) { QString message("Exception thrown while trying to build GUI models.\n" "GUI models might be in inconsistent state.\n\n"); QString details = QString::fromStdString(std::string(ex.what())); - DetailedMessageBox(GUI::Global::mainWindow, "GUI::ObjectBuilder failure", message, details) - .exec(); + DetailedMessageBox(gApp->mainWindow, "GUI::ObjectBuilder failure", message, details).exec(); return nullptr; } } diff --git a/GUI/View/Tool/Globals.h b/GUI/View/Tool/Globals.h deleted file mode 100644 index ce87ddd23b2..00000000000 --- a/GUI/View/Tool/Globals.h +++ /dev/null @@ -1,26 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Tool/Globals.h -//! @brief Defines global pointers. -//! -//! @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_VIEW_TOOL_GLOBALS_H -#define BORNAGAIN_GUI_VIEW_TOOL_GLOBALS_H - -class QWidget; - -namespace GUI::Global { - -inline class QWidget* mainWindow; - -} // namespace GUI::Global - -#endif // BORNAGAIN_GUI_VIEW_TOOL_GLOBALS_H diff --git a/GUI/View/Views/SimulationView.cpp b/GUI/View/Views/SimulationView.cpp index 8b47b8246eb..a77dcd8ad8b 100644 --- a/GUI/View/Views/SimulationView.cpp +++ b/GUI/View/Views/SimulationView.cpp @@ -22,8 +22,8 @@ #include "GUI/Model/Sample/SampleValidator.h" #include "GUI/Model/Sample/SamplesSet.h" #include "GUI/Support/Data/SimulationOptionsItem.h" +#include "GUI/View/Layout/AppConfig.h" #include "GUI/View/Loader/PythonScriptWidget.h" -#include "GUI/View/Tool/Globals.h" #include "GUI/View/Widget/GroupBoxes.h" #include <QButtonGroup> #include <QFormLayout> @@ -259,7 +259,7 @@ void SimulationView::simulate() void SimulationView::exportPythonScript() { readOptionsFromUI(); - auto* pythonWidget = new PythonScriptWidget(GUI::Global::mainWindow); + auto* pythonWidget = new PythonScriptWidget(gApp->mainWindow); pythonWidget->show(); pythonWidget->raise(); pythonWidget->generatePythonScript(gDoc->samples()->currentItem(), -- GitLab From e0ba4784be870d315f631ab4dbbdec7cafb2818b Mon Sep 17 00:00:00 2001 From: "Joachim Wuttke (h)" <j.wuttke@fz-juelich.de> Date: Wed, 13 Mar 2024 11:46:47 +0100 Subject: [PATCH 2/2] color gradient now an App property, not a data item property --- GUI/Model/Data/Data2DItem.cpp | 50 ----------------------------------- GUI/Model/Data/Data2DItem.h | 9 ------- GUI/Model/Job/JobItem.cpp | 10 +------ GUI/View/Layout/AppConfig.cpp | 31 ++++++++++++++++++++++ GUI/View/Layout/AppConfig.h | 19 ++++++++++--- GUI/View/Plotter/ColorMap.cpp | 6 +++-- GUI/View/Setup/AxesPanel.cpp | 15 +++++------ 7 files changed, 59 insertions(+), 81 deletions(-) diff --git a/GUI/Model/Data/Data2DItem.cpp b/GUI/Model/Data/Data2DItem.cpp index 20438633e22..df00526a0f8 100644 --- a/GUI/Model/Data/Data2DItem.cpp +++ b/GUI/Model/Data/Data2DItem.cpp @@ -21,47 +21,23 @@ #include "GUI/Model/Axis/BasicAxisItem.h" #include "GUI/Model/Mask/MasksQModel.h" #include "GUI/Model/Mask/MasksSet.h" -#include "GUI/Support/Data/ComboProperty.h" -#include "GUI/Support/Style/QCP_Util.h" #include "GUI/Support/XML/UtilXML.h" -#include <qcustomplot.h> namespace { namespace Tag { const QString BaseData("BaseData"); -const QString Gradient("Gradient"); const QString Interpolation("Interpolation"); const QString ZAxis("ZAxis"); } // namespace Tag -// gradient map for colormaps -const QMap<QString, QCPColorGradient> gradient_map = { - {"Grayscale", QCPColorGradient::gpGrayscale}, - {"Hot", QCPColorGradient::gpHot}, - {"Cold", QCPColorGradient::gpCold}, - {"Night", QCPColorGradient::gpNight}, - {"Candy", QCPColorGradient::gpCandy}, - {"Geography", QCPColorGradient::gpGeography}, - {"Ion", QCPColorGradient::gpIon}, - {"Thermal", QCPColorGradient::gpThermal}, - {"Polar", QCPColorGradient::gpPolar}, - {"Spectrum", QCPColorGradient::gpSpectrum}, - {"Jet", QCPColorGradient::gpJet}, - {"Hues", QCPColorGradient::gpHues}, - {"Inferno", GUI::QCP_Util::colorGradientInferno()}}; - -const QString startGradient = "Inferno"; - } // namespace Data2DItem::Data2DItem() : DataItem(M_TYPE) , m_is_interpolated(true) - , m_gradient(std::make_unique<ComboProperty>( - ComboProperty::fromList(::gradient_map.keys(), ::startGradient))) , m_z_axis(std::make_unique<AmplitudeAxisItem>()) { } @@ -132,22 +108,6 @@ bool Data2DItem::isZoomed() const return lowerX() > xMin() || upperX() < xMax() || lowerY() > yMin() || upperY() < yMax(); } -QCPColorGradient Data2DItem::currentGradientQCP() const -{ - return ::gradient_map.value(currentGradient()); -} - -QString Data2DItem::currentGradient() const -{ - return gradientCombo().currentValue(); -} - -void Data2DItem::setCurrentGradient(const QString& gradient) -{ - m_gradient->setCurrentValue(gradient); - emit gradientChanged(); -} - bool Data2DItem::isLog() const { return zAxisItem()->isLogScale(); @@ -261,11 +221,6 @@ void Data2DItem::writeTo(QXmlStreamWriter* w) const XML::writeAttribute(w, XML::Attrib::value, m_is_interpolated); w->writeEndElement(); - // gradient - w->writeStartElement(Tag::Gradient); - m_gradient->writeTo(w); - w->writeEndElement(); - // z axis w->writeStartElement(Tag::ZAxis); m_z_axis->writeTo(w); @@ -290,11 +245,6 @@ void Data2DItem::readFrom(QXmlStreamReader* r) XML::readAttribute(r, XML::Attrib::value, &m_is_interpolated); XML::gotoEndElementOfTag(r, tag); - // gradient - } else if (tag == Tag::Gradient) { - m_gradient->readFrom(r); - XML::gotoEndElementOfTag(r, tag); - // z axis } else if (tag == Tag::ZAxis) { m_z_axis->readFrom(r); diff --git a/GUI/Model/Data/Data2DItem.h b/GUI/Model/Data/Data2DItem.h index 3acd418ee42..3daf112bf90 100644 --- a/GUI/Model/Data/Data2DItem.h +++ b/GUI/Model/Data/Data2DItem.h @@ -19,11 +19,9 @@ #include <utility> class AmplitudeAxisItem; -class ComboProperty; class LineItem; class MasksQModel; class MasksSet; -class QCPColorGradient; class Data2DItem : public DataItem { Q_OBJECT @@ -51,11 +49,6 @@ public: void copyZRangeFromItem(DataItem* sourceItem); bool isZoomed() const; - QCPColorGradient currentGradientQCP() const; //!< Color scheme of the color map - QString currentGradient() const; - void setCurrentGradient(const QString& gradient); - const ComboProperty& gradientCombo() const { return *m_gradient; } - //... logarithmic Z scale bool isLog() const; void setLog(bool islog); @@ -96,7 +89,6 @@ public: void readFrom(QXmlStreamReader* r) override; signals: - void gradientChanged(); void interpolationChanged(bool isInterpol); void projectionCreated(); void projectionPositionChanged(const LineItem* projection); @@ -107,7 +99,6 @@ private: void updateAxesZoomLevel(); bool m_is_interpolated; - std::unique_ptr<ComboProperty> m_gradient; std::unique_ptr<AmplitudeAxisItem> m_z_axis; std::unique_ptr<MasksQModel> m_model; std::unique_ptr<MasksQModel> m_proj_model; diff --git a/GUI/Model/Job/JobItem.cpp b/GUI/Model/Job/JobItem.cpp index c57101eddd6..5c7dbdc5721 100644 --- a/GUI/Model/Job/JobItem.cpp +++ b/GUI/Model/Job/JobItem.cpp @@ -155,9 +155,6 @@ const DataItem* JobItem::createDiffDataItem() if (auto* spec_diff = dynamic_cast<Data1DItem*>(diffDataItem())) spec_diff->setDiffPlotStyle(); - if (auto* intensity_diff = dynamic_cast<Data2DItem*>(diffDataItem())) - intensity_diff->setCurrentGradient(m_dfile_item->data2DItem()->currentGradient()); - return m_diff_data_item.get(); } @@ -167,13 +164,8 @@ void JobItem::copyDatafileItemIntoJob(const DatafileItem* source) ASSERT(source->rank() == rank()); m_dfile_item.reset(source->clone()); - if (rank() == 1) { + if (rank() == 1) m_dfile_item->data1DItem()->setRealPlotStyle(); - } else if (rank() == 2) { - // use color scheme from loaded data - ASSERT(data2DItem()); - data2DItem()->setCurrentGradient(m_dfile_item->data2DItem()->currentGradient()); - } } void JobItem::adjustReaDataToJobInstrument() diff --git a/GUI/View/Layout/AppConfig.cpp b/GUI/View/Layout/AppConfig.cpp index 4fd4b061576..bc83ccc8543 100644 --- a/GUI/View/Layout/AppConfig.cpp +++ b/GUI/View/Layout/AppConfig.cpp @@ -13,12 +13,15 @@ // ************************************************************************************************ #include "GUI/View/Layout/AppConfig.h" +#include "GUI/Support/Data/ComboProperty.h" +#include "GUI/Support/Style/QCP_Util.h" #include <QApplication> #include <QDir> #include <QFile> #include <QSettings> #include <QStandardPaths> #include <QStyle> +#include <qcustomplot.h> BA_GUI_API_ std::unique_ptr<AppConfig> gApp; //!< global pointer to _the_ instance @@ -32,6 +35,24 @@ const QString S_SCRIPTIMPORTDIR = "ScriptImportDir"; const QString S_LASTUSEDIMPORFILTER1D = "LastUsedImportFilter1D"; const QString S_LASTUSEDIMPORFILTER2D = "LastUsedImportFilter2D"; +// gradient map for colormaps +const QMap<QString, QCPColorGradient> gradient_map = { + {"Grayscale", QCPColorGradient::gpGrayscale}, + {"Hot", QCPColorGradient::gpHot}, + {"Cold", QCPColorGradient::gpCold}, + {"Night", QCPColorGradient::gpNight}, + {"Candy", QCPColorGradient::gpCandy}, + {"Geography", QCPColorGradient::gpGeography}, + {"Ion", QCPColorGradient::gpIon}, + {"Thermal", QCPColorGradient::gpThermal}, + {"Polar", QCPColorGradient::gpPolar}, + {"Spectrum", QCPColorGradient::gpSpectrum}, + {"Jet", QCPColorGradient::gpJet}, + {"Hues", QCPColorGradient::gpHues}, + {"Inferno", GUI::QCP_Util::colorGradientInferno()}}; + +const QString startGradient = "Inferno"; + } // namespace @@ -50,6 +71,9 @@ AppConfig::AppConfig() styleSheetPalette.setColor(QPalette::Dark, QColor(255, 255, 255).darker(110)); QApplication::setPalette(styleSheetPalette); + color_gradient_combo = std::make_unique<ComboProperty>( + ComboProperty::fromList(::gradient_map.keys(), ::startGradient)); + xml_dir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); artifact_export_dir = QDir::homePath(); data_import_dir = QDir::homePath(); @@ -59,6 +83,8 @@ AppConfig::AppConfig() loadSettings(); } +AppConfig::~AppConfig() = default; + bool AppConfig::useNativeFileDialog() const { #ifdef _WIN32 @@ -100,3 +126,8 @@ void AppConfig::saveSettings() s.setValue(S_LASTUSEDIMPORFILTER2D, import_filter_2D); s.endGroup(); } + +QCPColorGradient AppConfig::currentColorGradient() const +{ + return ::gradient_map.value(color_gradient_combo->currentValue()); +} diff --git a/GUI/View/Layout/AppConfig.h b/GUI/View/Layout/AppConfig.h index 4afcf3ff3d7..af75521c61d 100644 --- a/GUI/View/Layout/AppConfig.h +++ b/GUI/View/Layout/AppConfig.h @@ -16,17 +16,24 @@ #define BORNAGAIN_GUI_VIEW_LAYOUT_APPCONFIG_H #include "Wrap/WinDllMacros.h" +#include <QObject> #include <QString> +class ComboProperty; +class QCPColorGradient; +class Widget; + //! Application-wide settings. -class AppConfig { +class AppConfig : public QObject { + Q_OBJECT public: AppConfig(); + ~AppConfig(); - bool useNativeFileDialog() const; + QWidget* mainWindow; //!< Pointer to _the_ MainWindow - class QWidget* mainWindow; //!< Pointer to _the_ MainWindow + std::unique_ptr<ComboProperty> color_gradient_combo; QString import_filter_1D; //!< Last used import filter for 1D files QString import_filter_2D; //!< Last used import filter for 2D files @@ -38,6 +45,12 @@ public: void saveSettings(); + bool useNativeFileDialog() const; + QCPColorGradient currentColorGradient() const; + +signals: + void gradientChanged(); + private: void loadSettings(); }; diff --git a/GUI/View/Plotter/ColorMap.cpp b/GUI/View/Plotter/ColorMap.cpp index f4a4d043772..53ca5b152f6 100644 --- a/GUI/View/Plotter/ColorMap.cpp +++ b/GUI/View/Plotter/ColorMap.cpp @@ -22,6 +22,7 @@ #include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Support/Style/QCP_Util.h" #include "GUI/Support/Style/Style.h" +#include "GUI/View/Layout/AppConfig.h" #include <qcustomplot.h> namespace { @@ -99,7 +100,8 @@ void ColorMap::itemToMap(Data2DItem* item) Qt::UniqueConnection); // color scheme - connect(item, &Data2DItem::gradientChanged, this, &ColorMap::setGradient, Qt::UniqueConnection); + connect(gApp.get(), &AppConfig::gradientChanged, this, &ColorMap::setGradient, + Qt::UniqueConnection); // interpolation connect(item, &Data2DItem::interpolationChanged, this, &ColorMap::setInterpolation, @@ -180,7 +182,7 @@ void ColorMap::setGradient() const Data2DItem* ii = data2DItem(); if (!ii) return; - m_qcp_map->setGradient(ii->currentGradientQCP()); + m_qcp_map->setGradient(gApp->currentColorGradient()); replot(); } diff --git a/GUI/View/Setup/AxesPanel.cpp b/GUI/View/Setup/AxesPanel.cpp index 1f8a2418ad6..588183c9b55 100644 --- a/GUI/View/Setup/AxesPanel.cpp +++ b/GUI/View/Setup/AxesPanel.cpp @@ -20,6 +20,7 @@ #include "GUI/Model/Job/DataSource.h" #include "GUI/Model/Project/ProjectDocument.h" #include "GUI/Support/Data/ComboProperty.h" +#include "GUI/View/Layout/AppConfig.h" #include "GUI/View/Numeric/ComboUtil.h" #include "GUI/View/Numeric/NumWidgetUtil.h" #include "GUI/View/Widget/GroupBoxes.h" @@ -47,14 +48,12 @@ AxesPanel::AxesPanel(DataSource* ds) m_updaters.clear(); layout->addRow("Color scheme:", - GUI::Util::createComboBox( - [this] { return m_data_source->currentData2DItem()->gradientCombo(); }, - [this](const QString& newVal) { - for (auto* item : m_data_source->allData2DItems()) - item->setCurrentGradient(newVal); - gDoc->setModified(); - }, - false, &m_updaters)); + GUI::Util::createComboBox([this] { return *gApp->color_gradient_combo; }, + [this](const QString& s) { + gApp->color_gradient_combo->setCurrentValue(s); + emit gApp->gradientChanged(); + }, + false, &m_updaters)); layout->addRow(GUI::Util::createCheckBox( "Interpolate", [this] { return m_data_source->currentData2DItem()->isInterpolated(); }, -- GitLab