From c65338f3d7965ccfe145cbac9ebaa4342d8d51df Mon Sep 17 00:00:00 2001 From: Gennady Pospelov <g.pospelov@fz-juelich.de> Date: Wed, 4 Feb 2015 18:11:26 +0100 Subject: [PATCH] New UniversalPropertyEditor to replace all scattered property editors --- GUI/coregui/Models/NJobItem.cpp | 24 +- GUI/coregui/Models/NJobItem.h | 4 +- GUI/coregui/Models/NJobModel.cpp | 13 +- GUI/coregui/Models/PropertyAttribute.h | 3 +- .../JobQueueWidgets/JobPropertiesWidget.cpp | 237 ++++++++++---- .../JobQueueWidgets/JobPropertiesWidget.h | 30 +- .../UniversalPropertyEditor.cpp | 295 ++++++++++++++++++ .../JobQueueWidgets/UniversalPropertyEditor.h | 95 ++++++ 8 files changed, 609 insertions(+), 92 deletions(-) create mode 100644 GUI/coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.cpp create mode 100644 GUI/coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.h diff --git a/GUI/coregui/Models/NJobItem.cpp b/GUI/coregui/Models/NJobItem.cpp index 427113002cd..e19f4ae4a9d 100644 --- a/GUI/coregui/Models/NJobItem.cpp +++ b/GUI/coregui/Models/NJobItem.cpp @@ -37,8 +37,8 @@ QMap<QString, QString> NJobItem::m_run_policies = initializeRunPolicies(); const QString NJobItem::P_IDENTIFIER = "Identifier"; -const QString NJobItem::P_BEGIN_TYPE = "Begin Time"; -const QString NJobItem::P_END_TYPE = "End Time"; +const QString NJobItem::P_BEGIN_TIME = "Begin Time"; +const QString NJobItem::P_END_TIME = "End Time"; const QString NJobItem::P_COMMENTS = "Comments"; const QString NJobItem::P_STATUS = "Status"; const QString NJobItem::P_PROGRESS = "Progress"; @@ -52,25 +52,29 @@ NJobItem::NJobItem(ParameterizedItem *parent) , m_instrumentModel(0) { setItemName(Constants::JobItemType); - registerProperty(P_IDENTIFIER, QString()); - registerProperty(P_BEGIN_TYPE, QString()); - registerProperty(P_END_TYPE, QString()); - registerProperty(P_COMMENTS, QString()); + registerProperty(P_IDENTIFIER, QString(), PropertyAttribute(PropertyAttribute::HIDDEN)); ComboProperty status; status << Constants::STATUS_IDLE << Constants::STATUS_RUNNING << Constants::STATUS_COMPLETED << Constants::STATUS_CANCELED << Constants::STATUS_FAILED; - registerProperty(P_STATUS, status.getVariant()); + registerProperty(P_STATUS, status.getVariant(), PropertyAttribute(PropertyAttribute::READONLY)); - registerProperty(P_PROGRESS, 0); - registerProperty(P_NTHREADS, -1); + registerProperty(P_BEGIN_TIME, QString(), PropertyAttribute(PropertyAttribute::READONLY)); + registerProperty(P_END_TIME, QString(), PropertyAttribute(PropertyAttribute::READONLY)); + registerProperty(P_COMMENTS, QString(), PropertyAttribute(PropertyAttribute::HIDDEN)); + + registerProperty(P_PROGRESS, 0, PropertyAttribute(PropertyAttribute::HIDDEN)); + registerProperty(P_NTHREADS, -1, PropertyAttribute(PropertyAttribute::HIDDEN)); ComboProperty policy; policy << QString("Immediately") << QString("In background") << QString("Submit only"); - registerProperty(P_RUN_POLICY, policy.getVariant()); + registerProperty(P_RUN_POLICY, policy.getVariant(), PropertyAttribute(PropertyAttribute::HIDDEN)); addToValidChildren(Constants::IntensityDataType); + setPropertyAppearance(ParameterizedItem::P_NAME, PropertyAttribute::VISIBLE); + + } diff --git a/GUI/coregui/Models/NJobItem.h b/GUI/coregui/Models/NJobItem.h index 6363f4dc50a..981a6884c07 100644 --- a/GUI/coregui/Models/NJobItem.h +++ b/GUI/coregui/Models/NJobItem.h @@ -26,8 +26,8 @@ class BA_CORE_API_ NJobItem : public ParameterizedItem Q_OBJECT public: static const QString P_IDENTIFIER; - static const QString P_BEGIN_TYPE; - static const QString P_END_TYPE; + static const QString P_BEGIN_TIME; + static const QString P_END_TIME; static const QString P_COMMENTS; static const QString P_STATUS; static const QString P_PROGRESS; diff --git a/GUI/coregui/Models/NJobModel.cpp b/GUI/coregui/Models/NJobModel.cpp index a90ae570e79..4e09f7a7223 100644 --- a/GUI/coregui/Models/NJobModel.cpp +++ b/GUI/coregui/Models/NJobModel.cpp @@ -101,10 +101,17 @@ void NJobModel::onSelectionChanged(const QItemSelection &selected, const QItemSe { Q_UNUSED(deselected); qDebug() << "NJobModel::onSelectionChanged" << selected; - if(!selected.empty() && !selected.first().indexes().empty()) { - QModelIndex index = selected.first().indexes().at(0); - emit selectionChanged(getJobItemForIndex(index)); + QModelIndexList indices = selected.indexes(); + if(indices.size()) { + emit selectionChanged(getJobItemForIndex(indices.back())); + } else { + emit selectionChanged(0); } + +// if(!selected.empty() && !selected.first().indexes().empty()) { +// QModelIndex index = selected.first().indexes().at(0); +// emit selectionChanged(getJobItemForIndex(index)); +// } } //! generates job name diff --git a/GUI/coregui/Models/PropertyAttribute.h b/GUI/coregui/Models/PropertyAttribute.h index 5298a2cd2a9..7b1ba056124 100644 --- a/GUI/coregui/Models/PropertyAttribute.h +++ b/GUI/coregui/Models/PropertyAttribute.h @@ -30,7 +30,8 @@ public: enum EAppearance { VISIBLE = 0x0000, HIDDEN = 0x0001, - DISABLED = 0x0002 + DISABLED = 0x0002, + READONLY = 0x0004 }; explicit PropertyAttribute(EAppearance appearance=VISIBLE, const AttLimits &limits=AttLimits::lowerLimited(0.0), int decimals=2, const QString &label = QString()) diff --git a/GUI/coregui/Views/Components/JobQueueWidgets/JobPropertiesWidget.cpp b/GUI/coregui/Views/Components/JobQueueWidgets/JobPropertiesWidget.cpp index 1592fafbf99..a5a9608a8e6 100644 --- a/GUI/coregui/Views/Components/JobQueueWidgets/JobPropertiesWidget.cpp +++ b/GUI/coregui/Views/Components/JobQueueWidgets/JobPropertiesWidget.cpp @@ -14,6 +14,7 @@ // ************************************************************************** // #include "JobPropertiesWidget.h" +#include "UniversalPropertyEditor.h" //#include "JobQueueModel.h" //#include "JobItem.h" #include "NJobModel.h" @@ -31,10 +32,10 @@ JobPropertiesWidget::JobPropertiesWidget(QWidget *parent) : QWidget(parent) , m_jobModel(0) - , m_variantManager(new QtVariantPropertyManager(this)) - , m_propertyBrowser(new QtTreePropertyBrowser(this)) , m_currentItem(0) , m_tabWidget(new QTabWidget) + , m_propertyEditor(0) + , m_commentsEditor(0) { // setMinimumSize(128, 128); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); @@ -42,18 +43,21 @@ JobPropertiesWidget::JobPropertiesWidget(QWidget *parent) setObjectName(QLatin1String("Job Properties")); // setStyleSheet("background-color:white;"); - m_variantManager = new QtVariantPropertyManager(this); - m_readonlyManager = new QtVariantPropertyManager(this); - connect(m_variantManager, SIGNAL(valueChanged(QtProperty *, const QVariant &)), - this, SLOT(valueChanged(QtProperty *, const QVariant &))); +// m_variantManager = new QtVariantPropertyManager(this); +// m_readonlyManager = new QtVariantPropertyManager(this); +// connect(m_variantManager, SIGNAL(valueChanged(QtProperty *, const QVariant &)), +// this, SLOT(valueChanged(QtProperty *, const QVariant &))); - QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory(this); - m_propertyBrowser->setFactoryForManager(m_variantManager, variantFactory); +// QtVariantEditorFactory *variantFactory = new QtVariantEditorFactory(this); +// m_propertyBrowser->setFactoryForManager(m_variantManager, variantFactory); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->setMargin(0); mainLayout->setSpacing(0); + + m_propertyEditor = new UniversalPropertyEditor(0, this); + m_commentsEditor = new QTextEdit(); QWidget *commentsWidget = new QWidget(); @@ -63,7 +67,7 @@ JobPropertiesWidget::JobPropertiesWidget(QWidget *parent) commentsWidget->setLayout(vlayout); m_tabWidget->setTabPosition(QTabWidget::South); - m_tabWidget->insertTab(JOB_PROPERTIES, m_propertyBrowser, "Job Properties"); + m_tabWidget->insertTab(JOB_PROPERTIES, m_propertyEditor, "Job Properties"); m_tabWidget->insertTab(JOB_COMMENTS, commentsWidget, "Details"); mainLayout->addWidget(m_tabWidget); @@ -77,35 +81,142 @@ void JobPropertiesWidget::setModel(NJobModel *model) { Q_ASSERT(model); if(model != m_jobModel) { + if(m_jobModel) + disconnect(m_jobModel, + SIGNAL( selectionChanged(NJobItem *) ), + this, + SLOT( setItem(NJobItem *) ) + ); + m_jobModel = model; connect(m_jobModel, SIGNAL( selectionChanged(NJobItem *) ), this, - SLOT( itemClicked(NJobItem *) ) + SLOT( setItem(NJobItem *) ) ); - connect(m_jobModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)) - , this, SLOT(dataChanged(QModelIndex, QModelIndex))); +// connect(m_jobModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)) +// , this, SLOT(dataChanged(QModelIndex, QModelIndex))); } -} -void JobPropertiesWidget::updateExpandState() -{ - QList<QtBrowserItem *> list = m_propertyBrowser->topLevelItems(); - QListIterator<QtBrowserItem *> it(list); - while (it.hasNext()) { - QtBrowserItem *item = it.next(); - QtProperty *prop = item->property(); - idToExpanded[propertyToId[prop]] = m_propertyBrowser->isExpanded(item); - } } -void JobPropertiesWidget::itemClicked(NJobItem *jobItem) +//void JobPropertiesWidget::updateExpandState() +//{ +// QList<QtBrowserItem *> list = m_propertyBrowser->topLevelItems(); +// QListIterator<QtBrowserItem *> it(list); +// while (it.hasNext()) { +// QtBrowserItem *item = it.next(); +// QtProperty *prop = item->property(); +// idToExpanded[propertyToId[prop]] = m_propertyBrowser->isExpanded(item); +// } +//} + + +void JobPropertiesWidget::setItem(NJobItem *jobItem) { qDebug() << "JobPropertiesWidget::itemClicked" << jobItem->itemName(); - Q_ASSERT(0); + + m_propertyEditor->setItem(jobItem); +// Q_ASSERT(0); + +// if (m_currentItem == jobItem) return; + +// if (m_currentItem) { +// clearEditor(); + +// disconnect(m_currentItem, SIGNAL(propertyItemChanged(QString)), +// this, SLOT(updateSubItems(QString))); +// } + +// m_currentItem = jobItem; + +// if (!m_currentItem) return; + +// addItemProperties(m_currentItem); +// connect(m_currentItem, SIGNAL(propertyItemChanged(QString)), +// this, SLOT(updateSubItems(QString))); +// connect(m_currentItem, SIGNAL(propertyChanged(QString)), +// this, SLOT(onPropertyChanged(QString))); + +} + + +//void JobPropertiesWidget::addItemProperties(const ParameterizedItem *item) +//{ +// QString item_type = item->modelType(); +// QtProperty *item_property = m_manager->addProperty( +// QtVariantPropertyManager::groupTypeId(), item_type); + +// addSubProperties(item_property, item); +// m_browser->addProperty(item_property); +//} + + +//void JobPropertiesWidget::addSubProperties(QtProperty *item_property, +// const ParameterizedItem *item) +//{ +// QList<QByteArray> property_names = item->dynamicPropertyNames(); +// for (int i = 0; i < property_names.length(); ++i) { +// QString prop_name = QString(property_names[i]); +// PropertyAttribute prop_attribute = item->getPropertyAttribute(prop_name); + +// if(prop_attribute.getAppearance() & PropertyAttribute::HIDDEN) continue; + +// QVariant prop_value = item->property(prop_name.toUtf8().data()); +// int type = GUIHelpers::getVariantType(prop_value); + +// QtVariantProperty *subProperty = 0; +// if (m_manager->isPropertyTypeSupported(type)) { + +// if(prop_attribute.getLabel().isEmpty()) { +// subProperty = m_manager->addProperty(type, prop_name); +// } else { +// subProperty = m_manager->addProperty(type, prop_attribute.getLabel()); +// } + +// subProperty->setValue(prop_value); + +// if(type == QVariant::Double) { +// subProperty->setAttribute(QLatin1String("decimals"), prop_attribute.getDecimals()); +// AttLimits limits = prop_attribute.getLimits(); +// if(limits.hasLowerLimit()) subProperty->setAttribute(QLatin1String("minimum"), limits.getLowerLimit()); +// if(limits.hasUpperLimit()) subProperty->setAttribute(QLatin1String("maximum"), limits.getUpperLimit()); +// } + +// QString toolTip = ToolTipDataBase::getSampleViewToolTip(item->modelType(), prop_name); +// if(!toolTip.isEmpty()) subProperty->setToolTip(toolTip); + +// if(prop_attribute.getAppearance() & PropertyAttribute::DISABLED) { +// subProperty->setEnabled(false); +// } + +// if (item->getSubItems().contains(prop_name)) { +// ParameterizedItem *subitem = item->getSubItems()[prop_name]; +// if (subitem) { +// addSubProperties(subProperty, subitem); +// } +// } + +// } else { +// subProperty = m_read_only_manager->addProperty(QVariant::String, +// prop_name); +// subProperty->setValue(QLatin1String("< Unknown Type >")); +// subProperty->setEnabled(false); +// } + +// item_property->addSubProperty(subProperty); +// ParameterizedItem *non_const_item = +// const_cast<ParameterizedItem *>(item); +// ItemIndexPair item_index_pair(non_const_item, i); +// m_property_to_item_index_pair[subProperty] = item_index_pair; +// m_item_to_index_to_property[item][i] = subProperty; +// m_item_to_propertyname_to_qtvariantproperty[item][prop_name] = subProperty; +// } +//} + // updateExpandState(); @@ -158,48 +269,48 @@ void JobPropertiesWidget::itemClicked(NJobItem *jobItem) // } // m_commentsEditor->setText(jobItem->getComments()); -} +//} -void JobPropertiesWidget::addProperty(QtVariantProperty *property, const QString &id) -{ - propertyToId[property] = id; - idToProperty[id] = property; - QtBrowserItem *item = m_propertyBrowser->addProperty(property); - if (idToExpanded.contains(id)) - m_propertyBrowser->setExpanded(item, idToExpanded[id]); -} +//void JobPropertiesWidget::addProperty(QtVariantProperty *property, const QString &id) +//{ +// propertyToId[property] = id; +// idToProperty[id] = property; +// QtBrowserItem *item = m_propertyBrowser->addProperty(property); +// if (idToExpanded.contains(id)) +// m_propertyBrowser->setExpanded(item, idToExpanded[id]); +//} -void JobPropertiesWidget::valueChanged(QtProperty *property, const QVariant &value) -{ - Q_ASSERT(0); - Q_UNUSED(property); - Q_UNUSED(value); -// if (!propertyToId.contains(property)) -// return; - -// if (!m_currentItem) -// return; - -// QString id = propertyToId[property]; -// if (id == JobQueueXML::JobNameAttribute) { -// m_currentItem->setName(value.value<QString>()); -// } -} +//void JobPropertiesWidget::valueChanged(QtProperty *property, const QVariant &value) +//{ +// Q_ASSERT(0); +// Q_UNUSED(property); +// Q_UNUSED(value); +//// if (!propertyToId.contains(property)) +//// return; +//// if (!m_currentItem) +//// return; -//! to update properties of currently selected item if they were changed from outside -void JobPropertiesWidget::dataChanged(const QModelIndex &index, const QModelIndex &) -{ - qDebug() << "JobPropertiesWidget::dataChanged(const QModelIndex &index, const QModelIndex &)"; -// Q_UNUSED(index); - NJobItem *jobItem = m_jobModel->getJobItemForIndex(index); - if(jobItem == m_currentItem) { - Q_ASSERT(0); -// idToProperty[JobQueueXML::JobNameAttribute]->setValue(jobItem->getName()); -// idToProperty[JobQueueXML::JobStatusAttribute]->setValue(jobItem->getStatusString()); -// idToProperty[JobQueueXML::JobBeginTimeAttribute]->setValue(jobItem->getBeginTime()); -// idToProperty[JobQueueXML::JobEndTimeAttribute]->setValue(jobItem->getEndTime()); - } -} +//// QString id = propertyToId[property]; +//// if (id == JobQueueXML::JobNameAttribute) { +//// m_currentItem->setName(value.value<QString>()); +//// } +//} + + +////! to update properties of currently selected item if they were changed from outside +//void JobPropertiesWidget::dataChanged(const QModelIndex &index, const QModelIndex &) +//{ +// qDebug() << "JobPropertiesWidget::dataChanged(const QModelIndex &index, const QModelIndex &)"; +//// Q_UNUSED(index); +// NJobItem *jobItem = m_jobModel->getJobItemForIndex(index); +// if(jobItem == m_currentItem) { +// Q_ASSERT(0); +//// idToProperty[JobQueueXML::JobNameAttribute]->setValue(jobItem->getName()); +//// idToProperty[JobQueueXML::JobStatusAttribute]->setValue(jobItem->getStatusString()); +//// idToProperty[JobQueueXML::JobBeginTimeAttribute]->setValue(jobItem->getBeginTime()); +//// idToProperty[JobQueueXML::JobEndTimeAttribute]->setValue(jobItem->getEndTime()); +// } +//} diff --git a/GUI/coregui/Views/Components/JobQueueWidgets/JobPropertiesWidget.h b/GUI/coregui/Views/Components/JobQueueWidgets/JobPropertiesWidget.h index 27138d614f1..639484cf8e6 100644 --- a/GUI/coregui/Views/Components/JobQueueWidgets/JobPropertiesWidget.h +++ b/GUI/coregui/Views/Components/JobQueueWidgets/JobPropertiesWidget.h @@ -28,6 +28,8 @@ class QtProperty; class QtVariantProperty; class QTextEdit; class QTabWidget; +class ParameterizedItem; +class UniversalPropertyEditor; //! Widget to show and change properties of currently selected JobItem //! Left buttom corner of JobQueueView @@ -43,29 +45,31 @@ public: QSize sizeHint() const { return QSize(64, 256); } QSize minimumSizeHint() const { return QSize(64, 64); } -public slots: - void itemClicked(NJobItem *item); - void dataChanged(const QModelIndex &, const QModelIndex &); +public slots: + void setItem(NJobItem *item); +// void dataChanged(const QModelIndex &, const QModelIndex &); private slots: - void valueChanged(QtProperty *property, const QVariant &value); +// void valueChanged(QtProperty *property, const QVariant &value); private: - void updateExpandState(); - void addProperty(QtVariantProperty *property, const QString &id); +// void updateExpandState(); +// void addProperty(QtVariantProperty *property, const QString &id); // JobQueueModel *m_jobQueueModel; + + //! clear editor + + NJobModel *m_jobModel; - class QtVariantPropertyManager *m_variantManager; - class QtVariantPropertyManager *m_readonlyManager; - class QtTreePropertyBrowser *m_propertyBrowser; - QMap<QtProperty *, QString> propertyToId; - QMap<QString, QtVariantProperty *> idToProperty; - QMap<QString, bool> idToExpanded; - NJobItem *m_currentItem; +// QMap<QtProperty *, QString> propertyToId; +// QMap<QString, QtVariantProperty *> idToProperty; +// QMap<QString, bool> idToExpanded; + NJobItem *m_currentItem; QTabWidget *m_tabWidget; + UniversalPropertyEditor *m_propertyEditor; QTextEdit *m_commentsEditor; }; diff --git a/GUI/coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.cpp b/GUI/coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.cpp new file mode 100644 index 00000000000..29642ee9675 --- /dev/null +++ b/GUI/coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.cpp @@ -0,0 +1,295 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.cpp +//! @brief Implements class UniversalPropertyEditor +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2015 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "UniversalPropertyEditor.h" +#include "PropertyVariantManager.h" +#include "PropertyVariantFactory.h" +#include "ParameterizedItem.h" +#include "tooltipdatabase.h" +#include "GUIHelpers.h" + +#include "qttreepropertybrowser.h" +#include "qtgroupboxpropertybrowser.h" +#include "qtbuttonpropertybrowser.h" + +#include <QtProperty> +#include <QItemSelectionModel> +#include <QVBoxLayout> +#include <QMetaProperty> +#include <QDebug> + +UniversalPropertyEditor::UniversalPropertyEditor(QItemSelectionModel *selection_model, + QWidget *parent) + : QWidget(parent) + , m_item(0) + , m_selection_model(0) +{ + setSelectionModel(selection_model); + + setWindowTitle(QLatin1String("Property Editor")); + setObjectName(QLatin1String("PropertyEditor")); + +// QtAbstractPropertyBrowser *browser = new QtGroupBoxPropertyBrowser(); +// QtAbstractPropertyBrowser *browser = new QtButtonPropertyBrowser(); + + QtTreePropertyBrowser *browser = new QtTreePropertyBrowser(this); + browser->setRootIsDecorated(false); + m_browser = browser; + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->addWidget(m_browser); + + m_read_only_manager = new PropertyVariantManager(this); + + m_manager = new PropertyVariantManager(this); + + QtVariantEditorFactory *factory = new PropertyVariantFactory(); + m_browser->setFactoryForManager(m_manager, factory); + + connect(m_manager, SIGNAL(valueChanged(QtProperty *, const QVariant &)), + this, SLOT(slotValueChanged(QtProperty *, const QVariant &))); + +} + +void UniversalPropertyEditor::setSelectionModel(QItemSelectionModel *selection_model) +{ + if(selection_model != m_selection_model) { + if(m_selection_model) + disconnect(m_selection_model, + SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + this, + SLOT(selectionChanged(QItemSelection,QItemSelection)) ); + + m_selection_model = selection_model; + connect(m_selection_model, + SIGNAL(selectionChanged(QItemSelection,QItemSelection)), + this, + SLOT(selectionChanged(QItemSelection,QItemSelection)) ); + + } +} + +// show property of currently selected object (triggered by the graphics scene) +// if more than one object is selected, show only last selected +void UniversalPropertyEditor::selectionChanged(const QItemSelection & selected, + const QItemSelection & deselected) +{ + (void)deselected; + QModelIndexList indices = selected.indexes(); + if(indices.size()) { + ParameterizedItem *item = static_cast<ParameterizedItem *>( + indices.back().internalPointer()); + setItem(item); + } else { + setItem(0); + } +} + + +void UniversalPropertyEditor::slotValueChanged(QtProperty *property, + const QVariant &value) +{ + qDebug() << "UniversalPropertyEditor::slotValueChanged()" << value; + if (!m_property_to_item_index_pair.contains(property)) + return; + + ItemIndexPair item_index_pair = + m_property_to_item_index_pair.value(property); + + if (item_index_pair.m_item) { + QList<QByteArray> prop_list = + item_index_pair.m_item->dynamicPropertyNames(); + if (item_index_pair.m_index > prop_list.length()) { + return; + } + qDebug() << "setting ..." << prop_list[item_index_pair.m_index].constData(); + item_index_pair.m_item->setProperty( + prop_list[item_index_pair.m_index].constData(), value); + } +} + + +void UniversalPropertyEditor::clearEditor() +{ + qDebug() << "UniversalPropertyEditor::clearEditor()"; + //updateExpandState(SaveExpandState); + + QListIterator<QtProperty *> it(m_browser->properties()); + while (it.hasNext()) { + m_browser->removeProperty(it.next()); + } + m_property_to_item_index_pair.clear(); + m_item_to_index_to_property.clear(); +} + + +void UniversalPropertyEditor::updateSubItems(const QString &name) +{ + qDebug() << "UniversalPropertyEditor::updateSubItems()"; + (void)name; + if (!m_item) return; + +// QListIterator<QtProperty *> it(m_browser->properties()); +// while (it.hasNext()) { +// m_browser->removeProperty(it.next()); +// } + clearEditor(); + + disconnect(m_item, SIGNAL(propertyItemChanged(QString)), + this, SLOT(updateSubItems(QString))); + addItemProperties(m_item); + connect(m_item, SIGNAL(propertyItemChanged(QString)), + this, SLOT(updateSubItems(QString))); + connect(m_item, SIGNAL(propertyChanged(QString)), + this, SLOT(onPropertyChanged(QString))); +} + +void UniversalPropertyEditor::onPropertyChanged(const QString &property_name) +{ + qDebug() << "UniversalPropertyEditor::onPropertyChanged() " << property_name ; + if(!m_item) return; + + QtVariantProperty *variant_property = m_item_to_propertyname_to_qtvariantproperty[m_item][property_name]; + if(variant_property) { + QVariant property_value = m_item->getRegisteredProperty(property_name); + + disconnect(m_item, SIGNAL(propertyChanged(QString)), + this, SLOT(onPropertyChanged(QString))); + disconnect(m_item, SIGNAL(propertyItemChanged(QString)), + this, SLOT(updateSubItems(QString))); + + variant_property->setValue(property_value); + + PropertyAttribute prop_attribute = m_item->getPropertyAttribute(property_name); + if(prop_attribute.getAppearance() & PropertyAttribute::DISABLED) { + variant_property->setEnabled(false); + } else { + variant_property->setEnabled(true); + } + + connect(m_item, SIGNAL(propertyChanged(QString)), + this, SLOT(onPropertyChanged(QString))); + connect(m_item, SIGNAL(propertyItemChanged(QString)), + this, SLOT(updateSubItems(QString))); + } +} + + +// assigns item to the property editor +void UniversalPropertyEditor::setItem(ParameterizedItem *item) +{ + if (m_item == item) return; + + if (m_item) { +// QListIterator<QtProperty *> it(m_browser->properties()); +// while (it.hasNext()) { +// m_browser->removeProperty(it.next()); +// } + clearEditor(); + + disconnect(m_item, SIGNAL(propertyItemChanged(QString)), + this, SLOT(updateSubItems(QString))); + } + + m_item = item; + + if (!m_item) return; + + addItemProperties(m_item); + connect(m_item, SIGNAL(propertyItemChanged(QString)), + this, SLOT(updateSubItems(QString))); + connect(m_item, SIGNAL(propertyChanged(QString)), + this, SLOT(onPropertyChanged(QString))); + +} + + +void UniversalPropertyEditor::addItemProperties(const ParameterizedItem *item) +{ + QString item_type = item->modelType(); + QtProperty *item_property = m_manager->addProperty( + QtVariantPropertyManager::groupTypeId(), item_type); + + addSubProperties(item_property, item); + + m_browser->addProperty(item_property); +} + + +void UniversalPropertyEditor::addSubProperties(QtProperty *item_property, + const ParameterizedItem *item) +{ + QList<QByteArray> property_names = item->dynamicPropertyNames(); + for (int i = 0; i < property_names.length(); ++i) { + QString prop_name = QString(property_names[i]); + PropertyAttribute prop_attribute = item->getPropertyAttribute(prop_name); + + if(prop_attribute.getAppearance() & PropertyAttribute::HIDDEN) continue; + + QVariant prop_value = item->property(prop_name.toUtf8().data()); + int type = GUIHelpers::getVariantType(prop_value); + + QtVariantPropertyManager *manager = m_manager; + if(prop_attribute.getAppearance() & PropertyAttribute::READONLY) manager = m_read_only_manager; + + QtVariantProperty *subProperty = 0; + if (m_manager->isPropertyTypeSupported(type)) { + + if(prop_attribute.getLabel().isEmpty()) { + subProperty = manager->addProperty(type, prop_name); + } else { + subProperty = manager->addProperty(type, prop_attribute.getLabel()); + } + + subProperty->setValue(prop_value); + + if(type == QVariant::Double) { + subProperty->setAttribute(QLatin1String("decimals"), prop_attribute.getDecimals()); + AttLimits limits = prop_attribute.getLimits(); + if(limits.hasLowerLimit()) subProperty->setAttribute(QLatin1String("minimum"), limits.getLowerLimit()); + if(limits.hasUpperLimit()) subProperty->setAttribute(QLatin1String("maximum"), limits.getUpperLimit()); + } + + QString toolTip = ToolTipDataBase::getSampleViewToolTip(item->modelType(), prop_name); + if(!toolTip.isEmpty()) subProperty->setToolTip(toolTip); + + if(prop_attribute.getAppearance() & PropertyAttribute::DISABLED) { + subProperty->setEnabled(false); + } + + if (item->getSubItems().contains(prop_name)) { + ParameterizedItem *subitem = item->getSubItems()[prop_name]; + if (subitem) { + addSubProperties(subProperty, subitem); + } + } + + } else { + subProperty = m_read_only_manager->addProperty(QVariant::String, + prop_name); + subProperty->setValue(QLatin1String("< Unknown Type >")); + subProperty->setEnabled(false); + } + + item_property->addSubProperty(subProperty); + ParameterizedItem *non_const_item = + const_cast<ParameterizedItem *>(item); + ItemIndexPair item_index_pair(non_const_item, i); + m_property_to_item_index_pair[subProperty] = item_index_pair; + m_item_to_index_to_property[item][i] = subProperty; + m_item_to_propertyname_to_qtvariantproperty[item][prop_name] = subProperty; + } +} + diff --git a/GUI/coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.h b/GUI/coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.h new file mode 100644 index 00000000000..cf5e7c3a027 --- /dev/null +++ b/GUI/coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.h @@ -0,0 +1,95 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file coregui/Views/Components/JobQueueWidgets/UniversalPropertyEditor.h +//! @brief Defines class UniversalPropertyEditor +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2015 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, M. Ganeva, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef UNIVERSALPROPERTYEDITOR_H +#define UNIVERSALPROPERTYEDITOR_H + +#include "WinDllMacros.h" +#include <QWidget> +#include <QMap> +#include <QString> + +class SampleDesignerInterface; +class QItemSelectionModel; +class QItemSelection; +class QtVariantPropertyManager; +class QtTreePropertyBrowser; +class QtProperty; +class QtVariantProperty; +class QVariant; +class QtAbstractPropertyBrowser; +class ParameterizedItem; + + +//! property editor to display and modify properties of currently selected ParameterizedItem +class BA_CORE_API_ UniversalPropertyEditor : public QWidget +{ + Q_OBJECT + +public: + UniversalPropertyEditor(QItemSelectionModel *selection_model, + QWidget *parent = 0); + virtual ~UniversalPropertyEditor(){} + + QObject *getObject() const; + struct ItemIndexPair { + ItemIndexPair(ParameterizedItem *item=0, int index=0) + : m_item(item), m_index(index) {} + ParameterizedItem *m_item; + int m_index; + }; + + void setSelectionModel(QItemSelectionModel *selection_model); + + //! assigns item to the property editor + void setItem(ParameterizedItem *item); + +public slots: + //! show property of currently selected object (triggered by graphics scene) + void selectionChanged(const QItemSelection & selected, + const QItemSelection & deselected); + +private slots: + void slotValueChanged(QtProperty *property, const QVariant &value); + void updateSubItems(const QString &name); + void onPropertyChanged(const QString &property_name); + +private: + //! clear editor + void clearEditor(); + + ParameterizedItem *m_item; //! object to modify + + QItemSelectionModel *m_selection_model; + + QMap<QtProperty *, ItemIndexPair> m_property_to_item_index_pair; + QMap<const ParameterizedItem *, QMap<int, QtVariantProperty *> > + m_item_to_index_to_property; + + QMap<const ParameterizedItem *, QMap<QString, QtVariantProperty *> > + m_item_to_propertyname_to_qtvariantproperty; + + + QtAbstractPropertyBrowser *m_browser; + QtVariantPropertyManager *m_manager; + QtVariantPropertyManager *m_read_only_manager; + + void addItemProperties(const ParameterizedItem *item); + void addSubProperties(QtProperty *item_property, + const ParameterizedItem *item); +}; + + +#endif // SAMPLEPROPERTYEDITOR_H -- GitLab