From b5e4de8d89afb507693d1b7a97c7677a926c01c0 Mon Sep 17 00:00:00 2001 From: "James C. Owens" Date: Sun, 8 Oct 2023 12:29:24 -0400 Subject: [PATCH] Implementation of add, edit, and delete sidestake buttons in options --- src/qt/editsidestakedialog.cpp | 2 +- src/qt/forms/editsidestakedialog.ui | 150 ++++++++++------------------ src/qt/forms/optionsdialog.ui | 17 ++++ src/qt/optionsdialog.cpp | 80 ++++++++++++++- src/qt/optionsdialog.h | 7 ++ src/qt/sidestaketablemodel.cpp | 20 ++++ src/qt/sidestaketablemodel.h | 1 + 7 files changed, 172 insertions(+), 105 deletions(-) diff --git a/src/qt/editsidestakedialog.cpp b/src/qt/editsidestakedialog.cpp index 5fe71ac552..0cb5fa7b2b 100644 --- a/src/qt/editsidestakedialog.cpp +++ b/src/qt/editsidestakedialog.cpp @@ -52,7 +52,7 @@ void EditSideStakeDialog::setModel(OptionsModel *model) return; } - mapper->setModel(model); + mapper->setModel(model->getSideStakeTableModel()); mapper->addMapping(ui->addressLineEdit, SideStakeTableModel::Address); mapper->addMapping(ui->allocationLineEdit, SideStakeTableModel::Allocation); mapper->addMapping(ui->descriptionLineEdit, SideStakeTableModel::Description); diff --git a/src/qt/forms/editsidestakedialog.ui b/src/qt/forms/editsidestakedialog.ui index 5e528b2b4c..221d9250d5 100644 --- a/src/qt/forms/editsidestakedialog.ui +++ b/src/qt/forms/editsidestakedialog.ui @@ -15,141 +15,91 @@ - - - Qt::Vertical - - - - 20 - 40 - - - - - - - + + Address - - - - Qt::Horizontal - - - - 10 - 20 - - - - - + - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - + Allocation - - + + + + + + + Description + + + + + + + + - Qt::Horizontal + Qt::Vertical - 10 - 20 + 20 + 40 - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Description + + + + Qt::Vertical - + + + 20 + 40 + + + - - + + - Qt::Horizontal - - - QSizePolicy::Expanding + Qt::Vertical - 10 - 20 + 20 + 40 - - + + + + Qt::Vertical + + + + 20 + 40 + + + - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 1c34716190..efb8ea568b 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -342,6 +342,9 @@ + + false + Edit @@ -351,6 +354,20 @@ + + + + false + + + Delete + + + + :/icons/remove:/icons/remove + + + diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 96757b2e79..42769858d2 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -11,6 +11,7 @@ #include "sidestaketablemodel.h" #include "editsidestakedialog.h" +#include #include #include #include @@ -147,7 +148,19 @@ void OptionsDialog::setModel(OptionsModel *model) sidestake_model->refresh(); - ui->sidestakingTableView->setModel(sidestake_model); + m_sidestake_proxy_model = new QSortFilterProxyModel(this); + m_sidestake_proxy_model->setSourceModel(sidestake_model); + m_sidestake_proxy_model->setDynamicSortFilter(true); + m_sidestake_proxy_model->setSortCaseSensitivity(Qt::CaseInsensitive); + m_sidestake_proxy_model->setFilterCaseSensitivity(Qt::CaseInsensitive); + + m_sidestake_filter_proxy_model = new QSortFilterProxyModel(this); + m_sidestake_filter_proxy_model->setSourceModel(m_sidestake_proxy_model); + m_sidestake_filter_proxy_model->setDynamicSortFilter(true); + m_sidestake_filter_proxy_model->setFilterCaseSensitivity(Qt::CaseInsensitive); + m_sidestake_filter_proxy_model->setFilterKeyColumn(-1); // All columns + + ui->sidestakingTableView->setModel(m_sidestake_filter_proxy_model); ui->sidestakingTableView->verticalHeader()->hide(); ui->sidestakingTableView->setSelectionBehavior(QAbstractItemView::SelectRows); ui->sidestakingTableView->setSelectionMode(QAbstractItemView::ExtendedSelection); @@ -161,11 +174,17 @@ void OptionsDialog::setModel(OptionsModel *model) ui->sidestakingTableView->horizontalHeader()->setStretchLastSection(true); ui->sidestakingTableView->setShowGrid(true); + ui->sidestakingTableView->sortByColumn(0, Qt::AscendingOrder); + connect(ui->enableSideStaking, &QCheckBox::toggled, this, &OptionsDialog::hideSideStakeEdit); connect(ui->enableSideStaking, &QCheckBox::toggled, this, &OptionsDialog::refreshSideStakeTableModel); connect(ui->pushButtonNewSideStake, &QPushButton::clicked, this, &OptionsDialog::newSideStakeButton_clicked); connect(ui->pushButtonEditSideStake, &QPushButton::clicked, this, &OptionsDialog::editSideStakeButton_clicked); + connect(ui->pushButtonDeleteSideStake, &QPushButton::clicked, this, &OptionsDialog::deleteSideStakeButton_clicked); + + connect(ui->sidestakingTableView->selectionModel(), &QItemSelectionModel::selectionChanged, + this, &OptionsDialog::sidestakeSelectionChanged); } /* update the display unit, to not use the default ("BTC") */ @@ -287,22 +306,54 @@ void OptionsDialog::newSideStakeButton_clicked() void OptionsDialog::editSideStakeButton_clicked() { - if (!model) { + if (!model || !ui->sidestakingTableView->selectionModel()) { + return; + } + + QModelIndexList indexes = ui->sidestakingTableView->selectionModel()->selectedRows(); + + if (indexes.isEmpty()) { return; } EditSideStakeDialog dialog(EditSideStakeDialog::EditSideStake, this); - dialog.setModel(model); + GRC::SideStake* sidestake = static_cast(indexes.at(0).internalPointer()); + QModelIndex orig_index = m_sidestake_filter_proxy_model->mapToSource(indexes.at(0)); + orig_index = m_sidestake_proxy_model->mapToSource(orig_index); + + dialog.setModel(model); + dialog.loadRow(orig_index.row()); + //dialog.loadRow(indexes.at(0).row()); dialog.exec(); } +void OptionsDialog::deleteSideStakeButton_clicked() +{ + if (!model || !ui->sidestakingTableView->selectionModel()) { + return; + } + + QModelIndexList indexes = ui->sidestakingTableView->selectionModel()->selectedRows(); + + if (indexes.isEmpty()) { + return; + } + + if (indexes.size() > 1) { + QMessageBox::warning(this, tr("Error"), tr("You can only delete one sidestake at a time."), QMessageBox::Ok); + } + + model->getSideStakeTableModel()->removeRows(indexes.at(0).row(), 1); +} + void OptionsDialog::showRestartWarning_Proxy() { if(!fRestartWarningDisplayed_Proxy) { - QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect after restarting Gridcoin."), QMessageBox::Ok); + QMessageBox::warning(this, tr("Warning"), tr("This setting will take effect" + " after restarting Gridcoin."), QMessageBox::Ok); fRestartWarningDisplayed_Proxy = true; } } @@ -499,3 +550,24 @@ bool OptionsDialog::eventFilter(QObject *object, QEvent *event) } return QDialog::eventFilter(object, event); } + +void OptionsDialog::sidestakeSelectionChanged() +{ + QTableView *table = ui->sidestakingTableView; + + if (table->selectionModel()->hasSelection()) { + QModelIndexList indexes = ui->sidestakingTableView->selectionModel()->selectedRows(); + + if (indexes.size() > 1) { + ui->pushButtonEditSideStake->setEnabled(false); + ui->pushButtonDeleteSideStake->setEnabled(false); + } else if (static_cast(indexes.at(0).internalPointer())->m_status + == GRC::SideStakeStatus::MANDATORY) { + ui->pushButtonEditSideStake->setEnabled(false); + ui->pushButtonDeleteSideStake->setEnabled(false); + } else { + ui->pushButtonEditSideStake->setEnabled(true); + ui->pushButtonDeleteSideStake->setEnabled(true); + } + } +} diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index bf95e9fce3..89d555bc40 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -7,6 +7,7 @@ namespace Ui { class OptionsDialog; } class OptionsModel; +class QSortFilterProxyModel; class MonitoredDataMapper; class QValidatedLineEdit; @@ -42,6 +43,7 @@ private slots: void newSideStakeButton_clicked(); void editSideStakeButton_clicked(); + void deleteSideStakeButton_clicked(); void showRestartWarning_Proxy(); void showRestartWarning_Lang(); @@ -72,6 +74,9 @@ private slots: bool fStakingEfficiencyValid; bool fMinStakeSplitValueValid; + QSortFilterProxyModel *m_sidestake_proxy_model; + QSortFilterProxyModel *m_sidestake_filter_proxy_model; + enum SideStakeTableColumnWidths { ADDRESS_COLUMN_WIDTH = 200, @@ -81,6 +86,8 @@ private slots: STATUS_COLUMN_WIDTH = 150 }; +private slots: + void sidestakeSelectionChanged(); }; #endif // BITCOIN_QT_OPTIONSDIALOG_H diff --git a/src/qt/sidestaketablemodel.cpp b/src/qt/sidestaketablemodel.cpp index 8514b10df9..94917e344e 100644 --- a/src/qt/sidestaketablemodel.cpp +++ b/src/qt/sidestaketablemodel.cpp @@ -223,6 +223,26 @@ QString SideStakeTableModel::addRow(const QString &address, const QString &alloc return QString::fromStdString(sidestake_address.ToString()); } +bool SideStakeTableModel::removeRows(int row, int count, const QModelIndex &parent) +{ + Q_UNUSED(parent); + GRC::SideStake* rec = m_priv->index(row); + + if(count != 1 || !rec || rec->m_status == GRC::SideStakeStatus::MANDATORY) + { + // Can only remove one row at a time, and cannot remove rows not in model. + // Also refuse to remove mandatory sidestakes. + return false; + } + { + GRC::GetSideStakeRegistry().NonContractDelete(rec->m_key); + } + + updateSideStakeTableModel(); + + return true; +} + SideStakeTableModel::EditStatus SideStakeTableModel::getEditStatus() const { return m_edit_status; diff --git a/src/qt/sidestaketablemodel.h b/src/qt/sidestaketablemodel.h index 24d7263e72..b1725f27b5 100644 --- a/src/qt/sidestaketablemodel.h +++ b/src/qt/sidestaketablemodel.h @@ -60,6 +60,7 @@ class SideStakeTableModel : public QAbstractTableModel QVariant headerData(int section, Qt::Orientation orientation, int role) const; QModelIndex index(int row, int column, const QModelIndex &parent) const; Qt::ItemFlags flags(const QModelIndex &index) const; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); void sort(int column, Qt::SortOrder order); /*@}*/