130 lines
3.9 KiB
C++
130 lines
3.9 KiB
C++
#include "DataGridWidget.h"
|
|
#include "CrudModel.h"
|
|
#include "CustomDataRole.h"
|
|
#include "RecordPanel.h"
|
|
#include "ResultTableModelUtil.h"
|
|
#include "util/PgLabItemDelegate.h"
|
|
#include <QAction>
|
|
#include <QItemSelectionModel>
|
|
#include <QSortFilterProxyModel>
|
|
#include <QSplitter>
|
|
#include <QStyle>
|
|
#include <QTableView>
|
|
#include <QToolBar>
|
|
#include <QVBoxLayout>
|
|
|
|
|
|
DataGridWidget::DataGridWidget(QWidget *parent)
|
|
: QWidget(parent)
|
|
{
|
|
auto layout = new QVBoxLayout(this);
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
m_toolbar = new QToolBar(this);
|
|
m_toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
|
layout->addWidget(m_toolbar);
|
|
|
|
m_actSave = new QAction(style()->standardIcon(QStyle::SP_DialogSaveButton), tr("Save"), this);
|
|
m_actSave->setShortcut(QKeySequence::Save);
|
|
m_actSave->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
|
m_actSave->setToolTip(tr("Save all pending changes to the database (Ctrl+S)"));
|
|
m_actSave->setEnabled(false);
|
|
addAction(m_actSave);
|
|
m_toolbar->addAction(m_actSave);
|
|
connect(m_actSave, &QAction::triggered, this, &DataGridWidget::onSave);
|
|
|
|
m_actRevert = new QAction(style()->standardIcon(QStyle::SP_DialogResetButton), tr("Revert"), this);
|
|
m_actRevert->setToolTip(tr("Discard all pending changes"));
|
|
m_actRevert->setEnabled(false);
|
|
m_toolbar->addAction(m_actRevert);
|
|
connect(m_actRevert, &QAction::triggered, this, &DataGridWidget::onRevert);
|
|
|
|
m_actRecord = new QAction(tr("Record"), this);
|
|
m_actRecord->setCheckable(true);
|
|
m_actRecord->setChecked(true);
|
|
m_actRecord->setToolTip(tr("Show the values of the current row next to the grid"));
|
|
m_toolbar->addAction(m_actRecord);
|
|
|
|
m_view = new QTableView(this);
|
|
SetTableViewDefault(m_view);
|
|
auto delegate = new PgLabItemDelegate(m_view);
|
|
m_view->setItemDelegate(delegate);
|
|
|
|
m_splitter = new QSplitter(Qt::Horizontal, this);
|
|
layout->addWidget(m_splitter);
|
|
m_splitter->addWidget(m_view);
|
|
|
|
m_recordPanel = new RecordPanel(this);
|
|
m_recordPanel->setFirstDataColumn(CrudModel::PreColumnCount);
|
|
m_splitter->addWidget(m_recordPanel);
|
|
m_splitter->setStretchFactor(0, 1);
|
|
m_splitter->setStretchFactor(1, 0);
|
|
|
|
connect(m_actRecord, &QAction::toggled, m_recordPanel, &QWidget::setVisible);
|
|
}
|
|
|
|
void DataGridWidget::setSourceModel(QAbstractItemModel *model)
|
|
{
|
|
if (!m_proxy) {
|
|
m_proxy = new QSortFilterProxyModel(this);
|
|
m_proxy->setSortRole(CustomSortRole);
|
|
}
|
|
disconnect(m_pendingChangesConnection);
|
|
disconnect(m_currentRowConnection);
|
|
m_proxy->setSourceModel(model);
|
|
m_view->setModel(m_proxy);
|
|
m_view->setSortingEnabled(true);
|
|
m_proxy->sort(0, Qt::AscendingOrder);
|
|
|
|
m_recordPanel->setModel(m_proxy);
|
|
m_currentRowConnection = connect(m_view->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &DataGridWidget::onCurrentRowChanged);
|
|
|
|
auto crud = qobject_cast<CrudModel *>(model);
|
|
m_actSave->setVisible(crud != nullptr);
|
|
m_actRevert->setVisible(crud != nullptr);
|
|
if (crud) {
|
|
m_pendingChangesConnection = connect(crud, &CrudModel::pendingChangesChanged, this, &DataGridWidget::onPendingChangesChanged);
|
|
onPendingChangesChanged(crud->hasPendingChanges());
|
|
}
|
|
else {
|
|
onPendingChangesChanged(false);
|
|
}
|
|
}
|
|
|
|
void DataGridWidget::onCurrentRowChanged(const QModelIndex ¤t)
|
|
{
|
|
m_recordPanel->setCurrentRow(current.row());
|
|
}
|
|
|
|
void DataGridWidget::onPendingChangesChanged(bool hasChanges)
|
|
{
|
|
m_actSave->setEnabled(hasChanges);
|
|
m_actRevert->setEnabled(hasChanges);
|
|
}
|
|
|
|
void DataGridWidget::onSave()
|
|
{
|
|
auto crud = qobject_cast<CrudModel *>(m_proxy->sourceModel());
|
|
if (!crud)
|
|
return;
|
|
|
|
commitOpenEditor();
|
|
crud->saveChanges();
|
|
}
|
|
|
|
void DataGridWidget::onRevert()
|
|
{
|
|
auto crud = qobject_cast<CrudModel *>(m_proxy->sourceModel());
|
|
if (!crud)
|
|
return;
|
|
|
|
commitOpenEditor();
|
|
crud->revertChanges();
|
|
}
|
|
|
|
void DataGridWidget::commitOpenEditor()
|
|
{
|
|
// Moving focus away from the editor makes the delegate commit its value, a toolbar click does not take focus
|
|
if (m_view->indexWidget(m_view->currentIndex()))
|
|
m_view->setFocus();
|
|
}
|