Compare commits

..

3 Commits

7 changed files with 79 additions and 15 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
set(TARGET_APP "GenericQtClient-Widgets") set(TARGET_APP "GenericQtClient-Widgets")
project(${TARGET_APP} VERSION 0.1.0 LANGUAGES CXX) project(${TARGET_APP} VERSION 0.2.0 LANGUAGES CXX)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
@ -63,6 +63,8 @@ target_link_libraries(${TARGET_APP} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
target_include_directories(${TARGET_APP} PRIVATE ${CORE_LIB_DIR}/) target_include_directories(${TARGET_APP} PRIVATE ${CORE_LIB_DIR}/)
target_link_libraries(${TARGET_APP} PRIVATE GenericCore) target_link_libraries(${TARGET_APP} PRIVATE GenericCore)
target_include_directories(${TARGET_APP} PRIVATE ${QR_LIB_DIR}/src)
target_link_libraries(${TARGET_APP} PRIVATE qrcode)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.

View File

@ -1,13 +1,15 @@
#include "edititemdialog.h" #include "edititemdialog.h"
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QLabel>
#include <QVBoxLayout> #include <QVBoxLayout>
#include "../views/itemdetailmapper.h" #include "../views/itemdetailmapper.h"
EditItemDialog::EditItemDialog(QTableView* tableView, QWidget* parent) EditItemDialog::EditItemDialog(QTableView* tableView, QWidget* parent)
: AbstractDialog(QDialogButtonBox::Close, parent) : AbstractDialog(QDialogButtonBox::Close, parent)
, m_tableView(tableView) {} , m_tableView(tableView)
, m_qrCodeDisplay(new QLabel("QR Code")) {}
void EditItemDialog::createContent() { void EditItemDialog::createContent() {
if (m_contentContainer) { if (m_contentContainer) {
@ -16,9 +18,17 @@ void EditItemDialog::createContent() {
setWindowTitle(tr("Edit item...")); setWindowTitle(tr("Edit item..."));
m_contentContainer = new QWidget(this);
QHBoxLayout* innerLayout = new QHBoxLayout(this);
m_contentContainer->setLayout(innerLayout);
m_detailMapper = new ItemDetailMapper(this); m_detailMapper = new ItemDetailMapper(this);
m_detailMapper->setModelMappings(m_tableView); m_detailMapper->setModelMappings(m_tableView);
m_contentContainer = m_detailMapper; innerLayout->addWidget(m_detailMapper);
updateQRCode();
connect(m_detailMapper, &ItemDetailMapper::contentChanged, this, &EditItemDialog::updateQRCode);
innerLayout->addWidget(m_qrCodeDisplay);
m_outerLayout->insertWidget(0, m_contentContainer); m_outerLayout->insertWidget(0, m_contentContainer);
} }
@ -32,3 +42,16 @@ void EditItemDialog::reject() {
m_detailMapper->revert(); m_detailMapper->revert();
QDialog::reject(); QDialog::reject();
} }
void EditItemDialog::updateQRCode(const QString text) {
QImage unscaledImage;
if (text.isEmpty()) {
unscaledImage = QImage("://no-picture-taking.png");
} else {
unscaledImage = m_generator.generateQr(text);
}
QImage image = unscaledImage.scaled(250, 250);
m_qrCodeDisplay->setPixmap(QPixmap::fromImage(image));
m_qrCodeDisplay->setToolTip(text);
}

View File

@ -1,6 +1,7 @@
#ifndef EDITITEMDIALOG_H #ifndef EDITITEMDIALOG_H
#define EDITITEMDIALOG_H #define EDITITEMDIALOG_H
#include "QrCodeGenerator.h"
#include "abstractdialog.h" #include "abstractdialog.h"
class QDoubleSpinBox; class QDoubleSpinBox;
@ -23,6 +24,9 @@ class EditItemDialog : public AbstractDialog {
void accept() override; void accept() override;
void reject() override; void reject() override;
private slots:
void updateQRCode(const QString text = "");
private: private:
QTableView* m_tableView = nullptr; QTableView* m_tableView = nullptr;
ItemDetailMapper* m_detailMapper; ItemDetailMapper* m_detailMapper;
@ -41,6 +45,9 @@ class EditItemDialog : public AbstractDialog {
QLabel* m_factorLabel = nullptr; QLabel* m_factorLabel = nullptr;
QDoubleSpinBox* m_factorBox = nullptr; QDoubleSpinBox* m_factorBox = nullptr;
QLabel* m_qrCodeDisplay = nullptr;
QrCodeGenerator m_generator;
}; };
#endif // EDITITEMDIALOG_H #endif // EDITITEMDIALOG_H

View File

@ -3,6 +3,7 @@
#include <QCloseEvent> #include <QCloseEvent>
#include <QFileDialog> #include <QFileDialog>
#include <QInputDialog>
#include <QMessageBox> #include <QMessageBox>
#include <QStandardPaths> #include <QStandardPaths>
#include <QUndoStack> #include <QUndoStack>
@ -45,10 +46,10 @@ MainWindow::MainWindow(QWidget* parent)
restoreGeometry(settings.value("geometry").toByteArray()); restoreGeometry(settings.value("geometry").toByteArray());
restoreState(settings.value("windowState").toByteArray()); restoreState(settings.value("windowState").toByteArray());
m_tableModel = m_core->getModel(); // m_tableModel = m_core->getModel();
// ui->tableView->setModel(m_tableModel.get()); // ui->tableView->setModel(m_tableModel.get());
m_sortModel = m_core->getSortFilterModel(); m_proxyModel = m_core->getSortFilterModel();
ui->tableView->setModel((QAbstractItemModel*)m_sortModel.get()); ui->tableView->setModel((QAbstractItemModel*)m_proxyModel.get());
ui->tableView->setSortingEnabled(true); ui->tableView->setSortingEnabled(true);
createActions(); createActions();
@ -194,7 +195,7 @@ void MainWindow::deleteCurrentItem() {
if (currentIndex == QModelIndex()) { if (currentIndex == QModelIndex()) {
qDebug() << "No current item. Nothing to remove."; qDebug() << "No current item. Nothing to remove.";
} else { } else {
m_sortModel->removeRows(currentIndex.row(), 1); m_proxyModel->removeRows(currentIndex.row(), 1);
} }
} }
@ -212,7 +213,7 @@ void MainWindow::deleteSelectedtItems() {
const int topRow = iter->top(); const int topRow = iter->top();
const int bottomRow = iter->bottom(); const int bottomRow = iter->bottom();
const int nRows = bottomRow - topRow + 1; const int nRows = bottomRow - topRow + 1;
m_sortModel->removeRows(topRow, nRows); m_proxyModel->removeRows(topRow, nRows);
} }
} }
} }
@ -278,6 +279,24 @@ void MainWindow::exportCSV() {
} }
} }
void MainWindow::findItems() {
showStatusMessage(tr("Invoked 'Edit|Find items'"));
bool ok;
QString text = QInputDialog::getText(this, tr("Find items"), tr("Enter the text to search for:"),
QLineEdit::Normal, "", &ok);
if (ok && !text.isEmpty()) {
const QItemSelection itemsToSelect = m_proxyModel->findItems(text);
if (itemsToSelect.empty()) {
ui->tableView->setCurrentIndex(QModelIndex());
ui->tableView->selectionModel()->select(QModelIndex(), QItemSelectionModel::ClearAndSelect);
} else {
ui->tableView->setCurrentIndex(itemsToSelect.first().topLeft());
ui->tableView->selectionModel()->select(itemsToSelect, QItemSelectionModel::ClearAndSelect);
}
}
}
void MainWindow::createActions() { void MainWindow::createActions() {
// TODO add generic menu actions (file/new, edit/cut, ...) // TODO add generic menu actions (file/new, edit/cut, ...)
createFileActions(); createFileActions();
@ -425,8 +444,7 @@ void MainWindow::createEditActions() {
m_findItemAct = make_unique<QAction>(tr("&Find item(s)"), this); m_findItemAct = make_unique<QAction>(tr("&Find item(s)"), this);
m_findItemAct->setShortcuts(QKeySequence::Find); m_findItemAct->setShortcuts(QKeySequence::Find);
m_findItemAct->setStatusTip(tr("Opens a dialog to find item(s) by containing text")); m_findItemAct->setStatusTip(tr("Opens a dialog to find item(s) by containing text"));
// connect(m_findItemAct, &QAction::triggered, this, &MainWindow::findItems); connect(m_findItemAct.get(), &QAction::triggered, this, &MainWindow::findItems);
m_findItemAct->setEnabled(false);
ui->menu_Edit->addAction(m_findItemAct.get()); ui->menu_Edit->addAction(m_findItemAct.get());
} }
@ -444,7 +462,7 @@ void MainWindow::createGuiDialogs() {
/// new item dialog /// new item dialog
m_newItemDialog = make_unique<NewItemDialog>(this); m_newItemDialog = make_unique<NewItemDialog>(this);
m_newItemDialog->createContent(); m_newItemDialog->createContent();
connect(m_newItemDialog.get(), &NewItemDialog::addItems, m_sortModel.get(), connect(m_newItemDialog.get(), &NewItemDialog::addItems, m_proxyModel.get(),
&GeneralSortFilterModel::appendItems); &GeneralSortFilterModel::appendItems);
/// edit item dialog /// edit item dialog
m_editItemDialog = make_unique<EditItemDialog>(ui->tableView, this); m_editItemDialog = make_unique<EditItemDialog>(ui->tableView, this);

View File

@ -60,13 +60,14 @@ class MainWindow : public QMainWindow {
void importCSV(); void importCSV();
void exportCSV(); void exportCSV();
/// 'Edit' slots
void findItems();
private: private:
Ui::MainWindow* ui; Ui::MainWindow* ui;
// GenericCore* m_core;
unique_ptr<GenericCore> m_core; unique_ptr<GenericCore> m_core;
shared_ptr<TableModel> m_tableModel; shared_ptr<GeneralSortFilterModel> m_proxyModel;
shared_ptr<GeneralSortFilterModel> m_sortModel;
QUndoStack* m_modelUndoStack; QUndoStack* m_modelUndoStack;
unique_ptr<QUndoView> m_modelUndoView; unique_ptr<QUndoView> m_modelUndoView;

View File

@ -10,6 +10,7 @@
#include <QPushButton> #include <QPushButton>
#include <QSpinBox> #include <QSpinBox>
#include <QTableView> #include <QTableView>
#include "model/metadata.h"
ItemDetailMapper::ItemDetailMapper(QWidget* parent) ItemDetailMapper::ItemDetailMapper(QWidget* parent)
: QWidget{parent} { : QWidget{parent} {
@ -101,12 +102,13 @@ bool ItemDetailMapper::submit() { return m_mapper->submit(); }
void ItemDetailMapper::revert() { m_mapper->revert(); } void ItemDetailMapper::revert() { m_mapper->revert(); }
void ItemDetailMapper::onCurrentIndexChanged(const QModelIndex& current, void ItemDetailMapper::onCurrentIndexChanged(const QModelIndex& current,
const QModelIndex& previous) { const QModelIndex& /*previous*/) {
if (!isEnabled()) { if (!isEnabled()) {
setEnabled(true); setEnabled(true);
} }
m_mapper->setCurrentModelIndex(current); m_mapper->setCurrentModelIndex(current);
updateButtons(current.row()); updateButtons(current.row());
emitContentChanged(current);
} }
void ItemDetailMapper::rowsInserted(const QModelIndex& parent, int start, int end) { void ItemDetailMapper::rowsInserted(const QModelIndex& parent, int start, int end) {
@ -147,3 +149,12 @@ void ItemDetailMapper::updateButtons(int row) {
m_previousButton->setEnabled(row > 0); m_previousButton->setEnabled(row > 0);
m_nextButton->setEnabled(row < m_model->rowCount() - 1); m_nextButton->setEnabled(row < m_model->rowCount() - 1);
} }
void ItemDetailMapper::emitContentChanged(const QModelIndex& currentIndex) {
// BUG QR-Code isn't updated after changes through the ItemDetailMapper #18
QString toStringText = "";
if (currentIndex.isValid()) {
toStringText = currentIndex.data(ToStringRole).toString();
}
emit contentChanged(toStringText);
}

View File

@ -24,6 +24,7 @@ class ItemDetailMapper : public QWidget {
void revert(); void revert();
signals: signals:
void contentChanged(const QString text);
private slots: private slots:
void onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous); void onCurrentIndexChanged(const QModelIndex& current, const QModelIndex& previous);
@ -32,6 +33,7 @@ class ItemDetailMapper : public QWidget {
void toPrevious(); void toPrevious();
void toNext(); void toNext();
void updateButtons(int row); void updateButtons(int row);
void emitContentChanged(const QModelIndex& currentIndex);
private: private:
/// *** members *** /// *** members ***