ResInsight: Integrated from Caf trunc. Multi variable fields (multiselect) with option values now handled. Improved PdmUi layout. Improved Viewer widget size behaviour, Xml keyword check.

p4#: 18777
This commit is contained in:
Jacob Støren 2012-09-18 15:21:04 +02:00
parent 01ee943155
commit e679ba07a5
23 changed files with 546 additions and 767 deletions

View File

@ -7,7 +7,9 @@ set( QOBJECT_HEADERS
cafAnimationToolBar.h
)
qt4_wrap_cpp( MOC_FILES_CPP ${QOBJECT_HEADERS} )
if ( (${CMAKE_VERSION} VERSION_LESS 2.8.6) OR (NOT CMAKE_AUTOMOC) )
qt4_wrap_cpp( MOC_FILES_CPP ${QOBJECT_HEADERS} )
endif()
# NOTE! Resources in this subfolder appends to the variable QRC_FILES in parent scope
# CMakeList.txt in the application folder (parent scope) must use the following syntax

View File

@ -18,6 +18,7 @@
//##################################################################################################
#include "cafPdmField.h"
#include "cafPdmObject.h"
#include <iostream>
@ -61,10 +62,24 @@ bool PdmFieldHandle::assertValid() const
std::cout << "Detected use of non-initialized field\n";
return false;
}
else
if (!PdmObject::isValidXmlElementName(m_keyword))
{
return true;
std::cout << "Detected keyword " << m_keyword.toStdString() << " which is an invalid Xml element name\n";
return false;
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmFieldHandle::setKeyword(const QString& keyword)
{
assert(PdmObject::isValidXmlElementName(keyword));
m_keyword = keyword;
}
//--------------------------------------------------------------------------------------------------

View File

@ -54,7 +54,7 @@ public:
void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; }
void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; }
void setKeyword(const QString& keyword) { m_keyword = keyword; }
void setKeyword(const QString& keyword);
QString keyword() const { return m_keyword; }
void setOwnerObject(PdmObject * owner) { m_ownerObject = owner; }

View File

@ -36,21 +36,61 @@ void caf::PdmField<DataType>::setValueFromUi(const QVariant& uiValue)
{
QVariant oldValue = PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
// Check whether we are handling selections of values or actual values
if (m_optionEntryCache.size())
{
// Check if we got an index into the option list
// This has an option based GUI, the uiValue is only indexes into the m_optionEntryCache
if (uiValue.type() == QVariant::UInt)
{
assert(uiValue.toUInt() < static_cast<unsigned int>(m_optionEntryCache.size()));
PdmFieldTypeSpecialization<DataType>::setFromVariant(m_optionEntryCache[uiValue.toUInt()].value, m_fieldValue);
}
else
else if (uiValue.type() == QVariant::List)
{
QList<QVariant> selectedIndexes = uiValue.toList();
QList<QVariant> valuesToSetInField;
if (selectedIndexes.isEmpty())
{
PdmFieldTypeSpecialization<DataType>::setFromVariant(valuesToSetInField, m_fieldValue);
}
else
{
if (selectedIndexes.front().type() == QVariant::UInt)
{
for (int i = 0; i < selectedIndexes.size(); ++i)
{
unsigned int opIdx = selectedIndexes[i].toUInt();
if (opIdx < static_cast<unsigned int>(m_optionEntryCache.size()))
{
valuesToSetInField.push_back(m_optionEntryCache[opIdx].value);
}
}
PdmFieldTypeSpecialization<DataType>::setFromVariant(valuesToSetInField, m_fieldValue);
}
else
{
// We are not getting indexes as expected from the UI. For now assert, to catch this condition
// but it should possibly be handled as setting the values explicitly. The code for that is below the assert
assert(false);
PdmFieldTypeSpecialization<DataType>::setFromVariant(uiValue, m_fieldValue);
m_optionEntryCache.clear();
}
}
}
else
{
// We are not getting indexes as expected from the UI. For now assert, to catch this condition
// but it should possibly be handled as setting the values explicitly. The code for that is below the assert
assert(false);
PdmFieldTypeSpecialization<DataType>::setFromVariant(uiValue, m_fieldValue);
m_optionEntryCache.clear();
}
}
else
{
{ // Not an option based GUI, the uiValue is a real field value
PdmFieldTypeSpecialization<DataType>::setFromVariant(uiValue, m_fieldValue);
}
@ -68,37 +108,74 @@ void caf::PdmField<DataType>::setValueFromUi(const QVariant& uiValue)
}
//--------------------------------------------------------------------------------------------------
///
/// Returns the option values that is to be displayed in the UI for this field.
/// This method calls the virtual PdmObject::calculateValueOptions to get the list provided from the
/// application, then possibly adds the current field value(s) to the list, to
/// make sure the actual values are shown
//--------------------------------------------------------------------------------------------------
template<typename DataType >
QList<PdmOptionItemInfo> caf::PdmField<DataType>::valueOptions(bool* useOptionsOnly)
{
// First check if the owner PdmObject has a value options specification.
// if it has, use it.
if (m_ownerObject)
{
m_optionEntryCache = m_ownerObject->calculateValueOptions(this, useOptionsOnly);
if (m_optionEntryCache.size())
{
// Find this field value in the list if present
// Make sure the options contain the field values, event though they not necessarily
// is supplied as possible options by the application. This is a convenience making sure
// the actual data in the pdmObject is shown correctly in the UI, and to prevent accidental
// changes of the field values
// Find the field value(s) in the list if present
QVariant convertedFieldValue = PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
unsigned int index;
bool foundFieldValue = PdmOptionItemInfo::findValue(m_optionEntryCache, convertedFieldValue, &index);
// If not found, we have to add it to the list, to be able to show it
std::vector<unsigned int> foundIndexes;
bool foundAllFieldValues = PdmOptionItemInfo::findValues(m_optionEntryCache, convertedFieldValue, foundIndexes);
// If not all are found, we have to add the missing to the list, to be able to show it
if (!foundFieldValue)
if (!foundAllFieldValues)
{
m_optionEntryCache.push_front(PdmOptionItemInfo(convertedFieldValue.toString(), convertedFieldValue, true, QIcon()));
if (convertedFieldValue.type() != QVariant::List) // Single value field
{
m_optionEntryCache.push_front(PdmOptionItemInfo(convertedFieldValue.toString(), convertedFieldValue, true, QIcon()));
}
else // The field value is a list of values
{
QList<QVariant> valuesSelectedInField = convertedFieldValue.toList();
for (int i= 0 ; i < valuesSelectedInField.size(); ++i)
{
bool isFound = false;
for (unsigned int opIdx = 0; opIdx < static_cast<unsigned int>(m_optionEntryCache.size()); ++opIdx)
{
if (valuesSelectedInField[i] == m_optionEntryCache[opIdx].value) isFound = true;
}
if (!isFound)
{
m_optionEntryCache.push_front(PdmOptionItemInfo(valuesSelectedInField[i].toString(), valuesSelectedInField[i], true, QIcon()));
}
}
}
}
if (m_optionEntryCache.size()) return m_optionEntryCache;
return m_optionEntryCache;
}
}
// If we have no options, use the options defined by the type. Normally only caf::AppEnum type
return PdmFieldTypeSpecialization<DataType>::valueOptions(useOptionsOnly, m_fieldValue);
}
//--------------------------------------------------------------------------------------------------
///
/// Extracts a QVariant representation of the data in the field to be used in the UI.
/// Note that for fields with a none empty valueOptions list the returned QVariant contains the
/// indexes to the selected options rather than the actual values, if they can be found.
/// If we cant find them, the method asserts, forcing the valueOptions to always contain the field values
//--------------------------------------------------------------------------------------------------
template<typename DataType >
QVariant caf::PdmField<DataType>::uiValue() const
@ -106,13 +183,34 @@ QVariant caf::PdmField<DataType>::uiValue() const
if (m_optionEntryCache.size())
{
QVariant convertedFieldValue = PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
unsigned int index;
bool foundFieldValue = PdmOptionItemInfo::findValue(m_optionEntryCache, convertedFieldValue, &index);
assert(foundFieldValue);
return QVariant(index);
}
std::vector<unsigned int> indexes;
PdmOptionItemInfo::findValues(m_optionEntryCache, convertedFieldValue, indexes);
if (convertedFieldValue.type() == QVariant::List)
{
if (indexes.size() == convertedFieldValue.toList().size())
{
QList<QVariant> returnList;
for(size_t i = 0; i < indexes.size(); ++i)
{
returnList.push_back(QVariant(indexes[i]));
}
return QVariant(returnList);
}
assert(false); // Did not find all the field values among the options available.
}
else
{
if (indexes.size() == 1) return QVariant(indexes.front());
}
return PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
assert(false);
return convertedFieldValue;
}
else
{
return PdmFieldTypeSpecialization<DataType>::convert(m_fieldValue);
}
}
//==================================================================================================

View File

@ -262,7 +262,7 @@ public:
int i;
for (i = 0; i < optionTexts.size(); ++i)
{
optionList.push_back(PdmOptionItemInfo(optionTexts[i]));
optionList.push_back(PdmOptionItemInfo(optionTexts[i], static_cast<unsigned int>(i)));
}
return optionList;

View File

@ -130,6 +130,8 @@ void PdmObject::writeFields(QXmlStreamWriter& xmlStream)
if (field->isIOWritable())
{
QString keyword = field->keyword();
assert(PdmObject::isValidXmlElementName(keyword));
xmlStream.writeStartElement("", keyword);
field->writeFieldData(xmlStream);
xmlStream.writeEndElement();
@ -277,5 +279,43 @@ void PdmObject::editorAttribute(const PdmFieldHandle* field, QString uiConfigNam
this->defineEditorAttribute(field, uiConfigName, attribute);
}
//--------------------------------------------------------------------------------------------------
/// Check if a string is a valid Xml element name
//
/// http://www.w3schools.com/xml/xml_elements.asp
///
/// XML elements must follow these naming rules:
/// Names can contain letters, numbers, and other characters
/// Names cannot start with a number or punctuation character
/// Names cannot start with the letters xml (or XML, or Xml, etc)
/// Names cannot contain spaces
//--------------------------------------------------------------------------------------------------
bool PdmObject::isValidXmlElementName(const QString& name)
{
if (name.size() > 0)
{
QChar firstChar = name[0];
if (firstChar.isDigit() || firstChar == '.')
{
return false;
}
}
if (name.size() >= 3)
{
if (name.left(3).compare("xml", Qt::CaseInsensitive) == 0)
{
return false;
}
}
if (name.contains(' '))
{
return false;
}
return true;
}
} //End of namespace caf

View File

@ -67,7 +67,7 @@ public: \
/// Place this in the cpp file, preferably above the constructor
#define CAF_PDM_SOURCE_INIT(ClassName, keyword) \
QString ClassName::classKeywordStatic() { return keyword; } \
QString ClassName::classKeywordStatic() { assert(PdmObject::isValidXmlElementName(keyword)); return keyword; } \
static bool PDM_OBJECT_STRING_CONCATENATE(pdm_object_factory_init_, __LINE__) = caf::PdmObjectFactory::instance()->registerCreator<ClassName>()
/// InitObject sets up the user interface related information for the object
@ -143,6 +143,11 @@ public: // Virtual
calculateValueOptions(const PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) { return QList<PdmOptionItemInfo>(); }
// For later // virtual void editorAttributeChangedByUI(const PdmFieldHandle* field, QString uiConfigName, const PdmUiAttributeHandle * attributes);
public:
/// Check if a string is a valid Xml element name
static bool isValidXmlElementName(const QString& name);
protected: // Virtual
/// Method gets called from PdmDocument after all objects are read.
/// Re-implement to set up internal pointers etc. in your data structure

View File

@ -1,668 +0,0 @@
namespace caf
{
class PdmUiItemInfo
{
// ....
const type_info* m_editorType;
int m_isHidden;
int m_isReadOnly;
};
class PdmUiItem
{
// ...
const type_info* editorType(const QString& uiConfigName);
void setEditorType(const QString& uiConfigName, const type_info* editorType);
bool isHidden(QString uiConfigName);
void setHidden(QString uiConfigName, bool isHidden);
bool readOnly(QString uiConfigName);
void setReadOnly(QString uiConfigName, bool isReadOnly);
virtual bool isGroup() { return false; }
private :
/// Map containing the UiItemInfo's for the different UiConfigurations
/// Each UiItemInfo member is undefined until set. If the member is undefined, we use the default
/// settings for that parameter.
std::map< QString, PdmUiItemInfo > m_uiConfigurations; // Empty config name is replacing m_dynamicItemInfo
};
class PdmUiOrdering
{
public:
PdmUiOrdering(): m_forgetRemainingFields(false) { };
virtual ~PdmUiOrdering()
{
for (size_t i = 0; i < m_createdGroups.size(); ++i)
{
delete m_createdGroups[i];
m_createdGroups[i] = NULL;
}
}
PdmUiGroup* addNewGroup(QString displayName)
{
PdmUiGroup* group = new PdmUiGroup;
group->setUiName(displayName);
m_createdGroups.push_back(group);
m_ordering.push_back(group);
}
void add(PdmUiItem* item) { m_ordering.push_back(item); }
bool forgetRemainingFields() const { return m_forgetRemainingFields; }
void setForgetRemainingFields(bool val) { m_forgetRemainingFields = val; }
const std::vector<PdmUiItem*>& uiItems() const { return m_ordering; }
private:
// Private copy constructor and assignment to prevent this. (The vectors below will make trouble)
PdmUiOrdering(const PdmUiOrdering& other) { }
PdmUiOrdering& operator= (const PdmUiOrdering& other) { }
std::vector<PdmUiItem*> m_ordering;
std::vector<PdmUiGroup*> m_createdGroups; /// Owned PdmUiGroups, for mem management
bool m_forgetRemainingFields;
};
class PdmUiGroup : public PdmUiItem, PdmUiOrdering
{
virtual bool isGroup() { return true; }
};
class PdmObject : public PdmUiItem
{
public:
/// For a specific field, return editor specific parameters used to customize the editor behavior..
void editorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute)
{
this->defineEditorAttribute(field, uiConfigName, attribute);
}
// For later // virtual void uiAttributeChangedByUI(const PdmFieldHandle* field, QString uiConfigName, const PdmUiAttributeHandle * attributes);
// Method to be called from the Ui classes creating Auto Gui to get the group information
// supplied by the \sa defineUiOrdering method that can be reimplemented
void uiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering)
{
this->defineUiOrdering(uiConfigName, uiOrdering);
if (!uiOrdering.forgetRemainingFields())
{
// Add the remaining Fields To UiConfig
for (size_t i = 0; i < m_fields.size(); ++i)
{
if (!uiOrdering.contains(m_fields[i]))
{
uiOrdering.add( m_fields[i]);
}
}
}
}
protected:
/// Override to customize the order and grouping of the Gui.
/// Fill up the uiOrdering object with groups and field references to create the gui structure
/// If the uiOrdering is empty, it is interpreted as meaning all fields w/o grouping.
virtual void defineUiOrdering(QString uiConfigName, PdmUiOrdering& uiOrdering) {}
/// Override to provide editor specific data for the field and uiConfigName
virtual void defineEditorAttribute(const PdmFieldHandle* field, QString uiConfigName, PdmUiEditorAttribute * attribute) {}
};
class PdmUiObjectEditorHandle: public QObject
{
public:
PdmUiObjectEditorHandle() : m_pdmObject(NULL) {}
~PdmUiObjectEditorHandle() {}
///
QWidget* getOrCreateWidget(QWidget* parent)
{
if (m_widget.isNull())
{
m_widget = this->createWidget(parent);
}
return m_widget;
}
QWidget* widget() { return m_widget; }
/// Virtual method to be overridden. Needs to set up the supplied widget
/// with all signals etc to make it communicate with this object
void setPdmObject(PdmObject* object, QString uiConfigName) { m_pdmObject = object; }
PdmObject* pdmObject() { return m_pdmObject; }
virtual void updateUi(QString uiConfigName) = 0;
protected:
virtual QWidget* createWidget(QWidget* parent) = 0;
private:
PdmObject* m_pdmObject;
QPointer<QWidget> m_widget;
};
class PdmUiFieldEditorHandle : public QObject
{
public:
PdmUiFieldEditorHandle() : m_field(NULL) {}
~PdmUiFieldEditorHandle()
{
if (m_field) m_field->removeFieldEditor(this);
if (!m_combinedWidget.isNull()) delete m_combinedWidget;
if (!m_editorWidget.isNull()) delete m_editorWidget ;
if (!m_labelWidget.isNull()) delete m_labelWidget;
}
///
PdmFieldHandle* field() { return m_field; }
void setField(PdmFieldHandle * field)
{
if (m_field) m_field->removeFieldEditor(this);
m_field = field;
if (m_field) m_field->addFieldEditor(this);
}
void setValueToField(const QVariant& value)
{
if (m_field) m_field->setUiValue(value);
}
void createWidgets(QWidget * parent)
{
if (m_combinedWidget.isNull()) m_combinedWidget = createCombinedWidget(parent);
if (m_editorWidget.isNull()) m_editorWidget = createEditorWidget(parent);
if (m_labelWidget.isNull()) m_labelWidget = createLabelWidget(parent);
}
QWidget* combinedWidget() { return m_combinedWidget; }
QWidget* editorWidget() { return m_editorWidget; }
QWidget* labelWidget() { return m_labelWidget; }
public: // Virtual interface to override
/// Update only the display of the data value, because some other view has changed it.
virtual void updateUiValue() = 0;
/// Supposed to update all parts of the widgets, both visibility, sensitivity, decorations and field data
virtual void updateUi(QString uiConfigName) = 0;
/// Supposed to do all wiring of singals and slots
virtual void connectUi() = 0;
protected: // Virtual interface to override
/// Implement one of these, or both editor and label. The widgets will be used in the parent layout according to
/// being "Label" Editor" or a single combined widget.
virtual QWidget* createCombinedWidget(QWidget * parent) { return NULL; }
virtual QWidget* createEditorWidget(QWidget * parent) { return NULL; }
virtual QWidget* createLabelWidget(QWidget * parent) { return NULL; }
private:
PdmFieldHandle* m_field;
QPointer<QWidget> m_combinedWidget;
QPointer<QWidget> m_editorWidget;
QPointer<QWidget> m_labelWidget;
};
class PdmFieldHandle
{
// ....
void removeFieldEditor(PdmUiFieldEditorHandle* fieldView) { m_fieldEditors.erase(fieldView); }
void addFieldEditor(PdmUiFieldEditorHandle* fieldView) { m_fieldEditors.insert(fieldView); }
private:
std::set<PdmUiFieldEditorHandle*> m_fieldEditors;
// ....
void setValueFromUI(...)
{
//...
std::set<PdmUiFieldEditorHandle*>::iterator it;
for (it = m_fieldEditors.begin(); it != m_fieldEditors.end(); ++it)
{
m_fieldEditors[i]->updateUiValue();
}
//...
}
};
class PdmPropertyWindow : public QWidget
{
public:
PdmPropertyWindow()
{
setLayout(new QHBoxLayout());
}
~PdmPropertyWindow()
{
if (m_currentObjectView) delete m_currentObjectView;
}
void setUiConfigurationName(QString uiConfigName)
{
// Reset everything, and possibly create widgets etc afresh
if (m_uiConfigName != uiConfigName)
{
m_uiConfigName = uiConfigName;
if (m_currentObjectView)
{
PdmObject* object = m_currentObjectView->pdmObject();
delete m_currentObjectView;
m_currentObjectView = NULL;
this->showProperties(object);
}
}
}
void showProperties(const PdmObject* object)
{
// Find specialized object view handle
// If the current ObjectView has the same type as the one to view, reuse, with Widget etc.
if (!(m_currentObjectView && m_currentObjectView->m_pdmObject->editorType(m_uiConfigName) == object->editorType(m_uiConfigName)))
{
// Remove Widget from layout
layout()->removeWidget(m_currentObjectView->widget());
delete m_currentObjectView;
m_currentObjectView = PdmObjViewFactory::instance()->create(object->editorType(m_uiConfigName));
if (!m_currentObjectView)
{
m_currentObjectView = new PdmUiDefaultObjectEditor();
}
// Create widget to handle this
QWidget * page = NULL;
page = m_currentObjectView->getOrCreateWidget(this);
CVF_ASSERT(page);
this->layout()->addWidget(page);
}
m_currentObjectView->setPdmObject(object);
m_currentObjectView->updateUi(m_uiConfigName);
}
private:
PdmUiObjectEditorHandle* m_currentObjectView;
QString m_uiConfigName;
};
class PdmUiEditorAttribute
{
public:
PdmUiEditorAttribute() {}
virtual ~PdmUiEditorAttribute() {}
};
class PdmUiDefaultObjectEditor : PdmUiObjectEditorHandle
{
public:
PdmUiDefaultObjectEditor() {};
~PdmUiDefaultObjectEditor() {}
protected:
virtual QWidget* createWidget(QWidget* parent)
{
m_mainWidget = new QWidget(parent);
m_layout = new QGridLayout();
m_mainWidget->setLayout(m_layout);
return m_mainWidget;
}
virtual void updateUi(QString uiConfigName)
{
PdmUiOrdering config;
m_pdmObject->uiOrdering(uiConfigName, &config);
// Set all fieldViews to be unvisited
std::map<QString, PdmFieldViewHandle*>::iterator it;
for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it)
{
it->second->setField(NULL);
}
// Set all group Boxes to be unvisited
m_newGroupBoxes.clear();
const std::vector<PdmUiItem*>& uiItems = config.uiItems();
recursiveSetupFieldsAndGroups(uiItems, m_mainWidget, m_layout, uiConfigName);
// Remove all fieldViews not mentioned by the configuration from the layout
std::map<QString, PdmFieldViewHandle*>::iterator it;
std::vector< QString > fvhToRemoveFromMap;
for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it)
{
if (it->second->field() == 0)
{
PdmFieldViewHandle* fvh = it->second;
delete fvh;
fvhToRemoveFromMap.push_back(it->first);
}
}
for (size_t i = 0; i < fvhToRemoveFromMap.size(); ++i)
{
m_fieldViews.erase(fvhToRemoveFromMap[i]);
}
// Remove all unmentioned group boxes
std::map<QString, QPointer<QGroupBox> >::iterator itOld;
std::map<QString, QPointer<QGroupBox> >::iterator itNew;
for (itOld = m_groupBoxes.begin(); itOld != m_groupBoxes.end(); ++itOld )
{
itNew = m_newGroupBoxes.find(itOld->first);
if (itNew == m_newGroupBoxes.end())
{
// The old groupBox is not present anymore, get rid of it
if (!itOld->second.isNull()) delete itOld->second;
}
}
m_groupBoxes = m_newGroupBoxes;
}
void recursiveSetupFieldsAndGroups(const std::vector<PdmUiItem*>& uiItems, QWidget* parent, QGridLayout* parentLayout, const QString& uiConfigName )
{
int currentRowIndex = 0;
for (size_t i = 0; i < uiItems.size(); ++i)
{
if (uiItems[i].isGroup())
{
const std::vector<PdmUiItem*>& groupChildren = uiItems[i]->uiItems();
QString groupBoxKey = uiItems[i]->uiName();
QGroupBox* groupBox = NULL;
QGridLayout* groupBoxLayout = NULL;
// Find or create groupBox
std::map<QString, QPointer<QGroupBox> >::iterator it;
it = m_groupBoxes.find(groupBoxKey);
if (it == m_groupBoxes.end())
{
groupBox = new QGroupBox( parent );
groupBox->setTitle(uiItems[i]->uiName());
m_newGroupBoxes[groupBoxKey] = groupBox;
groupBoxLayout = new QGridLayout();
groupBox->setLayout(groupBoxLayout);
}
else
{
groupBox = it->second;
CVF_ASSERT(groupBox);
groupBoxLayout = dynamic_cast<QGridLayout*>(groupBox->layout());
CVF_ASSERT(groupBoxLayout);
m_newGroupBoxes[uiItems[i]->uiName()];
}
/// Insert the group box at the correct position of the parent layout
parentLayout->addWidget(groupBox, currentRowIndex, 0, 1, 2);
recursiveSetupFieldsAndGroups(groupChildren, groupBox, groupBoxLayout);
currentRowIndex++;
}
else
{
PdmFieldHandle* field = dynamic_cast<PdmFieldHandle*>(uiItems[i]);
PdmUiFieldEditorHandle* fvh = NULL;
if (!field->isHidden(uiConfName))
{
// Find or create FieldView
std::map<QString, PdmUiFieldEditorHandle*>::iterator it;
it = m_fieldViews.find(field->keyword());
if (it == m_fieldViews.end())
{
if ( uiItems[i]->editorType(uiConfigName).isDefined() )
{
fvh = PdmFieldViewFactory::instance()->create( uiItems[i]->editorType(uiConfigName));
}
else
{
fvh = PdmFieldViewFactory::instance()->create(typeid(uiItems[i]));
}
m_fieldViews[field->keyword()] = fvh;
fvh->createWidgets(parent);
}
else
{
fvh = it->second;
}
CVF_ASSERT(fvh);
fvh->setField(field);
// Place the widget(s) into the correct parent and layout
QWidget* fieldCombinedWidget = fvh->combinedWidget();
if (combinedWidget)
{
combinedWidget->setParent(parent);
parentLayout->addWidget(combinedWidget, currentRowIndex, 0, 1, 2);
}
else
{
QWidget* fieldEditorWidget = fvh->editorWidget();
QWidget* fieldLabelWidget = fvh->labelWidget();
if (fieldEditorWidget)
{
fieldEditorWidget->setParent(parent); // To make sure this widget has the current group box as parent.
parentLayout->addWidget(fieldEditorWidget, currentRowIndex, 1);
}
if (fieldLabelWidget)
{
fieldLabelWidget->setParent(parent);
parentLayout->addWidget(fieldLabelWidget, currentRowIndex, 0);
}
}
fvh->updateUi(uiConfigName);
currentRowIndex++;
}
}
}
}
private:
std::map<QString, PdmUiFieldEditorHandle*> m_fieldViews;
std::map<QString, QPointer<QGroupBox> > m_groupBoxes;
std::map<QString, QPointer<QGroupBox> > m_newGroupBoxes; ///< used temporarily to store the new(complete) set of group boxes
QPointer<QWidget> m_mainWidget
QGridLayout* m_layout;
};
caf::Factory<PdmUiFieldEditorHandle, type_info>::instance()->registerCreator<PdmUiLineEditor>(typeid(PdmField<QString>));
caf::Factory<PdmUiFieldEditorHandle, type_info>::instance()->registerCreator<PdmUiLineEditor>(typeid(PdmField<int>));
caf::Factory<PdmUiFieldEditorHandle, type_info>::instance()->registerCreator<PdmUiLineEditor>(typeid(PdmField<double>));
caf::Factory<PdmUiFieldEditorHandle, type_info>::instance()->registerCreator<PdmUiLineEditor>(typeid(PdmField<size_t>));
caf::Factory<PdmUiFieldEditorHandle, type_info>::instance()->registerCreator<PdmUiLineEditor>(typeid(PdmUiFileEditor));
class PdmUiLineEditorAttribute : public PdmUiEditorAttribute
{
};
class PdmUiLineEditor : public PdmUiFieldEditorHandle
{
public:
PdmUiLineEditor() {}
virtual ~PdmUiLineEditor() {}
virtual void updateUiValue()
{
m_lineEdit->setText(m_field->uiValue().asString());
};
virtual void updateUi(const QString& uiConfigName)
{
CVF_ASSERT(!m_lineEdit.isNull());
CVF_ASSERT(!m_label.isNull());
QIcon ic = m_field->uiIcon(uiConfigName);
if (!ic.isNull())
{
m_label->setPixmap(ic->pixmap());
}
else
{
m_label->setText(m_field->uiName(uiConfigName));
}
m_label->show( !m_field->isHidden(uiConfigName));
m_lineEdit->setEnabled(!m_field->readOnly(uiConfigName));
m_label->setEnabled(!m_field->readOnly(uiConfigName));
PdmUiLineEditorAttribute leab;
m_field->ownerObject()->defineEditorAttribute(m_field, uiConfigName, &leab);
if (dynamic_cast<PdmField<int>*> (m_field))
{
m_lineEdit->setValidator(QIntValidator());
}
m_lineEdit->setAlignment(leab.alignment);
}
virtual void connectUi()
{
connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(slotEditingFinished()));
}
protected:
virtual QWidget* createEditorWidget(QWidget * parent)
{
m_lineEdit = new QLineEdit(parent);
return m_lineEdit;
}
virtual QWidget* createLabelWidget(QWidget * parent)
{
m_label = new QLabel(parent);
return m_label;
}
protected slots:
void slotEditingFinished()
{
QVariant v;
QString textValue = m_lineEdit->text();
v = textValue;
this->setValueToField(v);
}
private:
QPointer<QLineEdit> m_lineEdit;
QPointer<QLabel> m_label;
};
}
DemoPdmObj::DemoPdmObj()
{
CAF_PDM_InitObject("DemoPdmObj", "", "", "");
CAF_PDM_InitField(&f1, "f1", 1, "Field 1", "", "","");
CAF_PDM_InitField(&f2, "f2", 1, "Field 2", "", "","");
CAF_PDM_InitField(&f3, "f3", 1, "Field 3", "", "","");
CAF_PDM_InitField(&f4, "f4", 1, "Field 4", "", "","");
CAF_PDM_InitField(&f5, "f5", 1, "Field 5", "", "","");
f1.setEditorType(PdmUiFileEditor::editorName()); // "FileEditor" // typeid(PdmUiFileEditor) // "PdmUiFileEditor"
this->addFieldToGroup(configname, 0, &f1);
this->addFieldToGroup(configname, 0, &f2);
this->addFieldToGroup(configname, 1, &f3);
this->addFieldToGroup(configname, 1, &f4);
}
void DemoPdmObj::setUpUIConfiguration(QString uiConfigName, PdmUiOrdering& uiConfig)
{
if (uiConfigName == "DetailsView")
{
uiConfig->add(&f1);
PdmUiGroup* group1 = uiConfig->addNewGroup("Name1");
group1->add(&f2);
PdmUiGroup* group2 = uiConfig->addNewGroup("Name2");
group2->add(&f4);
PdmUiGroup* group3 = group2->addNewGroup("Name3");
group3->add(&f5);
uiConfig->add(&f3);
uiConfig->forgetRemainingFields();
} else if (uiConfigName == "NormalView")
{
} else if (uiConfigName == "AnimationPanel")
{
}
}

View File

@ -38,24 +38,49 @@ QStringList PdmOptionItemInfo::extractUiTexts(const QList<PdmOptionItemInfo>& op
}
//--------------------------------------------------------------------------------------------------
///
/// Finds the indexes into the optionList that the field value(s) corresponds to.
/// In the case where the field is some kind of array, several indexes might be returned
/// The returned bool is true if all the fieldValues were found.
//--------------------------------------------------------------------------------------------------
bool PdmOptionItemInfo::findValue(const QList<PdmOptionItemInfo>& optionList , QVariant fieldValue, unsigned int* indexToValue /*= NULL*/)
bool PdmOptionItemInfo::findValues(const QList<PdmOptionItemInfo>& optionList , QVariant fieldValue, std::vector<unsigned int>& foundIndexes)
{
// Find this field value in the list if present
unsigned int i;
bool foundFieldValue = false;
foundIndexes.clear();
for(i = 0; i < static_cast<unsigned int>(optionList.size()); ++i)
// Find this fieldvalue in the optionlist if present
// First handle lists/arrays of values
if (fieldValue.type() == QVariant::List)
{
if (optionList[i].value == fieldValue)
QList<QVariant> valuesSelectedInField = fieldValue.toList();
if (valuesSelectedInField.size())
{
foundFieldValue = true;
break;
for (int i= 0 ; i < valuesSelectedInField.size(); ++i)
{
for (unsigned int opIdx = 0; opIdx < static_cast<unsigned int>(optionList.size()); ++opIdx)
{
if (valuesSelectedInField[i] == optionList[opIdx].value)
{
foundIndexes.push_back(opIdx);
}
}
}
}
return (static_cast<size_t>(valuesSelectedInField.size()) <= foundIndexes.size());
}
else // Then handle single value fields
{
for(unsigned int opIdx = 0; opIdx < static_cast<unsigned int>(optionList.size()); ++opIdx)
{
if (optionList[opIdx].value == fieldValue)
{
foundIndexes.push_back(opIdx);
break;
}
}
return (foundIndexes.size() > 0);
}
if (indexToValue) *indexToValue = i;
return foundFieldValue;
}
@ -172,6 +197,21 @@ QString PdmUiItem::uiEditorTypeName(const QString& uiConfigName) const
return QString();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Qt::Alignment PdmUiItem::labelAlignment(QString uiConfigName) const
{
const PdmUiItemInfo* conInfo = configInfo(uiConfigName);
const PdmUiItemInfo* defInfo = defaultInfo();
const PdmUiItemInfo* sttInfo = m_staticItemInfo;
if (conInfo) return conInfo->m_labelAlignment;
if (defInfo) return defInfo->m_labelAlignment;
if (sttInfo) return sttInfo->m_labelAlignment;
return Qt::AlignLeft;
}
//--------------------------------------------------------------------------------------------------
///

View File

@ -40,7 +40,7 @@ public:
PdmUiItemInfo( QString uiName, QIcon icon = QIcon(), QString toolTip = "", QString whatsThis = "")
: m_uiName(uiName), m_icon(icon), m_toolTip(toolTip), m_whatsThis(whatsThis),
m_editorTypeName(""), m_isHidden(false) , m_isReadOnly(false)
m_editorTypeName(""), m_isHidden(false), m_isReadOnly(false), m_labelAlignment(Qt::AlignLeft)
{ }
private:
@ -52,6 +52,7 @@ private:
QString m_editorTypeName; ///< Use this exact type of editor to edit this UiItem
int m_isHidden; ///< UiItem should be hidden. -1 means not set
int m_isReadOnly; ///< UiItem should be insensitive, or read only. -1 means not set.
Qt::Alignment m_labelAlignment;
};
//==================================================================================================
@ -61,7 +62,7 @@ private:
class PdmOptionItemInfo
{
public:
PdmOptionItemInfo( QString anOptionUiText, QVariant aValue = QVariant(), bool anIsDimmed = false, QIcon anIcon = QIcon() )
PdmOptionItemInfo( QString anOptionUiText, QVariant aValue, bool anIsDimmed = false, QIcon anIcon = QIcon() )
: value(aValue), optionUiText(anOptionUiText), isDimmed(anIsDimmed), icon(anIcon)
{}
@ -71,10 +72,11 @@ public:
QVariant value;
// Static utility methods to handle QList of PdmOptionItemInfo
// Please regard as private to the PDM system
static QStringList extractUiTexts(const QList<PdmOptionItemInfo>& optionList );
static bool findValue (const QList<PdmOptionItemInfo>& optionList , QVariant fieldValue,
unsigned int* indexToValue = NULL);
static bool findValues (const QList<PdmOptionItemInfo>& optionList , QVariant fieldValue,
std::vector<unsigned int>& foundIndexes);
};
class PdmUiEditorHandle;
@ -114,6 +116,9 @@ public:
bool isUiReadOnly(QString uiConfigName = "");
void setUiReadOnly(bool isReadOnly, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_isReadOnly = isReadOnly; }
Qt::Alignment labelAlignment(QString uiConfigName = "") const;
void setLabelAlignment(Qt::Alignment alignment, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_labelAlignment = alignment; }
QString uiEditorTypeName(const QString& uiConfigName) const;
void setUiEditorTypeName(const QString& editorTypeName, QString uiConfigName = "") { m_configItemInfos[uiConfigName].m_editorTypeName = editorTypeName; }

View File

@ -24,7 +24,9 @@ set( QOBJECT_HEADERS
cafPdmUiPropertyView.h
)
qt4_wrap_cpp( MOC_FILES_CPP ${QOBJECT_HEADERS} )
if ( (${CMAKE_VERSION} VERSION_LESS 2.8.6) OR (NOT CMAKE_AUTOMOC) )
qt4_wrap_cpp( MOC_FILES_CPP ${QOBJECT_HEADERS} )
endif()
add_library( ${PROJECT_NAME}

View File

@ -87,7 +87,7 @@ QWidget* PdmUiColorEditor::createEditorWidget(QWidget * parent)
QWidget* placeholder = new QWidget(parent);
QHBoxLayout* layout = new QHBoxLayout(placeholder);
layout->setMargin(0);
layout->setContentsMargins(0,0,0,0);
layout->setSpacing(0);
m_colorPixmapLabel = new QLabel(parent);

View File

@ -59,20 +59,25 @@ void PdmUiComboBoxEditor::configureAndUpdateUi(const QString& uiConfigName)
m_comboBox->setEnabled(!field()->isUiReadOnly(uiConfigName));
// Demo code for attribute retreival when becoming relevant
// PdmUiComboBoxEditorAttribute attributes;
// field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes);
bool fromMenuOnly = false;
QList<PdmOptionItemInfo> enumNames = field()->valueOptions(&fromMenuOnly);
if (!enumNames.isEmpty() && fromMenuOnly == true)
QList<PdmOptionItemInfo> options = field()->valueOptions(&fromMenuOnly);
m_comboBox->blockSignals(true);
m_comboBox->clear();
if (!options.isEmpty())
{
m_comboBox->blockSignals(true);
m_comboBox->clear();
m_comboBox->addItems(PdmOptionItemInfo::extractUiTexts(enumNames));
m_comboBox->blockSignals(false);
m_comboBox->addItems(PdmOptionItemInfo::extractUiTexts(options));
m_comboBox->setCurrentIndex(field()->uiValue().toInt());
}
PdmUiComboBoxEditorAttribute attributes;
field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes);
m_comboBox->setCurrentIndex(field()->uiValue().toInt());
else
{
m_comboBox->addItem(field()->uiValue().toString());
m_comboBox->setCurrentIndex(0);
}
m_comboBox->blockSignals(false);
}

View File

@ -26,6 +26,8 @@
#include "cafPdmUiComboBoxEditor.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiListEditor.h"
#include <QWidget>
#include <QGridLayout>
@ -45,7 +47,30 @@ CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, QString);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, int);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, double);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiLineEditor, float);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector<QString>);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector<int>);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector<unsigned int>);
CAF_PDM_UI_REGISTER_DEFAULT_FIELD_EDITOR(PdmUiListEditor, std::vector<float>);
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiDefaultObjectEditor::PdmUiDefaultObjectEditor()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiDefaultObjectEditor::~PdmUiDefaultObjectEditor()
{
}
//--------------------------------------------------------------------------------------------------
///
@ -54,7 +79,9 @@ QWidget* PdmUiDefaultObjectEditor::createWidget(QWidget* parent)
{
m_mainWidget = new QWidget(parent);
m_layout = new QGridLayout();
m_layout->setContentsMargins(0, 0, 0, 0);
m_mainWidget->setLayout(m_layout);
return m_mainWidget;
}
@ -173,25 +200,34 @@ void PdmUiDefaultObjectEditor::recursiveSetupFieldsAndGroups(const std::vector<P
if (!field->isUiHidden(uiConfigName))
{
// Find or create FieldView
// Find or create FieldEditor
std::map<QString, PdmUiFieldEditorHandle*>::iterator it;
it = m_fieldViews.find(field->keyword());
if (it == m_fieldViews.end())
{
// If editor type is specified, find in factory
if ( !uiItems[i]->uiEditorTypeName(uiConfigName).isEmpty() )
{
fieldEditor = caf::Factory<PdmUiFieldEditorHandle, QString>::instance()->create(field->uiEditorTypeName(uiConfigName));
}
else
{
{
// Find the default field editor
QString editorTypeName = qStringTypeName(*field);
bool useOptionsOnly = true;
QList<PdmOptionItemInfo> options = field->valueOptions( &useOptionsOnly);
if (!options.empty())
// Handle a single value field with valueOptions: Make a combobox
if (field->uiValue().type() != QVariant::List)
{
editorTypeName = caf::PdmUiComboBoxEditor::uiEditorTypeName();
bool useOptionsOnly = true;
QList<PdmOptionItemInfo> options = field->valueOptions( &useOptionsOnly);
if (!options.empty())
{
editorTypeName = caf::PdmUiComboBoxEditor::uiEditorTypeName();
}
}
fieldEditor = caf::Factory<PdmUiFieldEditorHandle, QString>::instance()->create(editorTypeName);
@ -225,17 +261,29 @@ void PdmUiDefaultObjectEditor::recursiveSetupFieldsAndGroups(const std::vector<P
QWidget* fieldEditorWidget = fieldEditor->editorWidget();
QWidget* fieldLabelWidget = fieldEditor->labelWidget();
if (fieldEditorWidget)
{
fieldEditorWidget->setParent(parent); // To make sure this widget has the current group box as parent.
parentLayout->addWidget(fieldEditorWidget, currentRowIndex, 1, Qt::AlignTop);
}
bool labelOnTop = field->labelAlignment(uiConfigName) & Qt::AlignTop;
if (fieldLabelWidget)
{
fieldLabelWidget->setParent(parent);
parentLayout->addWidget(fieldLabelWidget, currentRowIndex, 0, Qt::AlignTop);
// Label widget will span two columns if aligned on top
int colSpan = labelOnTop ? 2 : 1;
parentLayout->addWidget(fieldLabelWidget, currentRowIndex, 0, 1, colSpan, Qt::AlignTop);
if (labelOnTop) currentRowIndex++;
}
if (fieldEditorWidget)
{
fieldEditorWidget->setParent(parent); // To make sure this widget has the current group box as parent.
// Label widget will span two columns if aligned on top
int colSpan = labelOnTop ? 2 : 1;
int colIndex = labelOnTop ? 0 : 1;
parentLayout->addWidget(fieldEditorWidget, currentRowIndex, colIndex, 1, colSpan, Qt::AlignTop);
}
}
fieldEditor->updateUi(uiConfigName);

View File

@ -39,8 +39,8 @@ class PdmUiItem;
class PdmUiDefaultObjectEditor : public PdmUiObjectEditorHandle
{
public:
PdmUiDefaultObjectEditor() {}
~PdmUiDefaultObjectEditor() {}
PdmUiDefaultObjectEditor();
~PdmUiDefaultObjectEditor();
protected:
virtual QWidget* createWidget(QWidget* parent);

View File

@ -81,7 +81,7 @@ QWidget* PdmUiFilePathEditor::createEditorWidget(QWidget * parent)
QWidget* placeholder = new QWidget(parent);
QHBoxLayout* layout = new QHBoxLayout(placeholder);
layout->setMargin(0);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
m_lineEdit = new QLineEdit(parent);

View File

@ -36,6 +36,8 @@
#include <assert.h>
#include "..\src\corelib\kernel\qcoreevent.h"
#include "..\src\gui\kernel\qevent.h"
//==================================================================================================
/// Helper class used to override flags to disable editable items
@ -43,12 +45,23 @@
class MyStringListModel : public QStringListModel
{
public:
MyStringListModel(QObject *parent = 0) : QStringListModel(parent) { }
MyStringListModel(QObject *parent = 0) : m_isItemsEditable(false), QStringListModel(parent) { }
virtual Qt::ItemFlags flags (const QModelIndex& index) const
{
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
if (m_isItemsEditable)
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
else
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
void setItemsEditable(bool isEditable)
{
m_isItemsEditable = isEditable;
}
private:
bool m_isItemsEditable;
};
@ -65,7 +78,7 @@ CAF_PDM_UI_FIELD_EDITOR_SOURCE_INIT(PdmUiListEditor);
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PdmUiListEditor::PdmUiListEditor()
PdmUiListEditor::PdmUiListEditor(): m_optionsOnly(false)
{
}
@ -94,7 +107,8 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName)
}
else
{
m_label->setText(field()->uiName(uiConfigName));
QString uiName = field()->uiName(uiConfigName);
m_label->setText(uiName);
}
m_label->setVisible(!field()->isUiHidden(uiConfigName));
@ -102,24 +116,74 @@ void PdmUiListEditor::configureAndUpdateUi(const QString& uiConfigName)
m_listView->setEnabled(!field()->isUiReadOnly(uiConfigName));
PdmUiListEditorAttribute attributes;
field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes);
/// Demo code Not used yet
// PdmUiListEditorAttribute attributes;
// field()->ownerObject()->editorAttribute(field(), uiConfigName, &attributes);
bool fromMenuOnly = false;
QList<PdmOptionItemInfo> enumNames = field()->valueOptions(&fromMenuOnly);
if (!enumNames.isEmpty() && fromMenuOnly == true)
MyStringListModel* strListModel = dynamic_cast<MyStringListModel*>(m_model.data());
assert(strListModel);
m_options = field()->valueOptions(&m_optionsOnly);
if (!m_options.isEmpty())
{
QStringList texts = PdmOptionItemInfo::extractUiTexts(enumNames);
m_model->setStringList(texts);
assert(m_optionsOnly); // Handling Additions on the fly not implemented
strListModel->setItemsEditable(false);
QModelIndex currentItem = m_listView->selectionModel()->currentIndex();
QStringList texts = PdmOptionItemInfo::extractUiTexts(m_options);
strListModel->setStringList(texts);
int col = 0;
int row = field()->uiValue().toInt();
QModelIndex mi = m_model->index(row, col);
QVariant fieldValue = field()->uiValue();
if (fieldValue.type() == QVariant::Int || fieldValue.type() == QVariant::UInt)
{
int col = 0;
int row = field()->uiValue().toInt();
QModelIndex mi = strListModel->index(row, col);
m_listView->selectionModel()->blockSignals(true);
m_listView->setSelectionMode(QAbstractItemView::SingleSelection);
m_listView->selectionModel()->select(mi, QItemSelectionModel::SelectCurrent);
m_listView->selectionModel()->setCurrentIndex(mi, QItemSelectionModel::SelectCurrent);
m_listView->selectionModel()->blockSignals(false);
}
else if (fieldValue.type() == QVariant::List)
{
QList<QVariant> valuesSelectedInField = fieldValue.toList();
QItemSelection selection;
for (int i= 0 ; i < valuesSelectedInField.size(); ++i)
{
QModelIndex mi = strListModel->index(valuesSelectedInField[i].toInt(), 0);
selection.append(QItemSelectionRange (mi));
}
m_listView->selectionModel()->blockSignals(true);
m_listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_listView->selectionModel()->select(selection, QItemSelectionModel::Select);
m_listView->selectionModel()->setCurrentIndex(currentItem, QItemSelectionModel::Current);
m_listView->selectionModel()->blockSignals(false);
}
}
else
{
m_listView->selectionModel()->blockSignals(true);
m_listView->selectionModel()->select(mi, QItemSelectionModel::SelectCurrent);
m_listView->selectionModel()->setCurrentIndex(mi, QItemSelectionModel::SelectCurrent);
QItemSelection selection = m_listView->selectionModel()->selection();
QModelIndex currentItem = m_listView->selectionModel()->currentIndex();
QVariant fieldValue = field()->uiValue();
QStringList texts = fieldValue.toStringList();
texts.push_back("");
strListModel->setStringList(texts);
strListModel->setItemsEditable(true);
m_listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_listView->selectionModel()->select(selection, QItemSelectionModel::Select);
m_listView->selectionModel()->setCurrentIndex(currentItem, QItemSelectionModel::Current);
m_listView->selectionModel()->blockSignals(false);
}
@ -137,6 +201,8 @@ QWidget* PdmUiListEditor::createEditorWidget(QWidget * parent)
m_listView->setModel(m_model);
connect(m_listView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection& )), this, SLOT(slotSelectionChanged(const QItemSelection&, const QItemSelection& )));
connect(m_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(slotListItemEdited(const QModelIndex&, const QModelIndex&)));
m_listView->installEventFilter(this);
return m_listView;
}
@ -155,19 +221,98 @@ QWidget* PdmUiListEditor::createLabelWidget(QWidget * parent)
//--------------------------------------------------------------------------------------------------
void PdmUiListEditor::slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
{
if (selected.indexes().size() == 1)
{
QModelIndex mi = selected.indexes()[0];
int col = mi.column();
int row = mi.row();
QVariant v;
v = row;
QVariant uintValue(v.toUInt());
if (m_options.isEmpty()) return;
this->setValueToField(uintValue);
//QModelIndexList idxList = selected.indexes();
QModelIndexList idxList = m_listView->selectionModel()->selectedIndexes();
QVariant fieldValue = field()->uiValue();
if (fieldValue.type() == QVariant::Int || fieldValue.type() == QVariant::UInt)
{
if (idxList.size() >= 1)
{
if (idxList[0].row() < m_options.size())
{
this->setValueToField(QVariant(static_cast<unsigned int>(idxList[0].row())));
}
}
}
else if (fieldValue.type() == QVariant::List)
{
QList<QVariant> valuesToSetInField;
for (int i = 0; i < idxList.size(); ++i)
{
if (idxList[i].row() < m_options.size())
{
valuesToSetInField.push_back(QVariant(static_cast<unsigned int>(idxList[i].row())));
}
}
this->setValueToField(valuesToSetInField);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void PdmUiListEditor::slotListItemEdited(const QModelIndex&, const QModelIndex&)
{
if (m_optionsOnly) return;
assert(m_options.isEmpty()); // Not supported yet
QStringList uiList = m_model->stringList();
// Remove dummy elements specifically at the end of list.
QStringList result;
foreach (const QString &str, uiList)
{
if (str != "" && str != " ") result += str;
}
this->setValueToField(result);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool PdmUiListEditor::eventFilter(QObject * listView, QEvent * event)
{
if (listView == m_listView && event->type() == QEvent::KeyPress)
{
if (m_optionsOnly) return false;
assert(m_options.isEmpty()); // Not supported yet
QKeyEvent* keyEv = static_cast<QKeyEvent*>(event);
if (keyEv->key() == Qt::Key_Delete || keyEv->key() == Qt::Key_Backspace )
{
QModelIndexList idxList = m_listView->selectionModel()->selectedIndexes();
bool isAnyDeleted = false;
while(idxList.size())
{
m_model->removeRow(idxList[0].row());
idxList = m_listView->selectionModel()->selectedIndexes();
isAnyDeleted = true;
}
if (isAnyDeleted)
{
QStringList uiList = m_model->stringList();
// Remove dummy elements specifically at the end of list.
QStringList result;
foreach (const QString &str, uiList)
{
if (str != "" && str != " ") result += str;
}
this->setValueToField(result);
}
return true;
}
}
return false;
}
} // end namespace caf

View File

@ -26,6 +26,7 @@ class QStringListModel;
class QItemSelection;
class QListView;
class QLabel;
class QModelIndex;
namespace caf
{
@ -54,14 +55,22 @@ protected:
virtual QWidget* createEditorWidget(QWidget * parent);
virtual QWidget* createLabelWidget(QWidget * parent);
virtual void configureAndUpdateUi(const QString& uiConfigName);
virtual bool eventFilter ( QObject * listView, QEvent * event ); // To catch delete key press in list view.
protected slots:
void slotSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected );
void slotListItemEdited(const QModelIndex&, const QModelIndex&);
private:
QPointer<QListView> m_listView;
QPointer<QLabel> m_label;
QPointer<QStringListModel> m_model;
QList<PdmOptionItemInfo> m_options;
bool m_optionsOnly;
};

View File

@ -37,7 +37,7 @@ PdmUiPropertyView::PdmUiPropertyView(QWidget* parent, Qt::WindowFlags f)
{
m_layout = new QVBoxLayout(this);
m_layout->insertStretch(1, 1);
m_layout->setMargin(0);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setSpacing(0);
setLayout(m_layout);
@ -110,7 +110,8 @@ void PdmUiPropertyView::showProperties(caf::PdmObject* object)
//m_currentObjectView = PdmObjViewFactory::instance()->create(object->editorType(m_uiConfigName));
if (!m_currentObjectView)
{
m_currentObjectView = new PdmUiDefaultObjectEditor();
PdmUiDefaultObjectEditor* defaultEditor = new PdmUiDefaultObjectEditor();
m_currentObjectView = defaultEditor;
}
// Create widget to handle this
@ -126,6 +127,15 @@ void PdmUiPropertyView::showProperties(caf::PdmObject* object)
m_currentObjectView->updateUi(m_uiConfigName);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmObject* PdmUiPropertyView::currentObject()
{
if (!m_currentObjectView) return NULL;
return m_currentObjectView->pdmObject();
}
} //End of namespace caf

View File

@ -41,7 +41,7 @@ public:
~PdmUiPropertyView();
void setUiConfigurationName(QString uiConfigName);
caf::PdmObject* currentObject();
public slots:
void showProperties(caf::PdmObject* object);

View File

@ -11,7 +11,9 @@ set( QOBJECT_HEADERS
cafViewer.h
)
qt4_wrap_cpp( MOC_FILES_CPP ${QOBJECT_HEADERS} )
if ( (${CMAKE_VERSION} VERSION_LESS 2.8.6) OR (NOT CMAKE_AUTOMOC) )
qt4_wrap_cpp( MOC_FILES_CPP ${QOBJECT_HEADERS} )
endif()
add_library( ${PROJECT_NAME}

View File

@ -69,7 +69,7 @@ caf::Viewer::Viewer(const QGLFormat& format, QWidget* parent)
QHBoxLayout* layout = new QHBoxLayout(m_layoutWidget);
layout->addWidget(this);
layout->setMargin(0);
layout->setContentsMargins(0, 0, 0, 0);
setAutoFillBackground(false);
setMouseTracking(true);
@ -378,6 +378,7 @@ void caf::Viewer::paintEvent(QPaintEvent* event)
cvf::ref<cvf::OpenGLContext> myOglContext = cvfOpenGLContext();
CVF_CHECK_OGL(myOglContext.p());
CVF_ASSERT(myOglContext->isContextValid());
QPainter painter(this);
@ -662,6 +663,23 @@ void caf::Viewer::debugShowRenderingSequencePartNames()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void caf::Viewer::enableNavigationPolicy(bool enable)
{
m_navigationPolicyEnabled = enable;
if (enable && m_navigationPolicy.notNull()) m_navigationPolicy->init();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QSize caf::Viewer::sizeHint() const
{
return QSize(500, 400);
}
void caf::Viewer::enableForcedImmediateMode(bool enable)
{
m_mainRendering->renderEngine()->enableForcedImmediateMode(enable);

View File

@ -88,7 +88,7 @@ public:
// Set the navigation policy
void setNavigationPolicy(caf::NavigationPolicy* navigationPolicy);
void enableNavigationPolicy(bool enable) { m_navigationPolicyEnabled = enable; }
void enableNavigationPolicy(bool enable);
void setView( const cvf::Vec3d& alongDirection, const cvf::Vec3d& upDirection );
void zoomAll();
@ -114,6 +114,9 @@ public slots:
virtual void slotEndAnimation();
int currentFrameIndex();
public:
virtual QSize sizeHint() const;
protected:
// Method to override if painting directly on the OpenGl Canvas is needed.
virtual void paintOverlayItems(QPainter* painter) {};