/*************************************************************************** * Copyright (c) 2002 Jürgen Riegel * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ #include #include #include #include #include #include #include #include #endif #include #include #include #include "DlgParameterImp.h" #include "ui_DlgParameter.h" #include "BitmapFactory.h" #include "DlgParameterFind.h" #include "DlgInputDialogImp.h" #include "FileDialog.h" #include "SpinBox.h" using namespace Gui::Dialog; /* TRANSLATOR Gui::Dialog::DlgParameterImp */ /** * Constructs a DlgParameterImp which is a child of 'parent', with the * name 'name' and widget flags set to 'f' * * The dialog will by default be modeless, unless you set 'modal' to * true to construct a modal dialog. */ DlgParameterImp::DlgParameterImp(QWidget* parent, Qt::WindowFlags fl) : QDialog(parent, fl | Qt::WindowMinMaxButtonsHint) , ui(new Ui_DlgParameter) { ui->setupUi(this); setupConnections(); ui->checkSort->setVisible(false); // for testing QStringList groupLabels; groupLabels << tr("Group"); paramGroup = new ParameterGroup(ui->splitter3); paramGroup->setHeaderLabels(groupLabels); paramGroup->setRootIsDecorated(false); paramGroup->setSortingEnabled(true); paramGroup->sortByColumn(0, Qt::AscendingOrder); paramGroup->header()->setProperty("showSortIndicator", QVariant(true)); QStringList valueLabels; valueLabels << tr("Name") << tr("Type") << tr("Value"); paramValue = new ParameterValue(ui->splitter3); paramValue->setHeaderLabels(valueLabels); paramValue->setRootIsDecorated(false); paramValue->header()->setSectionResizeMode(0, QHeaderView::Stretch); paramValue->setSortingEnabled(true); paramValue->sortByColumn(0, Qt::AscendingOrder); paramValue->header()->setProperty("showSortIndicator", QVariant(true)); QSizePolicy policy = paramValue->sizePolicy(); policy.setHorizontalStretch(3); paramValue->setSizePolicy(policy); #if 0 // This is needed for Qt's lupdate qApp->translate( "Gui::Dialog::DlgParameterImp", "System parameter" ); qApp->translate( "Gui::Dialog::DlgParameterImp", "User parameter" ); #endif ParameterManager* sys = App::GetApplication().GetParameterSet("System parameter"); const auto& rcList = App::GetApplication().GetParameterSetList(); for (const auto& it : rcList) { if (it.second != sys) { // for now ignore system parameters because they are nowhere used ui->parameterSet->addItem(tr(it.first.c_str()), QVariant(QByteArray(it.first.c_str()))); } } QByteArray cStr("User parameter"); ui->parameterSet->setCurrentIndex(ui->parameterSet->findData(cStr)); onChangeParameterSet(ui->parameterSet->currentIndex()); if (ui->parameterSet->count() < 2) { ui->parameterSet->hide(); } connect(ui->parameterSet, qOverload(&QComboBox::activated), this, &DlgParameterImp::onChangeParameterSet); connect(paramGroup, &QTreeWidget::currentItemChanged, this, &DlgParameterImp::onGroupSelected); onGroupSelected(paramGroup->currentItem()); // setup for function on_findGroup_changed: // store the current font properties because // we don't know what style sheet the user uses for FC defaultFont = paramGroup->font(); boldFont = defaultFont; boldFont.setBold(true); defaultColor = paramGroup->topLevelItem(0)->foreground(0); ui->findGroupLE->setPlaceholderText(tr("Search Group")); } /** * Destroys the object and frees any allocated resources */ DlgParameterImp::~DlgParameterImp() { // no need to delete child widgets, Qt does it all for us delete ui; } void DlgParameterImp::setupConnections() { // clang-format off connect(ui->buttonFind, &QPushButton::clicked, this, &DlgParameterImp::onButtonFindClicked); connect(ui->findGroupLE, &QLineEdit::textChanged, this, &DlgParameterImp::onFindGroupTtextChanged); connect(ui->buttonSaveToDisk, &QPushButton::clicked, this, &DlgParameterImp::onButtonSaveToDiskClicked); connect(ui->closeButton, &QPushButton::clicked, this, &DlgParameterImp::onCloseButtonClicked); connect(ui->checkSort, &QCheckBox::toggled, this, &DlgParameterImp::onCheckSortToggled); // clang-format on } void DlgParameterImp::onButtonFindClicked() { if (finder.isNull()) { finder = new DlgParameterFind(this); } finder->show(); } void DlgParameterImp::onFindGroupTtextChanged(const QString& SearchStr) { // search for group tree items and highlight found results QTreeWidgetItem* ExpandItem; // at first reset all items to the default font and expand state if (!foundList.empty()) { for (QTreeWidgetItem* item : std::as_const(foundList)) { item->setFont(0, defaultFont); item->setForeground(0, defaultColor); ExpandItem = item; // a group can be nested down to several levels // do not collapse if the search string is empty while (!SearchStr.isEmpty()) { if (!ExpandItem->parent()) { break; } else { ExpandItem->setExpanded(false); ExpandItem = ExpandItem->parent(); } } } } // expand the top level entries to get the initial tree state for (int i = 0; i < paramGroup->topLevelItemCount(); ++i) { paramGroup->topLevelItem(i)->setExpanded(true); } // don't perform a search if the string is empty if (SearchStr.isEmpty()) { return; } // search the tree widget foundList = paramGroup->findItems(SearchStr, Qt::MatchContains | Qt::MatchRecursive); if (!foundList.empty()) { // reset background style sheet if (!ui->findGroupLE->styleSheet().isEmpty()) { ui->findGroupLE->setStyleSheet(QString()); } for (QTreeWidgetItem* item : std::as_const(foundList)) { item->setFont(0, boldFont); item->setForeground(0, Qt::red); // expand its parent to see the item // a group can be nested down to several levels ExpandItem = item; while (true) { if (!ExpandItem->parent()) { break; } else { ExpandItem->setExpanded(true); ExpandItem = ExpandItem->parent(); } } // if there is only one item found, scroll to it if (foundList.size() == 1) { paramGroup->scrollToItem(foundList[0], QAbstractItemView::PositionAtCenter); } } } else { // Set red background to indicate no matching QString styleSheet = QString::fromLatin1(" QLineEdit {\n" " background-color: rgb(221,144,161);\n" " }\n"); ui->findGroupLE->setStyleSheet(styleSheet); } } /** * Sets the strings of the subwidgets using the current * language. */ void DlgParameterImp::changeEvent(QEvent* e) { if (e->type() == QEvent::LanguageChange) { ui->retranslateUi(this); paramGroup->headerItem()->setText(0, tr("Group")); paramValue->headerItem()->setText(0, tr("Name")); paramValue->headerItem()->setText(1, tr("Type")); paramValue->headerItem()->setText(2, tr("Value")); } else { QDialog::changeEvent(e); } } void DlgParameterImp::onCheckSortToggled(bool on) { paramGroup->setSortingEnabled(on); paramGroup->sortByColumn(0, Qt::AscendingOrder); paramGroup->header()->setProperty("showSortIndicator", QVariant(on)); paramValue->setSortingEnabled(on); paramValue->sortByColumn(0, Qt::AscendingOrder); paramValue->header()->setProperty("showSortIndicator", QVariant(on)); } void DlgParameterImp::onCloseButtonClicked() { close(); } void DlgParameterImp::accept() { close(); } void DlgParameterImp::reject() { close(); } void DlgParameterImp::showEvent(QShowEvent*) { ParameterGrp::handle hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("Preferences"); hGrp = hGrp->GetGroup("ParameterEditor"); std::string buf = hGrp->GetASCII("Geometry", ""); if (!buf.empty()) { int x1, y1, x2, y2; char sep; std::stringstream str(buf); str >> sep >> x1 >> sep >> y1 >> sep >> x2 >> sep >> y2; QRect rect; rect.setCoords(x1, y1, x2, y2); this->setGeometry(rect); } } void DlgParameterImp::closeEvent(QCloseEvent*) { ParameterGrp::handle hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("Preferences"); hGrp = hGrp->GetGroup("ParameterEditor"); QTreeWidgetItem* current = paramGroup->currentItem(); if (current) { QStringList paths; paths << current->text(0); QTreeWidgetItem* parent = current->parent(); while (parent) { paths.push_front(parent->text(0)); parent = parent->parent(); } QString path = paths.join(QLatin1String(".")); hGrp->SetASCII("LastParameterGroup", (const char*)path.toUtf8()); // save geometry of window const QRect& r = this->geometry(); std::stringstream str; str << "(" << r.left() << "," << r.top() << "," << r.right() << "," << r.bottom() << ")"; hGrp->SetASCII("Geometry", str.str().c_str()); } } void DlgParameterImp::onGroupSelected(QTreeWidgetItem* item) { if (item && item->type() == QTreeWidgetItem::UserType + 1) { bool sortingEnabled = paramValue->isSortingEnabled(); paramValue->clear(); Base::Reference _hcGrp = static_cast(item)->_hcGrp; static_cast(paramValue)->setCurrentGroup(_hcGrp); // filling up Text nodes std::vector> mcTextMap = _hcGrp->GetASCIIMap(); for (const auto& It2 : mcTextMap) { (void)new ParameterText(paramValue, QString::fromUtf8(It2.first.c_str()), It2.second.c_str(), _hcGrp); } // filling up Int nodes std::vector> mcIntMap = _hcGrp->GetIntMap(); for (const auto& It3 : mcIntMap) { (void)new ParameterInt(paramValue, QString::fromUtf8(It3.first.c_str()), It3.second, _hcGrp); } // filling up Float nodes std::vector> mcFloatMap = _hcGrp->GetFloatMap(); for (const auto& It4 : mcFloatMap) { (void)new ParameterFloat(paramValue, QString::fromUtf8(It4.first.c_str()), It4.second, _hcGrp); } // filling up bool nodes std::vector> mcBoolMap = _hcGrp->GetBoolMap(); for (const auto& It5 : mcBoolMap) { (void)new ParameterBool(paramValue, QString::fromUtf8(It5.first.c_str()), It5.second, _hcGrp); } // filling up UInt nodes std::vector> mcUIntMap = _hcGrp->GetUnsignedMap(); for (const auto& It6 : mcUIntMap) { (void)new ParameterUInt(paramValue, QString::fromUtf8(It6.first.c_str()), It6.second, _hcGrp); } paramValue->setSortingEnabled(sortingEnabled); } } /** Switches the type of parameters with name @a config. */ void DlgParameterImp::activateParameterSet(const char* config) { int index = ui->parameterSet->findData(QByteArray(config)); if (index != -1) { ui->parameterSet->setCurrentIndex(index); onChangeParameterSet(index); } } /** Switches the type of parameters either to user or system parameters. */ void DlgParameterImp::onChangeParameterSet(int itemPos) { ParameterManager* rcParMngr = App::GetApplication().GetParameterSet(ui->parameterSet->itemData(itemPos).toByteArray()); if (!rcParMngr) { return; } rcParMngr->CheckDocument(); ui->buttonSaveToDisk->setEnabled(rcParMngr->HasSerializer()); // remove all labels paramGroup->clear(); paramValue->clear(); // root labels std::vector> grps = rcParMngr->GetGroups(); for (const auto& grp : grps) { auto item = new ParameterGroupItem(paramGroup, grp); paramGroup->expandItem(item); item->setIcon(0, QApplication::style()->standardPixmap(QStyle::SP_ComputerIcon)); } // get the path of the last selected group in the editor ParameterGrp::handle hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->GetGroup("Preferences"); hGrp = hGrp->GetGroup("ParameterEditor"); QString path = QString::fromUtf8(hGrp->GetASCII("LastParameterGroup").c_str()); #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) QStringList paths = path.split(QLatin1String("."), Qt::SkipEmptyParts); #else QStringList paths = path.split(QLatin1String("."), QString::SkipEmptyParts); #endif QTreeWidgetItem* parent = nullptr; for (int index = 0; index < paramGroup->topLevelItemCount() && !paths.empty(); index++) { QTreeWidgetItem* child = paramGroup->topLevelItem(index); if (child->text(0) == paths.front()) { paths.pop_front(); parent = child; } } while (parent && !paths.empty()) { parent->setExpanded(true); QTreeWidgetItem* item = parent; parent = nullptr; for (int index = 0; index < item->childCount(); index++) { QTreeWidgetItem* child = item->child(index); if (child->text(0) == paths.front()) { paths.pop_front(); parent = child; break; } } } if (parent) { paramGroup->setCurrentItem(parent); } else if (paramGroup->topLevelItemCount() > 0) { paramGroup->setCurrentItem(paramGroup->topLevelItem(0)); } } void DlgParameterImp::onButtonSaveToDiskClicked() { int index = ui->parameterSet->currentIndex(); ParameterManager* parmgr = App::GetApplication().GetParameterSet(ui->parameterSet->itemData(index).toByteArray()); if (!parmgr) { return; } parmgr->SaveDocument(); } namespace Gui { bool validateInput(QWidget* parent, const QString& input) { if (input.isEmpty()) { return false; } for (int i = 0; i < input.size(); i++) { const char c = input.at(i).toLatin1(); if ((c < '0' || c > '9') && // Numbers (c < 'A' || c > 'Z') && // Uppercase letters (c < 'a' || c > 'z') && // Lowercase letters (c != ' ')) { // Space QMessageBox::warning(parent, DlgParameterImp::tr("Invalid input"), DlgParameterImp::tr("Invalid key name '%1'").arg(input)); return false; } } return true; } } // namespace Gui // -------------------------------------------------------------------- /* TRANSLATOR Gui::Dialog::ParameterGroup */ ParameterGroup::ParameterGroup(QWidget* parent) : QTreeWidget(parent) { menuEdit = new QMenu(this); expandAct = menuEdit->addAction(tr("Expand"), this, &ParameterGroup::onToggleSelectedItem); menuEdit->addSeparator(); subGrpAct = menuEdit->addAction(tr("Add sub-group"), this, &ParameterGroup::onCreateSubgroup); removeAct = menuEdit->addAction(tr("Remove group"), this, &ParameterGroup::onDeleteSelectedItem); renameAct = menuEdit->addAction(tr("Rename group"), this, &ParameterGroup::onRenameSelectedItem); menuEdit->addSeparator(); exportAct = menuEdit->addAction(tr("Export parameter"), this, &ParameterGroup::onExportToFile); importAct = menuEdit->addAction(tr("Import parameter"), this, &ParameterGroup::onImportFromFile); menuEdit->setDefaultAction(expandAct); } ParameterGroup::~ParameterGroup() = default; void ParameterGroup::contextMenuEvent(QContextMenuEvent* event) { QTreeWidgetItem* item = currentItem(); if (item && item->isSelected()) { expandAct->setEnabled(item->childCount() > 0); // do not allow one to import parameters from a non-empty parameter group importAct->setEnabled(item->childCount() == 0); if (item->isExpanded()) { expandAct->setText(tr("Collapse")); } else { expandAct->setText(tr("Expand")); } menuEdit->popup(event->globalPos()); } } void ParameterGroup::keyPressEvent(QKeyEvent* event) { if (event->matches(QKeySequence::Delete)) { onDeleteSelectedItem(); } else { QTreeWidget::keyPressEvent(event); } } void ParameterGroup::onDeleteSelectedItem() { QTreeWidgetItem* sel = currentItem(); if (sel && sel->isSelected() && sel->parent()) { if (QMessageBox::question(this, tr("Remove group"), tr("Do you really want to remove this parameter group?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) { QTreeWidgetItem* parent = sel->parent(); int index = parent->indexOfChild(sel); parent->takeChild(index); std::string groupName = sel->text(0).toStdString(); // must delete the tree item here because it and its children still // hold a reference to the parameter group delete sel; auto para = static_cast(parent); para->_hcGrp->RemoveGrp(groupName.c_str()); } } } void ParameterGroup::onToggleSelectedItem() { QTreeWidgetItem* sel = currentItem(); if (sel && sel->isSelected()) { if (sel->isExpanded()) { sel->setExpanded(false); } else if (sel->childCount() > 0) { sel->setExpanded(true); } } } void ParameterGroup::onCreateSubgroup() { bool ok; QString name = QInputDialog::getText(this, QObject::tr("New sub-group"), QObject::tr("Enter the name:"), QLineEdit::Normal, QString(), &ok, Qt::MSWindowsFixedSizeDialogHint); if (ok && Gui::validateInput(this, name)) { QTreeWidgetItem* item = currentItem(); if (item && item->isSelected()) { auto para = static_cast(item); Base::Reference hGrp = para->_hcGrp; if (hGrp->HasGroup(name.toLatin1())) { QMessageBox::critical(this, tr("Existing sub-group"), tr("The sub-group '%1' already exists.").arg(name)); return; } hGrp = hGrp->GetGroup(name.toLatin1()); (void)new ParameterGroupItem(para, hGrp); expandItem(para); } } } void ParameterGroup::onExportToFile() { QString file = FileDialog::getSaveFileName(this, tr("Export parameter to file"), QString(), QString::fromLatin1("XML (*.FCParam)")); if (!file.isEmpty()) { QTreeWidgetItem* item = currentItem(); if (item && item->isSelected()) { auto para = static_cast(item); Base::Reference hGrp = para->_hcGrp; hGrp->exportTo(file.toUtf8()); } } } void ParameterGroup::onImportFromFile() { QString file = FileDialog::getOpenFileName(this, tr("Import parameter from file"), QString(), QString::fromLatin1("XML (*.FCParam)")); if (!file.isEmpty()) { QTreeWidgetItem* item = currentItem(); if (item && item->isSelected()) { auto para = static_cast(item); Base::Reference hGrp = para->_hcGrp; // remove the items and internal parameter values QList childs = para->takeChildren(); for (auto& child : childs) { delete child; } try { hGrp->importFrom(file.toUtf8()); std::vector> cSubGrps = hGrp->GetGroups(); for (const auto& cSubGrp : cSubGrps) { new ParameterGroupItem(para, cSubGrp); } para->setExpanded(para->childCount()); } catch (const Base::Exception&) { QMessageBox::critical(this, tr("Import Error"), tr("Reading from '%1' failed.").arg(file)); } } } } void ParameterGroup::onRenameSelectedItem() { QTreeWidgetItem* sel = currentItem(); if (sel && sel->isSelected()) { editItem(sel, 0); } } void ParameterGroup::changeEvent(QEvent* e) { if (e->type() == QEvent::LanguageChange) { expandAct->setText(tr("Expand")); subGrpAct->setText(tr("Add sub-group")); removeAct->setText(tr("Remove group")); renameAct->setText(tr("Rename group")); exportAct->setText(tr("Export parameter")); importAct->setText(tr("Import parameter")); } else { QTreeWidget::changeEvent(e); } } // -------------------------------------------------------------------- /* TRANSLATOR Gui::Dialog::ParameterValue */ ParameterValue::ParameterValue(QWidget* parent) : QTreeWidget(parent) { menuEdit = new QMenu(this); changeAct = menuEdit->addAction(tr("Change value"), this, qOverload<>(&ParameterValue::onChangeSelectedItem)); menuEdit->addSeparator(); removeAct = menuEdit->addAction(tr("Remove key"), this, &ParameterValue::onDeleteSelectedItem); renameAct = menuEdit->addAction(tr("Rename key"), this, &ParameterValue::onRenameSelectedItem); menuEdit->setDefaultAction(changeAct); menuEdit->addSeparator(); menuNew = menuEdit->addMenu(tr("New")); newStrAct = menuNew->addAction(tr("New string item"), this, &ParameterValue::onCreateTextItem); newFltAct = menuNew->addAction(tr("New float item"), this, &ParameterValue::onCreateFloatItem); newIntAct = menuNew->addAction(tr("New integer item"), this, &ParameterValue::onCreateIntItem); newUlgAct = menuNew->addAction(tr("New unsigned item"), this, &ParameterValue::onCreateUIntItem); newBlnAct = menuNew->addAction(tr("New Boolean item"), this, &ParameterValue::onCreateBoolItem); connect(this, &ParameterValue::itemDoubleClicked, this, qOverload(&ParameterValue::onChangeSelectedItem)); } ParameterValue::~ParameterValue() = default; void ParameterValue::setCurrentGroup(const Base::Reference& hGrp) { _hcGrp = hGrp; } Base::Reference ParameterValue::currentGroup() const { return _hcGrp; } bool ParameterValue::edit(const QModelIndex& index, EditTrigger trigger, QEvent* event) { if (index.column() > 0) { return false; } return QTreeWidget::edit(index, trigger, event); } void ParameterValue::contextMenuEvent(QContextMenuEvent* event) { QTreeWidgetItem* item = currentItem(); if (item && item->isSelected()) { menuEdit->popup(event->globalPos()); } else { // There is a regression in Qt 5.12.9 where it isn't checked that a sub-menu (here menuNew) // can be popped up without its parent menu (menuEdit) and thus causes a crash. // A workaround is to simply call exec() instead. // // menuNew->popup(event->globalPos()); menuNew->exec(event->globalPos()); } } void ParameterValue::keyPressEvent(QKeyEvent* event) { if (event->matches(QKeySequence::Delete)) { onDeleteSelectedItem(); } else { QTreeWidget::keyPressEvent(event); } } void ParameterValue::resizeEvent(QResizeEvent* event) { QHeaderView* hv = header(); hv->setSectionResizeMode(QHeaderView::Stretch); QTreeWidget::resizeEvent(event); hv->setSectionResizeMode(QHeaderView::Interactive); } void ParameterValue::onChangeSelectedItem(QTreeWidgetItem* item, int col) { if (item->isSelected() && col > 0) { static_cast(item)->changeValue(); } } void ParameterValue::onChangeSelectedItem() { onChangeSelectedItem(currentItem(), 1); } void ParameterValue::onDeleteSelectedItem() { QTreeWidgetItem* sel = currentItem(); if (sel && sel->isSelected()) { takeTopLevelItem(indexOfTopLevelItem(sel)); static_cast(sel)->removeFromGroup(); delete sel; } } void ParameterValue::onRenameSelectedItem() { QTreeWidgetItem* sel = currentItem(); if (sel && sel->isSelected()) { editItem(sel, 0); } } void ParameterValue::onCreateTextItem() { bool ok; QString name = QInputDialog::getText(this, QObject::tr("New text item"), QObject::tr("Enter the name:"), QLineEdit::Normal, QString(), &ok, Qt::MSWindowsFixedSizeDialogHint); if (!ok || !Gui::validateInput(this, name)) { return; } std::vector> smap = _hcGrp->GetASCIIMap(); for (const auto& it : smap) { if (name == QLatin1String(it.first.c_str())) { QMessageBox::critical(this, tr("Existing item"), tr("The item '%1' already exists.").arg(name)); return; } } QString val = QInputDialog::getText(this, QObject::tr("New text item"), QObject::tr("Enter your text:"), QLineEdit::Normal, QString(), &ok, Qt::MSWindowsFixedSizeDialogHint); if (ok && !val.isEmpty()) { ParameterValueItem* pcItem; pcItem = new ParameterText(this, name, val.toUtf8(), _hcGrp); pcItem->appendToGroup(); } } void ParameterValue::onCreateIntItem() { bool ok; QString name = QInputDialog::getText(this, QObject::tr("New integer item"), QObject::tr("Enter the name:"), QLineEdit::Normal, QString(), &ok, Qt::MSWindowsFixedSizeDialogHint); if (!ok || !Gui::validateInput(this, name)) { return; } std::vector> lmap = _hcGrp->GetIntMap(); for (const auto& it : lmap) { if (name == QLatin1String(it.first.c_str())) { QMessageBox::critical(this, tr("Existing item"), tr("The item '%1' already exists.").arg(name)); return; } } int val = QInputDialog::getInt(this, QObject::tr("New integer item"), QObject::tr("Enter your number:"), 0, -2147483647, 2147483647, 1, &ok, Qt::MSWindowsFixedSizeDialogHint); if (ok) { ParameterValueItem* pcItem; pcItem = new ParameterInt(this, name, (long)val, _hcGrp); pcItem->appendToGroup(); } } void ParameterValue::onCreateUIntItem() { bool ok; QString name = QInputDialog::getText(this, QObject::tr("New unsigned item"), QObject::tr("Enter the name:"), QLineEdit::Normal, QString(), &ok, Qt::MSWindowsFixedSizeDialogHint); if (!ok || !Gui::validateInput(this, name)) { return; } std::vector> lmap = _hcGrp->GetUnsignedMap(); for (const auto& it : lmap) { if (name == QLatin1String(it.first.c_str())) { QMessageBox::critical(this, tr("Existing item"), tr("The item '%1' already exists.").arg(name)); return; } } DlgInputDialogImp dlg(QObject::tr("Enter your number:"), this, true, DlgInputDialogImp::UIntBox); dlg.setWindowTitle(QObject::tr("New unsigned item")); UIntSpinBox* edit = dlg.getUIntBox(); edit->setRange(0, UINT_MAX); if (dlg.exec() == QDialog::Accepted) { QString value = edit->text(); unsigned long val = value.toULong(&ok); if (ok) { ParameterValueItem* pcItem; pcItem = new ParameterUInt(this, name, val, _hcGrp); pcItem->appendToGroup(); } } } void ParameterValue::onCreateFloatItem() { bool ok; QString name = QInputDialog::getText(this, QObject::tr("New float item"), QObject::tr("Enter the name:"), QLineEdit::Normal, QString(), &ok, Qt::MSWindowsFixedSizeDialogHint); if (!ok || !Gui::validateInput(this, name)) { return; } std::vector> fmap = _hcGrp->GetFloatMap(); for (const auto& it : fmap) { if (name == QLatin1String(it.first.c_str())) { QMessageBox::critical(this, tr("Existing item"), tr("The item '%1' already exists.").arg(name)); return; } } double val = QInputDialog::getDouble(this, QObject::tr("New float item"), QObject::tr("Enter your number:"), 0, -2147483647, 2147483647, 12, &ok, Qt::MSWindowsFixedSizeDialogHint); if (ok) { ParameterValueItem* pcItem; pcItem = new ParameterFloat(this, name, val, _hcGrp); pcItem->appendToGroup(); } } void ParameterValue::onCreateBoolItem() { bool ok; QString name = QInputDialog::getText(this, QObject::tr("New Boolean item"), QObject::tr("Enter the name:"), QLineEdit::Normal, QString(), &ok, Qt::MSWindowsFixedSizeDialogHint); if (!ok || !Gui::validateInput(this, name)) { return; } std::vector> bmap = _hcGrp->GetBoolMap(); for (const auto& it : bmap) { if (name == QLatin1String(it.first.c_str())) { QMessageBox::critical(this, tr("Existing item"), tr("The item '%1' already exists.").arg(name)); return; } } QStringList list; list << QString::fromLatin1("true") << QString::fromLatin1("false"); QString val = QInputDialog::getItem(this, QObject::tr("New boolean item"), QObject::tr("Choose an item:"), list, 0, false, &ok, Qt::MSWindowsFixedSizeDialogHint); if (ok) { ParameterValueItem* pcItem; pcItem = new ParameterBool(this, name, (val == list[0] ? true : false), _hcGrp); pcItem->appendToGroup(); } } // --------------------------------------------------------------------------- ParameterGroupItem::ParameterGroupItem(ParameterGroupItem* parent, const Base::Reference& hcGrp) : QTreeWidgetItem(parent, QTreeWidgetItem::UserType + 1) , _hcGrp(hcGrp) { setFlags(flags() | Qt::ItemIsEditable); fillUp(); } ParameterGroupItem::ParameterGroupItem(QTreeWidget* parent, const Base::Reference& hcGrp) : QTreeWidgetItem(parent, QTreeWidgetItem::UserType + 1) , _hcGrp(hcGrp) { setFlags(flags() | Qt::ItemIsEditable); fillUp(); } ParameterGroupItem::~ParameterGroupItem() { // if the group has already been removed from the parameters then clear the observer list // as we cannot notify the attached observers here if (_hcGrp.getRefCount() == 1) { _hcGrp->ClearObserver(); } } void ParameterGroupItem::fillUp() { // filling up groups std::vector> vhcParamGrp = _hcGrp->GetGroups(); setText(0, QString::fromUtf8(_hcGrp->GetGroupName())); for (const auto& It : vhcParamGrp) { (void)new ParameterGroupItem(this, It); } } void ParameterGroupItem::setData(int column, int role, const QVariant& value) { if (role == Qt::EditRole) { QString oldName = text(0); QString newName = value.toString(); if (newName.isEmpty() || oldName == newName) { return; } if (!Gui::validateInput(treeWidget(), newName)) { return; } // first check if there is already a group with name "newName" auto item = static_cast(parent()); if (!item) { QMessageBox::critical(treeWidget(), QObject::tr("Rename group"), QObject::tr("The group '%1' cannot be renamed.").arg(oldName)); return; } if (item->_hcGrp->HasGroup(newName.toLatin1())) { QMessageBox::critical(treeWidget(), QObject::tr("Existing group"), QObject::tr("The group '%1' already exists.").arg(newName)); return; } else { // rename the group by adding a new group, copy the content and remove the old group if (!item->_hcGrp->RenameGrp(oldName.toLatin1(), newName.toLatin1())) { return; } } } QTreeWidgetItem::setData(column, role, value); } QVariant ParameterGroupItem::data(int column, int role) const { if (role == Qt::DecorationRole) { // The root item should keep its special pixmap if (parent()) { return this->isExpanded() ? QApplication::style()->standardPixmap(QStyle::SP_DirOpenIcon) : QApplication::style()->standardPixmap(QStyle::SP_DirClosedIcon); } } return QTreeWidgetItem::data(column, role); } // -------------------------------------------------------------------- ParameterValueItem::ParameterValueItem(QTreeWidget* parent, const Base::Reference& hcGrp) : QTreeWidgetItem(parent) , _hcGrp(hcGrp) { setFlags(flags() | Qt::ItemIsEditable); } ParameterValueItem::~ParameterValueItem() = default; void ParameterValueItem::setData(int column, int role, const QVariant& value) { if (role == Qt::EditRole) { QString oldName = text(0); QString newName = value.toString(); if (newName.isEmpty() || oldName == newName) { return; } if (!Gui::validateInput(treeWidget(), newName)) { return; } replace(oldName, newName); } QTreeWidgetItem::setData(column, role, value); } // -------------------------------------------------------------------- ParameterText::ParameterText(QTreeWidget* parent, QString label, const char* value, const Base::Reference& hcGrp) : ParameterValueItem(parent, hcGrp) { setIcon(0, BitmapFactory().iconFromTheme("Param_Text")); setText(0, label); setText(1, QString::fromLatin1("Text")); setText(2, QString::fromUtf8(value)); } ParameterText::~ParameterText() = default; void ParameterText::changeValue() { bool ok; QString txt = QInputDialog::getText(treeWidget(), QObject::tr("Change value"), QObject::tr("Enter your text:"), QLineEdit::Normal, text(2), &ok, Qt::MSWindowsFixedSizeDialogHint); if (ok) { setText(2, txt); _hcGrp->SetASCII(text(0).toLatin1(), txt.toUtf8()); } } void ParameterText::removeFromGroup() { _hcGrp->RemoveASCII(text(0).toLatin1()); } void ParameterText::replace(const QString& oldName, const QString& newName) { std::string val = _hcGrp->GetASCII(oldName.toLatin1()); _hcGrp->RemoveASCII(oldName.toLatin1()); _hcGrp->SetASCII(newName.toLatin1(), val.c_str()); } void ParameterText::appendToGroup() { _hcGrp->SetASCII(text(0).toLatin1(), text(2).toUtf8()); } // -------------------------------------------------------------------- ParameterInt::ParameterInt(QTreeWidget* parent, QString label, long value, const Base::Reference& hcGrp) : ParameterValueItem(parent, hcGrp) { setIcon(0, BitmapFactory().iconFromTheme("Param_Int")); setText(0, label); setText(1, QString::fromLatin1("Integer")); setText(2, QString::fromLatin1("%1").arg(value)); } ParameterInt::~ParameterInt() = default; void ParameterInt::changeValue() { bool ok; int num = QInputDialog::getInt(treeWidget(), QObject::tr("Change value"), QObject::tr("Enter your number:"), text(2).toInt(), -2147483647, 2147483647, 1, &ok, Qt::MSWindowsFixedSizeDialogHint); if (ok) { setText(2, QString::fromLatin1("%1").arg(num)); _hcGrp->SetInt(text(0).toLatin1(), (long)num); } } void ParameterInt::removeFromGroup() { _hcGrp->RemoveInt(text(0).toLatin1()); } void ParameterInt::replace(const QString& oldName, const QString& newName) { long val = _hcGrp->GetInt(oldName.toLatin1()); _hcGrp->RemoveInt(oldName.toLatin1()); _hcGrp->SetInt(newName.toLatin1(), val); } void ParameterInt::appendToGroup() { _hcGrp->SetInt(text(0).toLatin1(), text(2).toLong()); } // -------------------------------------------------------------------- ParameterUInt::ParameterUInt(QTreeWidget* parent, QString label, unsigned long value, const Base::Reference& hcGrp) : ParameterValueItem(parent, hcGrp) { setIcon(0, BitmapFactory().iconFromTheme("Param_UInt")); setText(0, label); setText(1, QString::fromLatin1("Unsigned")); setText(2, QString::fromLatin1("%1").arg(value)); } ParameterUInt::~ParameterUInt() = default; void ParameterUInt::changeValue() { bool ok; DlgInputDialogImp dlg(QObject::tr("Enter your number:"), treeWidget(), true, DlgInputDialogImp::UIntBox); dlg.setWindowTitle(QObject::tr("Change value")); UIntSpinBox* edit = dlg.getUIntBox(); edit->setRange(0, UINT_MAX); edit->setValue(text(2).toULong()); if (dlg.exec() == QDialog::Accepted) { QString value = edit->text(); unsigned long num = value.toULong(&ok); if (ok) { setText(2, QString::fromLatin1("%1").arg(num)); _hcGrp->SetUnsigned(text(0).toLatin1(), (unsigned long)num); } } } void ParameterUInt::removeFromGroup() { _hcGrp->RemoveUnsigned(text(0).toLatin1()); } void ParameterUInt::replace(const QString& oldName, const QString& newName) { unsigned long val = _hcGrp->GetUnsigned(oldName.toLatin1()); _hcGrp->RemoveUnsigned(oldName.toLatin1()); _hcGrp->SetUnsigned(newName.toLatin1(), val); } void ParameterUInt::appendToGroup() { _hcGrp->SetUnsigned(text(0).toLatin1(), text(2).toULong()); } // -------------------------------------------------------------------- ParameterFloat::ParameterFloat(QTreeWidget* parent, QString label, double value, const Base::Reference& hcGrp) : ParameterValueItem(parent, hcGrp) { setIcon(0, BitmapFactory().iconFromTheme("Param_Float")); setText(0, label); setText(1, QString::fromLatin1("Float")); setText(2, QString::fromLatin1("%1").arg(value)); } ParameterFloat::~ParameterFloat() = default; void ParameterFloat::changeValue() { bool ok; double num = QInputDialog::getDouble(treeWidget(), QObject::tr("Change value"), QObject::tr("Enter your number:"), text(2).toDouble(), -2147483647, 2147483647, 12, &ok, Qt::MSWindowsFixedSizeDialogHint); if (ok) { setText(2, QString::fromLatin1("%1").arg(num)); _hcGrp->SetFloat(text(0).toLatin1(), num); } } void ParameterFloat::removeFromGroup() { _hcGrp->RemoveFloat(text(0).toLatin1()); } void ParameterFloat::replace(const QString& oldName, const QString& newName) { double val = _hcGrp->GetFloat(oldName.toLatin1()); _hcGrp->RemoveFloat(oldName.toLatin1()); _hcGrp->SetFloat(newName.toLatin1(), val); } void ParameterFloat::appendToGroup() { _hcGrp->SetFloat(text(0).toLatin1(), text(2).toDouble()); } // -------------------------------------------------------------------- ParameterBool::ParameterBool(QTreeWidget* parent, QString label, bool value, const Base::Reference& hcGrp) : ParameterValueItem(parent, hcGrp) { setIcon(0, BitmapFactory().iconFromTheme("Param_Bool")); setText(0, label); setText(1, QString::fromLatin1("Boolean")); setText(2, QString::fromLatin1((value ? "true" : "false"))); } ParameterBool::~ParameterBool() = default; void ParameterBool::changeValue() { bool ok; QStringList list; list << QString::fromLatin1("true") << QString::fromLatin1("false"); int pos = (text(2) == list[0] ? 0 : 1); QString txt = QInputDialog::getItem(treeWidget(), QObject::tr("Change value"), QObject::tr("Choose an item:"), list, pos, false, &ok, Qt::MSWindowsFixedSizeDialogHint); if (ok) { setText(2, txt); _hcGrp->SetBool(text(0).toLatin1(), (txt == list[0] ? true : false)); } } void ParameterBool::removeFromGroup() { _hcGrp->RemoveBool(text(0).toLatin1()); } void ParameterBool::replace(const QString& oldName, const QString& newName) { bool val = _hcGrp->GetBool(oldName.toLatin1()); _hcGrp->RemoveBool(oldName.toLatin1()); _hcGrp->SetBool(newName.toLatin1(), val); } void ParameterBool::appendToGroup() { bool val = (text(2) == QLatin1String("true") ? true : false); _hcGrp->SetBool(text(0).toLatin1(), val); } #include "moc_DlgParameterImp.cpp"