Gui: support auto grouping editing for PropertyEnumeration

The PropertyEnumeration editor (PropertyEnumItem) will check for
separator characeter '|' in enumeration items to auto create
hierarchical groups of items using sub-menus for user to select.
This commit is contained in:
Zheng, Lei
2022-02-06 17:52:09 +08:00
committed by Uwe
parent 24a015d796
commit 88e6121efa
13 changed files with 202 additions and 26 deletions

View File

@@ -1530,7 +1530,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > PushButton {
background-color: #232932;
border: 1px solid #232932;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1539,6 +1540,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #232932; /* main background color */

View File

@@ -1497,7 +1497,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: #6e6e6e;
border: 1px solid #5a5a5a;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1506,6 +1507,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #6e6e6e; /* main background color */
@@ -2279,3 +2285,4 @@ Gui--UrlLabel {
color : rgba(0,91,255,255); /* Deep sky blue */
text-decoration : underline;
}

View File

@@ -1497,7 +1497,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: black;
border: 1px solid #1e1e1e;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1506,6 +1507,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #444444; /* main background color */

View File

@@ -1497,7 +1497,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: #6e6e6e;
border: 1px solid #5a5a5a;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1506,6 +1507,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #6e6e6e; /* main background color */

View File

@@ -1497,7 +1497,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: #6e6e6e;
border: 1px solid #5a5a5a;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1506,6 +1507,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #6e6e6e; /* main background color */

View File

@@ -1497,7 +1497,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: #2a2a2a;
border: 1px solid #1e1e1e;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1506,6 +1507,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #444444; /* main background color */

View File

@@ -1497,7 +1497,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: #2a2a2a;
border: 1px solid #1e1e1e;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1506,6 +1507,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #444444; /* main background color */

View File

@@ -1494,7 +1494,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: #b6b6b6;
border: 1px solid #828282;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1503,6 +1504,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #f5f5f5; /* main background color */

View File

@@ -1494,7 +1494,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: #b6b6b6;
border: 1px solid #828282;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1503,6 +1504,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #f5f5f5; /* main background color */

View File

@@ -1494,7 +1494,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: #b6b6b6;
border: 1px solid #828282;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1503,6 +1504,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #f5f5f5; /* main background color */

View File

@@ -1692,7 +1692,8 @@ Gui--ColorButton:pressed {
}
/* Pushbutton style for "..." inside Placement cell which launches Placement tool */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton,
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
background-color: #2a2a2a;
border: 1px solid #1e1e1e;
min-width: 16px; /* reset it due to larger value on regular QPushButton, same or bigger value as regular QPushButton min-height */
@@ -1701,6 +1702,11 @@ Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QPushButton {
padding: 0px; /* reset */
}
Gui--PropertyEditor--PropertyEditor > QWidget > QPushButton {
text-align:left;
padding-left: 2px;
}
/* Fix for Expressions description QFrame that is "broken" with initial reset */
Gui--PropertyEditor--PropertyEditor > QWidget > QWidget > QWidget > QWidget > QFrame {
background-color: #333333; /* main background color */

View File

@@ -24,7 +24,7 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QApplication>
# include <algorithm>
# include <QComboBox>
# include <QFontDatabase>
# include <QLocale>
@@ -32,6 +32,10 @@
# include <QPixmap>
# include <QTextStream>
# include <QTimer>
# include <QApplication>
# include <QPalette>
# include <QtGlobal>
# include <QMenu>
#endif
#include "PropertyItem.h"
@@ -2844,16 +2848,35 @@ void PropertyEnumItem::setValue(const QVariant& value)
setPropertyValue(data);
}
QWidget* PropertyEnumItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
class EnumItems;
struct EnumItem {
QString text;
QString fullText;
std::shared_ptr<EnumItems> children;
EnumItem(const QString &t = QString(), const QString &f = QString())
:text(t), fullText(f)
{}
void populate(QMenu *menu);
};
class EnumItems : public std::vector<EnumItem>
{
QComboBox *cb = new QComboBox(parent);
cb->setFrame(false);
cb->setDisabled(isReadOnly());
QObject::connect(cb, SIGNAL(activated(int)), receiver, method);
return cb;
};
void EnumItem::populate(QMenu *menu)
{
if (!children || children->empty()) {
auto action = menu->addAction(text);
action->setData(fullText);
return;
}
auto subMenu = menu->addMenu(text);
for (auto &item : *children)
item.populate(subMenu);
}
void PropertyEnumItem::setEditorData(QWidget *editor, const QVariant& data) const
QWidget* PropertyEnumItem::createEditor(QWidget* parent, const QObject* receiver, const char* method) const
{
const std::vector<App::Property*>& items = getPropertyData();
@@ -2863,7 +2886,7 @@ void PropertyEnumItem::setEditorData(QWidget *editor, const QVariant& data) cons
App::PropertyEnumeration* prop = static_cast<App::PropertyEnumeration*>(*it);
if (prop->getEnums() == nullptr) {
commonModes.clear();
break;
return nullptr;
}
const std::vector<std::string>& value = prop->getEnumVector();
if (it == items.begin()) {
@@ -2882,18 +2905,90 @@ void PropertyEnumItem::setEditorData(QWidget *editor, const QVariant& data) cons
}
}
QComboBox *cb = qobject_cast<QComboBox*>(editor);
if (!commonModes.isEmpty()) {
cb->clear();
cb->addItems(commonModes);
if (commonModes.isEmpty())
return nullptr;
int index = -1;
std::shared_ptr<EnumItems> enumItems;
for (auto &mode : commonModes) {
++index;
auto fields = mode.split(QStringLiteral("|"));
if (!enumItems && fields.size() <= 1)
continue;
if (!enumItems) {
enumItems = std::make_shared<EnumItems>();
for (int i=0; i<index; ++i)
enumItems->emplace_back(commonModes[i], mode);
}
auto children = enumItems;
int j = -1;
for (auto &field : fields) {
++j;
field = field.trimmed();
auto it = children->end();
if (field.isEmpty()) {
if (children->size())
--it;
else
continue;
} else {
it = std::find_if(children->begin(), children->end(),
[&field](const EnumItem &item) {
return item.text == field;
});
if (it == children->end())
it = children->emplace(children->end(), field, mode);
}
if (j + 1 == (int)fields.size())
break;
if (!it->children)
it->children = std::make_shared<EnumItems>();
children = it->children;
}
}
if (!enumItems) {
QComboBox *cb = new QComboBox(parent);
cb->setFrame(false);
cb->setDisabled(isReadOnly());
QObject::connect(cb, SIGNAL(activated(int)), receiver, method);
return cb;
}
auto button = new PropertyEnumButton(parent);
button->setDisabled(isReadOnly());
QMenu *menu = new QMenu(button);
for (auto &item : *enumItems)
item.populate(menu);
button->setMenu(menu);
QObject::connect(menu, &QMenu::aboutToShow, this, [=]() {
menu->setMinimumWidth(button->width());
});
QObject::connect(menu, &QMenu::triggered, this, [=](QAction *action) {
button->setText(action->data().toString());
button->picked();
});
QObject::connect(button, SIGNAL(picked()), receiver, method);
return button;
}
void PropertyEnumItem::setEditorData(QWidget *editor, const QVariant& data) const
{
if (auto cb = qobject_cast<QComboBox*>(editor)) {
cb->setEditable(false);
cb->setCurrentIndex(cb->findText(data.toString()));
}
else if (auto btn = qobject_cast<QPushButton*>(editor))
btn->setText(data.toString());
}
QVariant PropertyEnumItem::editorData(QWidget *editor) const
{
QComboBox *cb = qobject_cast<QComboBox*>(editor);
return QVariant(cb->currentText());
if (auto cb = qobject_cast<QComboBox*>(editor))
return QVariant(cb->currentText());
else if (auto btn = qobject_cast<QPushButton*>(editor))
return btn->text();
return QVariant();
}
// ---------------------------------------------------------------

View File

@@ -27,6 +27,8 @@
#include <QItemEditorFactory>
#include <QObject>
#include <QPointer>
#include <QPushButton>
#include <QItemEditorFactory>
#include <vector>
#include <App/PropertyStandard.h>
@@ -847,6 +849,18 @@ private:
PropertyStringListItem* m_enum;
};
class PropertyEnumButton : public QPushButton
{
Q_OBJECT
public:
PropertyEnumButton(QWidget *parent = nullptr)
:QPushButton(parent)
{}
Q_SIGNALS:
void picked();
};
/**
* Edit properties of string list type.
* \author Werner Mayer