//################################################################################################## // // Custom Visualization Core library // Copyright (C) 2011-2012 Ceetron AS // // This library is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at <> // for more details. // //################################################################################################## #include "cafUiPropertyCreatorPdm.h" #include #include #include #include #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafUiTreeModelPdm.h" #include "qtvariantproperty.h" #include "qtpropertymanager.h" #include "qteditorfactory.h" #include namespace caf { //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- UiPropertyCreatorPdm::UiPropertyCreatorPdm(QObject * parent) : QObject(parent), m_treeModel(NULL), m_selectionModel(NULL), m_propertyBrowser(NULL) { m_variantPropertyManager = new QtVariantPropertyManager(); m_variantEditorFactory = new QtVariantEditorFactory(); m_doublePropertyManager = new QtStringPropertyManager(); m_doubleEditorFactory = new QtLineEditFactory(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- UiPropertyCreatorPdm::~UiPropertyCreatorPdm() { delete m_variantPropertyManager; delete m_variantEditorFactory; delete m_doublePropertyManager; delete m_doubleEditorFactory; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::setPropertyBrowser(QtAbstractPropertyBrowser* propertyBrowser) { m_propertyBrowser = propertyBrowser; if (m_propertyBrowser) { m_propertyBrowser->setFactoryForManager(m_variantPropertyManager, m_variantEditorFactory); m_propertyBrowser->setFactoryForManager(m_doublePropertyManager, m_doubleEditorFactory); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::setModel(UiTreeModelPdm* treeModel, QItemSelectionModel* selectionModel) { clearWidgetsAndProperties(); m_treeModel = treeModel; if (m_treeModel) { connect(m_treeModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), SLOT(slotDataChanged(const QModelIndex &, const QModelIndex &))); } m_selectionModel = selectionModel; if (m_selectionModel) { connect(m_selectionModel, SIGNAL(currentChanged(const QModelIndex&, const QModelIndex&)), SLOT(slotCurrentChanged(const QModelIndex&, const QModelIndex&))); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::createAndShowPropertiesForIndex(const QModelIndex& index) { if (index.isValid()) { caf::PdmUiTreeItem* treeItem = caf::UiTreeModelPdm::getTreeItemFromIndex(index); assert(treeItem); caf::PdmObject* pdmObj = treeItem->dataObject(); if (m_propertyBrowser) { createAndShowPropertiesForObject(pdmObj); } emit selectedObjectChanged(pdmObj); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::createAndShowPropertiesForObject(caf::PdmObject* object) { assert(m_propertyBrowser); if (!object) return; // Disconnect listening on property manager during building of property browser content m_variantPropertyManager->disconnect(this); m_doublePropertyManager->disconnect(this); { std::vector fields; uiFields(object, fields); size_t i; for (i = 0; i < fields.size(); i++) { caf::PdmFieldHandle* field = fields[i]; assert(field); QString uiName = field->uiName(); QtProperty* qtProperty = NULL; bool fromMenuOnly = false; QList enumNames = field->valueOptions(&fromMenuOnly); // Check if we have an option menu to only show if (!enumNames.isEmpty() && fromMenuOnly == true) { QtVariantProperty* variantProperty = m_variantPropertyManager->addProperty(QtVariantPropertyManager::enumTypeId(), uiName); if (variantProperty) { variantProperty->setAttribute("enumNames", PdmOptionItemInfo::extractUiTexts(enumNames)); } else { assert(false); } qtProperty = variantProperty; } else if (!enumNames.isEmpty() ) { assert(false); // This is not yet supprted } else { QVariant uiValue = field->uiValue(); if (uiValue.type() == QVariant::Double) { qtProperty = m_doublePropertyManager->addProperty(uiName); } else { qtProperty = m_variantPropertyManager->addProperty(uiValue.type(), uiName); if (uiValue.type() == QVariant::Color) { QList subProperties = qtProperty->subProperties(); int i; for (i = 0; i < subProperties.size(); i++) { qtProperty->removeSubProperty(subProperties[i]); } } } } if (qtProperty) { qtProperty->setToolTip(field->uiToolTip()); qtProperty->setWhatsThis(field->uiWhatsThis()); m_properties[qtProperty] = field; if (!field->isUiHidden()) { m_propertyBrowser->addProperty(qtProperty); } } else { // Error } } setAllPropertyValuesFromDataSource(); } // Establish listening on property manager when all properties are updated from data source connect(m_variantPropertyManager, SIGNAL(valueChanged(QtProperty*, const QVariant&)), SLOT(slotWriteValueToDataSource(QtProperty*, const QVariant&))); connect(m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*, const QString&)), SLOT(slotWriteDoubleValueToDataSource(QtProperty*, const QString&))); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::clearWidgetsAndProperties() { if (m_propertyBrowser) { m_propertyBrowser->clear(); } m_properties.clear(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::setAllPropertyValuesFromDataSource() { std::map::iterator it; for (it = m_properties.begin(); it != m_properties.end(); it++) { #if 1 if (it->second->isUiHidden()) { QtProperty* prop = it->first; #if 0 it++; m_properties.erase(prop); delete prop; #endif m_propertyBrowser->removeProperty(prop); } else #endif { m_propertyBrowser->addProperty(it->first); QVariant uiValue = it->second->uiValue(); if (uiValue.type() == QVariant::Double) { QString text = uiValue.toString(); m_doublePropertyManager->setValue(it->first, text); } else { m_variantPropertyManager->setValue(it->first, uiValue); } QString uiName = it->second->uiName(); it->first->setPropertyName(uiName); bool fromMenuOnly = false; QList enumNames = it->second->valueOptions(&fromMenuOnly); if (!enumNames.isEmpty() && fromMenuOnly == true) { QtVariantProperty* variantProperty = dynamic_cast(it->first); if (variantProperty) { variantProperty->setAttribute("enumNames", PdmOptionItemInfo::extractUiTexts(enumNames)); } } } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::slotWriteValueToDataSource(QtProperty* uiProperty, const QVariant& newValue) { assert(uiProperty); caf::PdmFieldHandle* field = NULL; std::map::iterator it; for (it = m_properties.begin(); it != m_properties.end(); it++) { if (it->first == uiProperty) { field = it->second; } } if (!field) return; // Make sure we return a QVariant of unsigned int to tell pdm that we are using an option // index, and not an int value. QtVariantProperty* variantProperty = dynamic_cast (uiProperty); if (variantProperty && variantProperty->propertyType() == QtVariantPropertyManager::enumTypeId()) { QVariant uintValue(newValue.toUInt()); field->setValueFromUi(uintValue); } else { field->setValueFromUi(newValue); } if (m_selectionModel) { m_treeModel->emitDataChanged(m_selectionModel->currentIndex()); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::slotWriteDoubleValueToDataSource(QtProperty* uiProperty, const QString& newValue) { double doubleValue = newValue.toDouble(); slotWriteValueToDataSource(uiProperty, doubleValue); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::slotDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { if (m_selectionModel) { if (topLeft == m_selectionModel->currentIndex()) { // We must delay update of widgets to after the signal has returned QTimer::singleShot(0, this, SLOT(slotUpdateProperties())); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::slotCurrentChanged(const QModelIndex& current, const QModelIndex& previous) { clearWidgetsAndProperties(); createAndShowPropertiesForIndex(current); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void UiPropertyCreatorPdm::slotUpdateProperties() { setAllPropertyValuesFromDataSource(); } void UiPropertyCreatorPdm::uiFields(const caf::PdmObject* object, std::vector& fields) const { assert(object); object->fields(fields); } } // end namespace caf