diff --git a/Modules/Properties/files.cmake b/Modules/Properties/files.cmake index 5206c029e4..67d392d9b8 100644 --- a/Modules/Properties/files.cmake +++ b/Modules/Properties/files.cmake @@ -1,8 +1,11 @@ set(CPP_FILES + mitkFloatPropertyExtension.cpp mitkLoadPropertiesModule.cpp mitkPropertiesActivator.cpp mitkPropertyAliases.cpp mitkPropertyDescriptions.cpp + mitkPropertyExtension.cpp + mitkPropertyExtensions.cpp mitkPropertyFilter.cpp mitkPropertyFilters.cpp ) diff --git a/Modules/Properties/mitkFloatPropertyExtension.cpp b/Modules/Properties/mitkFloatPropertyExtension.cpp new file mode 100644 index 0000000000..10a83312b6 --- /dev/null +++ b/Modules/Properties/mitkFloatPropertyExtension.cpp @@ -0,0 +1,107 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkFloatPropertyExtension.h" + +namespace mitk +{ + struct FloatPropertyExtension::Impl + { + Impl(); + Impl(float minimum, float maximum, float singleStep, int decimals); + ~Impl(); + + int Decimals; + float Maximum; + float Minimum; + float SingleStep; + }; + + FloatPropertyExtension::Impl::Impl() + : Decimals(2), + Maximum(99.9999999999f), + Minimum(0.0f), + SingleStep(1.0f) + { + } + + FloatPropertyExtension::Impl::Impl(float minimum, float maximum, float singleStep, int decimals) + : Decimals(decimals), + Maximum(maximum), + Minimum(minimum), + SingleStep(singleStep) + { + } + + FloatPropertyExtension::Impl::~Impl() + { + } +} + +mitk::FloatPropertyExtension::FloatPropertyExtension() + : m_Impl(new Impl) +{ +} + +mitk::FloatPropertyExtension::FloatPropertyExtension(float minimum, float maximum, float singleStep, int decimals) + : m_Impl(new Impl(minimum, maximum, singleStep, decimals)) +{ +} + +mitk::FloatPropertyExtension::~FloatPropertyExtension() +{ + delete m_Impl; +} + +int mitk::FloatPropertyExtension::GetDecimals() const +{ + return m_Impl->Decimals; +} + +void mitk::FloatPropertyExtension::SetDecimals(int decimals) +{ + m_Impl->Decimals = decimals; +} + +float mitk::FloatPropertyExtension::GetMaximum() const +{ + return m_Impl->Maximum; +} + +void mitk::FloatPropertyExtension::SetMaximum(float maximum) +{ + m_Impl->Maximum = maximum; +} + +float mitk::FloatPropertyExtension::GetMinimum() const +{ + return m_Impl->Minimum; +} + +void mitk::FloatPropertyExtension::SetMinimum(float minimum) +{ + m_Impl->Minimum = minimum; +} + +float mitk::FloatPropertyExtension::GetSingleStep() const +{ + return m_Impl->SingleStep; +} + +void mitk::FloatPropertyExtension::SetSingleStep(float singleStep) +{ + m_Impl->SingleStep = singleStep; +} diff --git a/Modules/Properties/mitkFloatPropertyExtension.h b/Modules/Properties/mitkFloatPropertyExtension.h new file mode 100644 index 0000000000..3dd08fee52 --- /dev/null +++ b/Modules/Properties/mitkFloatPropertyExtension.h @@ -0,0 +1,50 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkFloatPropertyExtension_h +#define mitkFloatPropertyExtension_h + +#include "mitkPropertyExtension.h" +#include + +namespace mitk +{ + class Properties_EXPORT FloatPropertyExtension : public PropertyExtension + { + public: + FloatPropertyExtension(); + FloatPropertyExtension(float minimum, float maximum, float singleStep = 0.1f, int decimals = 2); + ~FloatPropertyExtension(); + + int GetDecimals() const; + void SetDecimals(int decimals); + + float GetMaximum() const; + void SetMaximum(float maximum); + + float GetMinimum() const; + void SetMinimum(float minimum); + + float GetSingleStep() const; + void SetSingleStep(float singleStep); + + private: + struct Impl; + Impl* m_Impl; + }; +} + +#endif diff --git a/Modules/Properties/mitkPropertiesActivator.cpp b/Modules/Properties/mitkPropertiesActivator.cpp index d02689236a..e579450d61 100644 --- a/Modules/Properties/mitkPropertiesActivator.cpp +++ b/Modules/Properties/mitkPropertiesActivator.cpp @@ -1,303 +1,387 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPropertyAliases.h" #include "mitkPropertyDescriptions.h" +#include "mitkPropertyExtension.h" +#include "mitkPropertyExtensions.h" #include "mitkPropertyFilters.h" #include #include #include #include class AliasEquals { public: AliasEquals(const std::string& alias) : m_Alias(alias) { } - bool operator()(std::pair element) + bool operator()(const std::pair& element) { return element.second == m_Alias; } private: std::string m_Alias; }; +class DeleteExtension +{ +public: + void operator()(const std::pair& element) + { + delete element.second; + } +}; + namespace mitk { class PropertiesActivator : public ModuleActivator { public: void Load(ModuleContext* context) { m_PropertyAliases = PropertyAliasesImpl::New(); context->RegisterService(m_PropertyAliases); m_PropertyDescriptions = PropertyDescriptionsImpl::New(); context->RegisterService(m_PropertyDescriptions); + m_PropertyExtensions = PropertyExtensionsImpl::New(); + context->RegisterService(m_PropertyExtensions); + m_PropertyFilters = PropertyFiltersImpl::New(); context->RegisterService(m_PropertyFilters); } void Unload(ModuleContext*) { } private: class PropertyAliasesImpl : public itk::LightObject, public PropertyAliases { public: mitkClassMacro(PropertyAliasesImpl, itk::LightObject); itkNewMacro(Self); bool AddAlias(const std::string& propertyName, const std::string& alias, bool overwrite); std::string GetAlias(const std::string& propertyName) const; std::string GetPropertyName(const std::string& alias) const; bool HasAlias(const std::string& propertyName) const; void RemoveAllAliases(); void RemoveAlias(const std::string& propertyName); private: std::map m_Aliases; }; class PropertyDescriptionsImpl : public itk::LightObject, public PropertyDescriptions { public: mitkClassMacro(PropertyDescriptionsImpl, itk::LightObject); itkNewMacro(Self); bool AddDescription(const std::string& propertyName, const std::string& description, bool overwrite); std::string GetDescription(const std::string& propertyName) const; bool HasDescription(const std::string& propertyName) const; void RemoveAllDescriptions(); void RemoveDescription(const std::string& propertyName); private: std::map m_Descriptions; }; + class PropertyExtensionsImpl : public itk::LightObject, public PropertyExtensions + { + public: + mitkClassMacro(PropertyExtensionsImpl, itk::LightObject); + itkNewMacro(Self); + + bool AddExtension(const std::string& propertyName, PropertyExtension* extension, bool overwrite); + PropertyExtension* GetExtension(const std::string& propertyName) const; + bool HasExtension(const std::string& propertyName) const; + void RemoveAllExtensions(); + void RemoveExtension(const std::string& propertyName); + + private: + std::map m_Extensions; + }; + class PropertyFiltersImpl : public itk::LightObject, public PropertyFilters { public: mitkClassMacro(PropertyFiltersImpl, itk::LightObject); itkNewMacro(Self); bool AddFilter(const PropertyFilter& filter, bool overwrite); bool AddFilter(const std::string& className, const PropertyFilter& filter, bool overwrite); std::map ApplyFilter(const std::map& propertyMap) const; std::map ApplyFilter(const std::string& className, const std::map& propertyMap) const; PropertyFilter GetFilter(const std::string& className) const; bool HasFilter(const std::string& className) const; void RemoveAllFilters(); void RemoveFilter(const std::string& className); private: std::map m_Filters; }; PropertyAliasesImpl::Pointer m_PropertyAliases; PropertyDescriptionsImpl::Pointer m_PropertyDescriptions; + PropertyExtensionsImpl::Pointer m_PropertyExtensions; PropertyFiltersImpl::Pointer m_PropertyFilters; }; bool PropertiesActivator::PropertyAliasesImpl::AddAlias(const std::string& propertyName, const std::string& alias, bool overwrite) { if (alias.empty()) return false; std::pair::iterator, bool> ret = m_Aliases.insert(std::make_pair(propertyName, alias)); if (!ret.second && overwrite) { ret.first->second = alias; ret.second = true; } return ret.second; } std::string PropertiesActivator::PropertyAliasesImpl::GetAlias(const std::string& propertyName) const { if (!propertyName.empty()) { std::map::const_iterator iter = m_Aliases.find(propertyName); if (iter != m_Aliases.end()) return iter->second; } return ""; } std::string PropertiesActivator::PropertyAliasesImpl::GetPropertyName(const std::string& alias) const { if (!alias.empty()) { std::map::const_iterator iter = std::find_if(m_Aliases.begin(), m_Aliases.end(), AliasEquals(alias)); if (iter != m_Aliases.end()) return iter->first; } return ""; } bool PropertiesActivator::PropertyAliasesImpl::HasAlias(const std::string& propertyName) const { return !propertyName.empty() ? m_Aliases.find(propertyName) != m_Aliases.end() : false; } void PropertiesActivator::PropertyAliasesImpl::RemoveAlias(const std::string& propertyName) { if (!propertyName.empty()) m_Aliases.erase(propertyName); } void PropertiesActivator::PropertyAliasesImpl::RemoveAllAliases() { m_Aliases.clear(); } bool PropertiesActivator::PropertyDescriptionsImpl::AddDescription(const std::string& propertyName, const std::string& description, bool overwrite) { if (!propertyName.empty()) { std::pair::iterator, bool> ret = m_Descriptions.insert(std::make_pair(propertyName, description)); if (!ret.second && overwrite) { ret.first->second = description; ret.second = true; } return ret.second; } return false; } std::string PropertiesActivator::PropertyDescriptionsImpl::GetDescription(const std::string& propertyName) const { if (!propertyName.empty()) { std::map::const_iterator iter = m_Descriptions.find(propertyName); if (iter != m_Descriptions.end()) return iter->second; } return ""; } bool PropertiesActivator::PropertyDescriptionsImpl::HasDescription(const std::string& propertyName) const { return !propertyName.empty() ? m_Descriptions.find(propertyName) != m_Descriptions.end() : false; } void PropertiesActivator::PropertyDescriptionsImpl::RemoveAllDescriptions() { m_Descriptions.clear(); } void PropertiesActivator::PropertyDescriptionsImpl::RemoveDescription(const std::string& propertyName) { if (!propertyName.empty()) m_Descriptions.erase(propertyName); } + bool PropertiesActivator::PropertyExtensionsImpl::AddExtension(const std::string& propertyName, PropertyExtension* extension, bool overwrite) + { + if (!propertyName.empty()) + { + std::pair::iterator, bool> ret = m_Extensions.insert(std::make_pair(propertyName, extension)); + + if (!ret.second && overwrite) + { + ret.first->second = extension; + ret.second = true; + } + + return ret.second; + } + + return false; + } + + PropertyExtension* PropertiesActivator::PropertyExtensionsImpl::GetExtension(const std::string& propertyName) const + { + if (!propertyName.empty()) + { + std::map::const_iterator iter = m_Extensions.find(propertyName); + + if (iter != m_Extensions.end()) + return iter->second; + } + + return NULL; + } + + bool PropertiesActivator::PropertyExtensionsImpl::HasExtension(const std::string& propertyName) const + { + return !propertyName.empty() + ? m_Extensions.find(propertyName) != m_Extensions.end() + : false; + } + + void PropertiesActivator::PropertyExtensionsImpl::RemoveAllExtensions() + { + std::for_each(m_Extensions.begin(), m_Extensions.end(), DeleteExtension()); + m_Extensions.clear(); + } + + void PropertiesActivator::PropertyExtensionsImpl::RemoveExtension(const std::string& propertyName) + { + if (!propertyName.empty()) + { + delete m_Extensions[propertyName]; + m_Extensions.erase(propertyName); + } + } + bool PropertiesActivator::PropertyFiltersImpl::AddFilter(const PropertyFilter& filter, bool overwrite) { return this->AddFilter("", filter, overwrite); } bool PropertiesActivator::PropertyFiltersImpl::AddFilter(const std::string& className, const PropertyFilter& filter, bool overwrite) { if (!filter.IsEmpty()) { std::pair::iterator, bool> ret = m_Filters.insert(std::make_pair(className, filter)); if (!ret.second && overwrite) { ret.first->second = filter; ret.second = true; } return ret.second; } return false; } std::map PropertiesActivator::PropertyFiltersImpl::ApplyFilter(const std::map& propertyMap) const { return this->ApplyFilter("", propertyMap); } std::map PropertiesActivator::PropertyFiltersImpl::ApplyFilter(const std::string& className, const std::map& propertyMap) const { std::map ret = propertyMap; PropertyFilter filter = this->GetFilter(""); if (!filter.IsEmpty()) ret = filter.Apply(ret); if (!className.empty()) { filter = this->GetFilter(className); if (!filter.IsEmpty()) ret = filter.Apply(ret); } return ret; } PropertyFilter PropertiesActivator::PropertyFiltersImpl::GetFilter(const std::string& className) const { std::map::const_iterator iter = m_Filters.find(className); if (iter != m_Filters.end()) return iter->second; return PropertyFilter(); } bool PropertiesActivator::PropertyFiltersImpl::HasFilter(const std::string& className) const { return m_Filters.find(className) != m_Filters.end(); } void PropertiesActivator::PropertyFiltersImpl::RemoveAllFilters() { m_Filters.clear(); } void PropertiesActivator::PropertyFiltersImpl::RemoveFilter(const std::string& className) { m_Filters.erase(className); } } US_EXPORT_MODULE_ACTIVATOR(Properties, mitk::PropertiesActivator) diff --git a/Modules/Properties/mitkPropertyExtension.cpp b/Modules/Properties/mitkPropertyExtension.cpp new file mode 100644 index 0000000000..a369cd1f51 --- /dev/null +++ b/Modules/Properties/mitkPropertyExtension.cpp @@ -0,0 +1,25 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkPropertyExtension.h" + +mitk::PropertyExtension::PropertyExtension() +{ +} + +mitk::PropertyExtension::~PropertyExtension() +{ +} diff --git a/Modules/Properties/mitkPropertyExtension.h b/Modules/Properties/mitkPropertyExtension.h new file mode 100644 index 0000000000..d947f8a33e --- /dev/null +++ b/Modules/Properties/mitkPropertyExtension.h @@ -0,0 +1,36 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkPropertyExtension_h +#define mitkPropertyExtension_h + +#include + +namespace mitk +{ + class Properties_EXPORT PropertyExtension + { + public: + PropertyExtension(); + virtual ~PropertyExtension(); + + private: + PropertyExtension(const PropertyExtension& other); + PropertyExtension& operator=(PropertyExtension other); + }; +} + +#endif diff --git a/Modules/Properties/mitkPropertyExtensions.cpp b/Modules/Properties/mitkPropertyExtensions.cpp new file mode 100644 index 0000000000..53f3e70c0a --- /dev/null +++ b/Modules/Properties/mitkPropertyExtensions.cpp @@ -0,0 +1,21 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkPropertyExtensions.h" + +mitk::PropertyExtensions::~PropertyExtensions() +{ +} diff --git a/Modules/Properties/mitkPropertyExtensions.h b/Modules/Properties/mitkPropertyExtensions.h new file mode 100644 index 0000000000..21d7bcf9ef --- /dev/null +++ b/Modules/Properties/mitkPropertyExtensions.h @@ -0,0 +1,42 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef mitkPropertyExtensions_h +#define mitkPropertyExtensions_h + +#include +#include + +namespace mitk +{ + class PropertyExtension; + + class Properties_EXPORT PropertyExtensions + { + public: + virtual ~PropertyExtensions(); + + virtual bool AddExtension(const std::string& propertyName, PropertyExtension* extension, bool overwrite = false) = 0; + virtual PropertyExtension* GetExtension(const std::string& propertyName) const = 0; + virtual bool HasExtension(const std::string& propertyName) const = 0; + virtual void RemoveAllExtensions() = 0; + virtual void RemoveExtension(const std::string& propertyName) = 0; + }; +} + +US_DECLARE_SERVICE_INTERFACE(mitk::PropertyExtensions, "org.mitk.services.PropertyExtensions") + +#endif diff --git a/Modules/Properties/mitkPropertyFilter.h b/Modules/Properties/mitkPropertyFilter.h index fffd08f3ec..24965dd12c 100644 --- a/Modules/Properties/mitkPropertyFilter.h +++ b/Modules/Properties/mitkPropertyFilter.h @@ -1,52 +1,53 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkPropertyFilter_h #define mitkPropertyFilter_h #include #include namespace mitk { class Properties_EXPORT PropertyFilter { public: enum List { Blacklist, Whitelist }; PropertyFilter(); ~PropertyFilter(); + PropertyFilter(const PropertyFilter& other); PropertyFilter& operator=(PropertyFilter other); void AddEntry(const std::string& propertyName, List list); std::map Apply(const std::map& propertyMap) const; bool HasEntry(const std::string& propertyName, List list) const; bool IsEmpty() const; void RemoveAllEntries(List list); void RemoveEntry(const std::string& propertyName, List list); private: class Impl; Impl* m_Impl; }; } #endif diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.cpp index 266f836828..501339b6a3 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.cpp @@ -1,172 +1,217 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ +#include "mitkGetPropertyService.h" #include "QmitkPropertyItemDelegate.h" +#include "QmitkPropertyItemModel.h" #include +#include +#include #include #include #include +#include -static mitk::BaseProperty* GetBaseProperty(const QVariant& data) +class PropertyEqualTo { - return data.isValid() - ? reinterpret_cast(data.value()) - : NULL; -} +public: + PropertyEqualTo(const mitk::BaseProperty* property) + : m_Property(property) + { + } + + bool operator()(const mitk::PropertyList::PropertyMapElementType& pair) const + { + return pair.second.GetPointer() == m_Property; + } + +private: + const mitk::BaseProperty* m_Property; +}; QmitkPropertyItemDelegate::QmitkPropertyItemDelegate(QObject* parent) : QStyledItemDelegate(parent) { } QmitkPropertyItemDelegate::~QmitkPropertyItemDelegate() { } QWidget* QmitkPropertyItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { QVariant data = index.data(Qt::EditRole); if (data.isValid()) { if (data.type() == QVariant::Int) { QSpinBox* spinBox = new QSpinBox(parent); connect(spinBox, SIGNAL(editingFinished()), this, SLOT(OnSpinBoxEditingFinished())); return spinBox; } if (data.type() == QVariant::Double || static_cast(data.type()) == QMetaType::Float) { QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent); - spinBox->setDecimals(4); - spinBox->setSingleStep(0.1); + mitk::PropertyExtensions* extensions = mitk::GetPropertyService(); + std::string name = this->GetPropertyName(index); - QString name = index.model()->data(index.model()->index(index.row(), index.column() - 1)).toString(); + if (extensions != NULL && !name.empty() && extensions->HasExtension(name)) + { + mitk::FloatPropertyExtension* extension = static_cast(extensions->GetExtension(name)); + + spinBox->setMinimum(extension->GetMinimum()); + spinBox->setMaximum(extension->GetMaximum()); + spinBox->setSingleStep(extension->GetSingleStep()); + spinBox->setDecimals(extension->GetDecimals()); + } + else + { + spinBox->setSingleStep(0.1); + spinBox->setDecimals(4); + } - if (name == "opacity") + if (name == "opacity") // TODO { spinBox->setMinimum(0.0); spinBox->setMaximum(1.0); } connect(spinBox, SIGNAL(editingFinished()), this, SLOT(OnSpinBoxEditingFinished())); return spinBox; } if (data.type() == QVariant::StringList) { QComboBox* comboBox = new QComboBox(parent); comboBox->addItems(data.toStringList()); connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnComboBoxCurrentIndexChanged(int))); return comboBox; } } return QStyledItemDelegate::createEditor(parent, option, index); } +std::string QmitkPropertyItemDelegate::GetPropertyName(const QModelIndex& index) const +{ + if (m_PropertyList.IsNotNull()) + { + mitk::BaseProperty* property = reinterpret_cast(index.data(mitk::PropertyRole).value()); + const mitk::PropertyList::PropertyMap* propertyMap = m_PropertyList->GetMap(); + + mitk::PropertyList::PropertyMap::const_iterator it = std::find_if(propertyMap->begin(), propertyMap->end(), PropertyEqualTo(property)); + + if (it != propertyMap->end()) + return it->first; + } + + return ""; +} + void QmitkPropertyItemDelegate::OnComboBoxCurrentIndexChanged(int) { QComboBox* comboBox = qobject_cast(sender()); emit commitData(comboBox); emit closeEditor(comboBox); } void QmitkPropertyItemDelegate::OnSpinBoxEditingFinished() { QAbstractSpinBox* spinBox = qobject_cast(sender()); emit commitData(spinBox); emit closeEditor(spinBox); } void QmitkPropertyItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QVariant data = index.data(); if (index.column() == 1 && data.type() == QVariant::Color) { painter->fillRect(option.rect, data.value()); return; } QStyledItemDelegate::paint(painter, option, index); } void QmitkPropertyItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { QVariant data = index.data(Qt::EditRole); if (!data.isValid()) return; if (data.type() == QVariant::StringList) { QComboBox* comboBox = qobject_cast(editor); comboBox->setCurrentIndex(comboBox->findText(index.data().toString())); } else { QStyledItemDelegate::setEditorData(editor, index); } } void QmitkPropertyItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { QVariant data = index.data(Qt::EditRole); if (!data.isValid()) return; if (data.type() == QVariant::Int) { QSpinBox* spinBox = qobject_cast(editor); model->setData(index, spinBox->value()); } else if (data.type() == QVariant::Double) { QDoubleSpinBox* spinBox = qobject_cast(editor); model->setData(index, spinBox->value()); } else if (static_cast(data.type()) == QMetaType::Float) { QDoubleSpinBox* spinBox = qobject_cast(editor); model->setData(index, static_cast(spinBox->value())); } else if (data.type() == QVariant::StringList) { QComboBox* comboBox = qobject_cast(editor); model->setData(index, comboBox->currentText()); } else { QStyledItemDelegate::setModelData(editor, model, index); } } -QSize QmitkPropertyItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const +void QmitkPropertyItemDelegate::SetPropertyList(mitk::PropertyList* propertyList) { - return QStyledItemDelegate::sizeHint(option, index); + if (m_PropertyList.GetPointer() != propertyList) + m_PropertyList = propertyList; } diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.h b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.h index a66796c1ae..e9825112fe 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.h +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemDelegate.h @@ -1,41 +1,48 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkPropertyItemDelegate_h #define QmitkPropertyItemDelegate_h #include +#include +#include class QmitkPropertyItemDelegate : public QStyledItemDelegate { Q_OBJECT public: explicit QmitkPropertyItemDelegate(QObject* parent = NULL); ~QmitkPropertyItemDelegate(); QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; void setEditorData(QWidget* editor, const QModelIndex& index) const; void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; - QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; + void SetPropertyList(mitk::PropertyList* propertyList); private slots: void OnComboBoxCurrentIndexChanged(int index); void OnSpinBoxEditingFinished(); + +private: + std::string GetPropertyName(const QModelIndex& index) const; + + mitk::WeakPointer m_PropertyList; }; #endif diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp index 463b5f89dc..0d78e56c7a 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp @@ -1,498 +1,502 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkGetPropertyService.h" #include "QmitkPropertiesPreferencePage.h" #include "QmitkPropertyItem.h" #include "QmitkPropertyItemModel.h" #include #include #include #include #include #include #include #include static QColor MitkToQt(const mitk::Color &color) { return QColor(color.GetRed() * 255, color.GetGreen() * 255, color.GetBlue() * 255); } static mitk::BaseProperty* GetBaseProperty(const QVariant& data) { return data.isValid() ? reinterpret_cast(data.value()) : NULL; } static mitk::Color QtToMitk(const QColor &color) { mitk::Color mitkColor; mitkColor.SetRed(color.red() / 255.0f); mitkColor.SetGreen(color.green() / 255.0f); mitkColor.SetBlue(color.blue() / 255.0f); return mitkColor; } class PropertyEqualTo { public: PropertyEqualTo(const mitk::BaseProperty* property) : m_Property(property) { } bool operator()(const mitk::PropertyList::PropertyMapElementType& pair) const { return pair.second.GetPointer() == m_Property; } private: const mitk::BaseProperty* m_Property; }; QmitkPropertyItemModel::QmitkPropertyItemModel(QObject* parent) : QAbstractItemModel(parent), m_PropertyAliases(NULL), m_PropertyFilters(NULL) { this->CreateRootItem(); } QmitkPropertyItemModel::~QmitkPropertyItemModel() { this->SetNewPropertyList(NULL); } int QmitkPropertyItemModel::columnCount(const QModelIndex& parent) const { if (parent.isValid()) return static_cast(parent.internalPointer())->GetColumnCount(); else return m_RootItem->GetColumnCount(); } void QmitkPropertyItemModel::CreateRootItem() { QList rootData; rootData << "Property" << "Value"; m_RootItem.reset(new QmitkPropertyItem(rootData)); this->reset(); } QVariant QmitkPropertyItemModel::data(const QModelIndex& index, int role) const { if(!index.isValid()) return QVariant(); mitk::BaseProperty* property = index.column() == 1 ? GetBaseProperty(static_cast(index.internalPointer())->GetData(1)) : NULL; if (role == Qt::DisplayRole) { if (index.column() == 0) { return static_cast(index.internalPointer())->GetData(0); } else if (index.column() == 1 && property != NULL) { if (mitk::ColorProperty* colorProperty = dynamic_cast(property)) return MitkToQt(colorProperty->GetValue()); else if (dynamic_cast(property) == NULL) return QString::fromStdString(property->GetValueAsString()); } } else if (index.column() == 1 && property != NULL) { if (role == Qt::CheckStateRole) { if (mitk::BoolProperty* boolProperty = dynamic_cast(property)) return boolProperty->GetValue() ? Qt::Checked : Qt::Unchecked; } else if (role == Qt::EditRole) { if (dynamic_cast(property) != NULL) { return QString::fromStdString(property->GetValueAsString()); } else if (mitk::IntProperty* intProperty = dynamic_cast(property)) { return intProperty->GetValue(); } else if (mitk::FloatProperty* floatProperty = dynamic_cast(property)) { return floatProperty->GetValue(); } else if (mitk::DoubleProperty* doubleProperty = dynamic_cast(property)) { return doubleProperty->GetValue(); } else if (mitk::EnumerationProperty* enumProperty = dynamic_cast(property)) { QStringList values; for (mitk::EnumerationProperty::EnumConstIterator it = enumProperty->Begin(); it != enumProperty->End(); it++) values << QString::fromStdString(it->second); return values; } else if (mitk::ColorProperty* colorProperty = dynamic_cast(property)) { return MitkToQt(colorProperty->GetValue()); } } + else if (role == mitk::PropertyRole) + { + return QVariant::fromValue(property); + } } return QVariant(); } QModelIndex QmitkPropertyItemModel::FindProperty(const mitk::BaseProperty* property) { if (property == NULL) return QModelIndex(); typedef mitk::PropertyList::PropertyMap PropertyMap; const PropertyMap* propertyMap = m_PropertyList->GetMap(); PropertyMap::const_iterator it = std::find_if(propertyMap->begin(), propertyMap->end(), PropertyEqualTo(property)); if (it == propertyMap->end()) return QModelIndex(); QString name = QString::fromStdString(it->first); if (!name.contains('.')) { QModelIndexList item = this->match(index(0, 0), Qt::DisplayRole, name, 1, Qt::MatchExactly); if (!item.empty()) return item[0]; } else { QStringList names = name.split('.'); QModelIndexList items = this->match(index(0, 0), Qt::DisplayRole, names.last(), -1, Qt::MatchRecursive | Qt::MatchExactly); foreach(QModelIndex item, items) { QModelIndex candidate = item; for (int i = names.length() - 1; i != 0; --i) { QModelIndex parent = item.parent(); if (parent.parent() == QModelIndex()) { if (parent.data() != names.first()) break; return candidate; } if (parent.data() != names[i - 1]) break; item = parent; } } } return QModelIndex(); } Qt::ItemFlags QmitkPropertyItemModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index); if (index.column() == 1) { if (index.data(Qt::EditRole).isValid()) flags |= Qt::ItemIsEditable; if (index.data(Qt::CheckStateRole).isValid()) flags |= Qt::ItemIsUserCheckable; } return flags; } mitk::PropertyList* QmitkPropertyItemModel::GetPropertyList() const { return m_PropertyList.GetPointer(); } QVariant QmitkPropertyItemModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) return m_RootItem->GetData(section); return QVariant(); } QModelIndex QmitkPropertyItemModel::index(int row, int column, const QModelIndex& parent) const { if (!this->hasIndex(row, column, parent)) return QModelIndex(); QmitkPropertyItem* parentItem = parent.isValid() ? static_cast(parent.internalPointer()) : m_RootItem.get(); QmitkPropertyItem* childItem = parentItem->GetChild(row); return childItem != NULL ? this->createIndex(row, column, childItem) : QModelIndex(); } void QmitkPropertyItemModel::OnPreferencesChanged(const berry::IBerryPreferences* preferences) { bool showAliases = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_ALIASES, true); bool filterProperties = preferences->GetBool(QmitkPropertiesPreferencePage::FILTER_PROPERTIES, true); bool updateAliases = showAliases != (m_PropertyAliases != NULL); bool updateFilters = filterProperties != (m_PropertyFilters != NULL); bool resetPropertyList = false; if (updateAliases) { m_PropertyAliases = showAliases ? mitk::GetPropertyService() : NULL; resetPropertyList = m_PropertyList.IsNotNull(); } if (updateFilters) { m_PropertyFilters = filterProperties ? mitk::GetPropertyService() : NULL; if (!resetPropertyList) resetPropertyList = m_PropertyList.IsNotNull(); } if (resetPropertyList) this->SetNewPropertyList(m_PropertyList.GetPointer()); } void QmitkPropertyItemModel::OnPropertyDeleted(const itk::Object* property, const itk::EventObject&) { /*QModelIndex index = this->FindProperty(static_cast(property)); if (index != QModelIndex()) this->reset();*/ } void QmitkPropertyItemModel::OnPropertyListDeleted(const itk::Object*) { this->CreateRootItem(); } void QmitkPropertyItemModel::OnPropertyModified(const itk::Object* property, const itk::EventObject&) { QModelIndex index = this->FindProperty(static_cast(property)); if (index != QModelIndex()) emit dataChanged(index, index); } QModelIndex QmitkPropertyItemModel::parent(const QModelIndex& child) const { if (!child.isValid()) return QModelIndex(); QmitkPropertyItem* parentItem = static_cast(child.internalPointer())->GetParent(); if (parentItem == m_RootItem.get()) return QModelIndex(); return this->createIndex(parentItem->GetRow(), 0, parentItem); } int QmitkPropertyItemModel::rowCount(const QModelIndex& parent) const { if (parent.column() > 0) return 0; QmitkPropertyItem *parentItem = parent.isValid() ? static_cast(parent.internalPointer()) : m_RootItem.get(); return parentItem->GetChildCount(); } bool QmitkPropertyItemModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (!index.isValid() || index.column() != 1 || (role != Qt::EditRole && role != Qt::CheckStateRole)) return false; mitk::BaseProperty* property = GetBaseProperty(static_cast(index.internalPointer())->GetData(1)); if (property == NULL) return false; if (mitk::BoolProperty* boolProperty = dynamic_cast(property)) { boolProperty->SetValue(value.toInt() == Qt::Checked ? true : false); } else if (mitk::StringProperty* stringProperty = dynamic_cast(property)) { stringProperty->SetValue(value.toString().toStdString()); } else if (mitk::IntProperty* intProperty = dynamic_cast(property)) { intProperty->SetValue(value.toInt()); } else if (mitk::FloatProperty* floatProperty = dynamic_cast(property)) { floatProperty->SetValue(value.toFloat()); } else if (mitk::DoubleProperty* doubleProperty = dynamic_cast(property)) { doubleProperty->SetValue(value.toDouble()); } else if (mitk::EnumerationProperty* enumProperty = dynamic_cast(property)) { std::string selection = value.toString().toStdString(); if (selection != enumProperty->GetValueAsString() && enumProperty->IsValidEnumerationValue(selection)) enumProperty->SetValue(selection); } else if (mitk::ColorProperty* colorProperty = dynamic_cast(property)) { colorProperty->SetValue(QtToMitk(value.value())); } m_PropertyList->InvokeEvent(itk::ModifiedEvent()); m_PropertyList->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); return true; } void QmitkPropertyItemModel::SetNewPropertyList(mitk::PropertyList* propertyList) { typedef mitk::PropertyList::PropertyMap PropertyMap; this->beginResetModel(); if (m_PropertyList.IsNotNull()) { mitk::MessageDelegate1 delegate(this, &QmitkPropertyItemModel::OnPropertyListDeleted); m_PropertyList.ObjectDelete.RemoveListener(delegate); const PropertyMap* propertyMap = m_PropertyList->GetMap(); for (PropertyMap::const_iterator propertyIt = propertyMap->begin(); propertyIt != propertyMap->end(); ++propertyIt) { std::map::const_iterator tagIt = m_PropertyModifiedTags.find(propertyIt->first); if (tagIt != m_PropertyModifiedTags.end()) propertyIt->second->RemoveObserver(tagIt->second); tagIt = m_PropertyDeletedTags.find(propertyIt->first); if (tagIt != m_PropertyDeletedTags.end()) propertyIt->second->RemoveObserver(tagIt->second); } m_PropertyModifiedTags.clear(); } m_PropertyList = propertyList; if (m_PropertyList.IsNotNull()) { mitk::MessageDelegate1 delegate(this, &QmitkPropertyItemModel::OnPropertyListDeleted); m_PropertyList.ObjectDelete.AddListener(delegate); mitk::MessageDelegate2 propertyDelegate(this, &QmitkPropertyItemModel::OnPropertyModified); itk::MemberCommand::Pointer modifiedCommand = itk::MemberCommand::New(); modifiedCommand->SetCallbackFunction(this, &QmitkPropertyItemModel::OnPropertyModified); const PropertyMap* propertyMap = m_PropertyList->GetMap(); for (PropertyMap::const_iterator it = propertyMap->begin(); it != propertyMap->end(); ++it) m_PropertyModifiedTags.insert(std::make_pair(it->first, it->second->AddObserver(itk::ModifiedEvent(), modifiedCommand))); itk::MemberCommand::Pointer deletedCommand = itk::MemberCommand::New(); deletedCommand->SetCallbackFunction(this, &QmitkPropertyItemModel::OnPropertyDeleted); for (PropertyMap::const_iterator it = propertyMap->begin(); it != propertyMap->end(); ++it) m_PropertyDeletedTags.insert(std::make_pair(it->first, it->second->AddObserver(itk::DeleteEvent(), deletedCommand))); } this->CreateRootItem(); if (m_PropertyList != NULL && !m_PropertyList->IsEmpty()) { mitk::PropertyList::PropertyMap filteredProperties; bool filterProperties = false; if (m_PropertyFilters != NULL && (m_PropertyFilters->HasFilter() || m_PropertyFilters->HasFilter(m_ClassName.toStdString()))) { filteredProperties = m_PropertyFilters->ApplyFilter(m_ClassName.toStdString(), *m_PropertyList->GetMap()); filterProperties = true; } const mitk::PropertyList::PropertyMap* propertyMap = !filterProperties ? m_PropertyList->GetMap() : &filteredProperties; mitk::PropertyList::PropertyMap::const_iterator end = propertyMap->end(); for (mitk::PropertyList::PropertyMap::const_iterator iter = propertyMap->begin(); iter != end; ++iter) { QStringList nameAndAlias(QString::fromStdString(iter->first)); nameAndAlias << (m_PropertyAliases != NULL ? QString::fromStdString(m_PropertyAliases->GetAlias(iter->first)) : ""); QList data; data << (nameAndAlias[1].isEmpty() ? nameAndAlias[0] : nameAndAlias[1]); data << QVariant::fromValue((reinterpret_cast(iter->second.GetPointer()))); m_RootItem->AppendChild(new QmitkPropertyItem(data)); } } this->endResetModel(); } void QmitkPropertyItemModel::SetPropertyList(mitk::PropertyList* propertyList, const QString& className) { if (m_PropertyList.GetPointer() != propertyList) { m_ClassName = className; this->SetNewPropertyList(propertyList); } } diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.h b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.h index c057eb8147..32553b3bb7 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.h +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.h @@ -1,74 +1,79 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkPropertyItemModel_h #define QmitkPropertyItemModel_h #include #include #include class QmitkPropertyItem; namespace berry { struct IBerryPreferences; } namespace mitk { class PropertyAliases; class PropertyFilters; + + enum + { + PropertyRole = Qt::UserRole + 1 + }; } class QmitkPropertyItemModel : public QAbstractItemModel { Q_OBJECT public: explicit QmitkPropertyItemModel(QObject* parent = NULL); ~QmitkPropertyItemModel(); int columnCount(const QModelIndex& parent = QModelIndex()) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; Qt::ItemFlags flags(const QModelIndex& index) const; mitk::PropertyList* GetPropertyList() const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; void OnPreferencesChanged(const berry::IBerryPreferences* preferences); QModelIndex parent(const QModelIndex& child) const; int rowCount(const QModelIndex& parent = QModelIndex()) const; bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); void SetPropertyList(mitk::PropertyList* propertyList, const QString& className = ""); private: void CreateRootItem(); QModelIndex FindProperty(const mitk::BaseProperty* property); void OnPropertyDeleted(const itk::Object* property, const itk::EventObject& event); void OnPropertyListDeleted(const itk::Object* propertyList); void OnPropertyModified(const itk::Object* property, const itk::EventObject& event); void SetNewPropertyList(mitk::PropertyList* propertyList); mitk::PropertyAliases* m_PropertyAliases; mitk::PropertyFilters* m_PropertyFilters; mitk::WeakPointer m_PropertyList; QString m_ClassName; std::auto_ptr m_RootItem; std::map m_PropertyDeletedTags; std::map m_PropertyModifiedTags; }; #endif diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp index 5158cefba1..ae3cf2f269 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.cpp @@ -1,269 +1,274 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkGetPropertyService.h" #include "QmitkPropertiesPreferencePage.h" #include "QmitkPropertyItemDelegate.h" #include "QmitkPropertyItemModel.h" #include "QmitkPropertyItemSortFilterProxyModel.h" #include "QmitkPropertyTreeView.h" #include #include #include #include const std::string QmitkPropertyTreeView::VIEW_ID = "org.mitk.views.properties"; QmitkPropertyTreeView::QmitkPropertyTreeView() : m_PropertyNameChangedTag(0), m_PropertyAliases(NULL), m_PropertyDescriptions(NULL), m_ShowGenuineNames(false), m_ProxyModel(NULL), - m_Model(NULL) + m_Model(NULL), + m_Delegate(NULL) { } QmitkPropertyTreeView::~QmitkPropertyTreeView() { } void QmitkPropertyTreeView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); m_Controls.filter->SetDefaultText("Filter"); m_Controls.description->hide(); m_ProxyModel = new QmitkPropertyItemSortFilterProxyModel(m_Controls.treeView); m_Model = new QmitkPropertyItemModel(m_ProxyModel); m_ProxyModel->setSourceModel(m_Model); m_ProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive); m_ProxyModel->setDynamicSortFilter(true); - m_Controls.treeView->setItemDelegateForColumn(1, new QmitkPropertyItemDelegate(m_Controls.treeView)); + m_Delegate = new QmitkPropertyItemDelegate(m_Controls.treeView); + + m_Controls.treeView->setItemDelegateForColumn(1, m_Delegate); m_Controls.treeView->setModel(m_ProxyModel); m_Controls.treeView->setColumnWidth(0, 150); m_Controls.treeView->sortByColumn(0, Qt::AscendingOrder); m_Controls.treeView->setSelectionBehavior(QAbstractItemView::SelectRows); m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.treeView->setEditTriggers(QAbstractItemView::SelectedClicked | QAbstractItemView::DoubleClicked); connect(m_Controls.filter, SIGNAL(textChanged(const QString&)), this, SLOT(OnFilterTextChanged(const QString&))); connect(m_Controls.treeView->selectionModel(), SIGNAL(currentRowChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(OnCurrentRowChanged(const QModelIndex&, const QModelIndex&))); connect(m_Model, SIGNAL(modelReset()), this, SLOT(OnModelReset())); } QString QmitkPropertyTreeView::GetPropertyNameOrAlias(const QModelIndex& index) { QString propertyName; if (index.isValid()) { QModelIndex current = index; while (current.isValid()) { QString name = m_ProxyModel->data(m_ProxyModel->index(current.row(), 0, current.parent())).toString(); propertyName.prepend(propertyName.isEmpty() ? name : name.append('.')); current = current.parent(); } } return propertyName; } void QmitkPropertyTreeView::OnCurrentRowChanged(const QModelIndex& current, const QModelIndex&) { if (m_PropertyDescriptions != NULL && current.isValid()) { QString name = this->GetPropertyNameOrAlias(current); if (!name.isEmpty()) { QString alias; bool isTrueName = true; if (m_PropertyAliases != NULL) { std::string trueName = m_PropertyAliases->GetPropertyName(name.toStdString()); if (!trueName.empty()) { alias = name; name = QString::fromStdString(trueName); isTrueName = false; } } QString description = QString::fromStdString(m_PropertyDescriptions->GetDescription(name.toStdString())); if (!description.isEmpty()) { if (!isTrueName && alias.isEmpty() && m_PropertyAliases != NULL) alias = QString::fromStdString(m_PropertyAliases->GetAlias(name.toStdString())); QString customizedDescription; if (!alias.isEmpty()) { if (m_ShowGenuineNames) { customizedDescription = "

" + alias + "

"; customizedDescription += "
" + name + "
"; } else { customizedDescription = "

" + alias + "

"; } } else { customizedDescription = "

" + name + "

"; } customizedDescription += description; m_Controls.description->setText(customizedDescription); m_Controls.description->show(); return; } } } m_Controls.description->hide(); } void QmitkPropertyTreeView::OnFilterTextChanged(const QString& filter) { m_ProxyModel->setFilterWildcard(filter); if (filter.isEmpty()) m_Controls.treeView->collapseAll(); else m_Controls.treeView->expandAll(); } void QmitkPropertyTreeView::OnModelReset() { m_Controls.description->hide(); } void QmitkPropertyTreeView::OnPreferencesChanged(const berry::IBerryPreferences* preferences) { bool showAliases = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_ALIASES, true); bool showDescriptions = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_DESCRIPTIONS, true); bool showGenuineNames = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_GENUINE_NAMES, true); bool updateAliases = showAliases != (m_PropertyAliases != NULL); bool updateDescriptions = showDescriptions != (m_PropertyDescriptions != NULL); bool updateGenuineNames = showGenuineNames != m_ShowGenuineNames; if (updateAliases) m_PropertyAliases = showAliases ? mitk::GetPropertyService() : NULL; if (updateDescriptions) m_PropertyDescriptions = showDescriptions ? mitk::GetPropertyService() : NULL; if (updateGenuineNames) m_ShowGenuineNames = showGenuineNames; if (updateDescriptions || updateGenuineNames) { QModelIndexList selection = m_Controls.treeView->selectionModel()->selectedRows(); if (!selection.isEmpty()) this->OnCurrentRowChanged(selection[0], selection[0]); } m_Model->OnPreferencesChanged(preferences); } void QmitkPropertyTreeView::OnPropertyNameChanged(const itk::EventObject&) { mitk::PropertyList* propertyList = m_Model->GetPropertyList(); if (propertyList != NULL) { mitk::BaseProperty* nameProperty = propertyList->GetProperty("name"); if (nameProperty != NULL) { std::ostringstream partName; partName << "Properties (" << nameProperty->GetValueAsString() << ')'; this->SetPartName(partName.str()); } } } void QmitkPropertyTreeView::OnSelectionChanged(berry::IWorkbenchPart::Pointer, const QList& nodes) { mitk::PropertyList* propertyList = m_Model->GetPropertyList(); if (propertyList != NULL) { mitk::BaseProperty* nameProperty = propertyList->GetProperty("name"); if (nameProperty != NULL) nameProperty->RemoveObserver(m_PropertyNameChangedTag); m_PropertyNameChangedTag = 0; } if (nodes.empty() || nodes.front().IsNull()) { this->SetPartName("Properties"); m_Model->SetPropertyList(NULL); + m_Delegate->SetPropertyList(NULL); } else { QString selectionClassName = nodes.front()->GetData() != NULL ? nodes.front()->GetData()->GetNameOfClass() : ""; m_Model->SetPropertyList(nodes.front()->GetPropertyList(), selectionClassName); + m_Delegate->SetPropertyList(nodes.front()->GetPropertyList()); OnPropertyNameChanged(itk::ModifiedEvent()); mitk::BaseProperty* nameProperty = nodes.front()->GetProperty("name"); if (nameProperty != NULL) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkPropertyTreeView::OnPropertyNameChanged); m_PropertyNameChangedTag = nameProperty->AddObserver(itk::ModifiedEvent(), command); } } if (!m_ProxyModel->filterRegExp().isEmpty()) m_Controls.treeView->expandAll(); } void QmitkPropertyTreeView::SetFocus() { m_Controls.filter->setFocus(); } diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.h b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.h index 2e8957c298..02e2373a28 100644 --- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.h +++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyTreeView.h @@ -1,70 +1,72 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef QmitkPropertyTreeView_h #define QmitkPropertyTreeView_h #include #include +class QmitkPropertyItemDelegate; class QmitkPropertyItemModel; class QmitkPropertyItemSortFilterProxyModel; namespace mitk { class PropertyAliases; class PropertyDescriptions; } class QmitkPropertyTreeView : public QmitkAbstractView { Q_OBJECT public: static const std::string VIEW_ID; berryObjectMacro(QmitkPropertyTreeView) QmitkPropertyTreeView(); ~QmitkPropertyTreeView(); void SetFocus(); protected: void CreateQtPartControl(QWidget* parent); private: QString GetPropertyNameOrAlias(const QModelIndex& index); void OnPreferencesChanged(const berry::IBerryPreferences* preferences); void OnPropertyNameChanged(const itk::EventObject& event); void OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList& nodes); private slots: void OnCurrentRowChanged(const QModelIndex& current, const QModelIndex& previous); void OnFilterTextChanged(const QString& filter); void OnModelReset(); private: unsigned long m_PropertyNameChangedTag; mitk::PropertyAliases* m_PropertyAliases; mitk::PropertyDescriptions* m_PropertyDescriptions; bool m_ShowGenuineNames; Ui::QmitkPropertyTreeView m_Controls; QmitkPropertyItemSortFilterProxyModel* m_ProxyModel; QmitkPropertyItemModel* m_Model; + QmitkPropertyItemDelegate* m_Delegate; }; #endif