Core: Fix adding VarSet props with existing prefix
This commit is contained in:
committed by
Chris Hennes
parent
ece64bea29
commit
8534affff0
@@ -46,6 +46,8 @@ using namespace Gui::Dialog;
|
||||
|
||||
const std::string DlgAddPropertyVarSet::GROUP_BASE = "Base";
|
||||
|
||||
const bool CLEAR_NAME = true;
|
||||
|
||||
DlgAddPropertyVarSet::DlgAddPropertyVarSet(QWidget* parent,
|
||||
ViewProviderVarSet* viewProvider)
|
||||
: QDialog(parent),
|
||||
@@ -65,7 +67,7 @@ DlgAddPropertyVarSet::~DlgAddPropertyVarSet() = default;
|
||||
void DlgAddPropertyVarSet::initializeGroup()
|
||||
{
|
||||
connect(&comboBoxGroup, &EditFinishedComboBox::editFinished,
|
||||
this, &DlgAddPropertyVarSet::onGroupDetermined);
|
||||
this, &DlgAddPropertyVarSet::onEditFinished);
|
||||
comboBoxGroup.setObjectName(QString::fromUtf8("comboBoxGroup"));
|
||||
comboBoxGroup.setInsertPolicy(QComboBox::InsertAtTop);
|
||||
comboBoxGroup.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
@@ -138,8 +140,8 @@ void DlgAddPropertyVarSet::initializeTypes()
|
||||
ui->comboBoxType->setCompleter(&completerType);
|
||||
ui->comboBoxType->setInsertPolicy(QComboBox::NoInsert);
|
||||
|
||||
connect(ui->comboBoxType, qOverload<int>(&QComboBox::currentIndexChanged),
|
||||
this, &DlgAddPropertyVarSet::onTypePropertyDetermined);
|
||||
connect(ui->comboBoxType, &QComboBox::currentTextChanged,
|
||||
this, &DlgAddPropertyVarSet::onEditFinished);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -149,12 +151,12 @@ static void printFocusChain(QWidget *widget) {
|
||||
QWidget* start = widget;
|
||||
int i = 0;
|
||||
do {
|
||||
FC_ERR(" " << widget->objectName().toUtf8().constData());
|
||||
FC_ERR(" " << widget->objectName().toStdString();
|
||||
widget = widget->nextInFocusChain();
|
||||
i++;
|
||||
} while (widget != nullptr && i < 30 && start != widget);
|
||||
QWidget *currentWidget = QApplication::focusWidget();
|
||||
FC_ERR(" Current focus widget:" << (currentWidget ? currentWidget->objectName().toUtf8().constData() : "None") << std::endl << std::endl);
|
||||
FC_ERR(" Current focus widget:" << (currentWidget ? currentWidget->objectName().toStdString() : "None") << std::endl << std::endl);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -165,8 +167,10 @@ void DlgAddPropertyVarSet::initializeWidgets(ViewProviderVarSet* viewProvider)
|
||||
|
||||
connect(this, &QDialog::finished,
|
||||
this, [viewProvider](int result) { viewProvider->onFinished(result); });
|
||||
connect(ui->lineEditName, &QLineEdit::editingFinished,
|
||||
this, &DlgAddPropertyVarSet::onEditFinished);
|
||||
connect(ui->lineEditName, &QLineEdit::textChanged,
|
||||
this, &DlgAddPropertyVarSet::onNamePropertyDetermined);
|
||||
this, &DlgAddPropertyVarSet::onNamePropertyChanged);
|
||||
|
||||
std::string title = "Add a property to " + varSet->getFullName();
|
||||
setWindowTitle(QString::fromStdString(title));
|
||||
@@ -188,11 +192,13 @@ void DlgAddPropertyVarSet::setOkEnabled(bool enabled)
|
||||
okButton->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void DlgAddPropertyVarSet::clearEditors()
|
||||
void DlgAddPropertyVarSet::clearEditors(bool clearName)
|
||||
{
|
||||
bool beforeBlocked = ui->lineEditName->blockSignals(true);
|
||||
ui->lineEditName->clear();
|
||||
ui->lineEditName->blockSignals(beforeBlocked);
|
||||
if (clearName) {
|
||||
bool beforeBlocked = ui->lineEditName->blockSignals(true);
|
||||
ui->lineEditName->clear();
|
||||
ui->lineEditName->blockSignals(beforeBlocked);
|
||||
}
|
||||
removeEditor();
|
||||
setOkEnabled(false);
|
||||
namePropertyToAdd.clear();
|
||||
@@ -249,9 +255,11 @@ bool DlgAddPropertyVarSet::isTypeWithEditor(const std::string& type)
|
||||
return typesWithoutEditor.find(type) == typesWithoutEditor.end();
|
||||
}
|
||||
|
||||
void DlgAddPropertyVarSet::createProperty(std::string& name, std::string& group)
|
||||
void DlgAddPropertyVarSet::createProperty()
|
||||
{
|
||||
std::string type = ui->comboBoxType->currentText().toUtf8().constData();
|
||||
std::string name = ui->lineEditName->text().toStdString();
|
||||
std::string group = comboBoxGroup.currentText().toStdString();
|
||||
std::string type = ui->comboBoxType->currentText().toStdString();
|
||||
|
||||
App::Property* prop;
|
||||
try {
|
||||
@@ -285,60 +293,81 @@ void DlgAddPropertyVarSet::createProperty(std::string& name, std::string& group)
|
||||
setOkEnabled(true);
|
||||
}
|
||||
|
||||
void DlgAddPropertyVarSet::onNamePropertyDetermined(const QString& text)
|
||||
{
|
||||
if (!namePropertyToAdd.empty()) {
|
||||
// We were already adding a property with this name. We have to remove
|
||||
// the property, the editor because it is associated with the property,
|
||||
// and we have to abort the transaction.
|
||||
void DlgAddPropertyVarSet::changePropertyToAdd() {
|
||||
// we were already adding a new property, the only option to get here
|
||||
// is a change of type or group.
|
||||
|
||||
std::string name = ui->lineEditName->text().toStdString();
|
||||
assert(name == namePropertyToAdd);
|
||||
|
||||
App::Property* prop = varSet->getPropertyByName(namePropertyToAdd.c_str());
|
||||
|
||||
std::string group = comboBoxGroup.currentText().toStdString();
|
||||
if (prop->getGroup() != group) {
|
||||
varSet->changeDynamicProperty(prop, group.c_str(), nullptr);
|
||||
}
|
||||
|
||||
std::string type = ui->comboBoxType->currentText().toStdString();
|
||||
if (prop->getTypeId() != Base::Type::fromName(type.c_str())) {
|
||||
// the property should have a different type
|
||||
varSet->removeDynamicProperty(namePropertyToAdd.c_str());
|
||||
removeEditor();
|
||||
App::Document* doc = varSet->getDocument();
|
||||
if (doc->hasPendingTransaction()) {
|
||||
doc->abortTransaction();
|
||||
}
|
||||
namePropertyToAdd.clear();
|
||||
createProperty();
|
||||
}
|
||||
if (text.isEmpty()) {
|
||||
// We can not define a property, so we should not have an editor for the value.
|
||||
clearEditors();
|
||||
return;
|
||||
}
|
||||
std::string name = text.toUtf8().constData();
|
||||
std::string group = comboBoxGroup.currentText().toUtf8().constData();
|
||||
if(name.empty() || group.empty()
|
||||
|| name != Base::Tools::getIdentifier(name)
|
||||
|| group != Base::Tools::getIdentifier(group)) {
|
||||
QMessageBox::critical(getMainWindow(),
|
||||
QObject::tr("Invalid name"),
|
||||
QObject::tr("The property name or group name must only contain alpha numericals,\n"
|
||||
"underscore, and must not start with a digit."));
|
||||
clearEditors();
|
||||
return;
|
||||
}
|
||||
|
||||
auto prop = varSet->getPropertyByName(name.c_str());
|
||||
if(prop && prop->getContainer() == varSet) {
|
||||
QMessageBox::critical(this,
|
||||
QObject::tr("Invalid name"),
|
||||
QObject::tr("The property '%1' already exists in '%2'").arg(
|
||||
QString::fromLatin1(name.c_str()),
|
||||
QString::fromLatin1(varSet->getFullName().c_str())));
|
||||
clearEditors();
|
||||
return;
|
||||
}
|
||||
|
||||
App::Document* doc = varSet->getDocument();
|
||||
doc->openTransaction("Add property VarSet");
|
||||
createProperty(name, group);
|
||||
|
||||
// FC_ERR("chain onNameDetermined");
|
||||
// printFocusChain(ui->lineEditName);
|
||||
}
|
||||
|
||||
void DlgAddPropertyVarSet::onGroupDetermined()
|
||||
|
||||
void DlgAddPropertyVarSet::clearCurrentProperty()
|
||||
{
|
||||
std::string group = comboBoxGroup.currentText().toUtf8().constData();
|
||||
removeEditor();
|
||||
varSet->removeDynamicProperty(namePropertyToAdd.c_str());
|
||||
App::Document* doc = varSet->getDocument();
|
||||
if (doc->hasPendingTransaction()) {
|
||||
doc->abortTransaction();
|
||||
}
|
||||
setOkEnabled(false);
|
||||
namePropertyToAdd.clear();
|
||||
}
|
||||
|
||||
class CreatePropertyException : public std::exception {
|
||||
public:
|
||||
explicit CreatePropertyException(const std::string& message) : msg(message) {}
|
||||
|
||||
const char* what() const noexcept override {
|
||||
return msg.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
void DlgAddPropertyVarSet::checkName() {
|
||||
std::string name = ui->lineEditName->text().toStdString();
|
||||
if(name.empty() || name != Base::Tools::getIdentifier(name)) {
|
||||
QMessageBox::critical(getMainWindow(),
|
||||
QObject::tr("Invalid name"),
|
||||
QObject::tr("The property name must only contain alpha numericals,\n"
|
||||
"underscore, and must not start with a digit."));
|
||||
clearEditors(!CLEAR_NAME);
|
||||
throw CreatePropertyException("Invalid name");
|
||||
}
|
||||
|
||||
if (namePropertyToAdd.empty()) {
|
||||
// we are adding a new property, check whether it doesn't already exist
|
||||
auto prop = varSet->getPropertyByName(name.c_str());
|
||||
if(prop && prop->getContainer() == varSet) {
|
||||
QMessageBox::critical(this,
|
||||
QObject::tr("Invalid name"),
|
||||
QObject::tr("The property '%1' already exists in '%2'").arg(
|
||||
QString::fromLatin1(name.c_str()),
|
||||
QString::fromLatin1(varSet->getFullName().c_str())));
|
||||
clearEditors(!CLEAR_NAME);
|
||||
throw CreatePropertyException("Invalid name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DlgAddPropertyVarSet::checkGroup() {
|
||||
std::string group = comboBoxGroup.currentText().toStdString();
|
||||
|
||||
if (group.empty() || group != Base::Tools::getIdentifier(group)) {
|
||||
QMessageBox::critical(this,
|
||||
@@ -346,36 +375,58 @@ void DlgAddPropertyVarSet::onGroupDetermined()
|
||||
QObject::tr("The group name must only contain alpha numericals,\n"
|
||||
"underscore, and must not start with a digit."));
|
||||
comboBoxGroup.setEditText(QString::fromUtf8("Base"));
|
||||
throw CreatePropertyException("Invalid name");
|
||||
}
|
||||
}
|
||||
|
||||
void DlgAddPropertyVarSet::checkType() {
|
||||
std::string type = ui->comboBoxType->currentText().toStdString();
|
||||
|
||||
if (Base::Type::fromName(type.c_str()) == Base::Type::badType()) {
|
||||
throw CreatePropertyException("Invalid name");
|
||||
}
|
||||
}
|
||||
|
||||
void DlgAddPropertyVarSet::onEditFinished() {
|
||||
/* The editor for the value is dynamically created if 1) the name has been
|
||||
* determined and 2) if the type of the property has been determined. The
|
||||
* group of the property is important too, but it is not essential, because
|
||||
* we can change the group after the property has been created.
|
||||
*
|
||||
* In this function we check whether we can create a property and therefore
|
||||
* an editor.
|
||||
*/
|
||||
|
||||
try {
|
||||
checkName();
|
||||
checkGroup();
|
||||
checkType();
|
||||
}
|
||||
catch (const CreatePropertyException& e) {
|
||||
if (!namePropertyToAdd.empty()) {
|
||||
clearCurrentProperty();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!namePropertyToAdd.empty()) {
|
||||
// we were already adding a property
|
||||
App::Property* prop = varSet->getPropertyByName(namePropertyToAdd.c_str());
|
||||
if (prop->getGroup() != group) {
|
||||
varSet->changeDynamicProperty(prop, group.c_str(), nullptr);
|
||||
}
|
||||
if (namePropertyToAdd.empty()) {
|
||||
// we are adding a new property
|
||||
App::Document* doc = varSet->getDocument();
|
||||
doc->openTransaction("Add property VarSet");
|
||||
createProperty();
|
||||
}
|
||||
else {
|
||||
// we were already adding a new property that should now be changed
|
||||
changePropertyToAdd();
|
||||
}
|
||||
|
||||
// FC_ERR("chain onGroupDetermined");
|
||||
// printFocusChain(&comboBoxGroup);
|
||||
ui->comboBoxType->setFocus();
|
||||
}
|
||||
|
||||
void DlgAddPropertyVarSet::onTypePropertyDetermined()
|
||||
void DlgAddPropertyVarSet::onNamePropertyChanged(const QString& text)
|
||||
{
|
||||
std::string type = ui->comboBoxType->currentText().toUtf8().constData();
|
||||
|
||||
if (!namePropertyToAdd.empty()) {
|
||||
// we were already adding a name, so check this property
|
||||
App::Property* prop = varSet->getPropertyByName(namePropertyToAdd.c_str());
|
||||
|
||||
if (prop->getTypeId() != Base::Type::fromName(type.c_str())) {
|
||||
// the property should have a different type
|
||||
std::string group = prop->getGroup();
|
||||
varSet->removeDynamicProperty(namePropertyToAdd.c_str());
|
||||
createProperty(namePropertyToAdd, group);
|
||||
}
|
||||
if (!namePropertyToAdd.empty() && text.toStdString() != namePropertyToAdd) {
|
||||
// The user decided to change the name of the property. This
|
||||
// invalidates the editor that is strictly associated with the property.
|
||||
clearCurrentProperty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,8 +449,8 @@ void DlgAddPropertyVarSet::accept()
|
||||
return;
|
||||
}
|
||||
|
||||
std::string group = comboBoxGroup.currentText().toUtf8().constData();
|
||||
std::string type = ui->comboBoxType->currentText().toUtf8().constData();
|
||||
std::string group = comboBoxGroup.currentText().toStdString();
|
||||
std::string type = ui->comboBoxType->currentText().toStdString();
|
||||
auto paramGroup = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/PropertyView");
|
||||
paramGroup->SetASCII("NewPropertyType", type.c_str());
|
||||
|
||||
@@ -79,17 +79,21 @@ private:
|
||||
void initializeWidgets(ViewProviderVarSet* viewProvider);
|
||||
|
||||
void setOkEnabled(bool enabled);
|
||||
void clearEditors();
|
||||
void clearEditors(bool clearName = true);
|
||||
void clearCurrentProperty();
|
||||
|
||||
void removeEditor();
|
||||
void addEditor(PropertyEditor::PropertyItem* propertyItem, std::string& type);
|
||||
|
||||
bool isTypeWithEditor(const std::string& type);
|
||||
void createProperty(std::string& name, std::string& group);
|
||||
void createProperty();
|
||||
void changePropertyToAdd();
|
||||
|
||||
void onNamePropertyDetermined(const QString& text);
|
||||
void onGroupDetermined();
|
||||
void onTypePropertyDetermined();
|
||||
void checkName();
|
||||
void checkGroup();
|
||||
void checkType();
|
||||
void onEditFinished();
|
||||
void onNamePropertyChanged(const QString& text);
|
||||
|
||||
void getSupportedTypes(std::vector<Base::Type>& types);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user