2022-05-10 10:06:48 +00:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
#include "bookwindow.h"
|
|
|
|
#include "bookdelegate.h"
|
|
|
|
#include "initdb.h"
|
|
|
|
|
2024-01-12 23:00:41 +00:00
|
|
|
#include <QApplication>
|
|
|
|
#include <QComboBox>
|
|
|
|
#include <QDataWidgetMapper>
|
|
|
|
#include <QGridLayout>
|
|
|
|
#include <QHeaderView>
|
|
|
|
#include <QLabel>
|
|
|
|
#include <QLineEdit>
|
|
|
|
#include <QMenu>
|
|
|
|
#include <QMenuBar>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QScrollBar>
|
|
|
|
#include <QSpinBox>
|
|
|
|
#include <QSqlDatabase>
|
|
|
|
#include <QTableView>
|
2011-04-27 10:05:43 +00:00
|
|
|
|
|
|
|
BookWindow::BookWindow()
|
|
|
|
{
|
|
|
|
if (!QSqlDatabase::drivers().contains("QSQLITE"))
|
2024-01-12 23:00:41 +00:00
|
|
|
QMessageBox::critical(this, tr("Unable to load database"),
|
|
|
|
tr("This demo needs the SQLITE driver"));
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2018-06-05 11:13:38 +00:00
|
|
|
// Initialize the database:
|
2011-04-27 10:05:43 +00:00
|
|
|
QSqlError err = initDb();
|
|
|
|
if (err.type() != QSqlError::NoError) {
|
|
|
|
showError(err);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-11-01 13:18:14 +00:00
|
|
|
// create the central widget for the window
|
|
|
|
window = new QWidget(this);
|
|
|
|
setCentralWidget(window);
|
|
|
|
|
|
|
|
createLayout();
|
|
|
|
|
|
|
|
createModel();
|
|
|
|
|
|
|
|
// Populate the model
|
|
|
|
if (!model->select()) {
|
|
|
|
showError(model->lastError());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
configureWidgets();
|
|
|
|
|
|
|
|
// create the mappings between the UI elements and the SQL model
|
|
|
|
createMappings();
|
|
|
|
|
|
|
|
tableView->setCurrentIndex(model->index(0, 0));
|
|
|
|
tableView->selectRow(0);
|
|
|
|
|
|
|
|
createMenuBar();
|
|
|
|
}
|
|
|
|
|
|
|
|
void BookWindow::showError(const QSqlError &err)
|
|
|
|
{
|
2024-01-12 23:00:41 +00:00
|
|
|
QMessageBox::critical(this, tr("Unable to initialize Database"),
|
|
|
|
tr("Error initializing database: %1").arg(err.text()));
|
2023-11-01 13:18:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BookWindow::createLayout()
|
|
|
|
{
|
|
|
|
tableView = new QTableView(window);
|
|
|
|
|
|
|
|
gridLayout = new QGridLayout(window);
|
|
|
|
|
|
|
|
titleLabel = new QLabel(tr("Title:"), window);
|
|
|
|
titleLineEdit = new QLineEdit(window);
|
|
|
|
authorLabel = new QLabel(tr("Author:"), window);
|
|
|
|
authorComboBox = new QComboBox(window);
|
|
|
|
genreLabel = new QLabel(tr("Genre:"), window);
|
|
|
|
genreComboBox = new QComboBox(window);
|
|
|
|
yearLabel = new QLabel(tr("Year:"), window);
|
|
|
|
yearSpinBox = new QSpinBox(window);
|
|
|
|
ratingLabel = new QLabel(tr("Rating:"), window);
|
|
|
|
ratingComboBox = new QComboBox(window);
|
|
|
|
|
|
|
|
gridLayout->addWidget(titleLabel, 0, 0, Qt::AlignRight);
|
|
|
|
gridLayout->addWidget(titleLineEdit, 0, 1, 1, 3);
|
|
|
|
gridLayout->addWidget(authorLabel, 1, 0, Qt::AlignRight);
|
|
|
|
gridLayout->addWidget(authorComboBox, 1, 1);
|
|
|
|
gridLayout->addWidget(yearLabel, 1, 2, Qt::AlignRight);
|
|
|
|
gridLayout->addWidget(yearSpinBox, 1, 3);
|
|
|
|
gridLayout->addWidget(genreLabel, 2, 0, Qt::AlignRight);
|
|
|
|
gridLayout->addWidget(genreComboBox, 2, 1);
|
|
|
|
gridLayout->addWidget(ratingLabel, 2, 2, Qt::AlignRight);
|
|
|
|
gridLayout->addWidget(ratingComboBox, 2, 3);
|
|
|
|
gridLayout->addWidget(tableView, 3, 0, 1, 4, Qt::AlignCenter);
|
|
|
|
gridLayout->setColumnStretch(1, 1000);
|
|
|
|
gridLayout->setColumnStretch(3, 1000);
|
|
|
|
|
|
|
|
gridLayout->setContentsMargins(18, 18, 18, 18);
|
|
|
|
gridLayout->setSpacing(18);
|
|
|
|
gridLayout->setAlignment(Qt::AlignHCenter);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BookWindow::createModel()
|
|
|
|
{
|
|
|
|
model = new QSqlRelationalTableModel(tableView);
|
2011-04-27 10:05:43 +00:00
|
|
|
model->setEditStrategy(QSqlTableModel::OnManualSubmit);
|
|
|
|
model->setTable("books");
|
|
|
|
|
|
|
|
authorIdx = model->fieldIndex("author");
|
|
|
|
genreIdx = model->fieldIndex("genre");
|
|
|
|
|
2023-11-01 13:18:14 +00:00
|
|
|
// Set the relations to the other database tables
|
2011-04-27 10:05:43 +00:00
|
|
|
model->setRelation(authorIdx, QSqlRelation("authors", "id", "name"));
|
|
|
|
model->setRelation(genreIdx, QSqlRelation("genres", "id", "name"));
|
|
|
|
|
2023-11-01 13:18:14 +00:00
|
|
|
// Set the localised header captions
|
2011-04-27 10:05:43 +00:00
|
|
|
model->setHeaderData(authorIdx, Qt::Horizontal, tr("Author Name"));
|
|
|
|
model->setHeaderData(genreIdx, Qt::Horizontal, tr("Genre"));
|
2018-06-05 11:13:38 +00:00
|
|
|
model->setHeaderData(model->fieldIndex("title"),
|
|
|
|
Qt::Horizontal, tr("Title"));
|
2011-04-27 10:05:43 +00:00
|
|
|
model->setHeaderData(model->fieldIndex("year"), Qt::Horizontal, tr("Year"));
|
2018-06-05 11:13:38 +00:00
|
|
|
model->setHeaderData(model->fieldIndex("rating"),
|
|
|
|
Qt::Horizontal, tr("Rating"));
|
2023-11-01 13:18:14 +00:00
|
|
|
}
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2023-11-01 13:18:14 +00:00
|
|
|
void BookWindow::configureWidgets()
|
|
|
|
{
|
|
|
|
tableView->setModel(model);
|
2024-07-02 14:02:54 +00:00
|
|
|
tableView->setItemDelegate(new BookDelegate(model->fieldIndex("rating"), tableView));
|
2023-11-01 13:18:14 +00:00
|
|
|
tableView->setColumnHidden(model->fieldIndex("id"), true);
|
|
|
|
tableView->verticalHeader()->setVisible(false);
|
|
|
|
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
|
|
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
|
|
|
|
|
|
// Lock and prohibit resizing of the width of the columns
|
|
|
|
tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
|
|
|
tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
|
|
|
tableView->horizontalHeader()->setFixedHeight(tableView->rowHeight(0));
|
|
|
|
|
|
|
|
// increment by two to consider the frame
|
|
|
|
tableView->setFixedWidth(tableView->horizontalHeader()->length() +
|
|
|
|
tableView->verticalScrollBar()->sizeHint().width() + 2);
|
|
|
|
tableView->setMaximumHeight(tableView->verticalHeader()->length() +
|
|
|
|
tableView->horizontalHeader()->height() + 2);
|
|
|
|
|
|
|
|
authorComboBox->setModel(model->relationModel(authorIdx));
|
|
|
|
authorComboBox->setModelColumn(model->relationModel(authorIdx)->fieldIndex("name"));
|
|
|
|
|
|
|
|
genreComboBox->setModel(model->relationModel(genreIdx));
|
|
|
|
genreComboBox->setModelColumn(model->relationModel(genreIdx)->fieldIndex("name"));
|
|
|
|
|
|
|
|
yearSpinBox->setMaximum(9999);
|
|
|
|
|
2024-07-02 14:02:54 +00:00
|
|
|
ratingComboBox->setItemDelegate(new BookDelegate(0, this));
|
|
|
|
ratingComboBox->setLabelDrawingMode(QComboBox::LabelDrawingMode::UseDelegate);
|
|
|
|
ratingComboBox->addItems({"0", "1", "2", "3", "4", "5"});
|
2011-04-27 10:05:43 +00:00
|
|
|
|
2024-07-02 14:02:54 +00:00
|
|
|
ratingComboBox->setIconSize(iconSize());
|
2023-11-01 13:18:14 +00:00
|
|
|
}
|
2018-06-08 09:59:52 +00:00
|
|
|
|
2023-11-01 13:18:14 +00:00
|
|
|
void BookWindow::createMappings()
|
|
|
|
{
|
2011-04-27 10:05:43 +00:00
|
|
|
QDataWidgetMapper *mapper = new QDataWidgetMapper(this);
|
|
|
|
mapper->setModel(model);
|
2024-07-02 14:02:54 +00:00
|
|
|
mapper->setItemDelegate(new BookDelegate(model->fieldIndex("rating"), this));
|
2023-11-01 13:18:14 +00:00
|
|
|
mapper->addMapping(titleLineEdit, model->fieldIndex("title"));
|
|
|
|
mapper->addMapping(yearSpinBox, model->fieldIndex("year"));
|
|
|
|
mapper->addMapping(authorComboBox, authorIdx);
|
|
|
|
mapper->addMapping(genreComboBox, genreIdx);
|
|
|
|
mapper->addMapping(ratingComboBox, model->fieldIndex("rating"), "currentIndex");
|
|
|
|
connect(tableView->selectionModel(),
|
2018-06-05 11:13:38 +00:00
|
|
|
&QItemSelectionModel::currentRowChanged,
|
|
|
|
mapper,
|
|
|
|
&QDataWidgetMapper::setCurrentModelIndex
|
|
|
|
);
|
2011-04-27 10:05:43 +00:00
|
|
|
}
|
2018-06-13 11:04:10 +00:00
|
|
|
|
|
|
|
void BookWindow::createMenuBar()
|
|
|
|
{
|
|
|
|
QAction *quitAction = new QAction(tr("&Quit"), this);
|
|
|
|
QAction *aboutAction = new QAction(tr("&About"), this);
|
|
|
|
QAction *aboutQtAction = new QAction(tr("&About Qt"), this);
|
|
|
|
|
|
|
|
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
|
|
|
|
fileMenu->addAction(quitAction);
|
|
|
|
|
|
|
|
QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
|
|
|
|
helpMenu->addAction(aboutAction);
|
|
|
|
helpMenu->addAction(aboutQtAction);
|
|
|
|
|
2023-02-20 10:18:35 +00:00
|
|
|
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
|
2018-06-13 11:04:10 +00:00
|
|
|
connect(aboutAction, &QAction::triggered, this, &BookWindow::about);
|
|
|
|
connect(aboutQtAction, &QAction::triggered, qApp, &QApplication::aboutQt);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BookWindow::about()
|
|
|
|
{
|
|
|
|
QMessageBox::about(this, tr("About Books"),
|
|
|
|
tr("<p>The <b>Books</b> example shows how to use Qt SQL classes "
|
|
|
|
"with a model/view framework."));
|
|
|
|
}
|