Using QDataWidgetMapper in ItemDetailMapper to work with the model data (current index of the TableView).
This commit is contained in:
@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
#include "../views/itemdetailmapper.h"
|
#include "../views/itemdetailmapper.h"
|
||||||
|
|
||||||
EditItemDialog::EditItemDialog(QWidget* parent)
|
EditItemDialog::EditItemDialog(QTableView* tableView, QWidget* parent)
|
||||||
: AbstractDialog(parent) {}
|
: AbstractDialog(parent)
|
||||||
|
, m_tableView(tableView) {}
|
||||||
|
|
||||||
void EditItemDialog::createContent() {
|
void EditItemDialog::createContent() {
|
||||||
if (m_contentContainer) {
|
if (m_contentContainer) {
|
||||||
@ -14,7 +15,18 @@ void EditItemDialog::createContent() {
|
|||||||
|
|
||||||
setWindowTitle(tr("Edit item..."));
|
setWindowTitle(tr("Edit item..."));
|
||||||
|
|
||||||
m_contentContainer = new ItemDetailMapper(this);
|
m_detailMapper = new ItemDetailMapper(this);
|
||||||
|
m_detailMapper->setModelMappings(m_tableView);
|
||||||
|
m_contentContainer = m_detailMapper;
|
||||||
|
|
||||||
m_outerLayout->insertWidget(0, m_contentContainer);
|
m_outerLayout->insertWidget(0, m_contentContainer);
|
||||||
|
|
||||||
|
void EditItemDialog::accept() {
|
||||||
|
m_detailMapper->submit();
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditItemDialog::reject() {
|
||||||
|
m_detailMapper->revert();
|
||||||
|
QDialog::reject();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,16 +7,26 @@ class QDoubleSpinBox;
|
|||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
|
class QTableView;
|
||||||
|
|
||||||
|
class ItemDetailMapper;
|
||||||
|
|
||||||
class EditItemDialog : public AbstractDialog {
|
class EditItemDialog : public AbstractDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
EditItemDialog(QWidget* parent = nullptr);
|
EditItemDialog(QTableView* tableView, QWidget* parent = nullptr);
|
||||||
|
|
||||||
/// AbstractDialog interface
|
/// AbstractDialog interface
|
||||||
void createContent() override;
|
void createContent() override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void accept() override;
|
||||||
|
void reject() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QTableView* m_tableView = nullptr;
|
||||||
|
ItemDetailMapper* m_detailMapper;
|
||||||
|
|
||||||
QLabel* m_nameLabel = nullptr;
|
QLabel* m_nameLabel = nullptr;
|
||||||
QLineEdit* m_nameEdit = nullptr;
|
QLineEdit* m_nameEdit = nullptr;
|
||||||
|
|
||||||
|
|||||||
@ -53,10 +53,13 @@ MainWindow::MainWindow(QWidget* parent)
|
|||||||
connect(this, &MainWindow::checkForUpdates, this,
|
connect(this, &MainWindow::checkForUpdates, this,
|
||||||
&MainWindow::on_actionCheck_for_update_triggered, Qt::QueuedConnection);
|
&MainWindow::on_actionCheck_for_update_triggered, Qt::QueuedConnection);
|
||||||
|
|
||||||
connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
// connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||||
&MainWindow::onSelectionChanged);
|
// &MainWindow::onSelectionChanged);
|
||||||
|
connect(ui->tableView->selectionModel(), &QItemSelectionModel::currentChanged, this,
|
||||||
|
&MainWindow::onCurrentChanged);
|
||||||
|
|
||||||
onSelectionChanged(QItemSelection(), QItemSelection());
|
onSelectionChanged(QItemSelection(), QItemSelection());
|
||||||
|
onCurrentChanged(QModelIndex(), QModelIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() { delete ui; }
|
MainWindow::~MainWindow() { delete ui; }
|
||||||
@ -104,6 +107,20 @@ void MainWindow::showStatusMessage(const QString text) {
|
|||||||
ui->statusbar->showMessage(text);
|
ui->statusbar->showMessage(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::onCurrentChanged(const QModelIndex& current, const QModelIndex& previous) {
|
||||||
|
// Q_UNUSED(current);
|
||||||
|
Q_UNUSED(previous);
|
||||||
|
|
||||||
|
// QItemSelection localSelection = ui->tableView->selectionModel()->selection();
|
||||||
|
if (current == QModelIndex()) {
|
||||||
|
// qDebug() << "Nothing selected. Disabling delete action";
|
||||||
|
m_deleteItemAct->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
// qDebug() << "Something selected. Enabling delete action";
|
||||||
|
m_deleteItemAct->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::onSelectionChanged(const QItemSelection& selected,
|
void MainWindow::onSelectionChanged(const QItemSelection& selected,
|
||||||
const QItemSelection& deselected) {
|
const QItemSelection& deselected) {
|
||||||
Q_UNUSED(selected);
|
Q_UNUSED(selected);
|
||||||
@ -162,6 +179,17 @@ void MainWindow::openEditItemDialog() {
|
|||||||
m_editItemDialog->show();
|
m_editItemDialog->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::deleteCurrentItem() {
|
||||||
|
showStatusMessage(tr("Invoked 'Edit|Delete Item'"));
|
||||||
|
// QItemSelection localSelection = ui->tableView->selectionModel()->selection();
|
||||||
|
const QModelIndex currentIndex = ui->tableView->selectionModel()->currentIndex();
|
||||||
|
if (currentIndex == QModelIndex()) {
|
||||||
|
qDebug() << "No current item. Nothing to remove.";
|
||||||
|
} else {
|
||||||
|
m_tableModel->removeRows(currentIndex.row(), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::deleteSelectedtItems() {
|
void MainWindow::deleteSelectedtItems() {
|
||||||
showStatusMessage(tr("Invoked 'Edit|Delete Item'"));
|
showStatusMessage(tr("Invoked 'Edit|Delete Item'"));
|
||||||
QItemSelection localSelection = ui->tableView->selectionModel()->selection();
|
QItemSelection localSelection = ui->tableView->selectionModel()->selection();
|
||||||
@ -349,7 +377,8 @@ void MainWindow::createEditActions() {
|
|||||||
m_deleteItemAct = make_unique<QAction>(tr("&Delete item(s)"), this);
|
m_deleteItemAct = make_unique<QAction>(tr("&Delete item(s)"), this);
|
||||||
m_deleteItemAct->setShortcuts(QKeySequence::Delete);
|
m_deleteItemAct->setShortcuts(QKeySequence::Delete);
|
||||||
m_deleteItemAct->setStatusTip(tr("Delete currently selected item(s)"));
|
m_deleteItemAct->setStatusTip(tr("Delete currently selected item(s)"));
|
||||||
connect(m_deleteItemAct.get(), &QAction::triggered, this, &MainWindow::deleteSelectedtItems);
|
// connect(m_deleteItemAct.get(), &QAction::triggered, this, &MainWindow::deleteSelectedtItems);
|
||||||
|
connect(m_deleteItemAct.get(), &QAction::triggered, this, &MainWindow::deleteCurrentItem);
|
||||||
ui->menu_Edit->addAction(m_deleteItemAct.get());
|
ui->menu_Edit->addAction(m_deleteItemAct.get());
|
||||||
|
|
||||||
ui->menu_Edit->addSeparator();
|
ui->menu_Edit->addSeparator();
|
||||||
@ -379,6 +408,6 @@ void MainWindow::createGuiDialogs() {
|
|||||||
connect(m_newItemDialog.get(), &NewItemDialog::addItems, m_tableModel.get(),
|
connect(m_newItemDialog.get(), &NewItemDialog::addItems, m_tableModel.get(),
|
||||||
&TableModel::appendItems);
|
&TableModel::appendItems);
|
||||||
/// edit item dialog
|
/// edit item dialog
|
||||||
m_editItemDialog = make_unique<EditItemDialog>(this);
|
m_editItemDialog = make_unique<EditItemDialog>(ui->tableView, this);
|
||||||
m_editItemDialog->createContent();
|
m_editItemDialog->createContent();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,7 @@ class MainWindow : public QMainWindow {
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void showStatusMessage(const QString text);
|
void showStatusMessage(const QString text);
|
||||||
|
void onCurrentChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||||
void onSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
void onSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
|
||||||
|
|
||||||
void onAboutClicked();
|
void onAboutClicked();
|
||||||
@ -47,6 +48,7 @@ class MainWindow : public QMainWindow {
|
|||||||
/// slots for menu actions
|
/// slots for menu actions
|
||||||
void openNewItemDialog();
|
void openNewItemDialog();
|
||||||
void openEditItemDialog();
|
void openEditItemDialog();
|
||||||
|
void deleteCurrentItem();
|
||||||
void deleteSelectedtItems();
|
void deleteSelectedtItems();
|
||||||
|
|
||||||
void onCleanStateChanged(bool clean);
|
void onCleanStateChanged(bool clean);
|
||||||
|
|||||||
@ -1,14 +1,30 @@
|
|||||||
#include "itemdetailmapper.h"
|
#include "itemdetailmapper.h"
|
||||||
|
|
||||||
|
#include <QAbstractItemModel>
|
||||||
|
#include <QDataWidgetMapper>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
#include <QPushButton>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
|
#include <QTableView>
|
||||||
|
|
||||||
ItemDetailMapper::ItemDetailMapper(QWidget* parent)
|
ItemDetailMapper::ItemDetailMapper(QWidget* parent)
|
||||||
: QWidget{parent} {
|
: QWidget{parent} {
|
||||||
|
/// model mapping
|
||||||
|
m_mapper = std::make_unique<QDataWidgetMapper>(this);
|
||||||
|
m_mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
|
||||||
|
|
||||||
|
/// model mapping buttons
|
||||||
|
m_nextButton = new QPushButton(tr("Ne&xt"));
|
||||||
|
m_previousButton = new QPushButton(tr("&Previous"));
|
||||||
|
|
||||||
|
connect(m_previousButton, &QAbstractButton::clicked, this, &ItemDetailMapper::toPrevious);
|
||||||
|
connect(m_nextButton, &QAbstractButton::clicked, this, &ItemDetailMapper::toNext);
|
||||||
|
|
||||||
|
/// the individual widgets
|
||||||
// REFACTOR deduce label names and types from meta data & use a factory
|
// REFACTOR deduce label names and types from meta data & use a factory
|
||||||
m_nameLabel = new QLabel("&Name");
|
m_nameLabel = new QLabel("&Name");
|
||||||
m_nameEdit = new QLineEdit();
|
m_nameEdit = new QLineEdit();
|
||||||
@ -44,5 +60,83 @@ ItemDetailMapper::ItemDetailMapper(QWidget* parent)
|
|||||||
layout->addWidget(m_factorLabel, 4, 0, 1, 1);
|
layout->addWidget(m_factorLabel, 4, 0, 1, 1);
|
||||||
layout->addWidget(m_factorBox, 4, 1, 1, 1);
|
layout->addWidget(m_factorBox, 4, 1, 1, 1);
|
||||||
|
|
||||||
|
layout->addWidget(m_previousButton, 5, 0, 1, 1);
|
||||||
|
layout->addWidget(m_nextButton, 5, 1, 1, 1);
|
||||||
|
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemDetailMapper::setModelMappings(QTableView* tableView) {
|
||||||
|
qDebug() << "Setting model...";
|
||||||
|
m_tableView = tableView;
|
||||||
|
m_model = tableView->model();
|
||||||
|
m_selectionModel = tableView->selectionModel();
|
||||||
|
|
||||||
|
m_mapper->setModel(m_model);
|
||||||
|
m_mapper->addMapping(m_nameEdit, 0);
|
||||||
|
m_mapper->addMapping(m_descriptionEdit, 1);
|
||||||
|
m_mapper->addMapping(m_infoEdit, 2);
|
||||||
|
m_mapper->addMapping(m_amountBox, 3);
|
||||||
|
m_mapper->addMapping(m_factorBox, 4);
|
||||||
|
|
||||||
|
m_mapper->setCurrentIndex(m_selectionModel->currentIndex().row());
|
||||||
|
|
||||||
|
connect(m_model, &QAbstractItemModel::rowsInserted, this, &ItemDetailMapper::rowsInserted);
|
||||||
|
connect(m_model, &QAbstractItemModel::rowsRemoved, this, &ItemDetailMapper::rowsRemoved);
|
||||||
|
connect(m_selectionModel, &QItemSelectionModel::currentChanged, this,
|
||||||
|
&ItemDetailMapper::onCurrentIndexChanged);
|
||||||
|
|
||||||
|
updateButtons(m_selectionModel->currentIndex().row());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ItemDetailMapper::submit() { return m_mapper->submit(); }
|
||||||
|
|
||||||
|
void ItemDetailMapper::revert() { m_mapper->revert(); }
|
||||||
|
|
||||||
|
void ItemDetailMapper::onCurrentIndexChanged(const QModelIndex& current,
|
||||||
|
const QModelIndex& previous) {
|
||||||
|
if (!isEnabled()) {
|
||||||
|
setEnabled(true);
|
||||||
|
}
|
||||||
|
m_mapper->setCurrentModelIndex(current);
|
||||||
|
updateButtons(current.row());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemDetailMapper::rowsInserted(const QModelIndex& parent, int start, int end) {
|
||||||
|
updateButtons(m_mapper->currentIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemDetailMapper::rowsRemoved(const QModelIndex& parent, int start, int end) {
|
||||||
|
if (m_model->rowCount() == 0) {
|
||||||
|
setEnabled(false);
|
||||||
|
|
||||||
|
m_nameEdit->clear();
|
||||||
|
m_descriptionEdit->clear();
|
||||||
|
m_infoEdit->clear();
|
||||||
|
m_amountBox->clear();
|
||||||
|
m_factorBox->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
updateButtons(m_mapper->currentIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemDetailMapper::toPrevious() {
|
||||||
|
int currentRow = m_selectionModel->currentIndex().row();
|
||||||
|
QModelIndex previousIndex = m_selectionModel->currentIndex().siblingAtRow(currentRow - 1);
|
||||||
|
if (previousIndex.isValid()) {
|
||||||
|
m_selectionModel->setCurrentIndex(previousIndex, QItemSelectionModel::ClearAndSelect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemDetailMapper::toNext() {
|
||||||
|
int currentRow = m_selectionModel->currentIndex().row();
|
||||||
|
QModelIndex nextIndex = m_selectionModel->currentIndex().siblingAtRow(currentRow + 1);
|
||||||
|
if (nextIndex.isValid()) {
|
||||||
|
m_selectionModel->setCurrentIndex(nextIndex, QItemSelectionModel::ClearAndSelect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemDetailMapper::updateButtons(int row) {
|
||||||
|
m_previousButton->setEnabled(row > 0);
|
||||||
|
m_nextButton->setEnabled(row < m_model->rowCount() - 1);
|
||||||
|
}
|
||||||
|
|||||||
@ -1,21 +1,48 @@
|
|||||||
#ifndef ITEMDETAILMAPPER_H
|
#ifndef ITEMDETAILMAPPER_H
|
||||||
#define ITEMDETAILMAPPER_H
|
#define ITEMDETAILMAPPER_H
|
||||||
|
|
||||||
|
#include <QDataWidgetMapper>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLineEdit;
|
class QLineEdit;
|
||||||
class QDoubleSpinBox;
|
class QDoubleSpinBox;
|
||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
|
class QPushButton;
|
||||||
|
class QAbstractItemModel;
|
||||||
|
class QItemSelectionModel;
|
||||||
|
class QTableView;
|
||||||
|
|
||||||
class ItemDetailMapper : public QWidget {
|
class ItemDetailMapper : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ItemDetailMapper(QWidget* parent = nullptr);
|
explicit ItemDetailMapper(QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
void setModelMappings(QTableView* tableView);
|
||||||
|
|
||||||
|
bool submit();
|
||||||
|
void revert();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous);
|
||||||
|
void rowsInserted(const QModelIndex& parent, int start, int end);
|
||||||
|
void rowsRemoved(const QModelIndex& parent, int start, int end);
|
||||||
|
void toPrevious();
|
||||||
|
void toNext();
|
||||||
|
void updateButtons(int row);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// *** members ***
|
||||||
|
/// Model stuff
|
||||||
|
QTableView* m_tableView = nullptr;
|
||||||
|
QAbstractItemModel* m_model = nullptr;
|
||||||
|
QItemSelectionModel* m_selectionModel = nullptr;
|
||||||
|
|
||||||
|
std::unique_ptr<QDataWidgetMapper> m_mapper;
|
||||||
|
|
||||||
|
/// GUI elements
|
||||||
QLabel* m_nameLabel = nullptr;
|
QLabel* m_nameLabel = nullptr;
|
||||||
QLineEdit* m_nameEdit = nullptr;
|
QLineEdit* m_nameEdit = nullptr;
|
||||||
|
|
||||||
@ -30,6 +57,9 @@ class ItemDetailMapper : public QWidget {
|
|||||||
|
|
||||||
QLabel* m_factorLabel = nullptr;
|
QLabel* m_factorLabel = nullptr;
|
||||||
QDoubleSpinBox* m_factorBox = nullptr;
|
QDoubleSpinBox* m_factorBox = nullptr;
|
||||||
|
|
||||||
|
QPushButton* m_nextButton;
|
||||||
|
QPushButton* m_previousButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ITEMDETAILMAPPER_H
|
#endif // ITEMDETAILMAPPER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user