Commit edada9bc authored by Bob Obara's avatar Bob Obara Committed by Kitware Robot

Merge topic 'creatingNewExpressionInQtInputsItems'

4f88ef70 ENH: Added new Attribute Editing Dialog
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: John Tourtellott's avatarJohn Tourtellott <john.tourtellott@kitware.com>
Merge-request: !1742
parents 0cd1e565 4f88ef70
......@@ -36,5 +36,12 @@ Example SBT Code:
```
See [SMTK Issue 270 to see what the resulting UI looks like.](https://gitlab.kitware.com/cmb/smtk/issues/270)
### Added qtAttributeEditorDialog class
This class can be used to edit a single attribute and is used to create new expressions for ValueItems (using the qtInputsItem class. Note that the current implementation does not undo changes made to the attribute using the dialog but does tell the caller the user requested a cancelation. In the current use case this means to delete the newly created expression attribute.
### Creating Expressions for ValueItems
With the introduction of qtAttributeEditorDialogs, it is now possible to create new expression attributes without having to change Views.
### Other Changes
* qtItem::updateItemData has been made public so that qtItems can be undated when their underlying attribute items are external changed.
......@@ -7,6 +7,7 @@ set(QAttrLibSrcs
qtUIManager.cxx
qtAttribute.cxx
qtAttributeDisplay.cxx
qtAttributeEditorDialog.cxx
qtAttributeItemInfo.cxx
qtBaseAttributeView.cxx
qtBaseView.cxx
......@@ -64,6 +65,7 @@ set(QAttrLibSrcs
set(QAttrLibUIs
qtAssociationView.ui
qtAttributeAssociation.ui
qtAttributeEditorWidget.ui
qtCollapsibleGroupWidgetInternals.ui
qtModelPanel.ui
qtNewAttributeWidget.ui
......@@ -78,6 +80,7 @@ set(QAttrLibMocHeaders
qtUIManager.h
qtAttribute.h
qtAttributeDisplay.h
qtAttributeEditorDialog.h
qtBaseAttributeView.h
qtBaseView.h
qtCategorySelectorView.h
......
......@@ -144,7 +144,7 @@ void qtAttribute::createWidget()
QVBoxLayout* layout = new QVBoxLayout(m_widget);
layout->setMargin(3);
m_widget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
m_widget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
}
void qtAttribute::addItem(qtItem* child)
......
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//=========================================================================
// .NAME qtAttributeEditorDialog - A Information Dialog for SMTK Operations
// .SECTION Description
// .SECTION Caveats
#include "smtk/extension/qt/qtAttributeEditorDialog.h"
#include "smtk/extension/qt/qtAttribute.h"
#include "smtk/extension/qt/qtBaseView.h"
#include "smtk/extension/qt/qtInstancedView.h"
#include "smtk/extension/qt/qtUIManager.h"
#include "ui_qtAttributeEditorWidget.h"
#include "smtk/attribute/Attribute.h"
#include "smtk/attribute/Definition.h"
#include "smtk/attribute/Item.h"
#include "smtk/attribute/ItemDefinition.h"
#include "smtk/attribute/Resource.h"
#include "smtk/view/View.h"
#include <QMessageBox>
#include <QPushButton>
using namespace smtk::extension;
qtAttributeEditorDialog::qtAttributeEditorDialog(const smtk::attribute::AttributePtr& attribute,
smtk::extension::qtUIManager* uiManager, QWidget* Parent)
: QDialog(Parent)
, m_attribute(attribute)
, m_uiManager(uiManager)
, m_widget(new Ui::qtAttributeEditorWidget())
, m_qtAttribute(nullptr)
{
m_widget->setupUi(this);
this->setObjectName("qtAttributeEditorDialog");
m_instancedViewDef = smtk::view::View::New("Instanced", "Contents");
smtk::view::View::Component& child =
m_instancedViewDef->details().addChild("InstancedAttributes").addChild("Att");
child.setAttribute("Name", m_attribute->name()).setAttribute("Type", m_attribute->type());
ViewInfo v(m_instancedViewDef, this->m_widget->attributeFrame, m_uiManager);
qtInstancedView* iview = dynamic_cast<qtInstancedView*>(qtInstancedView::createViewWidget(v));
m_instancedView.reset(iview);
m_widget->attributeName->setText(m_attribute->name().c_str());
m_widget->editAccept->setDefault(false);
m_widget->editAccept->setAutoDefault(false);
m_widget->editCancel->setDefault(false);
m_widget->editCancel->setAutoDefault(false);
QObject::connect(
m_widget->attributeName, SIGNAL(editingFinished()), this, SLOT(attributeNameChanged()));
QObject::connect(m_widget->editAccept, SIGNAL(pressed()), this, SLOT(accept()));
QObject::connect(m_widget->editCancel, SIGNAL(pressed()), this, SLOT(reject()));
}
qtAttributeEditorDialog::~qtAttributeEditorDialog()
{
delete m_widget;
}
void qtAttributeEditorDialog::hideCancel()
{
m_widget->editCancel->hide();
}
void qtAttributeEditorDialog::showCancel()
{
m_widget->editCancel->show();
}
void qtAttributeEditorDialog::attributeNameChanged()
{
std::string newName = m_widget->attributeName->text().toStdString();
if (newName == m_attribute->name())
{
return;
}
auto attResource = m_attribute->attributeResource();
// Lets see if the name is in use
auto att = attResource->findAttribute(newName);
if (att != nullptr)
{
std::string s;
s = "Can't rename " + m_attribute->type() + ":" + m_attribute->name() +
". There already exists an attribute of type: " + att->type() + " named " + att->name() +
".";
QMessageBox::warning(this, "Attribute Can't be Renamed", s.c_str());
m_widget->attributeName->setText(m_attribute->name().c_str());
return;
}
attResource->rename(m_attribute, newName);
}
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//=========================================================================
// .NAME qtAttributeEditorDialog - A Information Dialog for SMTK Operations
// .SECTION Description
// .SECTION Caveats
#ifndef _qtAttributeEditorDialog_h
#define _qtAttributeEditorDialog_h
#include "smtk/PublicPointerDefs.h"
#include "smtk/extension/qt/Exports.h"
#include "smtk/extension/qt/qtUIManager.h"
#include <QtWidgets/QDialog>
namespace Ui
{
class qtAttributeEditorWidget;
}
namespace smtk
{
namespace extension
{
class qtInstancedView;
class qtAttribute;
/**\brief Provides a mechanism to edit an attribute using a dialog mechanism instead of a panel.
*
* The dialog uses a qtInstanceVuew internally though we hope to make this more general in the
* future. Note that canceling or ok'ing the dialog results in the attribute being modified thoough
* the value returned using exec() does indicate whether the user accepted or canceled the changes.
* This limitation works with the initial use for the dialog which is creating new expression attributes
* for Value Items without changing Views. In this case, canceling means delete the newly created attribute
* so there is no issue with having modifying the attribute previously.
* There is an option to hide the cancel button which also gets around this limitation.
*/
class SMTKQTEXT_EXPORT qtAttributeEditorDialog : public QDialog
{
Q_OBJECT
public:
qtAttributeEditorDialog(const smtk::attribute::AttributePtr& attribute,
smtk::extension::qtUIManager* uiManager, QWidget* Parent);
~qtAttributeEditorDialog() override;
qtAttributeEditorDialog(const qtAttributeEditorDialog&) = delete;
qtAttributeEditorDialog& operator=(const qtAttributeEditorDialog&) = delete;
void hideCancel();
void showCancel();
public slots:
void attributeNameChanged();
private:
const smtk::attribute::AttributePtr& m_attribute;
QPointer<smtk::extension::qtUIManager> m_uiManager;
Ui::qtAttributeEditorWidget* m_widget;
smtk::extension::qtAttribute* m_qtAttribute;
std::unique_ptr<qtInstancedView> m_instancedView;
smtk::view::ViewPtr m_instancedViewDef;
};
}
}
#endif // _qtAttributeEditorDialog_h
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>qtAttributeEditorWidget</class>
<widget class="QWidget" name="qtAttributeEditorWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>422</width>
<height>300</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Attribute Editor</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="attributeLabel">
<property name="text">
<string>Attribute Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="attributeName"/>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QScrollArea" name="attributeScrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>398</width>
<height>159</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QFrame" name="attributeFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_2">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="editCancel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="editAccept">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
......@@ -72,6 +72,7 @@ qtDiscreteValueEditor::qtDiscreteValueEditor(
item->m_itemInfo.createNewDictionary(this->Internals->m_itemViewMap);
}
this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
this->createWidget();
}
......@@ -91,7 +92,6 @@ void qtDiscreteValueEditor::createWidget()
this->Internals->clearChildItems();
QBoxLayout* wlayout = new QVBoxLayout(this);
wlayout->setMargin(0);
if (!item || !item->isDiscrete())
{
return;
......@@ -123,7 +123,6 @@ void qtDiscreteValueEditor::createWidget()
combo->setToolTip(tooltip);
}
combo->addItems(discreteVals);
combo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QObject::connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(onInputValueChanged()),
Qt::QueuedConnection);
wlayout->addWidget(combo);
......@@ -242,7 +241,7 @@ void qtDiscreteValueEditor::updateContents()
{
this->Internals->m_childrenFrame = new QFrame(this);
this->Internals->m_childrenFrame->setObjectName("ChildItemsFrame");
QSizePolicy sizeFixedPolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
QSizePolicy sizeFixedPolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
QVBoxLayout* clayout = new QVBoxLayout(this->Internals->m_childrenFrame);
clayout->setMargin(3);
this->Internals->m_childrenFrame->setSizePolicy(sizeFixedPolicy);
......
......@@ -11,6 +11,7 @@
#include "smtk/extension/qt/qtInputsItem.h"
#include "smtk/attribute/Definition.h"
#include "smtk/extension/qt/qtAttributeEditorDialog.h"
#include "smtk/extension/qt/qtBaseAttributeView.h"
#include "smtk/extension/qt/qtDiscreteValueEditor.h"
#include "smtk/extension/qt/qtDoubleLineEdit.h"
......@@ -909,18 +910,6 @@ QWidget* qtInputsItem::createExpressionRefWidget(int elementIdx)
QObject::connect(combo, SIGNAL(currentIndexChanged(int)), this,
SLOT(onExpressionReferenceChanged()), Qt::QueuedConnection);
// check if there are attributes already created, if not
// disable the function checkbox
auto valItemDef = inputitem->definitionAs<ValueItemDefinition>();
smtk::attribute::DefinitionPtr attDef = valItemDef->expressionDefinition();
std::vector<smtk::attribute::AttributePtr> result;
if (attDef)
{
ResourcePtr lAttResource = attDef->resource();
lAttResource->findAttributes(attDef, result);
}
funCheck->setEnabled(result.size() > 0);
// create line edit for expression which is a const value
QWidget* valeditor = this->createEditBox(elementIdx, checkFrame);
......@@ -958,6 +947,7 @@ void qtInputsItem::displayExpressionWidget(bool checkstate)
return;
}
QComboBox* combo = static_cast<QComboBox*>(funCheck->property("FuncCombo").value<void*>());
combo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
QWidget* funcEditor = static_cast<QWidget*>(funCheck->property("FuncEditor").value<void*>());
if (!combo || !funcEditor)
......@@ -981,14 +971,14 @@ void qtInputsItem::displayExpressionWidget(bool checkstate)
{
attNames.push_back((*it)->name().c_str());
}
if (attNames.count() > 0)
{
attNames.sort();
combo->addItems(attNames);
}
attNames.sort();
// Now add Please Select and Create Options
attNames.insert(0, "Please Select");
attNames.insert(1, "Create...");
combo->addItems(attNames);
}
int setIndex = -1;
int setIndex = 0;
if (inputitem->isExpression(elementIdx))
{
smtk::attribute::RefItemPtr item = inputitem->expressionReference(elementIdx);
......@@ -1000,6 +990,7 @@ void qtInputsItem::displayExpressionWidget(bool checkstate)
{
// Not pointing to valid item - reset it
this->unsetValue(elementIdx);
setIndex = 0;
}
}
else
......@@ -1020,11 +1011,13 @@ void qtInputsItem::displayExpressionWidget(bool checkstate)
else
{
this->unsetValue(elementIdx);
setIndex = 0;
}
}
else if (inputitem->isSet(elementIdx))
{
this->unsetValue(elementIdx);
setIndex = 0;
}
}
combo->setCurrentIndex(setIndex);
......@@ -1069,9 +1062,56 @@ void qtInputsItem::onExpressionReferenceChanged()
return;
}
if (curIdx >= 0)
if (curIdx == 0)
{
item->unset(elementIdx);
inputitem->unset(elementIdx);
}
else if (curIdx == 1)
{
ResourcePtr lAttResource = item->attribute()->attributeResource();
auto valItemDef = inputitem->definitionAs<ValueItemDefinition>();
smtk::attribute::DefinitionPtr attDef = valItemDef->expressionDefinition();
auto attResource = attDef->resource();
smtk::attribute::AttributePtr newAtt = attResource->createAttribute(attDef->type());
auto editor =
new smtk::extension::qtAttributeEditorDialog(newAtt, m_itemInfo.uiManager(), m_widget);
auto status = editor->exec();
QStringList itemsInComboBox;
if (status == QDialog::Rejected)
{
attResource->removeAttribute(newAtt);
}
else
{
inputitem->setExpression(elementIdx, newAtt);
itemsInComboBox.append(newAtt->name().c_str());
}
for (int index = 2; index < comboBox->count(); index++)
{
itemsInComboBox << comboBox->itemText(index);
}
itemsInComboBox.sort();
// Now add Please Select and Create New Options
itemsInComboBox.insert(0, "Please Select");
itemsInComboBox.insert(1, "Create New");
comboBox->blockSignals(true);
comboBox->clear();
comboBox->addItems(itemsInComboBox);
auto expressionAtt = inputitem->expression();
if (expressionAtt == nullptr)
{
comboBox->setCurrentIndex(0);
}
else
{
auto index = itemsInComboBox.indexOf(expressionAtt->name().c_str());
comboBox->setCurrentIndex(index);
}
comboBox->blockSignals(false);
}
else
{
smtk::attribute::ResourcePtr lAttResource = item->attribute()->attributeResource();
AttributePtr attPtr = lAttResource->findAttribute(comboBox->currentText().toStdString());
if (elementIdx >= 0 && inputitem->isSet(elementIdx) &&
attPtr == inputitem->expression(elementIdx))
......@@ -1089,11 +1129,6 @@ void qtInputsItem::onExpressionReferenceChanged()
inputitem->unset(elementIdx);
}
}
else
{
item->unset(elementIdx);
inputitem->unset(elementIdx);
}
auto iview = dynamic_cast<qtBaseAttributeView*>(m_itemInfo.baseView().data());
if (iview)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment