Core: Add VarSet support to expression dialog
This allows users to directly add properties to variable sets from within the expression input dialog improving a workflow for parameterized design.
This commit is contained in:
committed by
Chris Hennes
parent
f331c91b89
commit
bfec0992f4
@@ -25,21 +25,30 @@
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QTreeWidget>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/ExpressionParser.h>
|
||||
#include <App/VarSet.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
#include "DlgExpressionInput.h"
|
||||
#include "ui_DlgExpressionInput.h"
|
||||
#include "Application.h"
|
||||
#include "Command.h"
|
||||
#include "Tools.h"
|
||||
|
||||
#include "ExpressionBinding.h"
|
||||
#include "BitmapFactory.h"
|
||||
#include "ViewProviderDocumentObject.h"
|
||||
|
||||
using namespace App;
|
||||
using namespace Gui::Dialog;
|
||||
|
||||
bool DlgExpressionInput::varSetsVisible = false;
|
||||
|
||||
DlgExpressionInput::DlgExpressionInput(const App::ObjectIdentifier & _path,
|
||||
std::shared_ptr<const Expression> _expression,
|
||||
const Base::Unit & _impliedUnit, QWidget *parent)
|
||||
@@ -56,6 +65,8 @@ DlgExpressionInput::DlgExpressionInput(const App::ObjectIdentifier & _path,
|
||||
// Setup UI
|
||||
ui->setupUi(this);
|
||||
|
||||
initializeVarSets();
|
||||
|
||||
// Connect signal(s)
|
||||
connect(ui->expression, &ExpressionLineEdit::textChanged,
|
||||
this, &DlgExpressionInput::textChanged);
|
||||
@@ -110,6 +121,98 @@ DlgExpressionInput::~DlgExpressionInput()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
static void getVarSetsDocument(std::vector<App::VarSet*>& varSets, App::Document* doc) {
|
||||
for (auto obj : doc->getObjects()) {
|
||||
auto varSet = dynamic_cast<App::VarSet*>(obj);
|
||||
if (varSet) {
|
||||
varSets.push_back(varSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<App::VarSet*> getAllVarSets()
|
||||
{
|
||||
std::vector<App::Document*> docs = App::GetApplication().getDocuments();
|
||||
std::vector<App::VarSet*> varSets;
|
||||
|
||||
for (auto doc : docs) {
|
||||
getVarSetsDocument(varSets, doc);
|
||||
}
|
||||
|
||||
return varSets;
|
||||
}
|
||||
|
||||
Base::Type DlgExpressionInput::getTypePath()
|
||||
{
|
||||
return path.getProperty()->getTypeId();
|
||||
}
|
||||
|
||||
Base::Type DlgExpressionInput::determineTypeVarSet()
|
||||
{
|
||||
Base::Type typePath = getTypePath();
|
||||
|
||||
// The type of the path is leading. If it is one of the types below, we
|
||||
// can create a property in the varset.
|
||||
if (typePath == App::PropertyString::getClassTypeId() ||
|
||||
typePath.isDerivedFrom(App::PropertyFloat::getClassTypeId()) ||
|
||||
typePath.isDerivedFrom(App::PropertyInteger::getClassTypeId())) {
|
||||
return typePath;
|
||||
}
|
||||
|
||||
// If we cannot determine the type by means of the path, for example when
|
||||
// dealing with a sketcher constraint list or with the x, y, or z of a
|
||||
// Placement, the type of the unit allows us to create a property in the
|
||||
// varset. Since unit properties are derived from App::PropertyFloat, it
|
||||
// allows us to create a property and set the value.
|
||||
|
||||
std::string unitTypeString = impliedUnit.getTypeString().toStdString();
|
||||
if (unitTypeString.empty()) {
|
||||
// no type was provided
|
||||
return Base::Type::badType();
|
||||
}
|
||||
|
||||
std::string typeString = "App::Property" + unitTypeString;
|
||||
// may return badType
|
||||
return Base::Type::fromName(typeString.c_str());
|
||||
}
|
||||
|
||||
bool DlgExpressionInput::typeOkForVarSet()
|
||||
{
|
||||
std::string unitType = impliedUnit.getTypeString().toStdString();
|
||||
return determineTypeVarSet() != Base::Type::badType();
|
||||
}
|
||||
|
||||
void DlgExpressionInput::initializeVarSets()
|
||||
{
|
||||
ui->labelInfoActive->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
ui->labelInfoActive->setWordWrap(true);
|
||||
|
||||
connect(ui->checkBoxVarSets, &QCheckBox::stateChanged,
|
||||
this, &DlgExpressionInput::onCheckVarSets);
|
||||
connect(ui->comboBoxVarSet, qOverload<int>(&QComboBox::currentIndexChanged),
|
||||
this, &DlgExpressionInput::onVarSetSelected);
|
||||
connect(ui->lineEditGroup, &QLineEdit::textChanged,
|
||||
this, &DlgExpressionInput::onTextChangedGroup);
|
||||
connect(ui->lineEditPropNew, &QLineEdit::textChanged,
|
||||
this, &DlgExpressionInput::namePropChanged);
|
||||
|
||||
std::vector<App::VarSet*> varSets = getAllVarSets();
|
||||
if (!varSets.empty() && typeOkForVarSet()) {
|
||||
ui->checkBoxVarSets->setVisible(true);
|
||||
ui->checkBoxVarSets->setCheckState(varSetsVisible ? Qt::Checked : Qt::Unchecked);
|
||||
ui->groupBoxVarSets->setVisible(varSetsVisible);
|
||||
if (varSetsVisible) {
|
||||
setupVarSets();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The dialog is shown without any VarSet options.
|
||||
varSetsVisible = false;
|
||||
ui->checkBoxVarSets->setVisible(false);
|
||||
ui->groupBoxVarSets->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void NumberRange::setRange(double min, double max)
|
||||
{
|
||||
minimum = min;
|
||||
@@ -154,28 +257,8 @@ QPoint DlgExpressionInput::expressionPosition() const
|
||||
return ui->expression->pos();
|
||||
}
|
||||
|
||||
void DlgExpressionInput::textChanged(const QString &text)
|
||||
void DlgExpressionInput::checkExpression(const QString& text)
|
||||
{
|
||||
if (text.isEmpty()) {
|
||||
ui->okBtn->setDisabled(true);
|
||||
ui->discardBtn->setDefault(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ui->okBtn->setDefault(true);
|
||||
|
||||
try {
|
||||
//resize the input field according to text size
|
||||
QFontMetrics fm(ui->expression->font());
|
||||
int width = QtTools::horizontalAdvance(fm, text) + 15;
|
||||
if (width < minimumWidth)
|
||||
ui->expression->setMinimumWidth(minimumWidth);
|
||||
else
|
||||
ui->expression->setMinimumWidth(width);
|
||||
|
||||
if(this->width() < ui->expression->minimumWidth())
|
||||
setMinimumWidth(ui->expression->minimumWidth());
|
||||
|
||||
//now handle expression
|
||||
std::shared_ptr<Expression> expr(ExpressionParser::parse(path.getDocumentObject(), text.toUtf8().constData()));
|
||||
|
||||
@@ -226,6 +309,39 @@ void DlgExpressionInput::textChanged(const QString &text)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static const bool NO_CHECK_EXPR = false;
|
||||
|
||||
void DlgExpressionInput::textChanged(const QString &text)
|
||||
{
|
||||
if (text.isEmpty()) {
|
||||
ui->okBtn->setDisabled(true);
|
||||
ui->discardBtn->setDefault(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ui->okBtn->setDefault(true);
|
||||
|
||||
try {
|
||||
//resize the input field according to text size
|
||||
QFontMetrics fm(ui->expression->font());
|
||||
int width = QtTools::horizontalAdvance(fm, text) + 15;
|
||||
if (width < minimumWidth)
|
||||
ui->expression->setMinimumWidth(minimumWidth);
|
||||
else
|
||||
ui->expression->setMinimumWidth(width);
|
||||
|
||||
if(this->width() < ui->expression->minimumWidth())
|
||||
setMinimumWidth(ui->expression->minimumWidth());
|
||||
|
||||
checkExpression(text);
|
||||
if (varSetsVisible) {
|
||||
// If varsets are visible, check whether the varset info also
|
||||
// agrees that the button should be enabled.
|
||||
// No need to check the expression in that function.
|
||||
updateVarSetInfo(NO_CHECK_EXPR);
|
||||
}
|
||||
}
|
||||
catch (Base::Exception & e) {
|
||||
ui->msg->setText(QString::fromUtf8(e.what()));
|
||||
@@ -279,5 +395,352 @@ void DlgExpressionInput::show()
|
||||
ui->expression->selectAll();
|
||||
}
|
||||
|
||||
class Binding : public Gui::ExpressionBinding
|
||||
{
|
||||
// helper class to compensate for the fact that
|
||||
// ExpressionBinding::setExpression is protected.
|
||||
public:
|
||||
Binding() = default;
|
||||
|
||||
void setExpression(std::shared_ptr<App::Expression> expr) override
|
||||
{
|
||||
ExpressionBinding::setExpression(expr);
|
||||
}
|
||||
};
|
||||
|
||||
static bool isNamePropOk(const QString& nameProp, App::DocumentObject* obj,
|
||||
std::stringstream& message)
|
||||
{
|
||||
if (!obj) {
|
||||
message << "Unknown object";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string name = nameProp.toStdString();
|
||||
if (name.empty()) {
|
||||
message << "Please provide a name for the property.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name != Base::Tools::getIdentifier(name)) {
|
||||
message << "Invalid property name (must only contain alphanumericals, underscore, "
|
||||
<< "and must not start with digit";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto prop = obj->getPropertyByName(name.c_str());
|
||||
if (prop && prop->getContainer() == obj) {
|
||||
message << name << " already exists";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const int ROLE_DOC = Qt::UserRole;
|
||||
static const int ROLE_VARSET_NAME = Qt::UserRole + 1;
|
||||
static const int ROLE_VARSET_LABEL = Qt::UserRole + 2;
|
||||
static const int ROLE_GROUP = Qt::UserRole + 3;
|
||||
|
||||
static QString getValue(QTreeWidgetItem* item, int role)
|
||||
{
|
||||
QVariant variant = item->data(0, role);
|
||||
return variant.toString();
|
||||
}
|
||||
|
||||
void DlgExpressionInput::acceptWithVarSet()
|
||||
{
|
||||
// all checks have been performed in updateVarSetInfo and textChanged that
|
||||
// decide to enable the button
|
||||
|
||||
// create a property in the VarSet
|
||||
QTreeWidgetItem *selected = treeWidget->currentItem();
|
||||
QString nameVarSet = getValue(selected, ROLE_VARSET_NAME);
|
||||
QString nameGroup = ui->lineEditGroup->text();
|
||||
QString nameProp = ui->lineEditPropNew->text();
|
||||
|
||||
QString nameDoc = getValue(selected, ROLE_DOC);
|
||||
App::Document* doc = App::GetApplication().getDocument(nameDoc.toUtf8());
|
||||
App::DocumentObject* obj = doc->getObject(nameVarSet.toUtf8());
|
||||
|
||||
std::string name = nameProp.toStdString();
|
||||
std::string group = nameGroup.toStdString();
|
||||
std::string type = getType();
|
||||
auto prop = obj->addDynamicProperty(type.c_str(), name.c_str(), group.c_str());
|
||||
|
||||
// Set the value of the property in the VarSet
|
||||
//
|
||||
// The value of the property is going to be the value that was originally
|
||||
// meant to be the value for the property that this dialog is targeting.
|
||||
Expression* exprSimplfied = expression->simplify();
|
||||
auto ne = dynamic_cast<NumberExpression*>(exprSimplfied);
|
||||
auto se = dynamic_cast<StringExpression*>(exprSimplfied);
|
||||
if (ne) {
|
||||
// the value is a number: directly assign it to the property instead of
|
||||
// making it an expression in the variable set
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.getDocument('%s').getObject('%s').%s = %f",
|
||||
obj->getDocument()->getName(),
|
||||
obj->getNameInDocument(),
|
||||
prop->getName(), ne->getValue());
|
||||
}
|
||||
else if (se) {
|
||||
// the value is a string: directly assign it to the property.
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.getDocument('%s').getObject('%s').%s = \"%s\"",
|
||||
obj->getDocument()->getName(),
|
||||
obj->getNameInDocument(),
|
||||
prop->getName(), se->getText().c_str());
|
||||
}
|
||||
else {
|
||||
// the value is an epxression: make an expression binding in the variable set.
|
||||
ObjectIdentifier objId(*prop);
|
||||
Binding binding;
|
||||
binding.bind(objId);
|
||||
binding.setExpression(expression);
|
||||
binding.apply();
|
||||
}
|
||||
|
||||
// Create a new expression that refers to the property in the variable set
|
||||
// for the original property that is the target of this dialog.
|
||||
expression.reset(ExpressionParser::parse(path.getDocumentObject(),
|
||||
prop->getFullName().c_str()));
|
||||
}
|
||||
|
||||
void DlgExpressionInput::accept() {
|
||||
if (varSetsVisible) {
|
||||
acceptWithVarSet();
|
||||
}
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
static void addGroupsVarSetComboBox(App::VarSet* varSet, QTreeWidgetItem* varSetItem)
|
||||
{
|
||||
std::vector<Property*> properties;
|
||||
std::set<std::string> namesGroup;
|
||||
varSet->getPropertyList(properties);
|
||||
for (auto prop : properties) {
|
||||
const char* nameGroup = prop->getGroup();
|
||||
if (!nameGroup || strcmp(nameGroup, "") == 0) {
|
||||
namesGroup.insert("Base");
|
||||
}
|
||||
else {
|
||||
namesGroup.insert(nameGroup);
|
||||
}
|
||||
}
|
||||
for (const auto& nameGroup : namesGroup) {
|
||||
// the item will be automatically destroyed when the varSetItem will be destroyed
|
||||
auto item = new QTreeWidgetItem(varSetItem);
|
||||
item->setText(0, QString::fromStdString(nameGroup));
|
||||
item->setData(0, ROLE_GROUP, QString::fromStdString(nameGroup));
|
||||
item->setData(0, ROLE_VARSET_NAME, varSetItem->data(0, ROLE_VARSET_NAME));
|
||||
item->setData(0, ROLE_VARSET_LABEL, varSetItem->data(0, ROLE_VARSET_LABEL));
|
||||
item->setData(0, ROLE_DOC, varSetItem->data(0, ROLE_DOC));
|
||||
}
|
||||
}
|
||||
|
||||
static void addVarSetsVarSetComboBox(std::vector<App::VarSet*>& varSets, QTreeWidgetItem* docItem)
|
||||
{
|
||||
for (auto varSet : varSets) {
|
||||
auto vp = Base::freecad_dynamic_cast<Gui::ViewProviderDocumentObject>(
|
||||
Gui::Application::Instance->getViewProvider(varSet));
|
||||
// the item will be automatically destroyed when the docItem will be destroyed
|
||||
auto item = new QTreeWidgetItem(docItem);
|
||||
item->setIcon(0, vp->getIcon());
|
||||
item->setText(0, QString::fromUtf8(varSet->Label.getValue()));
|
||||
item->setData(0, ROLE_VARSET_LABEL, QString::fromUtf8(varSet->Label.getValue()));
|
||||
item->setData(0, ROLE_VARSET_NAME, QString::fromUtf8(varSet->getNameInDocument()));
|
||||
item->setData(0, ROLE_DOC, docItem->data(0, ROLE_DOC));
|
||||
addGroupsVarSetComboBox(varSet, item);
|
||||
}
|
||||
}
|
||||
|
||||
static void addDocVarSetComboBox(App::Document* doc, QPixmap& docIcon, QTreeWidgetItem* rootItem)
|
||||
{
|
||||
if (!doc->testStatus(App::Document::TempDoc)) {
|
||||
std::vector<App::VarSet*> varSets;
|
||||
getVarSetsDocument(varSets, doc);
|
||||
if (!varSets.empty()) {
|
||||
// the item will be automatically destroyed when the rootItem will be destroyed
|
||||
auto item = new QTreeWidgetItem(rootItem);
|
||||
item->setIcon(0, docIcon);
|
||||
item->setText(0, QString::fromUtf8(doc->Label.getValue()));
|
||||
item->setData(0, ROLE_DOC, QByteArray(doc->getName()));
|
||||
item->setFlags(Qt::ItemIsEnabled);
|
||||
item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
|
||||
addVarSetsVarSetComboBox(varSets, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static QTreeWidget* createVarSetTreeWidget()
|
||||
{
|
||||
// the caller of the function is responsible of managing the tree widget
|
||||
auto treeWidget = new QTreeWidget();
|
||||
treeWidget->setColumnCount(1);
|
||||
treeWidget->setHeaderHidden(true);
|
||||
// the rootItem will be destroyed when the treeWidget will be destroyed
|
||||
QTreeWidgetItem *rootItem = treeWidget->invisibleRootItem();
|
||||
|
||||
QPixmap docIcon(Gui::BitmapFactory().pixmap("Document"));
|
||||
std::vector<App::Document*> docs = App::GetApplication().getDocuments();
|
||||
|
||||
for (auto doc : docs) {
|
||||
addDocVarSetComboBox(doc, docIcon, rootItem);
|
||||
}
|
||||
treeWidget->expandAll();
|
||||
|
||||
return treeWidget;
|
||||
}
|
||||
|
||||
void DlgExpressionInput::setupVarSets()
|
||||
{
|
||||
ui->comboBoxVarSet->clear();
|
||||
// createVarSetTreeWidget returns a dynamically allocated tree widget
|
||||
// the memory is managed by means of the unique pointer treeWidget.
|
||||
treeWidget.reset(createVarSetTreeWidget());
|
||||
ui->comboBoxVarSet->setModel(treeWidget->model());
|
||||
ui->comboBoxVarSet->setView(treeWidget.get());
|
||||
|
||||
ui->okBtn->setEnabled(false);
|
||||
}
|
||||
|
||||
std::string DlgExpressionInput::getType()
|
||||
{
|
||||
return determineTypeVarSet().getName();
|
||||
}
|
||||
|
||||
void DlgExpressionInput::onCheckVarSets(int state) {
|
||||
varSetsVisible = state == Qt::Checked;
|
||||
ui->groupBoxVarSets->setVisible(varSetsVisible);
|
||||
if (varSetsVisible) {
|
||||
setupVarSets();
|
||||
}
|
||||
else {
|
||||
ui->okBtn->setEnabled(true); // normal expression
|
||||
}
|
||||
}
|
||||
|
||||
void DlgExpressionInput::onVarSetSelected(int)
|
||||
{
|
||||
QTreeWidgetItem* selected = treeWidget->currentItem();
|
||||
|
||||
if (selected) {
|
||||
// if group is known, fill it in
|
||||
QVariant variantGroup = selected->data(0, ROLE_GROUP);
|
||||
if (variantGroup.isValid()) {
|
||||
ui->lineEditGroup->setText(variantGroup.toString());
|
||||
}
|
||||
else {
|
||||
ui->lineEditGroup->clear();
|
||||
}
|
||||
}
|
||||
|
||||
updateVarSetInfo();
|
||||
}
|
||||
|
||||
void DlgExpressionInput::onTextChangedGroup(const QString&)
|
||||
{
|
||||
updateVarSetInfo();
|
||||
}
|
||||
|
||||
void DlgExpressionInput::namePropChanged(const QString&)
|
||||
{
|
||||
updateVarSetInfo();
|
||||
}
|
||||
|
||||
static bool isNameGroupOk(const QString& nameGroup,
|
||||
std::stringstream& message)
|
||||
{
|
||||
std::string name = nameGroup.toStdString();
|
||||
if (name.empty() || name != Base::Tools::getIdentifier(name)) {
|
||||
message << "Invalid group name (must only contain alphanumericals, underscore, "
|
||||
<< "and must not start with digit";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DlgExpressionInput::reportVarSetInfo(const char* message)
|
||||
{
|
||||
ui->labelInfoActive->setText(QString::fromUtf8(message));
|
||||
}
|
||||
|
||||
bool DlgExpressionInput::reportGroup(QString& nameGroup)
|
||||
{
|
||||
if (nameGroup.isEmpty()) {
|
||||
reportVarSetInfo("Please provide a group.");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::stringstream message;
|
||||
if (!isNameGroupOk(nameGroup, message)) {
|
||||
reportVarSetInfo(message.str().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DlgExpressionInput::reportName(QTreeWidgetItem* item)
|
||||
{
|
||||
QString nameProp = ui->lineEditPropNew->text();
|
||||
QString nameVarSet = getValue(item, ROLE_VARSET_NAME);
|
||||
QString nameDoc = getValue(item, ROLE_DOC);
|
||||
App::Document* doc = App::GetApplication().getDocument(nameDoc.toUtf8());
|
||||
App::DocumentObject* obj = doc->getObject(nameVarSet.toUtf8());
|
||||
std::stringstream message;
|
||||
if (!isNamePropOk(nameProp, obj, message)) {
|
||||
reportVarSetInfo(message.str().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DlgExpressionInput::updateVarSetInfo(bool checkExpr)
|
||||
{
|
||||
QTreeWidgetItem* selected = treeWidget->currentItem();
|
||||
|
||||
if (selected) {
|
||||
QString nameGroup = ui->lineEditGroup->text();
|
||||
if (reportGroup(nameGroup)) {
|
||||
// needed to report something about the group, so disable the button
|
||||
ui->okBtn->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reportName(selected)) {
|
||||
// needed to report something about the name, so disable the button
|
||||
ui->okBtn->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
QString nameProp = ui->lineEditPropNew->text();
|
||||
QString labelVarSet = getValue(selected, ROLE_VARSET_LABEL);
|
||||
QString nameDoc = getValue(selected, ROLE_DOC);
|
||||
std::stringstream message;
|
||||
message << "Adding property " << nameProp.toStdString() << std::endl
|
||||
<< "of type " << getType() << std::endl
|
||||
<< "to variable set " << labelVarSet.toStdString() << std::endl
|
||||
<< "in group " << nameGroup.toStdString() << std::endl
|
||||
<< "in document " << nameDoc.toStdString() << ".";
|
||||
|
||||
reportVarSetInfo(message.str().c_str());
|
||||
if (checkExpr) {
|
||||
// We have to check the text of the expression as well
|
||||
try {
|
||||
checkExpression(ui->expression->text());
|
||||
ui->okBtn->setEnabled(true);
|
||||
}
|
||||
catch (Base::Exception& e) {
|
||||
ui->okBtn->setDisabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui->okBtn->setEnabled(false);
|
||||
reportVarSetInfo("Please select a variable set.");
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_DlgExpressionInput.cpp"
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
#define GUI_DIALOG_DLGEXPRESSIONINPUT_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTreeWidget>
|
||||
#include <App/ObjectIdentifier.h>
|
||||
#include <Base/Type.h>
|
||||
#include <Base/Unit.h>
|
||||
#include <memory>
|
||||
|
||||
@@ -78,14 +80,33 @@ public:
|
||||
|
||||
public Q_SLOTS:
|
||||
void show();
|
||||
void accept() override;
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent(QMouseEvent*) override;
|
||||
void mousePressEvent(QMouseEvent*) override;
|
||||
|
||||
private:
|
||||
Base::Type getTypePath();
|
||||
Base::Type determineTypeVarSet();
|
||||
bool typeOkForVarSet();
|
||||
void initializeVarSets();
|
||||
void checkExpression(const QString& text);
|
||||
void setupVarSets();
|
||||
std::string getType();
|
||||
void reportVarSetInfo(const char* message);
|
||||
bool reportName(QTreeWidgetItem* item);
|
||||
bool reportGroup(QString& nameGroup);
|
||||
void updateVarSetInfo(bool checkExpr = true);
|
||||
void acceptWithVarSet();
|
||||
|
||||
private Q_SLOTS:
|
||||
void textChanged(const QString & text);
|
||||
void setDiscarded();
|
||||
void onCheckVarSets(int state);
|
||||
void onVarSetSelected(int);
|
||||
void onTextChangedGroup(const QString&);
|
||||
void namePropChanged(const QString&);
|
||||
|
||||
private:
|
||||
::Ui::DlgExpressionInput *ui;
|
||||
@@ -96,6 +117,9 @@ private:
|
||||
NumberRange numberRange;
|
||||
|
||||
int minimumWidth;
|
||||
|
||||
static bool varSetsVisible;
|
||||
std::unique_ptr<QTreeWidget> treeWidget;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>414</width>
|
||||
<height>95</height>
|
||||
<height>272</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -29,94 +29,175 @@
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<property name="margin" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="ctrlArea">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
<widget class="QGroupBox" name="groupBoxVarSets">
|
||||
<property name="title">
|
||||
<string>Variable Sets</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayoutVarSets">
|
||||
<item row="1" column="2">
|
||||
<widget class="QLineEdit" name="lineEditGroup"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelGroup">
|
||||
<property name="text">
|
||||
<string>Group:</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="labelInfoActive">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>70</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelVarSet">
|
||||
<property name="text">
|
||||
<string>Variable Set:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QComboBox" name="comboBoxVarSet"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelInfo">
|
||||
<property name="text">
|
||||
<string>Info:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="LabelPropNew">
|
||||
<property name="text">
|
||||
<string>New Property:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLineEdit" name="lineEditPropNew">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Result:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="msg">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>190</red>
|
||||
<green>190</green>
|
||||
<blue>190</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBoxVarSets">
|
||||
<property name="text">
|
||||
<string>Show variable sets</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="ctrlArea">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="margin" stdset="0">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Result:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="msg">
|
||||
<property name="palette">
|
||||
<palette>
|
||||
<active>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</active>
|
||||
<inactive>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</inactive>
|
||||
<disabled>
|
||||
<colorrole role="Text">
|
||||
<brush brushstyle="SolidPattern">
|
||||
<color alpha="255">
|
||||
<red>190</red>
|
||||
<green>190</green>
|
||||
<blue>190</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</colorrole>
|
||||
</disabled>
|
||||
</palette>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
@@ -175,12 +256,12 @@
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="discardBtn">
|
||||
<property name="text">
|
||||
<string>&Clear</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Revert to last calculated value (as constant)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Clear</string>
|
||||
</property>
|
||||
<property name="autoDefault">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@@ -233,10 +314,6 @@
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>label</zorder>
|
||||
<zorder>expression</zorder>
|
||||
<zorder>widget</zorder>
|
||||
<zorder>ctrlArea</zorder>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
@@ -245,6 +322,12 @@
|
||||
<header>ExpressionCompleter.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>expression</tabstop>
|
||||
<tabstop>okBtn</tabstop>
|
||||
<tabstop>discardBtn</tabstop>
|
||||
<tabstop>checkBoxVarSets</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
|
||||
Reference in New Issue
Block a user