diff --git a/GUI/View/Common/ItemSelectorWidget.cpp b/GUI/View/Common/ItemSelectorWidget.cpp deleted file mode 100644 index 869c3e3b524c323c204343fbe393348cdb85dfb6..0000000000000000000000000000000000000000 --- a/GUI/View/Common/ItemSelectorWidget.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Common/ItemSelectorWidget.cpp -//! @brief Implements class ItemSelectorWidget -//! -//! @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/Common/ItemSelectorWidget.h" -#include "GUI/Model/Session/SessionDecorationModel.h" -#include "GUI/Model/Session/SessionModel.h" -#include "GUI/View/Tool/mainwindow_constants.h" -#include <QListView> -#include <QVBoxLayout> - -ItemSelectorWidget::ItemSelectorWidget(QWidget* parent) - : QWidget(parent), m_listView(new QListView), m_model(nullptr) -{ - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); - - auto* layout = new QVBoxLayout; - layout->setMargin(0); - - layout->addWidget(m_listView); - setLayout(layout); - - m_listView->setContextMenuPolicy(Qt::CustomContextMenu); - m_listView->setAttribute(Qt::WA_MacShowFocusRect, false); - - connect(m_listView, &QListView::customContextMenuRequested, this, - &ItemSelectorWidget::onCustomContextMenuRequested); -} - -ItemSelectorWidget::~ItemSelectorWidget() = default; - -QSize ItemSelectorWidget::sizeHint() const -{ - return QSize(GUI::Constants::ITEM_SELECTOR_WIDGET_WIDTH, - GUI::Constants::ITEM_SELECTOR_WIDGET_HEIGHT); -} - -QSize ItemSelectorWidget::minimumSizeHint() const -{ - return QSize(25, 25); -} - -void ItemSelectorWidget::setModel(SessionModel* model) -{ - if (model == m_model) - return; - - disconnectModel(); - m_model = model; - connectModel(); -} - -void ItemSelectorWidget::setItemDelegate(QAbstractItemDelegate* delegate) -{ - m_listView->setItemDelegate(delegate); -} - -QItemSelectionModel* ItemSelectorWidget::selectionModel() -{ - return m_listView->selectionModel(); -} - -QListView* ItemSelectorWidget::listView() -{ - return m_listView; -} - -void ItemSelectorWidget::select(const QModelIndex& index, - QItemSelectionModel::SelectionFlags command) -{ - selectionModel()->select(index, command); -} - -//! select last item if no selection exists - -void ItemSelectorWidget::updateSelection() -{ - if (!selectionModel()->hasSelection()) - selectLast(); -} - -void ItemSelectorWidget::selectLast() -{ - QModelIndex itemIndex = m_model->index(m_model->rowCount(QModelIndex()) - 1, 0, QModelIndex()); - selectionModel()->select(itemIndex, QItemSelectionModel::ClearAndSelect); -} - -void ItemSelectorWidget::onSelectionChanged(const QItemSelection& selected, const QItemSelection&) -{ - QModelIndexList indexes = selected.indexes(); - SessionItem* selectedItem(nullptr); - - if (!indexes.empty()) - selectedItem = m_model->itemForIndex(indexes.back()); - - emit selectionChanged(selectedItem); -} - -void ItemSelectorWidget::onCustomContextMenuRequested(const QPoint& point) -{ - emit contextMenuRequest(m_listView->mapToGlobal(point), m_listView->indexAt(point)); -} - -void ItemSelectorWidget::connectModel() -{ - if (!m_model) - return; - - m_decorationModel = std::make_unique<SessionDecorationModel>(nullptr, m_model); - m_listView->setModel(m_decorationModel.get()); - - connect(m_listView->selectionModel(), &QItemSelectionModel::selectionChanged, this, - &ItemSelectorWidget::onSelectionChanged, Qt::UniqueConnection); -} - -void ItemSelectorWidget::disconnectModel() -{ - m_listView->setModel(nullptr); - m_model = nullptr; -} - -//! provide default selection when widget is shown -void ItemSelectorWidget::showEvent(QShowEvent*) -{ - if (!m_model || !selectionModel()) - return; - - if (selectionModel()->selectedIndexes().isEmpty() && m_model->rowCount(QModelIndex()) != 0) - selectionModel()->select(m_model->index(0, 0, QModelIndex()), QItemSelectionModel::Select); -} diff --git a/GUI/View/Common/ItemSelectorWidget.h b/GUI/View/Common/ItemSelectorWidget.h deleted file mode 100644 index 950889910760b2cd448f67de9e879ef0881b1964..0000000000000000000000000000000000000000 --- a/GUI/View/Common/ItemSelectorWidget.h +++ /dev/null @@ -1,72 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Common/ItemSelectorWidget.h -//! @brief Defines class ItemSelectorWidget -//! -//! @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_COMMON_ITEMSELECTORWIDGET_H -#define BORNAGAIN_GUI_VIEW_COMMON_ITEMSELECTORWIDGET_H - -#include <QItemSelectionModel> -#include <QWidget> -#include <memory> - -class SessionModel; -class SessionItem; -class QItemSelection; -class QModelIndex; -class QAbstractItemDelegate; -class QListView; -class SessionDecorationModel; - -//! The ItemSelectorWidget class holds QListView to show top level items of SessionModel. -//! Used in InstrumentView and JobSelectorView to switch between items. - -class ItemSelectorWidget : public QWidget { - Q_OBJECT - -public: - ItemSelectorWidget(QWidget* parent = nullptr); - ~ItemSelectorWidget() override; - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - - void setModel(SessionModel* model); - void setItemDelegate(QAbstractItemDelegate* delegate); - - QItemSelectionModel* selectionModel(); - QListView* listView(); - -public slots: - void select(const QModelIndex& index, QItemSelectionModel::SelectionFlags command); - void updateSelection(); - void selectLast(); - -signals: - void selectionChanged(SessionItem* item); - void contextMenuRequest(const QPoint& point, const QModelIndex& index); - -private slots: - void onSelectionChanged(const QItemSelection& selected, const QItemSelection&); - void onCustomContextMenuRequested(const QPoint& point); - -protected: - void connectModel(); - void disconnectModel(); - void showEvent(class QShowEvent*) override; - - QListView* m_listView; - SessionModel* m_model; - std::unique_ptr<SessionDecorationModel> m_decorationModel; -}; - -#endif // BORNAGAIN_GUI_VIEW_COMMON_ITEMSELECTORWIDGET_H diff --git a/GUI/View/Common/ModelTreeView.cpp b/GUI/View/Common/ModelTreeView.cpp deleted file mode 100644 index aa408479536f50b333dccaf8c9748aee1acc2c89..0000000000000000000000000000000000000000 --- a/GUI/View/Common/ModelTreeView.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Common/ModelTreeView.cpp -//! @brief Implements class ModelTreeView -//! -//! @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/Common/ModelTreeView.h" -#include "GUI/Model/Session/SessionDecorationModel.h" -#include "GUI/Model/Session/SessionModel.h" -#include "GUI/Util/Error.h" -#include "GUI/View/Tool/StyleUtils.h" -#include <QTreeView> -#include <QVBoxLayout> - -ModelTreeView::ModelTreeView(QWidget* parent, SessionModel* model) - : QWidget(parent) - , m_tree(new QTreeView) - , m_decorationProxy(new SessionDecorationModel(this, model)) - , m_is_expanded(false) -{ - if (!model) - throw Error("ModelTreeView::ModelTreeView() -> Error. Nullptr as model."); - - setObjectName(model->getModelTag()); - - auto* layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(m_tree); - - GUI::Util::Style::setPropertyStyle(m_tree); - - m_decorationProxy->setSessionModel(model); - m_tree->setModel(m_decorationProxy); - - if (m_decorationProxy->rowCount(QModelIndex()) > 0) - setExpanded(true); - - setLayout(layout); -} - -void ModelTreeView::setItemDelegate(QAbstractItemDelegate* delegate) -{ - m_tree->setItemDelegate(delegate); -} - -void ModelTreeView::toggleExpanded() -{ - setExpanded(!isExpanded()); -} - -void ModelTreeView::setExpanded(bool expanded) -{ - ASSERT(m_tree); - if (expanded) { - m_tree->expandAll(); - m_tree->resizeColumnToContents(0); - m_tree->resizeColumnToContents(1); - } else { - m_tree->collapseAll(); - } - m_is_expanded = expanded; -} diff --git a/GUI/View/Common/ModelTreeView.h b/GUI/View/Common/ModelTreeView.h deleted file mode 100644 index a10255fe68b5ae2c16bb5a4e8b98ebdcf36f1ee2..0000000000000000000000000000000000000000 --- a/GUI/View/Common/ModelTreeView.h +++ /dev/null @@ -1,46 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Common/ModelTreeView.h -//! @brief Defines class ModelTreeView -//! -//! @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_COMMON_MODELTREEVIEW_H -#define BORNAGAIN_GUI_VIEW_COMMON_MODELTREEVIEW_H - -#include <QWidget> - -class QTreeView; -class SessionModel; -class SessionDecorationModel; -class QAbstractItemDelegate; - -//! Equivalent of QTreeView for SessionModel allowing to add visual decorations to the tree. -//! Additionaly provides expand/collapse utility methods. - -class ModelTreeView : public QWidget { - Q_OBJECT -public: - ModelTreeView(QWidget* parent, SessionModel* model); - - void setItemDelegate(QAbstractItemDelegate* delegate); - -public slots: - void toggleExpanded(); - void setExpanded(bool expanded); - bool isExpanded() const { return m_is_expanded; } - -private: - QTreeView* m_tree; - SessionDecorationModel* m_decorationProxy; - bool m_is_expanded; -}; - -#endif // BORNAGAIN_GUI_VIEW_COMMON_MODELTREEVIEW_H diff --git a/GUI/View/PropertyEditor/SessionModelDelegate.cpp b/GUI/View/Fit/FitParameterDelegate.cpp similarity index 81% rename from GUI/View/PropertyEditor/SessionModelDelegate.cpp rename to GUI/View/Fit/FitParameterDelegate.cpp index b4c34fc68d369936d1b6c4c193b1b252b36fb1f2..c8c94dcf588900eac5b34bb287beb0dc0db81b72 100644 --- a/GUI/View/PropertyEditor/SessionModelDelegate.cpp +++ b/GUI/View/Fit/FitParameterDelegate.cpp @@ -2,26 +2,26 @@ // // BornAgain: simulate and fit reflection and scattering // -//! @file GUI/View/PropertyEditor/SessionModelDelegate.cpp -//! @brief Implements class SessionModelDelegate +//! @file GUI/View/Fit/FitParameterDelegate.cpp +//! @brief Implements class FitParameterDelegate //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @copyright Forschungszentrum Jülich GmbH 2021 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) // // ************************************************************************************************ -#include "GUI/View/PropertyEditor/SessionModelDelegate.h" +#include "GUI/View/Fit/FitParameterDelegate.h" #include "GUI/Model/Session/SessionItem.h" #include "GUI/View/PropertyEditor/CustomEditors.h" #include "GUI/View/PropertyEditor/CustomEventFilters.h" #include "GUI/View/PropertyEditor/PropertyEditorFactory.h" #include <QApplication> -SessionModelDelegate::SessionModelDelegate(QObject* parent) : QStyledItemDelegate(parent) {} +FitParameterDelegate::FitParameterDelegate(QObject* parent) : QStyledItemDelegate(parent) {} -void SessionModelDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, +void FitParameterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (GUI::View::PropertyEditorFactory::hasStringRepresentation(index)) { @@ -31,7 +31,7 @@ void SessionModelDelegate::paint(QPainter* painter, const QStyleOptionViewItem& QStyledItemDelegate::paint(painter, option, index); } -QWidget* SessionModelDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, +QWidget* FitParameterDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { auto* result = createEditorFromIndex(index, parent); @@ -39,7 +39,7 @@ QWidget* SessionModelDelegate::createEditor(QWidget* parent, const QStyleOptionV if (auto* customEditor = dynamic_cast<CustomEditor*>(result)) { new TabFromFocusProxy(customEditor); connect(customEditor, &CustomEditor::dataChanged, this, - &SessionModelDelegate::onCustomEditorDataChanged); + &FitParameterDelegate::onCustomEditorDataChanged); } if (!result) // falling back to default behaviour @@ -50,7 +50,7 @@ QWidget* SessionModelDelegate::createEditor(QWidget* parent, const QStyleOptionV //! Propagates changed data from the editor to the model. -void SessionModelDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, +void FitParameterDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { if (!index.isValid()) @@ -64,7 +64,7 @@ void SessionModelDelegate::setModelData(QWidget* editor, QAbstractItemModel* mod //! Propagates the data change from the model to the editor (if it is still opened). -void SessionModelDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const +void FitParameterDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { if (!index.isValid()) return; @@ -77,7 +77,7 @@ void SessionModelDelegate::setEditorData(QWidget* editor, const QModelIndex& ind //! Increases height of the row by 20% wrt the default. -QSize SessionModelDelegate::sizeHint(const QStyleOptionViewItem& option, +QSize FitParameterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QSize result = QStyledItemDelegate::sizeHint(option, index); @@ -89,7 +89,7 @@ QSize SessionModelDelegate::sizeHint(const QStyleOptionViewItem& option, //! as a decoration (i.e. icon of material property), it will be hidden as soon as editor //! up and running. -void SessionModelDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, +void FitParameterDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyledItemDelegate::updateEditorGeometry(editor, option, index); @@ -97,7 +97,7 @@ void SessionModelDelegate::updateEditorGeometry(QWidget* editor, const QStyleOpt } -QWidget* SessionModelDelegate::createEditorFromIndex(const QModelIndex& index, +QWidget* FitParameterDelegate::createEditorFromIndex(const QModelIndex& index, QWidget* parent) const { if (index.internalPointer()) { @@ -109,7 +109,7 @@ QWidget* SessionModelDelegate::createEditorFromIndex(const QModelIndex& index, //! Notifies everyone that the editor has completed editing the data. -void SessionModelDelegate::onCustomEditorDataChanged(const QVariant&) +void FitParameterDelegate::onCustomEditorDataChanged(const QVariant&) { auto* editor = qobject_cast<CustomEditor*>(sender()); ASSERT(editor); @@ -118,7 +118,7 @@ void SessionModelDelegate::onCustomEditorDataChanged(const QVariant&) //! Paints custom text in a a place corresponding given index. -void SessionModelDelegate::paintCustomLabel(QPainter* painter, const QStyleOptionViewItem& option, +void FitParameterDelegate::paintCustomLabel(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, const QString& text) const { QStyleOptionViewItem opt = option; diff --git a/GUI/View/PropertyEditor/SessionModelDelegate.h b/GUI/View/Fit/FitParameterDelegate.h similarity index 76% rename from GUI/View/PropertyEditor/SessionModelDelegate.h rename to GUI/View/Fit/FitParameterDelegate.h index f31b1ffde2d90b20e23cca5464cea33012ab593f..e1b5dd590e4963a3f10aa52012b8e4084ec13d01 100644 --- a/GUI/View/PropertyEditor/SessionModelDelegate.h +++ b/GUI/View/Fit/FitParameterDelegate.h @@ -2,29 +2,29 @@ // // BornAgain: simulate and fit reflection and scattering // -//! @file GUI/View/PropertyEditor/SessionModelDelegate.h -//! @brief Defines class SessionModelDelegate +//! @file GUI/View/Fit/FitParameterDelegate.h +//! @brief Defines class FitParameterDelegate //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 +//! @copyright Forschungszentrum Jülich GmbH 2021 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) // // ************************************************************************************************ -#ifndef BORNAGAIN_GUI_VIEW_PROPERTYEDITOR_SESSIONMODELDELEGATE_H -#define BORNAGAIN_GUI_VIEW_PROPERTYEDITOR_SESSIONMODELDELEGATE_H +#ifndef BORNAGAIN_GUI_VIEW_FIT_FITPARAMETERDELEGATE_H +#define BORNAGAIN_GUI_VIEW_FIT_FITPARAMETERDELEGATE_H #include <QStyledItemDelegate> -//! The SessionModelDelegate class presents the content of SessionModel items in +//! The FitParameterDelegate class presents the content of SessionModel items in //! standard QTreeView. Extents base QItemDelegate with possibility to show/edit //! our custom QVariant's. -class SessionModelDelegate : public QStyledItemDelegate { +class FitParameterDelegate : public QStyledItemDelegate { Q_OBJECT public: - SessionModelDelegate(QObject* parent); + FitParameterDelegate(QObject* parent); void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; @@ -53,4 +53,4 @@ private: const QModelIndex& index, const QString& text) const; }; -#endif // BORNAGAIN_GUI_VIEW_PROPERTYEDITOR_SESSIONMODELDELEGATE_H +#endif // BORNAGAIN_GUI_VIEW_FIT_FITPARAMETERDELEGATE_H diff --git a/GUI/View/Fit/FitParameterWidget.cpp b/GUI/View/Fit/FitParameterWidget.cpp index eabb7952e2f004f2976c59222c3dbc9d7f16fb7f..8197ff867e0fb507e8bf57f793ee0c74bbf7e5e2 100644 --- a/GUI/View/Fit/FitParameterWidget.cpp +++ b/GUI/View/Fit/FitParameterWidget.cpp @@ -23,10 +23,10 @@ #include "GUI/Model/Group/FilterPropertyProxy.h" #include "GUI/Model/Job/JobItem.h" #include "GUI/Model/Job/JobModel.h" +#include "GUI/View/Fit/FitParameterDelegate.h" #include "GUI/View/Fit/ParameterTuningWidget.h" #include "GUI/View/Info/OverlayLabelController.h" #include "GUI/View/PropertyEditor/CustomEventFilters.h" -#include "GUI/View/PropertyEditor/SessionModelDelegate.h" #include "GUI/View/Tool/mainwindow_constants.h" #include <QAction> #include <QMenu> @@ -44,7 +44,6 @@ FitParameterWidget::FitParameterWidget(QWidget* parent) , m_removeFromFitParAction(nullptr) , m_removeFitParAction(nullptr) , m_fitParameterModel(nullptr) - , m_delegate(new SessionModelDelegate(this)) , m_keyboardFilter(new DeleteEventFilter(this)) , m_infoLabel(new OverlayLabelController(this)) { @@ -58,7 +57,7 @@ FitParameterWidget::FitParameterWidget(QWidget* parent) m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_treeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_treeView->setContextMenuPolicy(Qt::CustomContextMenu); - m_treeView->setItemDelegate(m_delegate); + m_treeView->setItemDelegate(new FitParameterDelegate(this)); m_treeView->setDragEnabled(true); m_treeView->setDragDropMode(QAbstractItemView::DragDrop); m_treeView->installEventFilter(m_keyboardFilter); diff --git a/GUI/View/Fit/FitParameterWidget.h b/GUI/View/Fit/FitParameterWidget.h index bc2ea82eabdcae0b21592f783d40cbb2330f73a8..321dfdbe53d799b7b600c77ff9e702c21a265d75 100644 --- a/GUI/View/Fit/FitParameterWidget.h +++ b/GUI/View/Fit/FitParameterWidget.h @@ -28,7 +28,6 @@ class ParameterItem; class FitParameterItem; class FitParameterLinkItem; class QItemSelection; -class SessionModelDelegate; class DeleteEventFilter; class OverlayLabelController; @@ -90,7 +89,6 @@ private: QAction* m_removeFromFitParAction; QAction* m_removeFitParAction; FitParameterProxyModel* m_fitParameterModel; - SessionModelDelegate* m_delegate; DeleteEventFilter* m_keyboardFilter; OverlayLabelController* m_infoLabel; }; diff --git a/GUI/View/PropertyEditor/CustomEditors.cpp b/GUI/View/PropertyEditor/CustomEditors.cpp index 58ba4bda10bf75e24d6da8c4b42fe50f541f9752..208be506db41c15aa8fa29d9b3451c45276ca616 100644 --- a/GUI/View/PropertyEditor/CustomEditors.cpp +++ b/GUI/View/PropertyEditor/CustomEditors.cpp @@ -14,25 +14,12 @@ #include "GUI/View/PropertyEditor/CustomEditors.h" #include "Base/Util/Assert.h" -#include "GUI/Model/Material/MaterialItem.h" -#include "GUI/Model/Material/MaterialItemUtils.h" #include "GUI/Model/State/SessionData.h" #include "GUI/Util/ComboProperty.h" #include "GUI/View/Common/ScientificSpinBox.h" -#include "GUI/View/Main/MainWindow.h" -#include "GUI/View/MaterialEditor/MaterialEditorDialog.h" #include "GUI/View/PropertyEditor/CustomEventFilters.h" -#include <QApplication> #include <QBoxLayout> -#include <QCheckBox> -#include <QColorDialog> #include <QComboBox> -#include <QDoubleSpinBox> -#include <QEvent> -#include <QKeyEvent> -#include <QLabel> -#include <QLineEdit> -#include <QToolButton> #include <cmath> namespace { @@ -66,64 +53,7 @@ void CustomEditor::setDataIntern(const QVariant& data) dataChanged(m_data); } -// --- MaterialPropertyEditor --- - -MaterialSelectionEditor::MaterialSelectionEditor(QWidget* parent) - : CustomEditor(parent) - , m_textLabel(new QLabel) - , m_pixmapLabel(new QLabel) - , m_focusFilter(new LostFocusFilter(this)) -{ - setMouseTracking(true); - setAutoFillBackground(true); - - auto* layout = new QHBoxLayout; - layout->setContentsMargins(4, 0, 0, 0); - - auto* button = new QToolButton; - button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred)); - button->setText(QLatin1String(" . . . ")); - button->setToolTip("Material selector"); - layout->addWidget(m_pixmapLabel); - layout->addWidget(m_textLabel); - layout->addStretch(1); - layout->addWidget(button); - setFocusPolicy(Qt::StrongFocus); - setAttribute(Qt::WA_InputMethodEnabled); - connect(button, &QToolButton::clicked, this, &MaterialSelectionEditor::buttonClicked); - - setLayout(layout); -} - -void MaterialSelectionEditor::buttonClicked() -{ - // temporarily installing filter to prevent loss of focus caused by too insistent dialog - installEventFilter(m_focusFilter); - const QString materialIdentifier = m_data.toString(); - const QString newMaterialIdentifier = MaterialEditorDialog::chooseMaterial( - baWin, gSessionData->projectDocument, materialIdentifier); - - removeEventFilter(m_focusFilter); - - if (!newMaterialIdentifier.isEmpty() && newMaterialIdentifier != materialIdentifier) - setDataIntern(newMaterialIdentifier); -} - -void MaterialSelectionEditor::initEditor() -{ - ASSERT(m_data.canConvert<QString>()); - auto* const material = GUI::MaterialUtil::findMaterial(m_data.toString()); - - m_textLabel->setText(material->itemName()); - - const int size = qApp->fontMetrics().height(); - QPixmap pixmap(size, size); - pixmap.fill(material->color()); - - m_pixmapLabel->setPixmap(pixmap); -} - -// --- CustomComboEditor --- +// --- ComboPropertyEditor --- ComboPropertyEditor::ComboPropertyEditor(QWidget* parent) : CustomEditor(parent), m_box(new QComboBox), m_wheel_event_filter(new WheelEventEater(this)) @@ -203,107 +133,7 @@ void ComboPropertyEditor::setConnected(bool isConnected) this, &ComboPropertyEditor::onIndexChanged); } -// --- ScientificDoublePropertyEditor --- - -ScientificDoublePropertyEditor::ScientificDoublePropertyEditor(QWidget* parent) - : CustomEditor(parent), m_lineEdit(new QLineEdit), m_validator(nullptr) -{ - setAutoFillBackground(true); - - auto* layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - - layout->addWidget(m_lineEdit); - - m_validator = new QDoubleValidator(0.0, 1e+200, 1000, this); - m_validator->setNotation(QDoubleValidator::ScientificNotation); - m_lineEdit->setValidator(m_validator); - - connect(m_lineEdit, &QLineEdit::editingFinished, this, - &ScientificDoublePropertyEditor::onEditingFinished); - - setLayout(layout); -} - -void ScientificDoublePropertyEditor::setLimits(const RealLimits& limits) -{ - double minimum = limits.hasLowerLimit() ? std::max(limits.lowerLimit(), -1e+200) : -1e+200; - double maximum = limits.hasUpperLimit() ? std::min(limits.upperLimit(), +1e+200) : +1e+200; - m_validator->setRange(minimum, maximum, 1000); -} - -void ScientificDoublePropertyEditor::onEditingFinished() -{ - double new_value = m_lineEdit->text().toDouble(); - - if (new_value != m_data.toDouble()) - setDataIntern(QVariant::fromValue(new_value)); -} - -void ScientificDoublePropertyEditor::initEditor() -{ - ASSERT(m_data.type() == QVariant::Double); - m_lineEdit->setText(QString::number(m_data.toDouble(), 'g')); -} - -// --- DoubleEditor --- - -DoubleEditor::DoubleEditor(QWidget* parent) - : CustomEditor(parent), m_doubleEditor(new QDoubleSpinBox) -{ - setAutoFillBackground(true); - setFocusPolicy(Qt::StrongFocus); - m_doubleEditor->setFocusPolicy(Qt::StrongFocus); - m_doubleEditor->setKeyboardTracking(false); - - auto* layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - - layout->addWidget(m_doubleEditor); - - connect(m_doubleEditor, - static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), - [=] { this->onEditingFinished(); }); - - setLayout(layout); - - setFocusProxy(m_doubleEditor); -} - -void DoubleEditor::setLimits(const RealLimits& limits) -{ - m_doubleEditor->setMaximum(std::numeric_limits<double>::max()); - m_doubleEditor->setMinimum(std::numeric_limits<double>::lowest()); - - if (limits.hasLowerLimit()) - m_doubleEditor->setMinimum(limits.lowerLimit()); - if (limits.hasUpperLimit()) - m_doubleEditor->setMaximum(static_cast<int>(limits.upperLimit())); -} - -void DoubleEditor::setDecimals(int decimals) -{ - m_doubleEditor->setDecimals(decimals); - m_doubleEditor->setSingleStep(singleStep(decimals)); -} - -void DoubleEditor::onEditingFinished() -{ - double new_value = m_doubleEditor->value(); - - if (new_value != m_data.toDouble()) - setDataIntern(QVariant::fromValue(new_value)); -} - -void DoubleEditor::initEditor() -{ - ASSERT(m_data.type() == QVariant::Double); - m_doubleEditor->setValue(m_data.toDouble()); -} - -// --- DoubleEditor --- +// --- ScientificSpinBoxEditor --- ScientificSpinBoxEditor::ScientificSpinBoxEditor(QWidget* parent) : CustomEditor(parent), m_doubleEditor(new ScientificSpinBox) @@ -358,82 +188,3 @@ void ScientificSpinBoxEditor::initEditor() ASSERT(m_data.type() == QVariant::Double); m_doubleEditor->setValue(m_data.toDouble()); } - -// --- IntEditor --- - -IntEditor::IntEditor(QWidget* parent) : CustomEditor(parent), m_intEditor(new QSpinBox) -{ - setAutoFillBackground(true); - m_intEditor->setFocusPolicy(Qt::StrongFocus); - m_intEditor->setKeyboardTracking(false); - - auto* layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - - layout->addWidget(m_intEditor); - - connect(m_intEditor, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), - [=] { this->onEditingFinished(); }); - - setLayout(layout); - - setFocusProxy(m_intEditor); -} - -void IntEditor::setLimits(const RealLimits& limits) -{ - m_intEditor->setMaximum(std::numeric_limits<int>::max()); - - if (limits.hasLowerLimit()) - m_intEditor->setMinimum(static_cast<int>(limits.lowerLimit())); - if (limits.hasUpperLimit()) - m_intEditor->setMaximum(static_cast<int>(limits.upperLimit())); -} - -void IntEditor::onEditingFinished() -{ - int new_value = m_intEditor->value(); - - if (new_value != m_data.toInt()) - setDataIntern(QVariant::fromValue(new_value)); -} - -void IntEditor::initEditor() -{ - if (!m_data.isValid() || m_data.type() != QVariant::Int) - return; - m_intEditor->setValue(m_data.toInt()); -} - -// --- BoolEditor --- - -BoolEditor::BoolEditor(QWidget* parent) : CustomEditor(parent), m_checkBox(new QCheckBox) -{ - setAutoFillBackground(true); - auto* layout = new QHBoxLayout; - layout->setContentsMargins(4, 0, 0, 0); - layout->addWidget(m_checkBox); - setLayout(layout); - - connect(m_checkBox, &QCheckBox::toggled, this, &BoolEditor::onCheckBoxChange); - setFocusProxy(m_checkBox); - m_checkBox->setText(tr("True")); -} - -void BoolEditor::onCheckBoxChange(bool value) -{ - if (value != m_data.toBool()) - setDataIntern(QVariant(value)); -} - -void BoolEditor::initEditor() -{ - ASSERT(m_data.type() == QVariant::Bool); - bool value = m_data.toBool(); - - m_checkBox->blockSignals(true); - m_checkBox->setChecked(value); - m_checkBox->setText(value ? "True" : "False"); - m_checkBox->blockSignals(false); -} diff --git a/GUI/View/PropertyEditor/CustomEditors.h b/GUI/View/PropertyEditor/CustomEditors.h index f8a79b7a3e8052b0049addb50226101361225dcd..10620bb16a63ce1804cfc9b8ead87601ecf233c7 100644 --- a/GUI/View/PropertyEditor/CustomEditors.h +++ b/GUI/View/PropertyEditor/CustomEditors.h @@ -46,25 +46,6 @@ protected: QVariant m_data; }; -//! Editor to select a material - -class BA_CORE_API_ MaterialSelectionEditor : public CustomEditor { - Q_OBJECT -public: - explicit MaterialSelectionEditor(QWidget* parent = nullptr); - -private slots: - void buttonClicked(); - -protected: - void initEditor() override; - -private: - QLabel* m_textLabel; - QLabel* m_pixmapLabel; - LostFocusFilter* m_focusFilter; -}; - //! Editor for ComboProperty variant. class ComboPropertyEditor : public CustomEditor { @@ -88,46 +69,6 @@ protected: class WheelEventEater* m_wheel_event_filter; }; -//! Editor for ScientificDoubleProperty variant. - -class ScientificDoublePropertyEditor : public CustomEditor { - Q_OBJECT -public: - ScientificDoublePropertyEditor(QWidget* parent = nullptr); - - void setLimits(const RealLimits& limits); - -private slots: - void onEditingFinished(); - -protected: - void initEditor() override; - -private: - class QLineEdit* m_lineEdit; - class QDoubleValidator* m_validator; -}; - -//! Editor for Double variant. - -class DoubleEditor : public CustomEditor { - Q_OBJECT -public: - DoubleEditor(QWidget* parent = nullptr); - - void setLimits(const RealLimits& limits); - void setDecimals(int decimals); - -private slots: - void onEditingFinished(); - -protected: - void initEditor() override; - -private: - class QDoubleSpinBox* m_doubleEditor; -}; - //! Editor for Double variant using ScientificSpinBox. class ScientificSpinBoxEditor : public CustomEditor { @@ -149,42 +90,4 @@ private: class ScientificSpinBox* m_doubleEditor; }; -//! Editor for Int variant. - -class IntEditor : public CustomEditor { - Q_OBJECT -public: - IntEditor(QWidget* parent = nullptr); - - void setLimits(const RealLimits& limits); - -private slots: - void onEditingFinished(); - -protected: - void initEditor() override; - -private: - class QSpinBox* m_intEditor; -}; - -//! Editor for boolean. - -class QCheckBox; - -class BoolEditor : public CustomEditor { - Q_OBJECT -public: - BoolEditor(QWidget* parent = nullptr); - -private slots: - void onCheckBoxChange(bool value); - -protected: - void initEditor() override; - -private: - QCheckBox* m_checkBox; -}; - #endif // BORNAGAIN_GUI_VIEW_PROPERTYEDITOR_CUSTOMEDITORS_H diff --git a/GUI/View/PropertyEditor/MultiComboPropertyEditor.cpp b/GUI/View/PropertyEditor/MultiComboPropertyEditor.cpp deleted file mode 100644 index ae56ca3f49c7d674d44d37a3f423ae901b4cb2a3..0000000000000000000000000000000000000000 --- a/GUI/View/PropertyEditor/MultiComboPropertyEditor.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/PropertyEditor/MultiComboPropertyEditor.cpp -//! @brief Defines MultiComboPropertyEditor class -//! -//! @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/PropertyEditor/MultiComboPropertyEditor.h" -#include "GUI/Util/ComboProperty.h" -#include "GUI/View/PropertyEditor/CustomEventFilters.h" -#include <QComboBox> -#include <QEvent> -#include <QLineEdit> -#include <QListView> -#include <QMouseEvent> -#include <QStandardItem> -#include <QStandardItemModel> -#include <QVBoxLayout> - -QCheckListStyledItemDelegate::QCheckListStyledItemDelegate(QObject* parent) - : QStyledItemDelegate(parent) -{ -} - -void QCheckListStyledItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const -{ - auto& styleOption = const_cast<QStyleOptionViewItem&>(option); - styleOption.showDecorationSelected = false; - QStyledItemDelegate::paint(painter, styleOption, index); -} - -// ---------------------------------------------------------------------------- -// https://stackoverflow.com/questions/8422760/combobox-of-checkboxes -// https://stackoverflow.com/questions/21186779/catch-mouse-button-pressed-signal-from-qcombobox-popup-menu -// https://gist.github.com/mistic100/c3b7f3eabc65309687153fe3e0a9a720 -// ---------------------------------------------------------------------------- - -MultiComboPropertyEditor::MultiComboPropertyEditor(QWidget* parent) - : CustomEditor(parent) - , m_box(new QComboBox) - , m_wheel_event_filter(new WheelEventEater(this)) - , m_model(new QStandardItemModel(this)) -{ - setAutoFillBackground(true); - setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - - m_box->installEventFilter(m_wheel_event_filter); - m_box->view()->viewport()->installEventFilter(this); - - // Editable mode will be used to have None/Multiple labels on top - m_box->setEditable(true); - m_box->lineEdit()->setReadOnly(true); - m_box->lineEdit()->installEventFilter(this); - connect(m_box->lineEdit(), &QLineEdit::selectionChanged, m_box->lineEdit(), - &QLineEdit::deselect); - - // transforms ordinary combo box into check list - m_box->setItemDelegate(new QCheckListStyledItemDelegate(this)); - m_box->setModel(m_model); - - auto* layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); - layout->addWidget(m_box); - setLayout(layout); - setConnected(true); -} - -QSize MultiComboPropertyEditor::sizeHint() const -{ - return m_box->sizeHint(); -} - -QSize MultiComboPropertyEditor::minimumSizeHint() const -{ - return m_box->minimumSizeHint(); -} - -//! Propagate check state from the model to ComboProperty. - -void MultiComboPropertyEditor::onModelDataChanged(const QModelIndex& topLeft, const QModelIndex&, - const QVector<int>&) -{ - // on Qt 5.9 roles remains empty for checked state. It will stop working if uncomment. - // if (!roles.contains(Qt::CheckStateRole)) - // return; - - auto* item = m_model->itemFromIndex(topLeft); - if (!item) - return; - - auto comboProperty = m_data.value<ComboProperty>(); - auto state = item->checkState() == Qt::Checked; - comboProperty.setSelected(topLeft.row(), state); - - updateBoxLabel(); - setDataIntern(QVariant::fromValue<ComboProperty>(comboProperty)); -} - -//! Processes press event in QComboBox's underlying list view. - -void MultiComboPropertyEditor::onClickedList(const QModelIndex& index) -{ - if (auto* item = m_model->itemFromIndex(index)) { - auto state = item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked; - item->setCheckState(state); - } -} - -//! Handles mouse clicks on QComboBox elements. - -bool MultiComboPropertyEditor::eventFilter(QObject* obj, QEvent* event) -{ - if (isClickToSelect(obj, event)) { - // Handles mouse clicks on QListView when it is expanded from QComboBox - // 1) Prevents list from closing while selecting items. - // 2) Correctly calculates underlying model index when mouse is over check box style - // element. - const auto* const mouseEvent = dynamic_cast<const QMouseEvent*>(event); - auto index = m_box->view()->indexAt(mouseEvent->pos()); - onClickedList(index); - return true; - } - - if (isClickToExpand(obj, event)) { - // Expands box when clicking on None/Multiple label - m_box->showPopup(); - return true; - } - - // Propagate to the parent class. - return QObject::eventFilter(obj, event); -} - -void MultiComboPropertyEditor::initEditor() -{ - if (!m_data.canConvert<ComboProperty>()) - return; - - auto property = m_data.value<ComboProperty>(); - - setConnected(false); - m_model->clear(); - - auto labels = property.getValues(); - auto selectedIndices = property.selectedIndices(); - - for (int i = 0; i < labels.size(); ++i) { - auto* item = new QStandardItem(labels[i]); - m_model->invisibleRootItem()->appendRow(item); - item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); - item->setCheckable(true); - - auto state = selectedIndices.contains(i) ? Qt::Checked : Qt::Unchecked; - item->setData(state, Qt::CheckStateRole); - } - - setConnected(true); - updateBoxLabel(); -} - -void MultiComboPropertyEditor::setConnected(bool isConnected) -{ - if (isConnected) - connect(m_model, &QStandardItemModel::dataChanged, this, - &MultiComboPropertyEditor::onModelDataChanged); - else - disconnect(m_model, &QStandardItemModel::dataChanged, this, - &MultiComboPropertyEditor::onModelDataChanged); -} - -//! Update text on QComboBox with the label provided by combo property. - -void MultiComboPropertyEditor::updateBoxLabel() -{ - auto combo = m_data.value<ComboProperty>(); - m_box->setCurrentText(combo.label()); -} - -bool MultiComboPropertyEditor::isClickToSelect(QObject* obj, QEvent* event) const -{ - return obj == m_box->view()->viewport() && event->type() == QEvent::MouseButtonRelease; -} - -bool MultiComboPropertyEditor::isClickToExpand(QObject* obj, QEvent* event) const -{ - return obj == m_box->lineEdit() && event->type() == QEvent::MouseButtonRelease; -} diff --git a/GUI/View/PropertyEditor/MultiComboPropertyEditor.h b/GUI/View/PropertyEditor/MultiComboPropertyEditor.h deleted file mode 100644 index ee5eee0cf4e8e6ec0a6048461c4f897ca5629440..0000000000000000000000000000000000000000 --- a/GUI/View/PropertyEditor/MultiComboPropertyEditor.h +++ /dev/null @@ -1,67 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/PropertyEditor/MultiComboPropertyEditor.h -//! @brief Defines MultiComboPropertyEditor class -//! -//! @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_PROPERTYEDITOR_MULTICOMBOPROPERTYEDITOR_H -#define BORNAGAIN_GUI_VIEW_PROPERTYEDITOR_MULTICOMBOPROPERTYEDITOR_H - -#include "GUI/View/PropertyEditor/CustomEditors.h" -#include <QStyledItemDelegate> -#include <memory> - -class QStandardItemModel; -class QModelIndex; -class QStyleOptionViewItem; - -//! Provides custom editor for ComboProperty with multi-select option. - -class MultiComboPropertyEditor : public CustomEditor { - Q_OBJECT -public: - explicit MultiComboPropertyEditor(QWidget* parent = nullptr); - - QSize sizeHint() const override; - QSize minimumSizeHint() const override; - -protected slots: - void onModelDataChanged(const QModelIndex&, const QModelIndex&, const QVector<int>&); - - void onClickedList(const QModelIndex& index); - -protected: - void initEditor() override; - -private: - bool eventFilter(QObject* obj, QEvent* event) override; - void setConnected(bool isConnected); - void updateBoxLabel(); - - bool isClickToSelect(QObject* obj, QEvent* event) const; - bool isClickToExpand(QObject* obj, QEvent* event) const; - - QComboBox* m_box; - class WheelEventEater* m_wheel_event_filter; - QStandardItemModel* m_model; -}; - -//! Provides custom style delegate for QComboBox to allow checkboxes. - -class QCheckListStyledItemDelegate : public QStyledItemDelegate { -public: - QCheckListStyledItemDelegate(QObject* parent = nullptr); - - void paint(QPainter* painter, const QStyleOptionViewItem& option, - const QModelIndex& index) const override; -}; - -#endif // BORNAGAIN_GUI_VIEW_PROPERTYEDITOR_MULTICOMBOPROPERTYEDITOR_H diff --git a/GUI/View/PropertyEditor/PropertyEditorFactory.cpp b/GUI/View/PropertyEditor/PropertyEditorFactory.cpp index 21d67a6744eb62d6ebbfbf168f81598706004493..f12d0391526b94142b6e6e02411869292708f0e6 100644 --- a/GUI/View/PropertyEditor/PropertyEditorFactory.cpp +++ b/GUI/View/PropertyEditor/PropertyEditorFactory.cpp @@ -13,33 +13,15 @@ // ************************************************************************************************ #include "GUI/View/PropertyEditor/PropertyEditorFactory.h" -#include "GUI/Model/Material/MaterialItem.h" -#include "GUI/Model/Material/MaterialItemUtils.h" -#include "GUI/Model/Sample/ItemWithMaterial.h" -#include "GUI/Model/Session/SessionFlags.h" +#include "GUI/Model/Session/SessionItem.h" #include "GUI/Util/ComboProperty.h" #include "GUI/View/Common/ScientificSpinBox.h" -#include "GUI/View/PropertyEditor/MultiComboPropertyEditor.h" -#include <QLabel> -#include <QLineEdit> +#include "GUI/View/PropertyEditor/CustomEditors.h" +#include <QModelIndex> #include <QSpinBox> -#include <limits> namespace { -QWidget* createCustomStringEditor(const SessionItem& item) -{ - if (item.isEditable()) { - auto* editor = new QLineEdit; - editor->setText(item.value().toString()); - return editor; - } - - auto* editor = new QLabel; - editor->setText(item.value().toString()); - return editor; -} - double getStep(double val) { return val == 0.0 ? 1.0 : val / 100.; @@ -50,44 +32,19 @@ bool isDoubleProperty(const QVariant& variant) return variant.type() == QVariant::Double; } -bool isIntProperty(const QVariant& variant) -{ - return variant.type() == QVariant::Int; -} - -bool isMaterialProperty(const QModelIndex& index) -{ - return index.data(SessionFlags::CustomEditorRole) == SessionItem::EDITOR_TYPE_MATERIAL - && index.column() == SessionFlags::ITEM_VALUE; -} - bool isComboProperty(const QVariant& variant) { return variant.canConvert<ComboProperty>(); } -bool isStringProperty(const QVariant& variant) -{ - return variant.type() == QVariant::String; -} - -bool isBoolProperty(const QVariant& variant) -{ - return variant.type() == QVariant::Bool; -} - } // namespace bool GUI::View::PropertyEditorFactory::hasStringRepresentation(const QModelIndex& index) { auto variant = index.data(); - if (isMaterialProperty(index)) - return true; if (isComboProperty(variant)) return true; - if (isBoolProperty(variant)) - return true; if (isDoubleProperty(variant) && index.internalPointer()) return true; @@ -97,24 +54,13 @@ bool GUI::View::PropertyEditorFactory::hasStringRepresentation(const QModelIndex QString GUI::View::PropertyEditorFactory::toString(const QModelIndex& index) { auto variant = index.data(); - if (isMaterialProperty(index)) { - const auto* materialItem = static_cast<SessionItem*>(index.internalPointer()); - const auto* itemWithMaterial = dynamic_cast<ItemWithMaterial*>(materialItem->parent()); - ASSERT(itemWithMaterial); - return itemWithMaterial->materialName(); - } if (isComboProperty(variant)) return variant.value<ComboProperty>().label(); - if (isBoolProperty(variant)) - return variant.toBool() ? "True" : "False"; if (isDoubleProperty(variant) && index.internalPointer()) { auto* item = static_cast<SessionItem*>(index.internalPointer()); - return item->editorType() == "ScientificDouble" - ? QString::number(item->value().toDouble(), 'g') - : item->editorType() == "ScientificSpinBox" - ? ScientificSpinBox::toString(item->value().toDouble(), item->decimals()) - : QString::number(item->value().toDouble(), 'f', item->decimals()); + // only "Scientific SpinBoxes" in Fit-Window + return ScientificSpinBox::toString(item->value().toDouble(), item->decimals()); } return ""; @@ -124,44 +70,16 @@ QWidget* GUI::View::PropertyEditorFactory::CreateEditor(const SessionItem& item, { QWidget* result(nullptr); - if (item.editorType() == SessionItem::EDITOR_TYPE_MATERIAL) { - // has to be checked first, because the property is a standard property and the following - // code would find a (wrong) editor - result = new MaterialSelectionEditor; - } else if (isDoubleProperty(item.value())) { - if (item.editorType() == "ScientificDouble") { - auto* editor = new ScientificDoublePropertyEditor; - auto limits = item.limits(); - editor->setLimits(limits); - result = editor; - } else if (item.editorType() == "ScientificSpinBox") { - auto* editor = new ScientificSpinBoxEditor; - auto limits = item.limits(); - editor->setLimits(limits); - editor->setDecimals(item.decimals()); - editor->setSingleStep(getStep(item.roleProperty(Qt::EditRole).toDouble())); - result = editor; - } else { - auto* editor = new DoubleEditor; - editor->setLimits(item.limits()); - editor->setDecimals(item.decimals()); - result = editor; - } - } else if (isIntProperty(item.value())) { - auto* editor = new IntEditor; + if (isDoubleProperty(item.value())) { + // only Scientific SpinBoxes in Fit-Window + auto* editor = new ScientificSpinBoxEditor; editor->setLimits(item.limits()); + editor->setDecimals(item.decimals()); + editor->setSingleStep(getStep(item.roleProperty(Qt::EditRole).toDouble())); result = editor; - } else if (isBoolProperty(item.value())) { - result = new BoolEditor; - } else if (isStringProperty(item.value())) { - result = createCustomStringEditor(item); - } else if (isComboProperty(item.value())) { - if (item.editorType() == "Default") { - result = new ComboPropertyEditor; - } else if (item.editorType() == "MultiSelectionComboEditor") { - result = new MultiComboPropertyEditor; - } - } + } else if (isComboProperty(item.value())) + result = new ComboPropertyEditor; + if (parent && result) result->setParent(parent); diff --git a/GUI/View/Toplevel/SessionModelView.cpp b/GUI/View/Toplevel/SessionModelView.cpp index 027a667e4a1039168eedfda29f4034fa556ca334..df58eb8ce370d97c0cbc1d55552a1c77fcbfd6f6 100644 --- a/GUI/View/Toplevel/SessionModelView.cpp +++ b/GUI/View/Toplevel/SessionModelView.cpp @@ -17,64 +17,103 @@ #include "GUI/Model/Instrument/InstrumentModel.h" #include "GUI/Model/Job/JobModel.h" #include "GUI/Model/Material/MaterialModel.h" +#include "GUI/Model/Sample/ItemWithMaterial.h" #include "GUI/Model/Sample/SampleModel.h" -#include "GUI/View/Common/ModelTreeView.h" +#include "GUI/Model/Session/SessionDecorationModel.h" +#include "GUI/Util/ComboProperty.h" #include "GUI/View/Main/ProjectManager.h" -#include "GUI/View/PropertyEditor/SessionModelDelegate.h" +#include "GUI/View/Tool/StyleUtils.h" +#include <QApplication> +#include <QStyledItemDelegate> #include <QToolBar> #include <QToolButton> +#include <QTreeView> #include <QVBoxLayout> -SessionModelView::SessionModelView(QWidget* parent, ProjectDocument* document) - : QWidget(parent) - , m_toolBar(new QToolBar) - , m_tabs(new QTabWidget) - , m_expandCollapseButton(new QToolButton) - , m_delegate(new SessionModelDelegate(this)) - , m_document(document) -{ - auto* layout = new QVBoxLayout; - layout->setMargin(0); - layout->setSpacing(0); +namespace { +//! The SessionModelDelegate class presents the content of SessionModel items in +//! standard QTreeView. Extents base QItemDelegate with possibility to show/edit +//! our custom QVariant's. - m_expandCollapseButton->setText("Expand / collapse tree"); - m_expandCollapseButton->setIcon(QIcon(":/images/toolbar_expand_collapse_tree.svg")); - m_expandCollapseButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); - m_expandCollapseButton->setToolTip("Click to switch between expanded/collapsed tree view"); - m_toolBar->addWidget(m_expandCollapseButton); - connect(m_expandCollapseButton, &QToolButton::clicked, this, - &SessionModelView::onExpandCollapseTree); +class SessionModelDelegate : public QStyledItemDelegate { +public: + SessionModelDelegate(QObject* parent) : QStyledItemDelegate(parent) {} - layout->addWidget(m_toolBar); - layout->addWidget(m_tabs); - setLayout(layout); + void paint(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index) const override + { + const bool isMaterialProperty = + index.data(SessionFlags::CustomEditorRole) == SessionItem::EDITOR_TYPE_MATERIAL + && index.column() == SessionFlags::ITEM_VALUE; - init_tabs(); -} + if (isMaterialProperty) { + const auto* materialItem = static_cast<SessionItem*>(index.internalPointer()); + const auto* itemWithMaterial = dynamic_cast<ItemWithMaterial*>(materialItem->parent()); + ASSERT(itemWithMaterial); + paintCustomLabel(painter, option, index, itemWithMaterial->materialName()); + } else if (index.data().canConvert<ComboProperty>()) + paintCustomLabel(painter, option, index, index.data().value<ComboProperty>().label()); + else + QStyledItemDelegate::paint(painter, option, index); + } -void SessionModelView::onExpandCollapseTree() -{ - m_content.at(m_tabs->currentIndex())->toggleExpanded(); -} +private: + void paintCustomLabel(QPainter* painter, const QStyleOptionViewItem& option, + const QModelIndex& index, const QString& text) const + { + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); // calling original method to take into accounts colors etc + opt.text = displayText(text, option.locale); // by overriding text with ours + const QWidget* widget = opt.widget; + QStyle* style = widget ? widget->style() : QApplication::style(); + style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, widget); + } +}; -//! Creates content for tab widget. +} // namespace -void SessionModelView::init_tabs() +SessionModelView::SessionModelView(QWidget* parent, ProjectDocument* document) : QWidget(parent) { - ASSERT(m_content.empty()); + auto* layout = new QVBoxLayout(this); + layout->setMargin(0); - for (auto* model : modelsForTabs()) { - auto* treeView = new ModelTreeView(this, model); - treeView->setItemDelegate(m_delegate); - m_tabs->addTab(treeView, treeView->objectName()); - m_content.push_back(treeView); - } -} + auto* tabs = new QTabWidget(this); + auto* m_expandButton = new QToolButton(this); + m_expandButton->setText("Expand tree"); + m_expandButton->setIcon(QIcon(":/images/toolbar_expand_collapse_tree.svg")); + m_expandButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + connect(m_expandButton, &QToolButton::clicked, [=]() { + auto* tree = static_cast<QTreeView*>(tabs->widget(tabs->currentIndex())); + tree->expandAll(); + tree->resizeColumnToContents(0); + tree->resizeColumnToContents(1); + }); -//! Returns list of models to show in tabs. + auto* m_collapseButton = new QToolButton(this); + m_collapseButton->setText("Collapse tree"); + m_collapseButton->setIcon(QIcon(":/images/toolbar_expand_collapse_tree.svg")); + m_collapseButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + connect(m_collapseButton, &QToolButton::clicked, [=]() { + auto* tree = static_cast<QTreeView*>(tabs->widget(tabs->currentIndex())); + tree->collapseAll(); + }); -QList<SessionModel*> SessionModelView::modelsForTabs() -{ - return {m_document->instrumentModel(), m_document->sampleModel(), m_document->realDataModel(), - m_document->materialModel(), m_document->jobModel()}; + auto* toolBar = new QToolBar; + toolBar->addWidget(m_expandButton); + toolBar->addWidget(m_collapseButton); + layout->addWidget(toolBar); + layout->addWidget(tabs); + + QList<SessionModel*> models{document->instrumentModel(), document->sampleModel(), + document->realDataModel(), document->materialModel(), + document->jobModel()}; + + for (auto* model : models) { + auto* treeView = new QTreeView(this); + GUI::Util::Style::setPropertyStyle(treeView); + treeView->setItemDelegate(new SessionModelDelegate(this)); + treeView->setModel(new SessionDecorationModel(treeView, model)); + treeView->setEditTriggers(QAbstractItemView::NoEditTriggers); // read-only! + tabs->addTab(treeView, model->getModelTag()); + } } diff --git a/GUI/View/Toplevel/SessionModelView.h b/GUI/View/Toplevel/SessionModelView.h index a3dff751c5eee12ad617c30ef242f30ecc18ea50..bae81de810223882c310a2ed228dd64e2627eacc 100644 --- a/GUI/View/Toplevel/SessionModelView.h +++ b/GUI/View/Toplevel/SessionModelView.h @@ -17,12 +17,6 @@ #include <QWidget> -class QToolBar; -class QTabWidget; -class QToolButton; -class SessionModel; -class ModelTreeView; -class SessionModelDelegate; class ProjectDocument; //! The SessionModelView is a technical view which shows the content all current application @@ -34,20 +28,6 @@ class SessionModelView : public QWidget { public: SessionModelView(QWidget* parent, ProjectDocument* document); - -private slots: - void onExpandCollapseTree(); - -private: - void init_tabs(); - QList<SessionModel*> modelsForTabs(); - - QToolBar* m_toolBar; - QTabWidget* m_tabs; - QToolButton* m_expandCollapseButton; - SessionModelDelegate* m_delegate; - QVector<ModelTreeView*> m_content; - ProjectDocument* m_document; }; #endif // BORNAGAIN_GUI_VIEW_TOPLEVEL_SESSIONMODELVIEW_H