Compare commits
6 Commits
5eee7a4a75
...
a8bf5b4032
| Author | SHA1 | Date | |
|---|---|---|---|
| a8bf5b4032 | |||
| c83ba2da9d | |||
| 232b9ceb78 | |||
| e915846b8a | |||
| 8a0d37f8f9 | |||
| bd056a00ce |
@ -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.
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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>
|
||||||
@ -13,6 +14,7 @@
|
|||||||
#include "dialogs/edititemdialog.h"
|
#include "dialogs/edititemdialog.h"
|
||||||
#include "dialogs/newitemdialog.h"
|
#include "dialogs/newitemdialog.h"
|
||||||
#include "genericcore.h"
|
#include "genericcore.h"
|
||||||
|
#include "model/generalsortfiltermodel.h"
|
||||||
#include "model/tablemodel.h"
|
#include "model/tablemodel.h"
|
||||||
|
|
||||||
static QStandardPaths::StandardLocation standardLocation = QStandardPaths::HomeLocation;
|
static QStandardPaths::StandardLocation standardLocation = QStandardPaths::HomeLocation;
|
||||||
@ -44,8 +46,11 @@ 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_proxyModel = m_core->getSortFilterModel();
|
||||||
|
ui->tableView->setModel((QAbstractItemModel*)m_proxyModel.get());
|
||||||
|
ui->tableView->setSortingEnabled(true);
|
||||||
|
|
||||||
createActions();
|
createActions();
|
||||||
createHelpMenu();
|
createHelpMenu();
|
||||||
@ -190,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_tableModel->removeRows(currentIndex.row(), 1);
|
m_proxyModel->removeRows(currentIndex.row(), 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,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_tableModel->removeRows(topRow, nRows);
|
m_proxyModel->removeRows(topRow, nRows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,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();
|
||||||
@ -421,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());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,8 +462,8 @@ 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_tableModel.get(),
|
connect(m_newItemDialog.get(), &NewItemDialog::addItems, m_proxyModel.get(),
|
||||||
&TableModel::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);
|
||||||
m_editItemDialog->createContent();
|
m_editItemDialog->createContent();
|
||||||
|
|||||||
@ -16,6 +16,7 @@ QT_END_NAMESPACE
|
|||||||
|
|
||||||
class GenericCore;
|
class GenericCore;
|
||||||
class TableModel;
|
class TableModel;
|
||||||
|
class GeneralSortFilterModel;
|
||||||
class NewItemDialog;
|
class NewItemDialog;
|
||||||
class EditItemDialog;
|
class EditItemDialog;
|
||||||
|
|
||||||
@ -59,12 +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;
|
||||||
QUndoStack* m_modelUndoStack;
|
QUndoStack* m_modelUndoStack;
|
||||||
unique_ptr<QUndoView> m_modelUndoView;
|
unique_ptr<QUndoView> m_modelUndoView;
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@ -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 ***
|
||||||
|
|||||||
Reference in New Issue
Block a user