diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index c5b36a6e1b..7b55ab4a58 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -270,6 +270,7 @@ set(Gui_MOC_HDRS DlgMaterialPropertiesImp.h DlgOnlineHelpImp.h DlgParameterImp.h + DlgParameterFind.h DlgPreferencesImp.h DlgProjectInformationImp.h DlgProjectUtility.h @@ -389,6 +390,7 @@ SET(Gui_UIC_SRCS DlgMaterialProperties.ui DlgOnlineHelp.ui DlgParameter.ui + DlgParameterFind.ui DlgPreferences.ui DlgProjectInformation.ui DlgProjectUtility.ui @@ -472,6 +474,7 @@ SET(Dialog_CPP_SRCS DlgMacroRecordImp.cpp DlgMaterialPropertiesImp.cpp DlgParameterImp.cpp + DlgParameterFind.cpp DlgProjectInformationImp.cpp DlgProjectUtility.cpp DlgPropertyLink.cpp @@ -504,6 +507,7 @@ SET(Dialog_HPP_SRCS DlgMacroRecordImp.h DlgMaterialPropertiesImp.h DlgParameterImp.h + DlgParameterFind.h DlgProjectInformationImp.h DlgProjectUtility.h DlgPropertyLink.h @@ -541,6 +545,7 @@ SET(Dialog_SRCS DlgMacroRecord.ui DlgMaterialProperties.ui DlgParameter.ui + DlgParameterFind.ui DlgProjectInformation.ui DlgProjectUtility.ui DlgPropertyLink.ui diff --git a/src/Gui/DlgParameter.ui b/src/Gui/DlgParameter.ui index 345090587f..761b9db7a5 100644 --- a/src/Gui/DlgParameter.ui +++ b/src/Gui/DlgParameter.ui @@ -36,6 +36,13 @@ 6 + + + + Find... + + + diff --git a/src/Gui/DlgParameterFind.cpp b/src/Gui/DlgParameterFind.cpp new file mode 100644 index 0000000000..fc931c5229 --- /dev/null +++ b/src/Gui/DlgParameterFind.cpp @@ -0,0 +1,280 @@ +/*************************************************************************** + * Copyright (c) 2019 Werner Mayer * + * * + * 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 +#endif + +#include "ui_DlgParameterFind.h" +#include "DlgParameterFind.h" +#include "DlgParameterImp.h" + + +using namespace Gui::Dialog; + +/* TRANSLATOR Gui::Dialog::DlgParameterFind */ + +DlgParameterFind::DlgParameterFind(DlgParameterImp* parent) + : QDialog(parent) + , ui(new Ui_DlgParameterFind) + , dialog(parent) +{ + ui->setupUi(this); + QPushButton* btn = ui->buttonBox->button(QDialogButtonBox::Ok); + if (btn) { + btn->setText(tr("Find Next")); + btn->setDisabled(true); + } +} + +/** + * Destroys the object and frees any allocated resources + */ +DlgParameterFind::~DlgParameterFind() +{ + // no need to delete child widgets, Qt does it all for us + delete ui; +} + +void DlgParameterFind::on_lineEdit_textChanged(const QString& text) +{ + QPushButton* btn = ui->buttonBox->button(QDialogButtonBox::Ok); + if (btn) { + bool ok = ui->checkGroups->isChecked() || + ui->checkNames->isChecked() || + ui->checkValues->isChecked(); + btn->setDisabled(!ok || text.isEmpty()); + } +} + +void DlgParameterFind::on_checkGroups_toggled(bool) +{ + QPushButton* btn = ui->buttonBox->button(QDialogButtonBox::Ok); + if (btn) { + bool ok = ui->checkGroups->isChecked() || + ui->checkNames->isChecked() || + ui->checkValues->isChecked(); + QString text = ui->lineEdit->text(); + btn->setDisabled(!ok || text.isEmpty()); + } +} + +void DlgParameterFind::on_checkNames_toggled(bool) +{ + QPushButton* btn = ui->buttonBox->button(QDialogButtonBox::Ok); + if (btn) { + bool ok = ui->checkGroups->isChecked() || + ui->checkNames->isChecked() || + ui->checkValues->isChecked(); + QString text = ui->lineEdit->text(); + btn->setDisabled(!ok || text.isEmpty()); + } +} + +void DlgParameterFind::on_checkValues_toggled(bool) +{ + QPushButton* btn = ui->buttonBox->button(QDialogButtonBox::Ok); + if (btn) { + bool ok = ui->checkGroups->isChecked() || + ui->checkNames->isChecked() || + ui->checkValues->isChecked(); + QString text = ui->lineEdit->text(); + btn->setDisabled(!ok || text.isEmpty()); + } +} + +bool DlgParameterFind::matches(QTreeWidgetItem* item, const Options& opt) const +{ + // check the group name + if (opt.group) { + // whole word matches + if (opt.match) { + if (item->text(0).compare(opt.text, Qt::CaseInsensitive) == 0) + return true; + } + else { + if (item->text(0).indexOf(opt.text, 0, Qt::CaseInsensitive) >= 0) + return true; + } + } + + if (opt.name || opt.value) { + ParameterGroupItem* group = static_cast(item); + Base::Reference hGrp = group->_hcGrp; + + auto boolMap = hGrp->GetBoolMap(); + auto intMap = hGrp->GetIntMap(); + auto uintMap = hGrp->GetUnsignedMap(); + auto floatMap = hGrp->GetFloatMap(); + auto asciiMap = hGrp->GetASCIIMap(); + + // check the name of an entry in the group + if (opt.name) { + if (opt.match) { + for (auto it : boolMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.compare(opt.text, Qt::CaseInsensitive) == 0) + return true; + } + for (auto it : intMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.compare(opt.text, Qt::CaseInsensitive) == 0) + return true; + } + for (auto it : uintMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.compare(opt.text, Qt::CaseInsensitive) == 0) + return true; + } + for (auto it : floatMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.compare(opt.text, Qt::CaseInsensitive) == 0) + return true; + } + for (auto it : asciiMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.compare(opt.text, Qt::CaseInsensitive) == 0) + return true; + } + } + else { + for (auto it : boolMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.indexOf(opt.text, 0, Qt::CaseInsensitive) >= 0) + return true; + } + for (auto it : intMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.indexOf(opt.text, 0, Qt::CaseInsensitive) >= 0) + return true; + } + for (auto it : uintMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.indexOf(opt.text, 0, Qt::CaseInsensitive) >= 0) + return true; + } + for (auto it : floatMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.indexOf(opt.text, 0, Qt::CaseInsensitive) >= 0) + return true; + } + for (auto it : asciiMap) { + QString text = QString::fromUtf8(it.first.c_str()); + if (text.indexOf(opt.text, 0, Qt::CaseInsensitive) >= 0) + return true; + } + } + } + + // check the value of an entry in the group + if (opt.value) { + if (opt.match) { + for (auto it : asciiMap) { + QString text = QString::fromUtf8(it.second.c_str()); + if (text.compare(opt.text, Qt::CaseInsensitive) == 0) + return true; + } + } + else { + for (auto it : asciiMap) { + QString text = QString::fromUtf8(it.second.c_str()); + if (text.indexOf(opt.text, 0, Qt::CaseInsensitive) >= 0) + return true; + } + } + } + } + + return false; +} + +QTreeWidgetItem* DlgParameterFind::findItem(QTreeWidgetItem* root, const Options& opt) const +{ + if (!root) + return nullptr; + + if (matches(root, opt)) { + // if the root matches then only return if it's not the current element + // as otherwise it would never move forward + if (root->treeWidget()->currentItem() != root) + return root; + } + + for (int i=0; ichildCount(); i++) { + QTreeWidgetItem* item = root->child(i); + if (matches(item, opt)) + return item; + item = findItem(item, opt); + if (item) + return item; + } + + return nullptr; +} + +void DlgParameterFind::accept() +{ + ParameterGroup* groupTree = dialog->findChild(); + if (groupTree) { + Options opt; + opt.text = ui->lineEdit->text(); + opt.group = ui->checkGroups->isChecked(); + opt.name = ui->checkNames->isChecked(); + opt.value = ui->checkValues->isChecked(); + opt.match = ui->checkMatch->isChecked(); + + QTreeWidgetItem* current = groupTree->currentItem(); + QTreeWidgetItem* next = findItem(current, opt); + while (!next && current) { + // go to the parent item and try again for each sibling after the current item + QTreeWidgetItem* parent = current->parent(); + if (parent) { + int index = parent->indexOfChild(current); + for (int i=index+1; ichildCount(); i++) { + next = findItem(parent->child(i), opt); + if (next) + break; + } + } + + if (!next) { + current = parent; + } + } + + // if search was successful then make it the current item + if (next) + groupTree->setCurrentItem(next); + else + QMessageBox::warning(this, tr("Not found"), tr("Can't find the text: %1").arg(opt.text)); + } +} + +void DlgParameterFind::reject() +{ + QDialog::reject(); +} + +#include "moc_DlgParameterFind.cpp" diff --git a/src/Gui/DlgParameterFind.h b/src/Gui/DlgParameterFind.h new file mode 100644 index 0000000000..fbc031a0a7 --- /dev/null +++ b/src/Gui/DlgParameterFind.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (c) 2019 Werner Mayer * + * * + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_DIALOG_DLGPARAMETERFIND_H +#define GUI_DIALOG_DLGPARAMETERFIND_H + +#include +#include + +class QTreeWidgetItem; + +namespace Gui { +namespace Dialog { + +class Ui_DlgParameterFind; +class DlgParameterImp; + +class GuiExport DlgParameterFind : public QDialog +{ + Q_OBJECT + +public: + DlgParameterFind(DlgParameterImp* parent); + ~DlgParameterFind(); + + void accept(); + void reject(); + +private Q_SLOTS: + void on_lineEdit_textChanged(const QString&); + void on_checkGroups_toggled(bool); + void on_checkNames_toggled(bool); + void on_checkValues_toggled(bool); + +private: + struct Options { + QString text; + bool group = true; + bool name = true; + bool value = true; + bool match = false; + }; + QTreeWidgetItem* findItem(QTreeWidgetItem* root, const Options& opt) const; + bool matches(QTreeWidgetItem* item, const Options& opt) const; + +private: + Ui_DlgParameterFind* ui; + DlgParameterImp* dialog; +}; + +} // namespace Dialog +} // namespace Gui + +#endif // GUI_DIALOG_DLGPARAMETERFIND_H diff --git a/src/Gui/DlgParameterFind.ui b/src/Gui/DlgParameterFind.ui new file mode 100644 index 0000000000..1ac820fbf9 --- /dev/null +++ b/src/Gui/DlgParameterFind.ui @@ -0,0 +1,151 @@ + + + Gui::Dialog::DlgParameterFind + + + + 0 + 0 + 443 + 212 + + + + Find + + + + + + + + + + + + + 0 + 0 + + + + Find what: + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + Look at + + + + + + Groups + + + true + + + + + + + Names + + + true + + + + + + + Values + + + true + + + + + + + + + + Match whole string only + + + true + + + + + + + + + + Qt::Vertical + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Gui::Dialog::DlgParameterFind + accept() + + + 433 + 202 + + + 157 + 274 + + + + + buttonBox + rejected() + Gui::Dialog::DlgParameterFind + reject() + + + 433 + 202 + + + 286 + 274 + + + + + diff --git a/src/Gui/DlgParameterImp.cpp b/src/Gui/DlgParameterImp.cpp index cd880dcbc1..766ad5ab98 100644 --- a/src/Gui/DlgParameterImp.cpp +++ b/src/Gui/DlgParameterImp.cpp @@ -35,6 +35,7 @@ #include "ui_DlgParameter.h" #include "DlgParameterImp.h" +#include "DlgParameterFind.h" #include "DlgInputDialogImp.h" #include "BitmapFactory.h" #include "FileDialog.h" @@ -117,6 +118,13 @@ DlgParameterImp::~DlgParameterImp() delete ui; } +void DlgParameterImp::on_buttonFind_clicked() +{ + if (finder.isNull()) + finder = new DlgParameterFind(this); + finder->show(); +} + /** * Sets the strings of the subwidgets using the current * language. @@ -561,6 +569,11 @@ 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) diff --git a/src/Gui/DlgParameterImp.h b/src/Gui/DlgParameterImp.h index 9f4fd8e1df..2f86121ae2 100644 --- a/src/Gui/DlgParameterImp.h +++ b/src/Gui/DlgParameterImp.h @@ -29,11 +29,13 @@ #include #include #include +#include namespace Gui { namespace Dialog { class Ui_DlgParameter; +class DlgParameterFind; /** * The DlgParameterImp class implements a dialog showing all parameters in a list view. @@ -54,6 +56,7 @@ public: protected Q_SLOTS: void onChangeParameterSet(int); + void on_buttonFind_clicked(); void on_buttonSaveToDisk_clicked(); void onGroupSelected(QTreeWidgetItem *); @@ -68,6 +71,7 @@ protected: QTreeWidget* paramGroup; QTreeWidget* paramValue; Ui_DlgParameter* ui; + QPointer finder; }; // -------------------------------------------------------------------- @@ -139,6 +143,8 @@ public: /** Sets the current parameter group that is displayed. */ void setCurrentGroup( const Base::Reference& _hcGrp ); + /** Returns the current parameter group that is displayed. */ + Base::Reference currentGroup() const; protected: /** Shows the context menu. */