From 4ff3e8b56958b95493801c79e12c9baa9431b109 Mon Sep 17 00:00:00 2001 From: tarapn79 Date: Fri, 29 Sep 2023 15:39:22 +0200 Subject: [PATCH] added SearchColumnDialog class --- .../gui/searchbar/searchcolumndialog.h | 54 ++++++++++ .../gui/searchbar/searchoptions_dialog.h | 12 ++- .../gui/src/searchbar/searchcolumndialog.cpp | 100 ++++++++++++++++++ .../src/searchbar/searchoptions_dialog.cpp | 58 ++++++---- 4 files changed, 201 insertions(+), 23 deletions(-) create mode 100644 plugins/gui/include/gui/searchbar/searchcolumndialog.h create mode 100644 plugins/gui/src/searchbar/searchcolumndialog.cpp diff --git a/plugins/gui/include/gui/searchbar/searchcolumndialog.h b/plugins/gui/include/gui/searchbar/searchcolumndialog.h new file mode 100644 index 00000000000..dea3799b538 --- /dev/null +++ b/plugins/gui/include/gui/searchbar/searchcolumndialog.h @@ -0,0 +1,54 @@ +// MIT License +// +// Copyright (c) 2019 Ruhr University Bochum, Chair for Embedded Security. All Rights reserved. +// Copyright (c) 2019 Marc Fyrbiak, Sebastian Wallat, Max Hoffmann ("ORIGINAL AUTHORS"). All rights reserved. +// Copyright (c) 2021 Max Planck Institute for Security and Privacy. All Rights reserved. +// Copyright (c) 2021 Jörn Langheinrich, Julian Speith, Nils Albartus, René Walendy, Simon Klix ("ORIGINAL AUTHORS"). All Rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once +#include +#include +#include +#include +#include +#include + +namespace hal { + + class SearchColumnDialog : public QDialog + { + Q_OBJECT + + QCheckBox* mCheckAllColumns; + QList mCheckColumn; + QDialogButtonBox* mButtonBox; + bool mDisableHandler; + private Q_SLOTS: + void handleCheckStateChanged(int state); + public Q_SLOTS: + void accept() override; + public: + SearchColumnDialog(const QStringList& colNames, const QList& selected); + QString selectedColumnNames() const; + QList selectedColumns() const; + }; + +} diff --git a/plugins/gui/include/gui/searchbar/searchoptions_dialog.h b/plugins/gui/include/gui/searchbar/searchoptions_dialog.h index 47a3995687f..969a4fa2043 100644 --- a/plugins/gui/include/gui/searchbar/searchoptions_dialog.h +++ b/plugins/gui/include/gui/searchbar/searchoptions_dialog.h @@ -51,7 +51,7 @@ namespace hal SearchOptionsDialog(QWidget *parent = nullptr); void emitOptions(); SearchOptions* getOptions() const; - void setOptions(SearchOptions* opts, QString searchString, QList columnNames, bool incSearch, int minIncSearch) const; + void setOptions(SearchOptions* opts, QString searchString, QList columnNames, bool incSearch, int minIncSearch); QString getText() const; int getMinIncSearchValue(); bool getIncrementalSearch(); @@ -62,11 +62,14 @@ namespace hal public Q_SLOTS: void emitStartSearch(); void incrementalSearchToggled(int); + void selectColumns(); //TODO can be deleted later on void testWidget(); private: QString mSearchText; + QList mSelectedColumns = {}; + QStringList mColumnNames; QGridLayout* mLayout; QComboBox* mInputBox; @@ -77,11 +80,10 @@ namespace hal QCheckBox* mExactMatchBox; QCheckBox* mCaseSensitiveBox; QCheckBox* mRegExBox; - QLabel* mColumnLabel; + //QLabel* mColumnLabel; QPushButton* mSearchBtn; QPushButton* mCloseBtn; - QListWidget* mListWidget; - - + QPushButton* mSelectColumnsBtn; + //QListWidget* mListWidget; }; } diff --git a/plugins/gui/src/searchbar/searchcolumndialog.cpp b/plugins/gui/src/searchbar/searchcolumndialog.cpp new file mode 100644 index 00000000000..2045e2768b6 --- /dev/null +++ b/plugins/gui/src/searchbar/searchcolumndialog.cpp @@ -0,0 +1,100 @@ +#include "gui/searchbar/searchcolumndialog.h" +#include +#include +#include + +namespace hal { + + SearchColumnDialog::SearchColumnDialog(const QStringList& colNames, const QList &selected) + : mDisableHandler(false) + { + setWindowTitle("Search in column:"); + QVBoxLayout* layout = new QVBoxLayout(this); + mCheckAllColumns = new QCheckBox("All columns", this); + connect(mCheckAllColumns,&QCheckBox::stateChanged,this,&SearchColumnDialog::handleCheckStateChanged); + layout->addWidget(mCheckAllColumns); + + QFrame* frame = new QFrame(this); + frame->setLineWidth(3); + frame->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel); + QVBoxLayout* flay = new QVBoxLayout(frame); + int inx = 0; + for (const QString& col : colNames) + { + QCheckBox* cbox = new QCheckBox(col, frame); + cbox->setChecked(selected.isEmpty() || selected.contains(inx)); + connect(cbox,&QCheckBox::stateChanged,this,&SearchColumnDialog::handleCheckStateChanged); + flay->addWidget(cbox); + mCheckColumn.append(cbox); + ++inx; + } + layout->addWidget(frame); + + mButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + connect(mButtonBox,&QDialogButtonBox::accepted,this,&QDialog::accept); + connect(mButtonBox,&QDialogButtonBox::rejected,this,&QDialog::reject); + layout->addWidget(mButtonBox); + handleCheckStateChanged(0); + } + + void SearchColumnDialog::handleCheckStateChanged(int state) + { + if (mDisableHandler) return; + if (sender()==mCheckAllColumns && state == Qt::Checked) + { + mDisableHandler = true; + for (QCheckBox* cbox : mCheckColumn) + cbox->setChecked(true); + mDisableHandler = false; + } + bool allChecked = true; + bool nullChecked = true; + + for (const QCheckBox* cbox : mCheckColumn) + { + if (cbox->isChecked()) + nullChecked = false; + else + allChecked = false; + } + + if (mCheckAllColumns->isChecked() != allChecked) + mCheckAllColumns->setChecked(allChecked); + + mButtonBox->button(QDialogButtonBox::Ok)->setDisabled(nullChecked); + } + + QString SearchColumnDialog::selectedColumnNames() const + { + if (mCheckAllColumns->isChecked()) return "All columns"; + + QString retval; + for (const QCheckBox* cbox : mCheckColumn) + { + if (!cbox->isChecked()) continue; + if (!retval.isEmpty()) retval += ','; + retval += cbox->text(); + } + return retval; + } + + QList SearchColumnDialog::selectedColumns() const + { + QList retval; + if (mCheckAllColumns->isChecked()) return retval; + + int inx = 0; + for (const QCheckBox* cbox : mCheckColumn) + { + if (cbox->isChecked()) retval.append(inx); + ++inx; + } + return retval; + } + + void SearchColumnDialog::accept() + { + handleCheckStateChanged(0); + QDialog::accept(); + } +} diff --git a/plugins/gui/src/searchbar/searchoptions_dialog.cpp b/plugins/gui/src/searchbar/searchoptions_dialog.cpp index c8c55dafeff..0b98505219b 100644 --- a/plugins/gui/src/searchbar/searchoptions_dialog.cpp +++ b/plugins/gui/src/searchbar/searchoptions_dialog.cpp @@ -1,4 +1,5 @@ #include "gui/searchbar/searchoptions_dialog.h" +#include "gui/searchbar/searchcolumndialog.h" #include #include @@ -36,36 +37,39 @@ namespace hal mRegExBox = new QCheckBox("Regular expression", this); //Column widgets - mColumnLabel = new QLabel(this); - mColumnLabel->setText("Search in:"); + /*mColumnLabel = new QLabel(this); + mColumnLabel->setText("Search in:");*/ - mListWidget = new QListWidget(this); + /*mListWidget = new QListWidget(this); mListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); - mListWidget->setMaximumHeight(150); + mListWidget->setMaximumHeight(150);*/ //Pushbuttons mSearchBtn = new QPushButton("Search", this); mCloseBtn = new QPushButton("Close", this); + mSelectColumnsBtn = new QPushButton("Search in columns", this); //Connect widgets with layout mLayout->addWidget(mInputBox, 0, 0, 0, 3, Qt::AlignTop); - mLayout->addWidget(mColumnLabel, 1, 2); + //mLayout->addWidget(mColumnLabel, 1, 2); mLayout->addWidget(mIncrementalSearchBox, 1, 0, 1, 2); - mLayout->addWidget(mListWidget, 2, 2, 5, Qt::AlignLeft); + //mLayout->addWidget(mListWidget, 2, 2, 5, Qt::AlignLeft); mLayout->addWidget(mSpinBoxLabel, 2, 0, Qt::AlignRight); mLayout->addWidget(mSpinBox, 2, 1); mLayout->addWidget(mExactMatchBox, 3, 0, 1, 2); mLayout->addWidget(mCaseSensitiveBox, 4, 0, 1, 2); mLayout->addWidget(mRegExBox, 5, 0, 1, 2); - mLayout->addWidget(mSearchBtn, 6, 0); - mLayout->addWidget(mCloseBtn, 6, 1); + mLayout->addWidget(mSelectColumnsBtn, 6, 0); + mLayout->addWidget(mSearchBtn, 7, 0); + mLayout->addWidget(mCloseBtn, 7, 1); mLayout->setHorizontalSpacing(20); connect(mCloseBtn, &QPushButton::clicked, this, &SearchOptionsDialog::close); connect(mSearchBtn, &QPushButton::clicked, this, &SearchOptionsDialog::emitStartSearch); + connect(mSelectColumnsBtn, &QPushButton::clicked, this, &SearchOptionsDialog::selectColumns); connect(mIncrementalSearchBox, &QCheckBox::stateChanged, this, &SearchOptionsDialog::incrementalSearchToggled); - connect(mListWidget, &QListWidget::itemSelectionChanged, this, &SearchOptionsDialog::testWidget); + //connect(mListWidget, &QListWidget::itemSelectionChanged, this, &SearchOptionsDialog::testWidget); //TODO maybe delete this because edit triggers also the mSearchBtn signal as if it was clicked. Currently the emit search is emited twice while pressing Enter // discuss with Joern @@ -77,14 +81,14 @@ namespace hal } //TODO can be deleted later on - void SearchOptionsDialog::testWidget() + /* void SearchOptionsDialog::testWidget() { auto list = mListWidget->selectedItems(); for(auto elem : list){ qInfo() << elem->text(); } - } + }*/ void SearchOptionsDialog::emitStartSearch() { @@ -96,7 +100,7 @@ namespace hal void SearchOptionsDialog::emitOptions() { mSearchText = mInputBox->currentText(); - int options = SearchOptions::toInt(mExactMatchBox->isChecked(), mCaseSensitiveBox->isChecked(), mRegExBox->isChecked(), {}); //TO-DO: fill the columns + int options = SearchOptions::toInt(mExactMatchBox->isChecked(), mCaseSensitiveBox->isChecked(), mRegExBox->isChecked(), mSelectedColumns); //TO-DO: fill the columns qInfo() << "Emit search with string: " << mSearchText << " and options: " << options; Q_EMIT emitOptions(mSearchText, options); @@ -108,7 +112,7 @@ namespace hal SearchOptions* retval = new SearchOptions(); //get index of each selected column - QList selectedItems = {}; + /*QList selectedItems = {}; for(auto elem : mListWidget->selectedItems()){ int index = mListWidget->row(elem); if(index > 0) @@ -117,23 +121,29 @@ namespace hal selectedItems = {}; break; } - } - retval->setOptions(mExactMatchBox->isChecked(), mCaseSensitiveBox->isChecked(), mRegExBox->isChecked(), selectedItems); //TO-DO: fill the columns + }*/ + retval->setOptions(mExactMatchBox->isChecked(), mCaseSensitiveBox->isChecked(), mRegExBox->isChecked(), mSelectedColumns); //TO-DO: fill the columns return retval; } - void SearchOptionsDialog::setOptions(SearchOptions* opts, QString searchString, QList columnNames, bool incSearch, int minIncSearch) const + void SearchOptionsDialog::setOptions(SearchOptions* opts, QString searchString, QList columnNames, bool incSearch, int minIncSearch) { //set the parameters of the Dialog to previous ones or do default mLineEdit->setText(searchString); + QStringList a = {}; mExactMatchBox->setChecked(opts->isExactMatch()); mCaseSensitiveBox->setChecked(opts->isCaseSensitive()); mRegExBox->setChecked(opts->isRegularExpression()); mIncrementalSearchBox->setChecked(incSearch); + if(!columnNames.isEmpty()) + { + for(QString name : columnNames) + mColumnNames.append(name); + } //add the given column names into the widget if there are any, if not then hide the widget - if(!columnNames.isEmpty()){ + /*if(!columnNames.isEmpty()){ mListWidget->addItem("All columns"); for (auto elem : columnNames) { @@ -142,7 +152,7 @@ namespace hal }else{ mListWidget->hide(); mColumnLabel->hide(); - } + }*/ } QString SearchOptionsDialog::getText() const @@ -167,4 +177,16 @@ namespace hal mSpinBox->setDisabled(!state); } + void SearchOptionsDialog::selectColumns() + { + + hal::SearchColumnDialog scd(mColumnNames, mSelectedColumns); + if (scd.exec() == QDialog::Accepted) + { + + mSelectColumnsBtn->setText(scd.selectedColumnNames()); + mSelectedColumns = scd.selectedColumns(); + } + } + }