From 7f72dcbb4adbf6969ca04bf1e00fe71366048703 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Tue, 12 Sep 2017 08:10:51 +0200 Subject: [PATCH] #1883 AppFwk : Use UiWidgetBAsedObjectEditor from CustomObjectEditor --- .../cafTestApplication/CustomObjectEditor.cpp | 616 ++++-------------- .../cafTestApplication/CustomObjectEditor.h | 93 +-- .../cafTestApplication/MainWindow.cpp | 2 +- 3 files changed, 155 insertions(+), 556 deletions(-) diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.cpp b/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.cpp index 9113beed03..41f0435b0d 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.cpp +++ b/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.cpp @@ -1,7 +1,7 @@ //################################################################################################## // // Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS +// Copyright (C) 2017 Ceetron Solutions AS // // This library may be used under the terms of either the GNU General Public License or // the GNU Lesser General Public License as follows: @@ -34,25 +34,31 @@ // //################################################################################################## - #include "CustomObjectEditor.h" -#include "cafPdmField.h" -#include "cafPdmObject.h" -#include "cafPdmProxyValueField.h" -#include "cafPdmUiCheckBoxEditor.h" -#include "cafPdmUiComboBoxEditor.h" -#include "cafPdmUiDateEditor.h" -#include "cafPdmUiFieldEditorHandle.h" -#include "cafPdmUiFieldEditorHelper.h" -#include "cafPdmUiLineEditor.h" -#include "cafPdmUiListEditor.h" -#include "cafPdmUiOrdering.h" +#include "cafPdmUiGroup.h" +#include "QMinimizePanel.h" + +#include #include -#include -#include -#include + + +//================================================================================================== +/// +//================================================================================================== +class WidgetCellIds +{ +public: + WidgetCellIds(QWidget* w, const std::vector& occupiedCellIds) + : m_customWidget(w), + m_customWidgetCellIds(occupiedCellIds) + { + } + + QWidget* m_customWidget; + std::vector m_customWidgetCellIds; +}; namespace caf @@ -64,7 +70,7 @@ namespace caf //-------------------------------------------------------------------------------------------------- CustomObjectEditor::CustomObjectEditor() { - m_columnCount = 2; + m_columnCount = 3; m_rowCount = 2; } @@ -73,30 +79,52 @@ CustomObjectEditor::CustomObjectEditor() //-------------------------------------------------------------------------------------------------- CustomObjectEditor::~CustomObjectEditor() { - // If there are field editor present, the usage of this editor has not cleared correctly - // The intended usage is to call the method setPdmObject(NULL) before closing the dialog - CAF_ASSERT(m_fieldViews.size() == 0); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::defineGrid(int rows, int columns) +void CustomObjectEditor::defineGridLayout(int rowCount, int columnCount) { - m_rowCount = rows; - m_columnCount = columns; + m_rowCount = rowCount; + m_columnCount = columnCount; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::addWidget(QWidget* w, int row, int column, int rowSpan, int columnSpan, Qt::Alignment /*= 0*/) +void CustomObjectEditor::addWidget(QWidget* w, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment /*= 0*/) { CAF_ASSERT(isAreaAvailable(row, column, rowSpan, columnSpan)); - m_customWidgetAreas.push_back(WidgetAndArea(w, CustomObjectEditor::cellIds(row, column, rowSpan, columnSpan))); + // The ownership of item is transferred to the layout, and it's the layout's responsibility to delete it. - m_layout->addWidget(w, row, column, rowSpan, columnSpan); + m_customWidgetAreas.push_back(WidgetCellIds(w, CustomObjectEditor::cellIds(row, column, rowSpan, columnSpan))); + + m_layout->addWidget(w, row, column, rowSpan, columnSpan, alignment); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CustomObjectEditor::removeWidget(QWidget* w) +{ + size_t indexToRemove = size_t(-1); + for (size_t i = 0; i < m_customWidgetAreas.size(); i++) + { + if (w == m_customWidgetAreas[i].m_customWidget) + { + indexToRemove = i; + break; + } + } + + if (indexToRemove != size_t(-1)) + { + m_layout->removeWidget(w); + + m_customWidgetAreas.erase(m_customWidgetAreas.begin() + indexToRemove); + } } //-------------------------------------------------------------------------------------------------- @@ -104,7 +132,62 @@ void CustomObjectEditor::addWidget(QWidget* w, int row, int column, int rowSpan, //-------------------------------------------------------------------------------------------------- void CustomObjectEditor::addBlankCell(int row, int column) { - m_customWidgetAreas.push_back(WidgetAndArea(nullptr, CustomObjectEditor::cellIds(row, column, 1, 1))); + m_customWidgetAreas.push_back(WidgetCellIds(nullptr, CustomObjectEditor::cellIds(row, column, 1, 1))); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QWidget* CustomObjectEditor::createWidget(QWidget* parent) +{ + QWidget* m_mainWidget = PdmUiWidgetBasedObjectEditor::createWidget(parent); + + m_layout = new QGridLayout(); + m_layout->setContentsMargins(0, 0, 0, 0); + m_mainWidget->setLayout(m_layout); + + return m_mainWidget; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CustomObjectEditor::setupFieldsAndGroups(const std::vector& uiItems, QWidget* parent, const QString& uiConfigName) +{ + setupTopLevelGroupsInGridLayout(uiItems, parent, m_layout, uiConfigName); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CustomObjectEditor::setupTopLevelGroupsInGridLayout(const std::vector& uiItems, QWidget* parent, QGridLayout* parentLayout, const QString& uiConfigName) +{ + resetCellId(); + + QWidget* previousTabOrderWidget = NULL; + + for (size_t i = 0; i < uiItems.size(); ++i) + { + if (uiItems[i]->isUiHidden(uiConfigName)) continue; + + if (uiItems[i]->isUiGroup()) + { + PdmUiGroup* group = static_cast(uiItems[i]); + QMinimizePanel* groupBox = findOrCreateGroupBox(group, parent, uiConfigName); + + /// Insert the group box at the correct position of the parent layout + int nextCellId = getNextAvailableCellId(); + std::pair rowCol = rowAndColumn(nextCellId); + parentLayout->addWidget(groupBox, rowCol.first, rowCol.second, 1, 1); + + QGridLayout* groupBoxLayout = this->groupBoxLayout(groupBox); + + const std::vector& groupChildren = group->uiItems(); + recursiveSetupFieldsAndGroups(groupChildren, groupBox->contentFrame(), groupBoxLayout, uiConfigName); + } + + // NB! Only groups at top level are handled, fields at top level are not added to layout + } } //-------------------------------------------------------------------------------------------------- @@ -115,7 +198,7 @@ bool CustomObjectEditor::isAreaAvailable(int row, int column, int rowSpan, int c auto candidateCells = CustomObjectEditor::cellIds(row, column, rowSpan, columnSpan); for (auto candidateCell : candidateCells) { - if (isCellOccupied(candidateCell)) + if (!isCellIdAvailable(candidateCell)) { return false; } @@ -130,7 +213,7 @@ bool CustomObjectEditor::isAreaAvailable(int row, int column, int rowSpan, int c //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool CustomObjectEditor::isCellOccupied(int cellId) const +bool CustomObjectEditor::isCellIdAvailable(int cellId) const { for (auto customArea : m_customWidgetAreas) { @@ -138,161 +221,29 @@ bool CustomObjectEditor::isCellOccupied(int cellId) const { if (cellId == occupiedCell) { - return true; + return false; } } } - return false; + return true; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::removeWidget(QWidget* w) +void CustomObjectEditor::resetCellId() { - size_t indexToRemove = 10000; - for (size_t i = 0; i < m_customWidgetAreas.size(); i++) - { - if (w == m_customWidgetAreas[i].m_customWidget) - { - indexToRemove = i; - break; - } - } - - if (indexToRemove < 10000) - { - m_layout->removeWidget(w); - - m_customWidgetAreas.erase(m_customWidgetAreas.begin() + indexToRemove); - } + m_currentCellId = 0; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QWidget* CustomObjectEditor::createWidget(QWidget* parent) +std::pair CustomObjectEditor::rowAndColumn(int cellId) const { - m_mainWidget = new QWidget(parent); - m_layout = new QGridLayout(); - m_layout->setContentsMargins(0, 0, 0, 0); - m_mainWidget->setLayout(m_layout); - - return m_mainWidget; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::configureAndUpdateUi(const QString& uiConfigName) -{ - PdmUiOrdering config; - if (pdmObject()) - { - caf::PdmUiObjectHandle* uiObject = uiObj(pdmObject()); - if (uiObject) - { - uiObject->uiOrdering(uiConfigName, config); - } - } - - // Set all fieldViews to be unvisited - std::map::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& uiItems = config.uiItems(); - - // TODO: Review that is it not breaking anything to have fields with identical keywords - // { - // std::set fieldKeywordNames; - // std::set groupNames; - // - // recursiveVerifyUniqueNames(uiItems, uiConfigName, &fieldKeywordNames, &groupNames); - // } - - recursiveSetupFieldsAndGroupsRoot(uiItems, m_mainWidget, m_layout, uiConfigName); - - // Remove all fieldViews not mentioned by the configuration from the layout - - std::vector< PdmFieldHandle* > fvhToRemoveFromMap; - for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it) - { - if (it->second->field() == 0) - { - PdmUiFieldEditorHandle* 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 >::iterator itOld; - std::map >::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 CustomObjectEditor::cleanupBeforeSettingPdmObject() -{ - std::map::iterator it; - for (it = m_fieldViews.begin(); it != m_fieldViews.end(); ++it) - { - PdmUiFieldEditorHandle* fvh = it->second; - delete fvh; - } - m_fieldViews.clear(); - - m_newGroupBoxes.clear(); - - std::map >::iterator groupIt; - for (groupIt = m_groupBoxes.begin(); groupIt != m_groupBoxes.end(); ++groupIt) - { - if (!groupIt->second.isNull()) groupIt->second->deleteLater(); - } - - m_groupBoxes.clear(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::resetDynamicCellCounter() -{ - m_dynamicCellIndex = 0; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::pair CustomObjectEditor::rowAndCell(int cellId) const -{ - int column = cellId % m_columnCount; - int row = cellId / m_columnCount; + int column = cellId % m_columnCount; + int row = cellId / m_columnCount; return std::make_pair(row, column); } @@ -310,18 +261,18 @@ int CustomObjectEditor::cellId(int row, int column) const //-------------------------------------------------------------------------------------------------- int CustomObjectEditor::getNextAvailableCellId() { - while (isCellOccupied(m_dynamicCellIndex) && m_dynamicCellIndex < (m_rowCount * m_columnCount)) + while (!isCellIdAvailable(m_currentCellId) && m_currentCellId < (m_rowCount * m_columnCount)) { - m_dynamicCellIndex++; + m_currentCellId++; } - if (isCellOccupied(m_dynamicCellIndex)) + if (!isCellIdAvailable(m_currentCellId)) { return -1; } else { - return m_dynamicCellIndex++; + return m_currentCellId++; } } @@ -343,326 +294,5 @@ std::vector CustomObjectEditor::cellIds(int row, int column, int rowSpan, i return cells; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::recursiveSetupFieldsAndGroupsRoot(const std::vector& uiItems, QWidget* parent, QGridLayout* parentLayout, const QString& uiConfigName) -{ - resetDynamicCellCounter(); - - QWidget* previousTabOrderWidget = NULL; - - for (size_t i = 0; i < uiItems.size(); ++i) - { - if (uiItems[i]->isUiHidden(uiConfigName)) continue; - - if (uiItems[i]->isUiGroup()) - { - PdmUiGroup* group = static_cast(uiItems[i]); - const std::vector& groupChildren = group->uiItems(); - - QString groupBoxKey = group->keyword(); - QMinimizePanel* groupBox = NULL; - QGridLayout* groupBoxLayout = NULL; - - // Find or create groupBox - std::map >::iterator it; - it = m_groupBoxes.find(groupBoxKey); - - if (it == m_groupBoxes.end()) - { - groupBox = new QMinimizePanel(parent); - groupBox->setTitle(group->uiName(uiConfigName)); - groupBox->setObjectName(group->keyword()); - groupBoxLayout = new QGridLayout(); - groupBox->contentFrame()->setLayout(groupBoxLayout); - connect(groupBox, SIGNAL(expandedChanged(bool)), this, SLOT(groupBoxExpandedStateToggled(bool))); - - m_newGroupBoxes[groupBoxKey] = groupBox; - } - else - { - groupBox = it->second; - CAF_ASSERT(groupBox); - - groupBoxLayout = dynamic_cast(groupBox->contentFrame()->layout()); - CAF_ASSERT(groupBoxLayout); - - m_newGroupBoxes[groupBoxKey] = groupBox; - } - - /// Insert the group box at the correct position of the parent layout - - int nextCellId = getNextAvailableCellId(); - std::pair rowCol = rowAndCell(nextCellId); - parentLayout->addWidget(groupBox, rowCol.first, rowCol.second, 1, 1); - - // Set Expanded state - bool isExpanded = isUiGroupExpanded(group); - groupBox->setExpanded(isExpanded); - - // Update the title to be able to support dynamic group names - groupBox->setTitle(group->uiName(uiConfigName)); - - recursiveSetupFieldsAndGroups(groupChildren, groupBox->contentFrame(), groupBoxLayout, uiConfigName); - } - } - - // TODO : how to handle fields at top level - //recursiveSetupFieldsAndGroups(uiItems, parent, parentLayout, uiConfigName); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::recursiveSetupFieldsAndGroups(const std::vector& uiItems, QWidget* parent, QGridLayout* parentLayout, const QString& uiConfigName) -{ - int currentRowIndex = 0; - QWidget* previousTabOrderWidget = NULL; - - for (size_t i = 0; i < uiItems.size(); ++i) - { - if (uiItems[i]->isUiHidden(uiConfigName)) continue; - - if (uiItems[i]->isUiGroup()) - { - PdmUiGroup* group = static_cast(uiItems[i]); - const std::vector& groupChildren = group->uiItems(); - - QString groupBoxKey = group->keyword(); - QMinimizePanel* groupBox = NULL; - QGridLayout* groupBoxLayout = NULL; - - // Find or create groupBox - std::map >::iterator it; - it = m_groupBoxes.find(groupBoxKey); - - if (it == m_groupBoxes.end()) - { - groupBox = new QMinimizePanel( parent ); - groupBox->setTitle(group->uiName(uiConfigName)); - groupBox->setObjectName(group->keyword()); - groupBoxLayout = new QGridLayout(); - groupBox->contentFrame()->setLayout(groupBoxLayout); - connect(groupBox, SIGNAL(expandedChanged(bool)), this, SLOT(groupBoxExpandedStateToggled(bool))); - - m_newGroupBoxes[groupBoxKey] = groupBox; - } - else - { - groupBox = it->second; - CAF_ASSERT(groupBox); - - groupBoxLayout = dynamic_cast(groupBox->contentFrame()->layout()); - CAF_ASSERT(groupBoxLayout); - - m_newGroupBoxes[groupBoxKey] = groupBox; - } - - /// Insert the group box at the correct position of the parent layout - - parentLayout->addWidget(groupBox, currentRowIndex, 0, 1, 2); - - // Set Expanded state - bool isExpanded = isUiGroupExpanded(group); - groupBox->setExpanded(isExpanded); - - // Update the title to be able to support dynamic group names - groupBox->setTitle(group->uiName(uiConfigName)); - - recursiveSetupFieldsAndGroups(groupChildren, groupBox->contentFrame(), groupBoxLayout, uiConfigName); - currentRowIndex++; - } - else - { - PdmUiFieldHandle* field = dynamic_cast(uiItems[i]); - PdmUiFieldEditorHandle* fieldEditor = NULL; - - // Find or create FieldEditor - std::map::iterator it; - it = m_fieldViews.find(field->fieldHandle()); - - if (it == m_fieldViews.end()) - { - fieldEditor = PdmUiFieldEditorHelper::fieldEditorForField(field, uiConfigName); - - if (fieldEditor) - { - m_fieldViews[field->fieldHandle()] = fieldEditor; - fieldEditor->createWidgets(parent); - } - else - { - // This assert happens if no editor is available for a given field - // If the macro for registering the editor is put as the single statement - // in a cpp file, a dummy static class must be used to make sure the compile unit - // is included - // - // See cafPdmUiCoreColor3f and cafPdmUiCoreVec3d - - // This assert will trigger for PdmChildArrayField and PdmChildField - // Consider to exclude assert or add editors for these types if the assert is reintroduced - //CAF_ASSERT(false); - } - } - else - { - fieldEditor = it->second; - } - - if (fieldEditor) - { - fieldEditor->setField(field); - - // Place the widget(s) into the correct parent and layout - QWidget* fieldCombinedWidget = fieldEditor->combinedWidget(); - - if (fieldCombinedWidget) - { - fieldCombinedWidget->setParent(parent); - parentLayout->addWidget(fieldCombinedWidget, currentRowIndex, 0, 1, 2); - } - else - { - - PdmUiItemInfo::LabelPosType labelPos = field->uiLabelPosition(uiConfigName); - bool labelOnTop = (labelPos == PdmUiItemInfo::TOP); - bool editorSpanBoth = labelOnTop; - - QWidget* fieldEditorWidget = fieldEditor->editorWidget(); - - if (labelPos != PdmUiItemInfo::HIDDEN) - { - QWidget* fieldLabelWidget = fieldEditor->labelWidget(); - if (fieldLabelWidget ) - { - fieldLabelWidget->setParent(parent); - - // Label widget will span two columns if aligned on top - int colSpan = labelOnTop ? 2 : 1; - // If the label is on the side, and the editor can expand vertically, allign the label with the top edge of the editor - if (!labelOnTop && (fieldEditorWidget->sizePolicy().verticalPolicy() & QSizePolicy::ExpandFlag)) - parentLayout->addWidget(fieldLabelWidget, currentRowIndex, 0, 1, colSpan, Qt::AlignTop); - else - parentLayout->addWidget(fieldLabelWidget, currentRowIndex, 0, 1, colSpan, Qt::AlignVCenter); - - fieldLabelWidget->show(); - - if (labelOnTop) currentRowIndex++; - } - } - else - { - QWidget* fieldLabelWidget = fieldEditor->labelWidget(); - if (fieldLabelWidget ) fieldLabelWidget->hide(); - editorSpanBoth = true; // To span both columns when there is no label - } - - - 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 = editorSpanBoth ? 2 : 1; - int colIndex = editorSpanBoth ? 0 : 1; - parentLayout->addWidget(fieldEditorWidget, currentRowIndex, colIndex, 1, colSpan, Qt::AlignTop); - - if (previousTabOrderWidget) QWidget::setTabOrder(previousTabOrderWidget, fieldEditorWidget); - - previousTabOrderWidget = fieldEditorWidget; - } - - } - - fieldEditor->updateUi(uiConfigName); - - currentRowIndex++; - } - - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool CustomObjectEditor::isUiGroupExpanded(const PdmUiGroup* uiGroup) -{ - if (uiGroup->hasForcedExpandedState()) return uiGroup->forcedExpandedState(); - - auto kwMapPair = m_objectKeywordGroupUiNameExpandedState.find(pdmObject()->xmlCapability()->classKeyword()); - if ( kwMapPair != m_objectKeywordGroupUiNameExpandedState.end() ) - { - QString keyword = uiGroup->keyword(); - - auto uiNameExpStatePair = kwMapPair->second.find(keyword); - if ( uiNameExpStatePair != kwMapPair->second.end() ) - { - return uiNameExpStatePair->second; - } - } - - return uiGroup->isExpandedByDefault(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::recursiveVerifyUniqueNames(const std::vector& uiItems, const QString& uiConfigName, std::set* fieldKeywordNames, std::set* groupNames) -{ - for (size_t i = 0; i < uiItems.size(); ++i) - { - if (uiItems[i]->isUiGroup()) - { - PdmUiGroup* group = static_cast(uiItems[i]); - const std::vector& groupChildren = group->uiItems(); - - QString groupBoxKey = group->keyword(); - - if (groupNames->find(groupBoxKey) != groupNames->end()) - { - // It is not supported to have two groups with identical names - CAF_ASSERT(false); - } - else - { - groupNames->insert(groupBoxKey); - } - - recursiveVerifyUniqueNames(groupChildren, uiConfigName, fieldKeywordNames, groupNames); - } - else - { - PdmUiFieldHandle* field = dynamic_cast(uiItems[i]); - - QString fieldKeyword = field->fieldHandle()->keyword(); - if (fieldKeywordNames->find(fieldKeyword) != fieldKeywordNames->end()) - { - // It is not supported to have two fields with identical names - CAF_ASSERT(false); - } - else - { - fieldKeywordNames->insert(fieldKeyword); - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void CustomObjectEditor::groupBoxExpandedStateToggled(bool isExpanded) -{ - if (!this->pdmObject()->xmlCapability()) return; - - QString objKeyword = this->pdmObject()->xmlCapability()->classKeyword(); - QMinimizePanel* panel = dynamic_cast(this->sender()); - - if (!panel) return; - - m_objectKeywordGroupUiNameExpandedState[objKeyword][panel->objectName()] = isExpanded; -} } // end namespace caf diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.h b/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.h index 497fbc4309..2b2d12dcc8 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.h +++ b/Fwk/AppFwk/cafTests/cafTestApplication/CustomObjectEditor.h @@ -1,7 +1,7 @@ //################################################################################################## // // Custom Visualization Core library -// Copyright (C) 2011-2013 Ceetron AS +// Copyright (C) 2017 Ceetron Solutions AS // // This library may be used under the terms of either the GNU General Public License or // the GNU Lesser General Public License as follows: @@ -34,100 +34,69 @@ // //################################################################################################## - #pragma once -#include "cafPdmUiObjectEditorHandle.h" +#include "cafPdmUiWidgetBasedObjectEditor.h" -#include - -#include #include -#include -#include -#include "QMinimizePanel.h" + +#include class QGridLayout; +class QString; +class QWidget; + +class WidgetCellIds; namespace caf { -class PdmUiFieldEditorHandle; + class PdmUiItem; class PdmUiGroup; -class WidgetAndArea -{ -public: - WidgetAndArea(QWidget* w, const std::vector& occupiedCellIds) - : m_customWidget(w), - m_customWidgetCellIds(occupiedCellIds) - { - } - - QWidget* m_customWidget; - std::vector m_customWidgetCellIds; -}; - - //================================================================================================== -/// +/// Automatically layout top level groups into a grid layout +/// +/// User defined external widgets can be inserted into grid layout cells, and these cells +/// are excluded for automatic layout //================================================================================================== - -class CustomObjectEditor : public PdmUiObjectEditorHandle +class CustomObjectEditor : public PdmUiWidgetBasedObjectEditor { Q_OBJECT public: CustomObjectEditor(); ~CustomObjectEditor(); - void defineGrid(int rows, int columns); + void defineGridLayout(int rowCount, int columnCount); // See QGridLayout::addWidget - void addWidget(QWidget* w, int row, int column, int rowSpan, int columnSpan, Qt::Alignment = 0); + void addWidget(QWidget* w, int row, int column, int rowSpan, int columnSpan, Qt::Alignment alignment = 0); + void removeWidget(QWidget* w); void addBlankCell(int row, int column); - bool isCellOccupied(int cellId) const; - - void removeWidget(QWidget* w); - bool isAreaAvailable(int row, int column, int rowSpan, int columnSpan) const; - -protected: - virtual QWidget* createWidget(QWidget* parent) override; - virtual void configureAndUpdateUi(const QString& uiConfigName) override; - virtual void cleanupBeforeSettingPdmObject() override; - -protected slots: - void groupBoxExpandedStateToggled(bool isExpanded); private: - void resetDynamicCellCounter(); - std::pair rowAndCell(int cellId) const; - int cellId(int row, int column) const; + virtual QWidget* createWidget(QWidget* parent) override; + virtual void setupFieldsAndGroups(const std::vector& uiItems, QWidget* parent, const QString& uiConfigName) override; + void setupTopLevelGroupsInGridLayout(const std::vector& uiItems, QWidget* parent, QGridLayout* parentLayout, const QString& uiConfigName); + bool isAreaAvailable(int row, int column, int rowSpan, int columnSpan) const; + bool isCellIdAvailable(int cellId) const; + void resetCellId(); int getNextAvailableCellId(); - + int cellId(int row, int column) const; + std::pair rowAndColumn(int cellId) const; std::vector cellIds(int row, int column, int rowSpan, int columnSpan) const; - void recursiveSetupFieldsAndGroupsRoot(const std::vector& uiItems, QWidget* parent, QGridLayout* parentLayout, const QString& uiConfigName); - void recursiveSetupFieldsAndGroups(const std::vector& uiItems, QWidget* parent, QGridLayout* parentLayout, const QString& uiConfigName); - bool isUiGroupExpanded(const PdmUiGroup* uiGroup); - void recursiveVerifyUniqueNames(const std::vector& uiItems, const QString& uiConfigName, std::set* fieldKeywordNames, std::set* groupNames); +private: + QPointer m_layout; - std::map m_fieldViews; - std::map > m_groupBoxes; - std::map > m_newGroupBoxes; ///< used temporarily to store the new(complete) set of group boxes + int m_rowCount; + int m_columnCount; + int m_currentCellId; - QPointer m_mainWidget; - QPointer m_layout; - - std::map > m_objectKeywordGroupUiNameExpandedState; - - int m_rowCount; - int m_columnCount; - int m_dynamicCellIndex; - - std::vector m_customWidgetAreas; + std::vector m_customWidgetAreas; }; diff --git a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp index 1c6ced09b0..a105bc71a7 100644 --- a/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp +++ b/Fwk/AppFwk/cafTests/cafTestApplication/MainWindow.cpp @@ -652,7 +652,7 @@ void MainWindow::setPdmRoot(caf::PdmObjectHandle* pdmRoot) pdmRoot->descendantsIncludingThisOfType(obj); if (obj.size() == 1) { - m_customObjectEditor->defineGrid(5, 4); + m_customObjectEditor->defineGridLayout(5, 4); m_customObjectEditor->setPdmObject(obj[0]); m_customObjectEditor->addBlankCell(0, 0);