From 8af6e9297260337dd347cda354b23ac805ce3f58 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 22 Nov 2018 09:58:52 +0100 Subject: [PATCH 01/42] Added inja as submodule --- .gitmodules | 3 +++ CMakeLists.txt | 1 + inja | 1 + 3 files changed, 5 insertions(+) create mode 100644 .gitmodules create mode 160000 inja diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f75d422 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "inja"] + path = inja + url = git@github.com:pantor/inja.git diff --git a/CMakeLists.txt b/CMakeLists.txt index d819e35..792dcb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,4 +5,5 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() +add_subdirectory(inja) add_subdirectory(source) diff --git a/inja b/inja new file mode 160000 index 0000000..7dbdd44 --- /dev/null +++ b/inja @@ -0,0 +1 @@ +Subproject commit 7dbdd44b0eba24b6f6b742001814a98553c52833 From a2b85eba83e9af615db30f90051d9cb76df7dfe9 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 24 Nov 2018 19:55:16 +0100 Subject: [PATCH 02/42] Added Catch2 tests, moved Age-class to own library --- CMakeLists.txt | 1 + conanfile.txt | 1 + source/{ => Age}/Age.cpp | 0 source/{ => Age}/Age.h | 0 source/Age/CMakeLists.txt | 23 +++++++++++++++++++++++ source/CMakeLists.txt | 3 ++- source/MetaData/CMakeLists.txt | 1 + source/MetaData/MetaDataModel.h | 2 +- source/ResultWidget/CMakeLists.txt | 1 + source/ResultWidget/PRMap.h | 2 +- source/ResultWidget/ResultModel.h | 2 +- test/Age.cpp | 17 +++++++++++++++++ test/CMakeLists.txt | 21 +++++++++++++++++++++ test/dummy.cpp | 7 +++++++ test/main.cpp | 2 ++ 15 files changed, 79 insertions(+), 4 deletions(-) rename source/{ => Age}/Age.cpp (100%) rename source/{ => Age}/Age.h (100%) create mode 100644 source/Age/CMakeLists.txt create mode 100644 test/Age.cpp create mode 100644 test/CMakeLists.txt create mode 100644 test/dummy.cpp create mode 100644 test/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d819e35..4603e7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,3 +6,4 @@ include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() add_subdirectory(source) +add_subdirectory(test) diff --git a/conanfile.txt b/conanfile.txt index dd246ef..7591bc8 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,5 +1,6 @@ [requires] protobuf/3.6.1@bincrafters/stable +catch2/2.4.2@bincrafters/stable [generators] cmake diff --git a/source/Age.cpp b/source/Age/Age.cpp similarity index 100% rename from source/Age.cpp rename to source/Age/Age.cpp diff --git a/source/Age.h b/source/Age/Age.h similarity index 100% rename from source/Age.h rename to source/Age/Age.h diff --git a/source/Age/CMakeLists.txt b/source/Age/CMakeLists.txt new file mode 100644 index 0000000..820be2c --- /dev/null +++ b/source/Age/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.6) + +project(Age LANGUAGES CXX) + +find_package(Qt5Core REQUIRED) + +add_library(${PROJECT_NAME} + Age.cpp +) + +set_target_properties(${PROJECT_NAME} + PROPERTIES CXX_STANDARD 14 +) + +target_include_directories(${PROJECT_NAME} + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_link_libraries(${PROJECT_NAME} + PUBLIC + Qt5::Core +) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index ab95560..72bf70e 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -37,7 +37,6 @@ add_executable(${PROJECT_NAME} WIN32 LogoTest.cpp DataModel.cpp mainwindow.cpp - Age.cpp ${LOGO_TEST_UI} ${LOGO_TEST_QRC} ${DataModel_PROTO_SRCS} @@ -57,6 +56,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE + Age CheckableItem CheckableTest CheckableTestModel @@ -73,6 +73,7 @@ target_link_libraries(${PROJECT_NAME} ${Protobuf_LIBRARIES} ) +add_subdirectory(Age) add_subdirectory(CheckableItem) add_subdirectory(CheckableTest) add_subdirectory(CheckableTestModel) diff --git a/source/MetaData/CMakeLists.txt b/source/MetaData/CMakeLists.txt index b61703a..e00d8de 100644 --- a/source/MetaData/CMakeLists.txt +++ b/source/MetaData/CMakeLists.txt @@ -41,6 +41,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE + Age Qt5::Widgets ${Protobuf_LIBRARIES} ) diff --git a/source/MetaData/MetaDataModel.h b/source/MetaData/MetaDataModel.h index d2ebaa7..0c8bbeb 100644 --- a/source/MetaData/MetaDataModel.h +++ b/source/MetaData/MetaDataModel.h @@ -1,6 +1,6 @@ #pragma once -#include "../Age.h" +#include "Age.h" #include "MetaDataModel.pb.h" diff --git a/source/ResultWidget/CMakeLists.txt b/source/ResultWidget/CMakeLists.txt index b85d0c1..bfdd22c 100644 --- a/source/ResultWidget/CMakeLists.txt +++ b/source/ResultWidget/CMakeLists.txt @@ -30,5 +30,6 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE + Age Qt5::Widgets ) diff --git a/source/ResultWidget/PRMap.h b/source/ResultWidget/PRMap.h index 5ad5bcf..6d9104c 100644 --- a/source/ResultWidget/PRMap.h +++ b/source/ResultWidget/PRMap.h @@ -1,6 +1,6 @@ #pragma once -#include "../Age.h" +#include "Age.h" #include class PRMap diff --git a/source/ResultWidget/ResultModel.h b/source/ResultWidget/ResultModel.h index 1c290f4..ae6dd78 100644 --- a/source/ResultWidget/ResultModel.h +++ b/source/ResultWidget/ResultModel.h @@ -1,6 +1,6 @@ #pragma once -#include "../Age.h" +#include "Age.h" #include class TestResult diff --git a/test/Age.cpp b/test/Age.cpp new file mode 100644 index 0000000..46948b8 --- /dev/null +++ b/test/Age.cpp @@ -0,0 +1,17 @@ +#include + +#include "Age.h" + +TEST_CASE("default initialization") +{ + Age age; + REQUIRE(age.years() == 0); + REQUIRE(age.months() == 0); + REQUIRE(age.toString() == "0;0"); + + Age age2; + REQUIRE(!(age < age)); + REQUIRE(!(age < age2)); +} + + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..5984746 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.5) +project(run-tests) + +find_package(Catch2 REQUIRED) + +add_executable(${PROJECT_NAME} + main.cpp + dummy.cpp + Age.cpp +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE + Catch2::Catch2 + Age +) + +include(CTest) +include(Catch) +catch_discover_tests(${PROJECT_NAME}) + diff --git a/test/dummy.cpp b/test/dummy.cpp new file mode 100644 index 0000000..0eb8941 --- /dev/null +++ b/test/dummy.cpp @@ -0,0 +1,7 @@ +#include + +TEST_CASE("Dummy") +{ + REQUIRE(true == true); +} + diff --git a/test/main.cpp b/test/main.cpp new file mode 100644 index 0000000..4ed06df --- /dev/null +++ b/test/main.cpp @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include From 09f8fa4faf6b2b818ded3a8b9da3a7dccaee400e Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 24 Nov 2018 20:08:01 +0100 Subject: [PATCH 03/42] Added some more tests --- test/Age.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/Age.cpp b/test/Age.cpp index 46948b8..34b3788 100644 --- a/test/Age.cpp +++ b/test/Age.cpp @@ -14,4 +14,16 @@ TEST_CASE("default initialization") REQUIRE(!(age < age2)); } +TEST_CASE("year/month initialization") +{ + for (unsigned int year = 0; year <= 100; ++year) + { + for (unsigned int month = 1; month <= 12; ++month) + { + Age age(year, month); + REQUIRE(age.years() == year); + REQUIRE(age.months() == month); + } + } +} From 220f92453d9d9cb959b6ec2c13fd340b3c74cb8b Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 25 Nov 2018 14:30:45 +0100 Subject: [PATCH 04/42] Added more Age-class tests --- source/Age/Age.cpp | 10 +++++----- test/Age.cpp | 13 ++++++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/source/Age/Age.cpp b/source/Age/Age.cpp index 81415e9..05613a4 100644 --- a/source/Age/Age.cpp +++ b/source/Age/Age.cpp @@ -4,8 +4,8 @@ #include Age::Age(unsigned int years, unsigned int months) - : m_years(years) - , m_months(months) + : m_years(years) + , m_months(months) { } @@ -37,7 +37,7 @@ Age::Age(const QDate &birth, const QDate &reference) m_years = years; m_months = months; } - + bool Age::operator<(const Age &cmp) const { if (m_years == cmp.m_years) @@ -47,7 +47,7 @@ bool Age::operator<(const Age &cmp) const return m_years < cmp.m_years; } - + unsigned int Age::years() const { return m_years; @@ -57,7 +57,7 @@ unsigned int Age::months() const { return m_months; } - + std::string Age::toString() const { std::ostringstream result; diff --git a/test/Age.cpp b/test/Age.cpp index 34b3788..22b0fbb 100644 --- a/test/Age.cpp +++ b/test/Age.cpp @@ -18,7 +18,7 @@ TEST_CASE("year/month initialization") { for (unsigned int year = 0; year <= 100; ++year) { - for (unsigned int month = 1; month <= 12; ++month) + for (unsigned int month = 0; month < 12; ++month) { Age age(year, month); @@ -27,3 +27,14 @@ TEST_CASE("year/month initialization") } } } + +TEST_CASE("age by reference") +{ + QDate birth(1970, 1, 1); + QDate reference(1980, 1, 1); + + Age age(birth, reference); + + REQUIRE(age.years() == 10); + REQUIRE(age.months() == 0); +} From 4fefdc65c5f7df1168c71255f3019aeebef1b7e2 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 2 Dec 2018 15:22:44 +0100 Subject: [PATCH 05/42] Open first command line argument as file --- source/LogoTest.cpp | 14 ++++++++-- source/mainwindow.cpp | 63 +++++++++++++++++++++++++++---------------- source/mainwindow.h | 13 ++++++--- 3 files changed, 61 insertions(+), 29 deletions(-) diff --git a/source/LogoTest.cpp b/source/LogoTest.cpp index 30539a1..1f15804 100644 --- a/source/LogoTest.cpp +++ b/source/LogoTest.cpp @@ -4,8 +4,18 @@ int main(int argc, char **argv) { QApplication app(argc, argv); - MainWindow mainWindow; - mainWindow.show(); + + std::unique_ptr mainWindow; + if (argc < 2) + { + mainWindow = std::make_unique(nullptr); + } + else + { + mainWindow = std::make_unique(nullptr, argv[1]); + } + + mainWindow->show(); return app.exec(); } diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 20d877a..cf307db 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -1,8 +1,6 @@ #include "mainwindow.h" #include "ui_mainwindow.h" -#include "DataModel.h" - #include #include #include @@ -21,16 +19,45 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) + , m_dataModel(this) { ui->setupUi(this); + setupUi(); + + newFile(); +} + +MainWindow::MainWindow(QWidget *parent, const QString &filename) + : QMainWindow(parent) + , ui(new Ui::MainWindow) + , m_dataModel(this) +{ + ui->setupUi(this); + setupUi(); + + openFile(filename); +} + +void MainWindow::setupUi() +{ + ui->metaDataWidget->setModel(&m_dataModel.m_metaData); + ui->verbEndWidget->setModel(&m_dataModel.m_verbEnd); + ui->genusWidget->setModel(&m_dataModel.m_genus); + ui->pluralWidget->setModel(&m_dataModel.m_plural); + ui->akkusativDativWidget->setAkkusativModel(&m_dataModel.m_akkusativ); + ui->akkusativDativWidget->setDativModel(&m_dataModel.m_dativ); + ui->v2SvkWidget->setV2SvkModel(&m_dataModel.m_v2Svk); + ui->lateSkillsWidget->setPassivModel(&m_dataModel.m_passiv); + ui->lateSkillsWidget->setGenitivModel(&m_dataModel.m_genitiv); + ui->resultWidget->setModel(&m_dataModel.m_results); connect(ui->actionNew, &QAction::triggered, this, &MainWindow::newFile); - connect(ui->actionOpen, &QAction::triggered, this, &MainWindow::openFile); + connect(ui->actionOpen, &QAction::triggered, this, qOverload<>(&MainWindow::openFile)); connect(ui->actionSave, &QAction::triggered, this, qOverload<>(&MainWindow::saveFile)); connect(ui->actionSave_as, &QAction::triggered, this, &MainWindow::saveFileAs); connect(ui->actionPrint, &QAction::triggered, this, &MainWindow::print); - newFile(); + connect(&m_dataModel, &DataModel::modelChanged, this, &MainWindow::dataModelChanged); } MainWindow::~MainWindow() @@ -42,21 +69,6 @@ void MainWindow::newFile() { closeFile(); - m_dataModel = std::make_unique(this); - ui->metaDataWidget->setModel(&m_dataModel->m_metaData); - ui->verbEndWidget->setModel(&m_dataModel->m_verbEnd); - ui->genusWidget->setModel(&m_dataModel->m_genus); - ui->pluralWidget->setModel(&m_dataModel->m_plural); - ui->akkusativDativWidget->setAkkusativModel(&m_dataModel->m_akkusativ); - ui->akkusativDativWidget->setDativModel(&m_dataModel->m_dativ); - ui->v2SvkWidget->setV2SvkModel(&m_dataModel->m_v2Svk); - ui->lateSkillsWidget->setPassivModel(&m_dataModel->m_passiv); - ui->lateSkillsWidget->setGenitivModel(&m_dataModel->m_genitiv); - - ui->resultWidget->setModel(&m_dataModel->m_results); - - connect(&*m_dataModel, &DataModel::modelChanged, this, &MainWindow::dataModelChanged); - setWindowModified(false); setWindowTitle("untitled[*]"); m_filename = ""; @@ -72,10 +84,15 @@ void MainWindow::openFile() return; } + openFile(filename); +} + +void MainWindow::openFile(const QString &filename) +{ closeFile(); std::fstream protoInFile(filename.toStdString(), std::ios::in | std::ios::binary); - m_dataModel->read(protoInFile); + m_dataModel.read(protoInFile); setWindowModified(false); setWindowTitle(filename + "[*]"); @@ -133,7 +150,7 @@ void MainWindow::closeFile() void MainWindow::print() const { //std::ofstream htmlfile("print.html"); - //htmlfile << m_dataModel->toHtml(); + //htmlfile << m_dataModel.toHtml(); QPrinter printer; @@ -144,7 +161,7 @@ void MainWindow::print() const } QTextDocument printDoc; - printDoc.setHtml(QString::fromStdString(m_dataModel->toHtml())); + printDoc.setHtml(QString::fromStdString(m_dataModel.toHtml())); printDoc.print(&printer); } @@ -164,7 +181,7 @@ void MainWindow::saveFile(const QString &filename) { std::fstream protoOutFile(filename.toStdString(), std::ios::out | std::ios::trunc | std::ios::binary); - m_dataModel->write(protoOutFile); + m_dataModel.write(protoOutFile); qDebug() << "Wrote" << filename; diff --git a/source/mainwindow.h b/source/mainwindow.h index 78fa2bb..c2cf130 100644 --- a/source/mainwindow.h +++ b/source/mainwindow.h @@ -1,8 +1,10 @@ #pragma once -#include +#include "DataModel.h" + +#include +#include -#include class DataModel; class QDataWidgetMapper; @@ -17,17 +19,19 @@ class MainWindow : public QMainWindow private: Ui::MainWindow *ui; - std::unique_ptr m_dataModel; + DataModel m_dataModel; QString m_filename; bool m_saveOnClose = false; public: - MainWindow(QWidget *parent = nullptr); + MainWindow(QWidget *parent); + MainWindow(QWidget *parent, const QString &filename); ~MainWindow(); public slots: void newFile(); void openFile(); + void openFile(const QString &filename); void saveFile(); void saveFileAs(); void closeFile(); @@ -38,5 +42,6 @@ protected: void closeEvent(QCloseEvent *event) override; private: + void setupUi(); void saveFile(const QString &filename); }; From f38b9194fdf572cb9b290a87fcdbf64c47bc33b1 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 8 Dec 2018 16:39:33 +0100 Subject: [PATCH 06/42] Renamed LogoTest.cpp to ESGRAF48.cpp --- source/CMakeLists.txt | 2 +- source/{LogoTest.cpp => ESGRAF48.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename source/{LogoTest.cpp => ESGRAF48.cpp} (100%) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 72bf70e..0a0f40f 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -34,7 +34,7 @@ protobuf_generate_cpp(DataModel_PROTO_SRCS DataModel_PROTO_HDRS ${DataModel_PROTO_FILES}) add_executable(${PROJECT_NAME} WIN32 - LogoTest.cpp + ESGRAF48.cpp DataModel.cpp mainwindow.cpp ${LOGO_TEST_UI} diff --git a/source/LogoTest.cpp b/source/ESGRAF48.cpp similarity index 100% rename from source/LogoTest.cpp rename to source/ESGRAF48.cpp From bdf9706e58a82c301f0013567f6cee359169e492 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 9 Dec 2018 11:11:55 +0100 Subject: [PATCH 07/42] Added pdf export --- source/mainwindow.cpp | 30 ++++++++++++++++++++++++++++++ source/mainwindow.h | 2 ++ source/mainwindow.ui | 9 +++++++++ 3 files changed, 41 insertions(+) diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index cf307db..e91549a 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -56,6 +56,7 @@ void MainWindow::setupUi() connect(ui->actionSave, &QAction::triggered, this, qOverload<>(&MainWindow::saveFile)); connect(ui->actionSave_as, &QAction::triggered, this, &MainWindow::saveFileAs); connect(ui->actionPrint, &QAction::triggered, this, &MainWindow::print); + connect(ui->actionExport_PDF, &QAction::triggered, this, qOverload<>(&MainWindow::savePdf)); connect(&m_dataModel, &DataModel::modelChanged, this, &MainWindow::dataModelChanged); } @@ -172,6 +173,22 @@ void MainWindow::dataModelChanged() setWindowModified(true); } +void MainWindow::savePdf() +{ + QFileDialog saveFilenameDialog(this); + saveFilenameDialog.setDefaultSuffix("pdf"); + saveFilenameDialog.setFileMode(QFileDialog::AnyFile); + saveFilenameDialog.setNameFilter("PDF File (*.pdf)"); + saveFilenameDialog.setWindowTitle("Save file"); + + if (!saveFilenameDialog.exec()) + { + return; + } + + savePdf(saveFilenameDialog.selectedFiles().first()); +} + void MainWindow::closeEvent(QCloseEvent *event) { closeFile(); @@ -190,3 +207,16 @@ void MainWindow::saveFile(const QString &filename) m_filename = filename; m_saveOnClose = false; } + +void MainWindow::savePdf(const QString &filename) +{ + QPrinter printer; + printer.setOutputFormat(QPrinter::PdfFormat); + printer.setPaperSize(QPrinter::A4); + printer.setOutputFileName(filename); + + QTextDocument printDoc; + printDoc.setHtml(QString::fromStdString(m_dataModel.toHtml())); + + printDoc.print(&printer); +} diff --git a/source/mainwindow.h b/source/mainwindow.h index c2cf130..9675fb7 100644 --- a/source/mainwindow.h +++ b/source/mainwindow.h @@ -37,6 +37,7 @@ public slots: void closeFile(); void print() const; void dataModelChanged(); + void savePdf(); protected: void closeEvent(QCloseEvent *event) override; @@ -44,4 +45,5 @@ protected: private: void setupUi(); void saveFile(const QString &filename); + void savePdf(const QString &filename); }; diff --git a/source/mainwindow.ui b/source/mainwindow.ui index 86d0199..9622ce3 100644 --- a/source/mainwindow.ui +++ b/source/mainwindow.ui @@ -133,6 +133,7 @@ + @@ -228,6 +229,14 @@ Ctrl+P + + + Export PDF + + + Export as PDF file + + From 59c409c872772203b2d3dce8501d23336bed87ae Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 12 Jan 2019 16:50:04 +0100 Subject: [PATCH 08/42] Print headline and meta-data --- source/CMakeLists.txt | 1 + source/DataModel.cpp | 26 +++---------- source/DataModel.h | 31 +++------------- source/MetaData/MetaDataModel.cpp | 62 +++++++++++++++---------------- source/MetaData/MetaDataModel.h | 7 ++-- source/PrintableModel.cpp | 12 ++++++ source/PrintableModel.h | 13 +++++++ source/mainwindow.cpp | 23 +++++++----- source/mainwindow.h | 1 + 9 files changed, 87 insertions(+), 89 deletions(-) create mode 100644 source/PrintableModel.cpp create mode 100644 source/PrintableModel.h diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 0a0f40f..895a7a4 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -35,6 +35,7 @@ protobuf_generate_cpp(DataModel_PROTO_SRCS DataModel_PROTO_HDRS add_executable(${PROJECT_NAME} WIN32 ESGRAF48.cpp + PrintableModel.cpp DataModel.cpp mainwindow.cpp ${LOGO_TEST_UI} diff --git a/source/DataModel.cpp b/source/DataModel.cpp index 216eb8c..d108729 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -59,28 +59,14 @@ void DataModel::read(std::istream &inStream) m_genitiv.read(dataModel.lateskillsgenitiv()); m_passiv.read(dataModel.lateskillspassiv()); } - -std::string DataModel::toHtml() const + +void DataModel::printTo(QPainter &painter) const { - std::stringstream out; + painter.setFont(h1Font()); + painter.drawText(0, painter.fontMetrics().lineSpacing(), "ESGRAF 4-8 Auswertungsbogen"); + painter.translate(0, 3 * painter.fontMetrics().lineSpacing()); - out << "" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "

ESGRAF 4-8 Auswertungsbogen

" << std::endl; - out << "

" << std::endl; - out << m_metaData.toHtml(); - out << "

" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - - return out.str(); + m_metaData.printTo(painter); } void DataModel::pluralModelChanged() diff --git a/source/DataModel.h b/source/DataModel.h index 71a9352..3469e3e 100644 --- a/source/DataModel.h +++ b/source/DataModel.h @@ -1,5 +1,7 @@ #pragma once +#include "PrintableModel.h" + #include "MetaData/MetaDataModel.h" #include "GenusModel.h" #include "VerbEndModel.h" @@ -12,9 +14,9 @@ #include "ResultModel.h" -#include +#include -class DataModel : public QObject +class DataModel : public QObject, public PrintableModel { Q_OBJECT @@ -34,35 +36,14 @@ public: public: DataModel(QObject *parent); - std::string toHtml() const; - void write(std::ostream &outStream) const; void read(std::istream &inStream); + void printTo(QPainter &painter) const override; + signals: void modelChanged(); -private: - template - void write( - const ModelType &model, QJsonObject &target, const char *name) const - { - QJsonObject jsonObject; - model.write(jsonObject); - target[name] = jsonObject; - } - - template - void read( - ModelType &model, const QJsonObject &source, const char *name) const - { - const auto &jsonObject = source[name]; - if (jsonObject.isObject()) - { - model.read(jsonObject.toObject()); - } - } - private slots: void pluralModelChanged(); void metaDataChanged(); diff --git a/source/MetaData/MetaDataModel.cpp b/source/MetaData/MetaDataModel.cpp index 94c2a62..32ab815 100644 --- a/source/MetaData/MetaDataModel.cpp +++ b/source/MetaData/MetaDataModel.cpp @@ -130,39 +130,37 @@ void MetaDataModel::write(ESGRAF48::MetaDataModel &model) const model.set_remarks(m_remarks.toStdString()); } -std::string MetaDataModel::toHtml() const +void MetaDataModel::printTo(QPainter &painter) const { - std::ostringstream out; + painter.setFont(tableFont()); - out << "" - << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" - << std::endl; - out << "" << std::endl; - out << "" - << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" - << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" - << std::endl; - out << "" - << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "" << std::endl; - out << "
Name, Vorname" << m_participant.toHtmlEscaped().toStdString() << "Untersucher(in)" << m_instructor.toHtmlEscaped().toStdString() << "
Geburtsdatum" << m_dateOfBirth.toString("dd.MM.yyyy").toHtmlEscaped().toStdString() << "Bemerkungen
Untersuchungsdatum" << m_dateOfTest.toString("dd.MM.yyyy").toHtmlEscaped().toStdString() << "" - << m_remarks.trimmed().toHtmlEscaped().replace("\n", "
").toStdString() << "
Alter am Testtag" << getAge().toString() << "
" << std::endl; + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); - return out.str(); + auto hasRemarks = !m_remarks.trimmed().isEmpty(); + + painter.drawText(0, 0, "Name, Vorname"); + painter.drawText(0.25 * width, 0, m_participant); + painter.drawText(0.5 * width, 0, "Untersucher(in)"); + painter.drawText(0.75 * width, 0, m_instructor); + + painter.translate(0, height); + + painter.drawText(0, 0, "Geburtsdatum"); + painter.drawText(0.25 * width, 0, m_dateOfBirth.toString("dd.MM.yyyy")); + if (hasRemarks) + { + painter.drawText(0.5 * width, 0, "Bemerkungen:"); + painter.drawText(QRect(0.5 * width, 0.5 * height, width, 2 * height), m_remarks); + } + + painter.translate(0, height); + + painter.drawText(0, 0, "Untersuchungsdatum"); + painter.drawText(0.25 * width, 0, m_dateOfTest.toString("dd.MM.yyyy")); + + painter.translate(0, height); + + painter.drawText(0, 0, "Alter am Testtag"); + painter.drawText(0.25 * width, 0, getAge().toString().c_str()); } diff --git a/source/MetaData/MetaDataModel.h b/source/MetaData/MetaDataModel.h index 0c8bbeb..3164b90 100644 --- a/source/MetaData/MetaDataModel.h +++ b/source/MetaData/MetaDataModel.h @@ -1,5 +1,7 @@ #pragma once +#include "../PrintableModel.h" + #include "Age.h" #include "MetaDataModel.pb.h" @@ -7,9 +9,8 @@ #include #include #include -#include -class MetaDataModel : public QAbstractTableModel +class MetaDataModel : public QAbstractTableModel, public PrintableModel { Q_OBJECT @@ -33,7 +34,7 @@ public: void read(const ESGRAF48::MetaDataModel &model); void write(ESGRAF48::MetaDataModel &model) const; - std::string toHtml() const; + void printTo(QPainter &painter) const override; Age getAge() const { diff --git a/source/PrintableModel.cpp b/source/PrintableModel.cpp new file mode 100644 index 0000000..ba9c0a1 --- /dev/null +++ b/source/PrintableModel.cpp @@ -0,0 +1,12 @@ +#include "PrintableModel.h" + +QFont PrintableModel::h1Font() +{ + return QFont("Helvetica", 16); +} + +QFont PrintableModel::tableFont() +{ + return QFont("Helvetica", 10); +} + diff --git a/source/PrintableModel.h b/source/PrintableModel.h new file mode 100644 index 0000000..46d2c65 --- /dev/null +++ b/source/PrintableModel.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +class PrintableModel +{ +public: + virtual void printTo(QPainter &painter) const = 0; + +protected: + static QFont h1Font(); + static QFont tableFont(); +}; diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index e91549a..0a5c8de 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -150,10 +151,9 @@ void MainWindow::closeFile() void MainWindow::print() const { - //std::ofstream htmlfile("print.html"); - //htmlfile << m_dataModel.toHtml(); - QPrinter printer; + printer.setPaperSize(QPrinter::A4); + printer.setPageMargins(30, 20, 30, 20, QPrinter::Millimeter); QPrintDialog dialog(&printer); if (dialog.exec() != QDialog::Accepted) @@ -161,10 +161,12 @@ void MainWindow::print() const return; } - QTextDocument printDoc; - printDoc.setHtml(QString::fromStdString(m_dataModel.toHtml())); + QPainter painter; + painter.begin(&printer); - printDoc.print(&printer); + m_dataModel.printTo(painter); + + painter.end(); } void MainWindow::dataModelChanged() @@ -213,10 +215,13 @@ void MainWindow::savePdf(const QString &filename) QPrinter printer; printer.setOutputFormat(QPrinter::PdfFormat); printer.setPaperSize(QPrinter::A4); + printer.setPageMargins(30, 20, 30, 20, QPrinter::Millimeter); printer.setOutputFileName(filename); - QTextDocument printDoc; - printDoc.setHtml(QString::fromStdString(m_dataModel.toHtml())); + QPainter painter; + painter.begin(&printer); - printDoc.print(&printer); + m_dataModel.printTo(painter); + + painter.end(); } diff --git a/source/mainwindow.h b/source/mainwindow.h index 9675fb7..006262f 100644 --- a/source/mainwindow.h +++ b/source/mainwindow.h @@ -4,6 +4,7 @@ #include #include +#include class DataModel; From 463dc275d05b6f78e9b9d819ab735a2fdd30c0a1 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 12 Jan 2019 21:42:52 +0100 Subject: [PATCH 09/42] Some prototypical table output --- source/DataModel.cpp | 1 + source/MetaData/MetaDataModel.cpp | 2 + source/PrintableModel.cpp | 9 +++ source/PrintableModel.h | 3 + source/SubTests/V2Svk/V2SvkModel.cpp | 101 +++++++++++++++++++++++++++ source/SubTests/V2Svk/V2SvkModel.h | 6 +- 6 files changed, 121 insertions(+), 1 deletion(-) diff --git a/source/DataModel.cpp b/source/DataModel.cpp index d108729..9376392 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -67,6 +67,7 @@ void DataModel::printTo(QPainter &painter) const painter.translate(0, 3 * painter.fontMetrics().lineSpacing()); m_metaData.printTo(painter); + m_v2Svk.printTo(painter); } void DataModel::pluralModelChanged() diff --git a/source/MetaData/MetaDataModel.cpp b/source/MetaData/MetaDataModel.cpp index 32ab815..5eecf6a 100644 --- a/source/MetaData/MetaDataModel.cpp +++ b/source/MetaData/MetaDataModel.cpp @@ -163,4 +163,6 @@ void MetaDataModel::printTo(QPainter &painter) const painter.drawText(0, 0, "Alter am Testtag"); painter.drawText(0.25 * width, 0, getAge().toString().c_str()); + + painter.translate(0, 2 * height); } diff --git a/source/PrintableModel.cpp b/source/PrintableModel.cpp index ba9c0a1..7da134b 100644 --- a/source/PrintableModel.cpp +++ b/source/PrintableModel.cpp @@ -5,8 +5,17 @@ QFont PrintableModel::h1Font() return QFont("Helvetica", 16); } +QFont PrintableModel::h2Font() +{ + return QFont("Helvetica", 12); +} + QFont PrintableModel::tableFont() { return QFont("Helvetica", 10); } +QPen PrintableModel::tablePen() +{ + return QPen(Qt::black, 1, Qt::SolidLine); +} diff --git a/source/PrintableModel.h b/source/PrintableModel.h index 46d2c65..5d99c31 100644 --- a/source/PrintableModel.h +++ b/source/PrintableModel.h @@ -9,5 +9,8 @@ public: protected: static QFont h1Font(); + static QFont h2Font(); static QFont tableFont(); + + static QPen tablePen(); }; diff --git a/source/SubTests/V2Svk/V2SvkModel.cpp b/source/SubTests/V2Svk/V2SvkModel.cpp index 2196ba4..17e4284 100644 --- a/source/SubTests/V2Svk/V2SvkModel.cpp +++ b/source/SubTests/V2Svk/V2SvkModel.cpp @@ -199,3 +199,104 @@ void V2SvkModel::read(const ESGRAF48::V2SvkModel &model) emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); } + +void V2SvkModel::printTo(QPainter &painter) const +{ + painter.setFont(h2Font()); + + painter.drawText( + 0, 0, "Subtest 1: Verbzweitstellungsregel (V2) und Subjekt-Verb-Kontrollregel (SVK)"); + + painter.translate(0, 1.5 * painter.fontMetrics().lineSpacing()); + + painter.setFont(tableFont()); + painter.setPen(tablePen()); + + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); + + auto drawTextSquare = [&](double left, double top, double width, double height, + const QString &text) { + painter.drawText(left, top, width, height, Qt::AlignCenter, text); + painter.drawLine(left, top, left + width, top); + painter.drawLine(left + width, top, left + width, top + height); + painter.drawLine(left + width, top + height, left, top + height); + painter.drawLine(left, top + height, left, top); + }; + + auto drawCheckSquare = [&](double left, double top, double width, double height, bool checked) { + drawTextSquare(left, top, width, height, checked ? "\u2612" : "\u2610"); + }; + + auto drawResultSquare = [&](bool right, bool bold, unsigned int value, double y) { + double cellWidth = 0.03 * width; + double x = width - cellWidth - (right ? 0 : 0.04 * width); + + drawTextSquare(x, y, cellWidth, height, QString::number(value)); + }; + + auto drawGreySquare = [&](double left, double top, double width, double height) { + auto prevBrush = painter.brush(); + + painter.setBrush(QBrush(QColor(224, 224, 224))); + painter.drawRect(left, top, width, height); + + painter.setBrush(prevBrush); + }; + + auto x = 0.0; + auto y = 0.0; + auto cellWidth = 0.2 * width; + drawTextSquare(x, y, cellWidth, 2 * height, "W-Fragen"); + x += cellWidth; + drawTextSquare(x, y, cellWidth, height, "Affe"); + x += cellWidth; + drawTextSquare(x, y, cellWidth, height, "Schwein"); + x += cellWidth; + drawTextSquare(x, y, cellWidth, height, "Gans"); + + x = 0.2 * width; + y += height; + cellWidth = 0.05 * width; + for (int i = 0; i < 12; ++i) + { + drawCheckSquare(x, y, cellWidth, height, true); + x += cellWidth; + } + drawResultSquare(false, false, 9, y); + + x = 0; + y += height; + cellWidth = 0.2 * width; + drawTextSquare(x, y, cellWidth, height, "Verbtrennung"); + x += cellWidth; + cellWidth = 0.05 * width; + drawGreySquare(x, y, cellWidth, height); + x += cellWidth; + drawCheckSquare(x, y, cellWidth, height, true); + x += cellWidth; + drawGreySquare(x, y, 5 * cellWidth, height); + x += 5 * cellWidth; + drawCheckSquare(x, y, cellWidth, height, true); + x += cellWidth; + drawGreySquare(x, y, 2 * cellWidth, height); + x += 2 * cellWidth; + drawCheckSquare(x, y, cellWidth, height, true); + x += cellWidth; + drawGreySquare(x, y, cellWidth, height); + x += cellWidth; + drawResultSquare(false, false, 2, y); + + x = 0; + y += height; + cellWidth = 0.2 * width; + drawTextSquare(x, y, cellWidth, height, "SVK: /-st/"); + x += cellWidth; + cellWidth = 0.05 * width; + for (int i = 0; i < 12; ++i) + { + drawCheckSquare(x, y, cellWidth, height, true); + x += cellWidth; + } + drawResultSquare(true, false, 8, y); +} diff --git a/source/SubTests/V2Svk/V2SvkModel.h b/source/SubTests/V2Svk/V2SvkModel.h index 519508a..becad53 100644 --- a/source/SubTests/V2Svk/V2SvkModel.h +++ b/source/SubTests/V2Svk/V2SvkModel.h @@ -1,9 +1,11 @@ #pragma once +#include "../../PrintableModel.h" + #include "CheckableTestModel.h" #include "V2SvkModel.pb.h" -class V2SvkModel : public CheckableTestModel +class V2SvkModel : public CheckableTestModel, public PrintableModel { Q_OBJECT @@ -16,6 +18,8 @@ public: void write(ESGRAF48::V2SvkModel &model) const; void read(const ESGRAF48::V2SvkModel &model); + void printTo(QPainter &painter) const override; + protected: bool isValidIndex(const QModelIndex &index) const override; }; From 61bcb7566c22f006f1f151c41ec9dfc0fb4e37c0 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 13 Jan 2019 18:44:07 +0100 Subject: [PATCH 10/42] Print subtest 1 --- source/CheckableItem/CheckableItem.cpp | 21 --- source/CheckableItem/CheckableItem.h | 3 - source/CheckableItem/CheckableItems.cpp | 28 +-- source/CheckableItem/CheckableItems.h | 3 +- source/CheckableTest/CheckableTest.cpp | 7 + source/CheckableTest/CheckableTest.h | 2 + .../CheckableTestModel/CheckableTestModel.cpp | 24 --- .../CheckableTestModel/CheckableTestModel.h | 3 - source/PrintableModel.cpp | 2 +- source/SubTests/V2Svk/V2SvkModel.cpp | 161 ++++++++++++------ source/SubTests/V2Svk/V2SvkModel.h | 4 +- source/mainwindow.cpp | 4 +- 12 files changed, 127 insertions(+), 135 deletions(-) diff --git a/source/CheckableItem/CheckableItem.cpp b/source/CheckableItem/CheckableItem.cpp index 6d6a16a..faed665 100644 --- a/source/CheckableItem/CheckableItem.cpp +++ b/source/CheckableItem/CheckableItem.cpp @@ -34,24 +34,3 @@ unsigned int CheckableItem::points() const { return m_checked ? m_value : 0; } - -void CheckableItem::write(QJsonObject &json) const -{ - json["text"] = m_text.c_str(); - json["checked"] = m_checked; -} - -void CheckableItem::read(const QJsonObject &json) -{ - const auto &text = json["text"]; - if (text.isString()) - { - m_text = text.toString().toStdString(); - } - - const auto &checked = json["checked"]; - if (checked.isBool()) - { - m_checked = checked.toBool(); - } -} diff --git a/source/CheckableItem/CheckableItem.h b/source/CheckableItem/CheckableItem.h index a37086e..89feffe 100644 --- a/source/CheckableItem/CheckableItem.h +++ b/source/CheckableItem/CheckableItem.h @@ -24,7 +24,4 @@ public: void setValue(unsigned int value); unsigned int points() const; - - void write(QJsonObject &json) const; - void read(const QJsonObject &json); }; diff --git a/source/CheckableItem/CheckableItems.cpp b/source/CheckableItem/CheckableItems.cpp index 30532f3..f9b59f3 100644 --- a/source/CheckableItem/CheckableItems.cpp +++ b/source/CheckableItem/CheckableItems.cpp @@ -2,6 +2,8 @@ #include +#include + CheckableItems::CheckableItems(std::initializer_list itemNames) { for (const auto &itemName : itemNames) @@ -10,27 +12,9 @@ CheckableItems::CheckableItems(std::initializer_list itemNames) } } -void CheckableItems::write(QJsonArray &json) const +unsigned int CheckableItems::getPoints() const { - for (const auto &item : *this) - { - QJsonObject itemObject; - item.write(itemObject); - json.append(itemObject); - } -} - -void CheckableItems::read(const QJsonArray &json) -{ - clear(); - - for (const auto &itemObject : json) - { - if (itemObject.isObject()) - { - CheckableItem item; - item.read(itemObject.toObject()); - emplace_back(item); - } - } + return std::accumulate(begin(), end(), 0, [](int base, const CheckableItem &item) { + return base + item.points(); + }); } diff --git a/source/CheckableItem/CheckableItems.h b/source/CheckableItem/CheckableItems.h index 164f829..b147e27 100644 --- a/source/CheckableItem/CheckableItems.h +++ b/source/CheckableItem/CheckableItems.h @@ -10,6 +10,5 @@ class CheckableItems : public std::vector public: CheckableItems(std::initializer_list itemNames); - void write(QJsonArray &json) const; - void read(const QJsonArray &json); + unsigned int getPoints() const; }; diff --git a/source/CheckableTest/CheckableTest.cpp b/source/CheckableTest/CheckableTest.cpp index 0d0cbf5..fabf0c3 100644 --- a/source/CheckableTest/CheckableTest.cpp +++ b/source/CheckableTest/CheckableTest.cpp @@ -1,5 +1,7 @@ #include "CheckableTest.h" +#include + CheckableTest::CheckableTest( const char *name, std::initializer_list items) : m_name(name) @@ -26,3 +28,8 @@ CheckableItems &CheckableTest::items() { return m_items; } + +unsigned int CheckableTest::getPoints() const +{ + return m_items.getPoints(); +} diff --git a/source/CheckableTest/CheckableTest.h b/source/CheckableTest/CheckableTest.h index 32f6da0..f4a0c20 100644 --- a/source/CheckableTest/CheckableTest.h +++ b/source/CheckableTest/CheckableTest.h @@ -17,6 +17,8 @@ public: const QString &name() const; const CheckableItems &items() const; CheckableItems &items(); + + unsigned int getPoints() const; }; using CheckableTests = std::vector; diff --git a/source/CheckableTestModel/CheckableTestModel.cpp b/source/CheckableTestModel/CheckableTestModel.cpp index 493bd76..7b66014 100644 --- a/source/CheckableTestModel/CheckableTestModel.cpp +++ b/source/CheckableTestModel/CheckableTestModel.cpp @@ -107,30 +107,6 @@ QVariant CheckableTestModel::headerData( return QAbstractTableModel::headerData(section, orientation, role); } -void CheckableTestModel::write(QJsonObject &json) const -{ - for (const auto &test : m_tests) - { - QJsonArray testData; - test.items().write(testData); - json[test.name()] = testData; - } -} - -void CheckableTestModel::read(const QJsonObject &json) -{ - for (auto &test : m_tests) - { - auto testData = json[test.name()]; - if (testData.isArray()) - { - test.items().read(testData.toArray()); - } - } - - emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); -} - bool CheckableTestModel::isValidIndex(const QModelIndex &index) const { if (index.row() < m_tests.size()) diff --git a/source/CheckableTestModel/CheckableTestModel.h b/source/CheckableTestModel/CheckableTestModel.h index 7b4ed9d..2fd5434 100644 --- a/source/CheckableTestModel/CheckableTestModel.h +++ b/source/CheckableTestModel/CheckableTestModel.h @@ -25,9 +25,6 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - void write(QJsonObject &json) const; - void read(const QJsonObject &json); - unsigned int getPoints() const; protected: diff --git a/source/PrintableModel.cpp b/source/PrintableModel.cpp index 7da134b..2f5a16c 100644 --- a/source/PrintableModel.cpp +++ b/source/PrintableModel.cpp @@ -12,7 +12,7 @@ QFont PrintableModel::h2Font() QFont PrintableModel::tableFont() { - return QFont("Helvetica", 10); + return QFont("Helvetica", 8); } QPen PrintableModel::tablePen() diff --git a/source/SubTests/V2Svk/V2SvkModel.cpp b/source/SubTests/V2Svk/V2SvkModel.cpp index 17e4284..e621207 100644 --- a/source/SubTests/V2Svk/V2SvkModel.cpp +++ b/source/SubTests/V2Svk/V2SvkModel.cpp @@ -29,7 +29,7 @@ V2SvkModel::V2SvkModel(QObject *parent) }; } -unsigned int V2SvkModel::getV2Points() +unsigned int V2SvkModel::getV2Points() const { unsigned int points = 0; @@ -49,7 +49,7 @@ unsigned int V2SvkModel::getV2Points() return points; } -unsigned int V2SvkModel::getSvkPoints() +unsigned int V2SvkModel::getSvkPoints() const { unsigned int points = 0; @@ -207,8 +207,6 @@ void V2SvkModel::printTo(QPainter &painter) const painter.drawText( 0, 0, "Subtest 1: Verbzweitstellungsregel (V2) und Subjekt-Verb-Kontrollregel (SVK)"); - painter.translate(0, 1.5 * painter.fontMetrics().lineSpacing()); - painter.setFont(tableFont()); painter.setPen(tablePen()); @@ -228,7 +226,7 @@ void V2SvkModel::printTo(QPainter &painter) const drawTextSquare(left, top, width, height, checked ? "\u2612" : "\u2610"); }; - auto drawResultSquare = [&](bool right, bool bold, unsigned int value, double y) { + auto drawResultSquare = [&](bool right, unsigned int value, double y) { double cellWidth = 0.03 * width; double x = width - cellWidth - (right ? 0 : 0.04 * width); @@ -237,66 +235,119 @@ void V2SvkModel::printTo(QPainter &painter) const auto drawGreySquare = [&](double left, double top, double width, double height) { auto prevBrush = painter.brush(); + auto prevPen = painter.pen(); painter.setBrush(QBrush(QColor(224, 224, 224))); - painter.drawRect(left, top, width, height); - + painter.setPen(QPen(Qt::NoPen)); + QPointF points[4] = {{left, top}, {left + width, top}, {left + width, top + height}, {left, top + height}}; + painter.drawPolygon(points, 4); + + painter.setPen(tablePen()); + painter.drawLine(left, top, left + width, top); + painter.drawLine(left + width, top, left + width, top + height); + painter.drawLine(left + width, top + height, left, top + height); + painter.drawLine(left, top + height, left, top); + painter.setBrush(prevBrush); + painter.setPen(prevPen); }; - auto x = 0.0; - auto y = 0.0; - auto cellWidth = 0.2 * width; - drawTextSquare(x, y, cellWidth, 2 * height, "W-Fragen"); - x += cellWidth; - drawTextSquare(x, y, cellWidth, height, "Affe"); - x += cellWidth; - drawTextSquare(x, y, cellWidth, height, "Schwein"); - x += cellWidth; - drawTextSquare(x, y, cellWidth, height, "Gans"); + std::set blockStarters = {0, 3, 5, 7}; + std::set v2Tests = {0, 1, 3, 5, 7, 8}; + std::set svkTests = {2, 4, 6, 9, 10}; - x = 0.2 * width; - y += height; - cellWidth = 0.05 * width; - for (int i = 0; i < 12; ++i) + double x = 0; + double y = 0; + auto testIndex = 0; + for (const auto &test : m_tests) { - drawCheckSquare(x, y, cellWidth, height, true); - x += cellWidth; + double rowHeaderWidth = 0.2 * width; + double resultCellWidth = test.size() > 8 ? 0.05 * width : 0.1 * width; + double rowHeight = height; + + if (blockStarters.find(testIndex) != blockStarters.end()) + { + y += rowHeight; + drawTextSquare(x, y, rowHeaderWidth, 2 * rowHeight, test.name()); + x += rowHeaderWidth; + + std::vector> columnHeaders; + for (const auto &item : test.items()) + { + const auto &itemText = item.getText(); + if (!columnHeaders.empty() && columnHeaders.back().first == itemText) + { + columnHeaders.back().second++; + } + else + { + columnHeaders.emplace_back(itemText, 1); + } + } + + for (const auto &columnHeader : columnHeaders) + { + double cellWidth = columnHeader.second * resultCellWidth; + drawTextSquare(x, y, cellWidth, rowHeight, columnHeader.first.c_str()); + x += cellWidth; + } + x = rowHeaderWidth; + y += rowHeight; + } + else + { + drawTextSquare(x, y, rowHeaderWidth, rowHeight, test.name()); + x += rowHeaderWidth; + } + + unsigned int emptyItemsStack = 0; + for (const auto &item : test.items()) + { + if (item.getText().empty()) + { + emptyItemsStack++; + } + else + { + if (emptyItemsStack > 0) + { + drawGreySquare(x - emptyItemsStack * resultCellWidth, y, + emptyItemsStack * resultCellWidth, rowHeight); + emptyItemsStack = 0; + } + + drawCheckSquare(x, y, resultCellWidth, rowHeight, item.isChecked()); + } + x += resultCellWidth; + } + if (emptyItemsStack > 0) + { + drawGreySquare(x - emptyItemsStack * resultCellWidth, y, + emptyItemsStack * resultCellWidth, rowHeight); + emptyItemsStack = 0; + } + + if (v2Tests.find(testIndex) != v2Tests.end()) + { + drawResultSquare(false, test.getPoints(), y); + } + + if (svkTests.find(testIndex) != svkTests.end()) + { + drawResultSquare(true, test.getPoints(), y); + } + + x = 0; + y += rowHeight; + + testIndex++; } - drawResultSquare(false, false, 9, y); x = 0; y += height; - cellWidth = 0.2 * width; - drawTextSquare(x, y, cellWidth, height, "Verbtrennung"); - x += cellWidth; - cellWidth = 0.05 * width; - drawGreySquare(x, y, cellWidth, height); - x += cellWidth; - drawCheckSquare(x, y, cellWidth, height, true); - x += cellWidth; - drawGreySquare(x, y, 5 * cellWidth, height); - x += 5 * cellWidth; - drawCheckSquare(x, y, cellWidth, height, true); - x += cellWidth; - drawGreySquare(x, y, 2 * cellWidth, height); - x += 2 * cellWidth; - drawCheckSquare(x, y, cellWidth, height, true); - x += cellWidth; - drawGreySquare(x, y, cellWidth, height); - x += cellWidth; - drawResultSquare(false, false, 2, y); - x = 0; - y += height; - cellWidth = 0.2 * width; - drawTextSquare(x, y, cellWidth, height, "SVK: /-st/"); - x += cellWidth; - cellWidth = 0.05 * width; - for (int i = 0; i < 12; ++i) - { - drawCheckSquare(x, y, cellWidth, height, true); - x += cellWidth; - } - drawResultSquare(true, false, 8, y); + painter.drawText(x, y, 0.85 * width, height, Qt::AlignRight | Qt::AlignVCenter, + "Rohwertpunkte Total:"); + drawResultSquare(false, getV2Points(), y); + drawResultSquare(true, getSvkPoints(), y); } diff --git a/source/SubTests/V2Svk/V2SvkModel.h b/source/SubTests/V2Svk/V2SvkModel.h index becad53..c7090c3 100644 --- a/source/SubTests/V2Svk/V2SvkModel.h +++ b/source/SubTests/V2Svk/V2SvkModel.h @@ -12,8 +12,8 @@ class V2SvkModel : public CheckableTestModel, public PrintableModel public: V2SvkModel(QObject *parent); - unsigned int getV2Points(); - unsigned int getSvkPoints(); + unsigned int getV2Points() const; + unsigned int getSvkPoints() const; void write(ESGRAF48::V2SvkModel &model) const; void read(const ESGRAF48::V2SvkModel &model); diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 0a5c8de..88a67e3 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -153,7 +153,7 @@ void MainWindow::print() const { QPrinter printer; printer.setPaperSize(QPrinter::A4); - printer.setPageMargins(30, 20, 30, 20, QPrinter::Millimeter); + printer.setPageMargins(20, 20, 20, 20, QPrinter::Millimeter); QPrintDialog dialog(&printer); if (dialog.exec() != QDialog::Accepted) @@ -215,7 +215,7 @@ void MainWindow::savePdf(const QString &filename) QPrinter printer; printer.setOutputFormat(QPrinter::PdfFormat); printer.setPaperSize(QPrinter::A4); - printer.setPageMargins(30, 20, 30, 20, QPrinter::Millimeter); + printer.setPageMargins(20, 20, 20, 20, QPrinter::Millimeter); printer.setOutputFileName(filename); QPainter painter; From d298238ae88ca60ee295a5e79a024e262040e95c Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 13 Jan 2019 19:54:09 +0100 Subject: [PATCH 11/42] Refactored printing code from model to base-class --- source/CMakeLists.txt | 3 +- source/MetaData/CMakeLists.txt | 1 + source/MetaData/MetaDataModel.h | 2 +- source/PrintableModel.cpp | 21 ------- source/PrintableModel.h | 16 ----- source/PrintableModel/CMakeLists.txt | 25 ++++++++ source/PrintableModel/PrintableModel.cpp | 78 ++++++++++++++++++++++++ source/PrintableModel/PrintableModel.h | 25 ++++++++ source/SubTests/V2Svk/CMakeLists.txt | 1 + source/SubTests/V2Svk/V2SvkModel.cpp | 63 ++++--------------- source/SubTests/V2Svk/V2SvkModel.h | 2 +- 11 files changed, 146 insertions(+), 91 deletions(-) delete mode 100644 source/PrintableModel.cpp delete mode 100644 source/PrintableModel.h create mode 100644 source/PrintableModel/CMakeLists.txt create mode 100644 source/PrintableModel/PrintableModel.cpp create mode 100644 source/PrintableModel/PrintableModel.h diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 895a7a4..f1329f6 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -35,7 +35,6 @@ protobuf_generate_cpp(DataModel_PROTO_SRCS DataModel_PROTO_HDRS add_executable(${PROJECT_NAME} WIN32 ESGRAF48.cpp - PrintableModel.cpp DataModel.cpp mainwindow.cpp ${LOGO_TEST_UI} @@ -61,6 +60,7 @@ target_link_libraries(${PROJECT_NAME} CheckableItem CheckableTest CheckableTestModel + PrintableModel MetaData VerbEnd Plural @@ -78,6 +78,7 @@ add_subdirectory(Age) add_subdirectory(CheckableItem) add_subdirectory(CheckableTest) add_subdirectory(CheckableTestModel) +add_subdirectory(PrintableModel) add_subdirectory(MetaData) add_subdirectory(SubTests) diff --git a/source/MetaData/CMakeLists.txt b/source/MetaData/CMakeLists.txt index e00d8de..ab2b0f0 100644 --- a/source/MetaData/CMakeLists.txt +++ b/source/MetaData/CMakeLists.txt @@ -42,6 +42,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE Age + PrintableModel Qt5::Widgets ${Protobuf_LIBRARIES} ) diff --git a/source/MetaData/MetaDataModel.h b/source/MetaData/MetaDataModel.h index 3164b90..7774f99 100644 --- a/source/MetaData/MetaDataModel.h +++ b/source/MetaData/MetaDataModel.h @@ -1,6 +1,6 @@ #pragma once -#include "../PrintableModel.h" +#include "PrintableModel.h" #include "Age.h" diff --git a/source/PrintableModel.cpp b/source/PrintableModel.cpp deleted file mode 100644 index 2f5a16c..0000000 --- a/source/PrintableModel.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "PrintableModel.h" - -QFont PrintableModel::h1Font() -{ - return QFont("Helvetica", 16); -} - -QFont PrintableModel::h2Font() -{ - return QFont("Helvetica", 12); -} - -QFont PrintableModel::tableFont() -{ - return QFont("Helvetica", 8); -} - -QPen PrintableModel::tablePen() -{ - return QPen(Qt::black, 1, Qt::SolidLine); -} diff --git a/source/PrintableModel.h b/source/PrintableModel.h deleted file mode 100644 index 5d99c31..0000000 --- a/source/PrintableModel.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -class PrintableModel -{ -public: - virtual void printTo(QPainter &painter) const = 0; - -protected: - static QFont h1Font(); - static QFont h2Font(); - static QFont tableFont(); - - static QPen tablePen(); -}; diff --git a/source/PrintableModel/CMakeLists.txt b/source/PrintableModel/CMakeLists.txt new file mode 100644 index 0000000..0a09f00 --- /dev/null +++ b/source/PrintableModel/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.6) + +project(PrintableModel LANGUAGES CXX) + +find_package(Qt5Core REQUIRED) +find_package(Qt5Widgets REQUIRED) + +add_library(${PROJECT_NAME} + PrintableModel.cpp +) + +set_target_properties(${PROJECT_NAME} + PROPERTIES CXX_STANDARD 14 +) + +target_include_directories(${PROJECT_NAME} + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE + Qt5::Core + Qt5::Widgets +) diff --git a/source/PrintableModel/PrintableModel.cpp b/source/PrintableModel/PrintableModel.cpp new file mode 100644 index 0000000..21d57a2 --- /dev/null +++ b/source/PrintableModel/PrintableModel.cpp @@ -0,0 +1,78 @@ +#include "PrintableModel.h" + +QFont PrintableModel::h1Font() +{ + return QFont("Helvetica", 16); +} + +QFont PrintableModel::h2Font() +{ + return QFont("Helvetica", 12); +} + +QFont PrintableModel::tableFont() +{ + return QFont("Helvetica", 8); +} + +QPen PrintableModel::tablePen() +{ + return QPen(Qt::black, 1, Qt::SolidLine); +} + +void PrintableModel::drawTextSquare(QPainter &painter, const QRectF &cell, const QString &text) +{ + auto prevPen = painter.pen(); + painter.setPen(tablePen()); + + painter.drawText(cell, Qt::AlignCenter, text); + + painter.drawLine(cell.topLeft(), cell.topRight()); + painter.drawLine(cell.topRight(), cell.bottomRight()); + painter.drawLine(cell.bottomRight(), cell.bottomLeft()); + painter.drawLine(cell.bottomLeft(), cell.topLeft()); + + painter.setPen(prevPen); +} + +void PrintableModel::PrintableModel::drawCheckSquare(QPainter &painter, const QRectF &cell, + bool checked) +{ + drawTextSquare(painter, cell, checked ? "\u2612" : "\u2610"); +} + +void PrintableModel::drawResultSquare(QPainter &painter, double y, bool rightCell, + unsigned int value) +{ + auto prevPen = painter.pen(); + painter.setPen(tablePen()); + + double pageWidth = painter.device()->width(); + double cellWidth = 0.03 * pageWidth; + double cellHeight = painter.fontMetrics().lineSpacing(); + double x = pageWidth - cellWidth - (rightCell ? 0 : 0.04 * pageWidth); + + drawTextSquare(painter, {x, y, cellWidth, cellHeight}, QString::number(value)); + + painter.setPen(prevPen); +} + +void PrintableModel::drawGreySquare(QPainter &painter, const QRectF &cell) +{ + auto prevBrush = painter.brush(); + auto prevPen = painter.pen(); + + painter.setBrush(QBrush(QColor(224, 224, 224))); + painter.setPen(QPen(Qt::NoPen)); + QPointF points[4] = {cell.topLeft(), cell.topRight(), cell.bottomRight(), cell.bottomLeft()}; + painter.drawPolygon(points, 4); + + painter.setPen(tablePen()); + painter.drawLine(cell.topLeft(), cell.topRight()); + painter.drawLine(cell.topRight(), cell.bottomRight()); + painter.drawLine(cell.bottomRight(), cell.bottomLeft()); + painter.drawLine(cell.bottomLeft(), cell.topLeft()); + + painter.setBrush(prevBrush); + painter.setPen(prevPen); +} diff --git a/source/PrintableModel/PrintableModel.h b/source/PrintableModel/PrintableModel.h new file mode 100644 index 0000000..ab08433 --- /dev/null +++ b/source/PrintableModel/PrintableModel.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include +#include + +class PrintableModel +{ +public: + virtual void printTo(QPainter &painter) const = 0; + +protected: + static QFont h1Font(); + static QFont h2Font(); + static QFont tableFont(); + + static QPen tablePen(); + + static void drawTextSquare(QPainter &painter, const QRectF &cell, const QString &text); + static void drawCheckSquare(QPainter &painter, const QRectF &cell, bool checked); + static void drawResultSquare(QPainter &painter, double y, bool rightCell, unsigned int value); + static void drawGreySquare(QPainter &painter, const QRectF &cell); +}; diff --git a/source/SubTests/V2Svk/CMakeLists.txt b/source/SubTests/V2Svk/CMakeLists.txt index caf6c8c..5cd3661 100644 --- a/source/SubTests/V2Svk/CMakeLists.txt +++ b/source/SubTests/V2Svk/CMakeLists.txt @@ -42,6 +42,7 @@ target_link_libraries(${PROJECT_NAME} CheckableItem CheckableTest CheckableTestModel + PrintableModel Qt5::Widgets ${Protobuf_LIBRARIES} ) diff --git a/source/SubTests/V2Svk/V2SvkModel.cpp b/source/SubTests/V2Svk/V2SvkModel.cpp index e621207..ab9a833 100644 --- a/source/SubTests/V2Svk/V2SvkModel.cpp +++ b/source/SubTests/V2Svk/V2SvkModel.cpp @@ -213,45 +213,6 @@ void V2SvkModel::printTo(QPainter &painter) const auto width = painter.device()->width(); auto height = 1.5 * painter.fontMetrics().lineSpacing(); - auto drawTextSquare = [&](double left, double top, double width, double height, - const QString &text) { - painter.drawText(left, top, width, height, Qt::AlignCenter, text); - painter.drawLine(left, top, left + width, top); - painter.drawLine(left + width, top, left + width, top + height); - painter.drawLine(left + width, top + height, left, top + height); - painter.drawLine(left, top + height, left, top); - }; - - auto drawCheckSquare = [&](double left, double top, double width, double height, bool checked) { - drawTextSquare(left, top, width, height, checked ? "\u2612" : "\u2610"); - }; - - auto drawResultSquare = [&](bool right, unsigned int value, double y) { - double cellWidth = 0.03 * width; - double x = width - cellWidth - (right ? 0 : 0.04 * width); - - drawTextSquare(x, y, cellWidth, height, QString::number(value)); - }; - - auto drawGreySquare = [&](double left, double top, double width, double height) { - auto prevBrush = painter.brush(); - auto prevPen = painter.pen(); - - painter.setBrush(QBrush(QColor(224, 224, 224))); - painter.setPen(QPen(Qt::NoPen)); - QPointF points[4] = {{left, top}, {left + width, top}, {left + width, top + height}, {left, top + height}}; - painter.drawPolygon(points, 4); - - painter.setPen(tablePen()); - painter.drawLine(left, top, left + width, top); - painter.drawLine(left + width, top, left + width, top + height); - painter.drawLine(left + width, top + height, left, top + height); - painter.drawLine(left, top + height, left, top); - - painter.setBrush(prevBrush); - painter.setPen(prevPen); - }; - std::set blockStarters = {0, 3, 5, 7}; std::set v2Tests = {0, 1, 3, 5, 7, 8}; std::set svkTests = {2, 4, 6, 9, 10}; @@ -268,7 +229,7 @@ void V2SvkModel::printTo(QPainter &painter) const if (blockStarters.find(testIndex) != blockStarters.end()) { y += rowHeight; - drawTextSquare(x, y, rowHeaderWidth, 2 * rowHeight, test.name()); + drawTextSquare(painter, {x, y, rowHeaderWidth, 2 * rowHeight}, test.name()); x += rowHeaderWidth; std::vector> columnHeaders; @@ -288,7 +249,7 @@ void V2SvkModel::printTo(QPainter &painter) const for (const auto &columnHeader : columnHeaders) { double cellWidth = columnHeader.second * resultCellWidth; - drawTextSquare(x, y, cellWidth, rowHeight, columnHeader.first.c_str()); + drawTextSquare(painter, {x, y, cellWidth, rowHeight}, columnHeader.first.c_str()); x += cellWidth; } x = rowHeaderWidth; @@ -296,7 +257,7 @@ void V2SvkModel::printTo(QPainter &painter) const } else { - drawTextSquare(x, y, rowHeaderWidth, rowHeight, test.name()); + drawTextSquare(painter, {x, y, rowHeaderWidth, rowHeight}, test.name()); x += rowHeaderWidth; } @@ -311,30 +272,30 @@ void V2SvkModel::printTo(QPainter &painter) const { if (emptyItemsStack > 0) { - drawGreySquare(x - emptyItemsStack * resultCellWidth, y, - emptyItemsStack * resultCellWidth, rowHeight); + drawGreySquare(painter, {x - emptyItemsStack * resultCellWidth, y, + emptyItemsStack * resultCellWidth, rowHeight}); emptyItemsStack = 0; } - drawCheckSquare(x, y, resultCellWidth, rowHeight, item.isChecked()); + drawCheckSquare(painter, {x, y, resultCellWidth, rowHeight}, item.isChecked()); } x += resultCellWidth; } if (emptyItemsStack > 0) { - drawGreySquare(x - emptyItemsStack * resultCellWidth, y, - emptyItemsStack * resultCellWidth, rowHeight); + drawGreySquare(painter, {x - emptyItemsStack * resultCellWidth, y, + emptyItemsStack * resultCellWidth, rowHeight}); emptyItemsStack = 0; } if (v2Tests.find(testIndex) != v2Tests.end()) { - drawResultSquare(false, test.getPoints(), y); + drawResultSquare(painter, y, false, test.getPoints()); } if (svkTests.find(testIndex) != svkTests.end()) { - drawResultSquare(true, test.getPoints(), y); + drawResultSquare(painter, y, true, test.getPoints()); } x = 0; @@ -348,6 +309,6 @@ void V2SvkModel::printTo(QPainter &painter) const painter.drawText(x, y, 0.85 * width, height, Qt::AlignRight | Qt::AlignVCenter, "Rohwertpunkte Total:"); - drawResultSquare(false, getV2Points(), y); - drawResultSquare(true, getSvkPoints(), y); + drawResultSquare(painter, y, false, getV2Points()); + drawResultSquare(painter, y, true, getSvkPoints()); } diff --git a/source/SubTests/V2Svk/V2SvkModel.h b/source/SubTests/V2Svk/V2SvkModel.h index c7090c3..2b282ee 100644 --- a/source/SubTests/V2Svk/V2SvkModel.h +++ b/source/SubTests/V2Svk/V2SvkModel.h @@ -1,6 +1,6 @@ #pragma once -#include "../../PrintableModel.h" +#include "PrintableModel.h" #include "CheckableTestModel.h" #include "V2SvkModel.pb.h" From 95fc97048884fb637c33223c9aac0ca22cd543d5 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 24 Jan 2019 21:09:00 +0100 Subject: [PATCH 12/42] Disabled unit tests --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4603e7c..9df6c34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,4 +6,4 @@ include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() add_subdirectory(source) -add_subdirectory(test) +#add_subdirectory(test) From fc9e387b28b332a5393e1658dafb6c2030bf1a8e Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 27 Jan 2019 18:28:39 +0100 Subject: [PATCH 13/42] Changed name and datamodel of subtest 4 / dativ options Fixes #19 --- proto/DativModel.proto | 34 ++++----- source/SubTests/AkkusativDativ/DativModel.cpp | 70 +++++++++---------- 2 files changed, 52 insertions(+), 52 deletions(-) diff --git a/proto/DativModel.proto b/proto/DativModel.proto index b3bb021..696d5ab 100644 --- a/proto/DativModel.proto +++ b/proto/DativModel.proto @@ -6,14 +6,14 @@ message DativModel { message TiereModel { - bool Tiger = 1; - bool Katze = 2; - bool Affe = 3; - bool Gans = 4; - bool Baer = 5; + bool Affe = 1; + bool Gans = 2; + bool Tiger = 3; + bool Hund = 4; + bool Elefant = 5; bool Pferd = 6; - bool Hund = 7; - bool Elefant = 8; + bool Baer = 7; + bool Katze = 8; } message VersteckeModel @@ -28,19 +28,19 @@ message DativModel bool Baum2 = 8; } - message FutterModel + message NomTiereModel { - bool Salat = 1; - bool Fleisch = 2; - bool Knochen = 3; - bool Banane = 4; - bool Apfel = 5; - bool Karotte = 6; - bool Honig = 7; - bool Zucker = 8; + bool Gans = 1; + bool Tiger = 2; + bool Hund = 3; + bool Affe = 4; + bool Elefant = 5; + bool Pferd = 6; + bool Baer = 7; + bool Katze = 8; } TiereModel Tiere = 1; VersteckeModel Verstecke = 2; - FutterModel Futter = 3; + NomTiereModel NomTiere = 3; } diff --git a/source/SubTests/AkkusativDativ/DativModel.cpp b/source/SubTests/AkkusativDativ/DativModel.cpp index 081dfdb..3741833 100644 --- a/source/SubTests/AkkusativDativ/DativModel.cpp +++ b/source/SubTests/AkkusativDativ/DativModel.cpp @@ -4,11 +4,11 @@ DativModel::DativModel(QObject *parent) : CheckableTestModel(parent) { m_tests = {{"Dativ Nominalphrase", - {"Tiger", "Katze", "Affe", "Gans", "Bär", "Pferd", "Hund", "Elefant"}}, + {"Affe", "Gans", "Tiger", "Hund", "Elefant", "Pferd", "Bär", "Katze"}}, {"Präpositionalphrase (Verstecke)", {"Vorhang", "Kiste", "Holz", "Kiste", "Baum", "Vorhang", "Holz", "Baum"}}, {"Nominalphrase (Tiere)", - {"Salat", "Fleisch", "Knochen", "Banane", "Apfel", "Karotte", "Honig", "Zucker"}}}; + {"Gans", "Tiger", "Hund", "Affe", "Elefant", "Pferd", "Bär", "Katze"}}}; } void DativModel::read(const ESGRAF48::DativModel &model) @@ -17,14 +17,14 @@ void DativModel::read(const ESGRAF48::DativModel &model) { auto &testItems = m_tests.at(0).items(); - testItems[0].setState(tiereModel.tiger()); - testItems[1].setState(tiereModel.katze()); - testItems[2].setState(tiereModel.affe()); - testItems[3].setState(tiereModel.gans()); - testItems[4].setState(tiereModel.baer()); + testItems[0].setState(tiereModel.affe()); + testItems[1].setState(tiereModel.gans()); + testItems[2].setState(tiereModel.tiger()); + testItems[3].setState(tiereModel.hund()); + testItems[4].setState(tiereModel.elefant()); testItems[5].setState(tiereModel.pferd()); - testItems[6].setState(tiereModel.hund()); - testItems[7].setState(tiereModel.elefant()); + testItems[6].setState(tiereModel.baer()); + testItems[7].setState(tiereModel.katze()); } const auto &versteckeModel = model.verstecke(); @@ -41,18 +41,18 @@ void DativModel::read(const ESGRAF48::DativModel &model) testItems[7].setState(versteckeModel.baum2()); } - const auto &futterModel = model.futter(); + const auto &nomTiereModel = model.nomtiere(); { auto &testItems = m_tests.at(2).items(); - testItems[0].setState(futterModel.salat()); - testItems[1].setState(futterModel.fleisch()); - testItems[2].setState(futterModel.knochen()); - testItems[3].setState(futterModel.banane()); - testItems[4].setState(futterModel.apfel()); - testItems[5].setState(futterModel.karotte()); - testItems[6].setState(futterModel.honig()); - testItems[7].setState(futterModel.zucker()); + testItems[0].setState(nomTiereModel.gans()); + testItems[1].setState(nomTiereModel.tiger()); + testItems[2].setState(nomTiereModel.hund()); + testItems[3].setState(nomTiereModel.affe()); + testItems[4].setState(nomTiereModel.elefant()); + testItems[5].setState(nomTiereModel.pferd()); + testItems[6].setState(nomTiereModel.baer()); + testItems[7].setState(nomTiereModel.katze()); } emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); @@ -65,14 +65,14 @@ void DativModel::write(ESGRAF48::DativModel &model) const { const auto &testItems = m_tests.at(0).items(); - tiereModel->set_tiger(testItems[0].isChecked()); - tiereModel->set_katze(testItems[1].isChecked()); - tiereModel->set_affe(testItems[2].isChecked()); - tiereModel->set_gans(testItems[3].isChecked()); - tiereModel->set_baer(testItems[4].isChecked()); + tiereModel->set_affe(testItems[0].isChecked()); + tiereModel->set_gans(testItems[1].isChecked()); + tiereModel->set_tiger(testItems[2].isChecked()); + tiereModel->set_hund(testItems[3].isChecked()); + tiereModel->set_elefant(testItems[4].isChecked()); tiereModel->set_pferd(testItems[5].isChecked()); - tiereModel->set_hund(testItems[6].isChecked()); - tiereModel->set_elefant(testItems[7].isChecked()); + tiereModel->set_baer(testItems[6].isChecked()); + tiereModel->set_katze(testItems[7].isChecked()); } auto *versteckeModel = model.mutable_verstecke(); @@ -90,18 +90,18 @@ void DativModel::write(ESGRAF48::DativModel &model) const versteckeModel->set_baum2(testItems[7].isChecked()); } - auto *futterModel = model.mutable_futter(); - if (futterModel != nullptr) + auto *nomTiereModel = model.mutable_nomtiere(); + if (nomTiereModel != nullptr) { const auto &testItems = m_tests.at(2).items(); - futterModel->set_salat(testItems[0].isChecked()); - futterModel->set_fleisch(testItems[1].isChecked()); - futterModel->set_knochen(testItems[2].isChecked()); - futterModel->set_banane(testItems[3].isChecked()); - futterModel->set_apfel(testItems[4].isChecked()); - futterModel->set_karotte(testItems[5].isChecked()); - futterModel->set_honig(testItems[6].isChecked()); - futterModel->set_zucker(testItems[7].isChecked()); + nomTiereModel->set_gans(testItems[0].isChecked()); + nomTiereModel->set_tiger(testItems[1].isChecked()); + nomTiereModel->set_hund(testItems[2].isChecked()); + nomTiereModel->set_affe(testItems[3].isChecked()); + nomTiereModel->set_elefant(testItems[4].isChecked()); + nomTiereModel->set_pferd(testItems[5].isChecked()); + nomTiereModel->set_baer(testItems[6].isChecked()); + nomTiereModel->set_katze(testItems[7].isChecked()); } } From c044bebece17b7d9b64b027931365c2fd8e4568c Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 27 Jan 2019 20:09:10 +0100 Subject: [PATCH 14/42] Use the maximum test-age for subjects past that age --- source/MetaData/MetaDataModel.cpp | 5 +++++ source/MetaData/MetaDataModel.h | 11 +++-------- source/ResultWidget/PRMap.cpp | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/MetaData/MetaDataModel.cpp b/source/MetaData/MetaDataModel.cpp index 94c2a62..f2911e8 100644 --- a/source/MetaData/MetaDataModel.cpp +++ b/source/MetaData/MetaDataModel.cpp @@ -166,3 +166,8 @@ std::string MetaDataModel::toHtml() const return out.str(); } + +Age MetaDataModel::getAge() const +{ + return {m_dateOfBirth, m_dateOfTest}; +} diff --git a/source/MetaData/MetaDataModel.h b/source/MetaData/MetaDataModel.h index 0c8bbeb..72811e6 100644 --- a/source/MetaData/MetaDataModel.h +++ b/source/MetaData/MetaDataModel.h @@ -24,19 +24,14 @@ public: MetaDataModel(QObject *parent); int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data( - const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; - bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole) override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; void read(const ESGRAF48::MetaDataModel &model); void write(ESGRAF48::MetaDataModel &model) const; std::string toHtml() const; - Age getAge() const - { - return { m_dateOfBirth, m_dateOfTest }; - } + Age getAge() const; }; diff --git a/source/ResultWidget/PRMap.cpp b/source/ResultWidget/PRMap.cpp index 41e76dc..8c1cc7b 100644 --- a/source/ResultWidget/PRMap.cpp +++ b/source/ResultWidget/PRMap.cpp @@ -20,7 +20,7 @@ unsigned int PRMap::lookup(const Age &age, const unsigned int &points) if (m_ages.back() < age) { - return m_ages.size() - 1; + return m_ages.size() - 2; } for (size_t index = 1; index < m_ages.size(); ++index) From 88e75d24883e4238aa2d420384393cfdddf85504 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Tue, 29 Jan 2019 14:01:17 +0100 Subject: [PATCH 15/42] Install conan deps via cmake --- CMakeLists.txt | 5 + cmake/conan.cmake | 516 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 521 insertions(+) create mode 100644 cmake/conan.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9df6c34..0a8da5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,11 @@ cmake_minimum_required(VERSION 3.5) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +include(cmake/conan.cmake) +conan_cmake_run(CONANFILE conanfile.txt + BASIC_SETUP + BUILD missing) + include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() diff --git a/cmake/conan.cmake b/cmake/conan.cmake new file mode 100644 index 0000000..28d2126 --- /dev/null +++ b/cmake/conan.cmake @@ -0,0 +1,516 @@ +# The MIT License (MIT) + +# Copyright (c) 2018 JFrog + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + + +# This file comes from: https://github.com/conan-io/cmake-conan. Please refer +# to this repository for issues and documentation. + +# Its purpose is to wrap and launch Conan C/C++ Package Manager when cmake is called. +# It will take CMake current settings (os, compiler, compiler version, architecture) +# and translate them to conan settings for installing and retrieving dependencies. + +# It is intended to facilitate developers building projects that have conan dependencies, +# but it is only necessary on the end-user side. It is not necessary to create conan +# packages, in fact it shouldn't be use for that. Check the project documentation. + + +include(CMakeParseArguments) + +function(_get_msvc_ide_version result) + set(${result} "" PARENT_SCOPE) + if(NOT MSVC_VERSION VERSION_LESS 1400 AND MSVC_VERSION VERSION_LESS 1500) + set(${result} 8 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1500 AND MSVC_VERSION VERSION_LESS 1600) + set(${result} 9 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1600 AND MSVC_VERSION VERSION_LESS 1700) + set(${result} 10 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1700 AND MSVC_VERSION VERSION_LESS 1800) + set(${result} 11 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1800 AND MSVC_VERSION VERSION_LESS 1900) + set(${result} 12 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1900 AND MSVC_VERSION VERSION_LESS 1910) + set(${result} 14 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1910 AND MSVC_VERSION VERSION_LESS 1920) + set(${result} 15 PARENT_SCOPE) + else() + message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") + endif() +endfunction() + +function(conan_cmake_settings result) + #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER}) + #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER_ID}) + #message(STATUS "VERSION " ${CMAKE_CXX_COMPILER_VERSION}) + #message(STATUS "FLAGS " ${CMAKE_LANG_FLAGS}) + #message(STATUS "LIB ARCH " ${CMAKE_CXX_LIBRARY_ARCHITECTURE}) + #message(STATUS "BUILD TYPE " ${CMAKE_BUILD_TYPE}) + #message(STATUS "GENERATOR " ${CMAKE_GENERATOR}) + #message(STATUS "GENERATOR WIN64 " ${CMAKE_CL_64}) + + message(STATUS "Conan: Automatic detection of conan settings from cmake") + + parse_arguments(${ARGV}) + + if(ARGUMENTS_BUILD_TYPE) + set(_CONAN_SETTING_BUILD_TYPE ${ARGUMENTS_BUILD_TYPE}) + elseif(CMAKE_BUILD_TYPE) + set(_CONAN_SETTING_BUILD_TYPE ${CMAKE_BUILD_TYPE}) + else() + message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") + endif() + if(ARGUMENTS_ARCH) + set(_CONAN_SETTING_ARCH ${ARGUMENTS_ARCH}) + endif() + #handle -s os setting + if(CMAKE_SYSTEM_NAME) + #use default conan os setting if CMAKE_SYSTEM_NAME is not defined + set(CONAN_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(CONAN_SYSTEM_NAME Macos) + endif() + set(CONAN_SUPPORTED_PLATFORMS Windows Linux Macos Android iOS FreeBSD WindowsStore) + list (FIND CONAN_SUPPORTED_PLATFORMS "${CONAN_SYSTEM_NAME}" _index) + if (${_index} GREATER -1) + #check if the cmake system is a conan supported one + set(_CONAN_SETTING_OS ${CONAN_SYSTEM_NAME}) + else() + message(FATAL_ERROR "cmake system ${CONAN_SYSTEM_NAME} is not supported by conan. Use one of ${CONAN_SUPPORTED_PLATFORMS}") + endif() + endif() + + get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (";${_languages};" MATCHES ";CXX;") + set(LANGUAGE CXX) + set(USING_CXX 1) + elseif (";${_languages};" MATCHES ";C;") + set(LANGUAGE C) + set(USING_CXX 0) + else () + message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.") + endif() + + if (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL GNU) + # using GCC + # TODO: Handle other params + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(COMPILER_VERSION ${MAJOR}.${MINOR}) + if(${MAJOR} GREATER 4) + set(COMPILER_VERSION ${MAJOR}) + endif() + set(_CONAN_SETTING_COMPILER gcc) + set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION}) + if (USING_CXX) + conan_cmake_detect_gnu_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL AppleClang) + # using AppleClang + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(_CONAN_SETTING_COMPILER apple-clang) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + if (USING_CXX) + set(_CONAN_SETTING_COMPILER_LIBCXX libc++) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang) + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + if(APPLE) + cmake_policy(GET CMP0025 APPLE_CLANG_POLICY_ENABLED) + if(NOT APPLE_CLANG_POLICY_ENABLED) + message(STATUS "Conan: APPLE and Clang detected. Assuming apple-clang compiler. Set CMP0025 to avoid it") + set(_CONAN_SETTING_COMPILER apple-clang) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + else() + set(_CONAN_SETTING_COMPILER clang) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + endif() + if (USING_CXX) + set(_CONAN_SETTING_COMPILER_LIBCXX libc++) + endif () + else() + set(_CONAN_SETTING_COMPILER clang) + if(${MAJOR} GREATER 7) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}) + else() + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + endif() + if (USING_CXX) + conan_cmake_detect_gnu_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + endif() + elseif(${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL MSVC) + set(_VISUAL "Visual Studio") + _get_msvc_ide_version(_VISUAL_VERSION) + if("${_VISUAL_VERSION}" STREQUAL "") + message(FATAL_ERROR "Conan: Visual Studio not recognized") + else() + set(_CONAN_SETTING_COMPILER ${_VISUAL}) + set(_CONAN_SETTING_COMPILER_VERSION ${_VISUAL_VERSION}) + endif() + + if(NOT _CONAN_SETTING_ARCH) + if (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "64") + set(_CONAN_SETTING_ARCH x86_64) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "^ARM") + message(STATUS "Conan: Using default ARM architecture from MSVC") + set(_CONAN_SETTING_ARCH armv6) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "86") + set(_CONAN_SETTING_ARCH x86) + else () + message(FATAL_ERROR "Conan: Unknown MSVC architecture [${MSVC_${LANGUAGE}_ARCHITECTURE_ID}]") + endif() + endif() + + conan_cmake_detect_vs_runtime(_vs_runtime) + message(STATUS "Conan: Detected VS runtime: ${_vs_runtime}") + set(_CONAN_SETTING_COMPILER_RUNTIME ${_vs_runtime}) + + if (CMAKE_GENERATOR_TOOLSET) + set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) + elseif(CMAKE_VS_PLATFORM_TOOLSET AND (CMAKE_GENERATOR STREQUAL "Ninja")) + set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) + endif() + else() + message(FATAL_ERROR "Conan: compiler setup not recognized") + endif() + + # If profile is defined it is used + if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE) + set(_SETTINGS -pr ${ARGUMENTS_DEBUG_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "Release" AND ARGUMENTS_RELEASE_PROFILE) + set(_SETTINGS -pr ${ARGUMENTS_RELEASE_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" AND ARGUMENTS_RELWITHDEBINFO_PROFILE) + set(_SETTINGS -pr ${ARGUMENTS_RELWITHDEBINFO_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" AND ARGUMENTS_MINSIZEREL_PROFILE) + set(_SETTINGS -pr ${ARGUMENTS_MINSIZEREL_PROFILE}) + elseif(ARGUMENTS_PROFILE) + set(_SETTINGS -pr ${ARGUMENTS_PROFILE}) + endif() + + if(NOT _SETTINGS OR ARGUMENTS_PROFILE_AUTO STREQUAL "ALL") + set(ARGUMENTS_PROFILE_AUTO arch build_type compiler compiler.version + compiler.runtime compiler.libcxx compiler.toolset) + endif() + + # Automatic from CMake + foreach(ARG ${ARGUMENTS_PROFILE_AUTO}) + string(TOUPPER ${ARG} _arg_name) + string(REPLACE "." "_" _arg_name ${_arg_name}) + if(_CONAN_SETTING_${_arg_name}) + set(_SETTINGS ${_SETTINGS} -s ${ARG}=${_CONAN_SETTING_${_arg_name}}) + endif() + endforeach() + + foreach(ARG ${ARGUMENTS_SETTINGS}) + set(_SETTINGS ${_SETTINGS} -s ${ARG}) + endforeach() + + message(STATUS "Conan: Settings= ${_SETTINGS}") + + set(${result} ${_SETTINGS} PARENT_SCOPE) +endfunction() + + +function(conan_cmake_detect_gnu_libcxx result) + # Allow -D_GLIBCXX_USE_CXX11_ABI=ON/OFF as argument to cmake + if(DEFINED _GLIBCXX_USE_CXX11_ABI) + if(_GLIBCXX_USE_CXX11_ABI) + set(${result} libstdc++11 PARENT_SCOPE) + return() + else() + set(${result} libstdc++ PARENT_SCOPE) + return() + endif() + endif() + + # Check if there's any add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0) + get_directory_property(defines DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS) + foreach(define ${defines}) + if(define STREQUAL "_GLIBCXX_USE_CXX11_ABI=0") + set(${result} libstdc++ PARENT_SCOPE) + return() + endif() + endforeach() + + # Use C++11 stdlib as default if gcc is 5.1+ + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.1") + set(${result} libstdc++ PARENT_SCOPE) + else() + set(${result} libstdc++11 PARENT_SCOPE) + endif() +endfunction() + + +function(conan_cmake_detect_vs_runtime result) + string(TOUPPER ${CMAKE_BUILD_TYPE} build_type) + set(variables CMAKE_CXX_FLAGS_${build_type} CMAKE_C_FLAGS_${build_type} CMAKE_CXX_FLAGS CMAKE_C_FLAGS) + foreach(variable ${variables}) + string(REPLACE " " ";" flags ${${variable}}) + foreach (flag ${flags}) + if(${flag} STREQUAL "/MD" OR ${flag} STREQUAL "/MDd" OR ${flag} STREQUAL "/MT" OR ${flag} STREQUAL "/MTd") + string(SUBSTRING ${flag} 1 -1 runtime) + set(${result} ${runtime} PARENT_SCOPE) + return() + endif() + endforeach() + endforeach() + if(${build_type} STREQUAL "DEBUG") + set(${result} "MDd" PARENT_SCOPE) + else() + set(${result} "MD" PARENT_SCOPE) + endif() +endfunction() + + +macro(parse_arguments) + set(options BASIC_SETUP CMAKE_TARGETS UPDATE KEEP_RPATHS NO_OUTPUT_DIRS OUTPUT_QUIET) + set(oneValueArgs CONANFILE DEBUG_PROFILE RELEASE_PROFILE RELWITHDEBINFO_PROFILE MINSIZEREL_PROFILE + PROFILE ARCH BUILD_TYPE INSTALL_FOLDER CONAN_COMMAND) + set(multiValueArgs REQUIRES OPTIONS IMPORTS SETTINGS BUILD ENV GENERATORS PROFILE_AUTO) + cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) +endmacro() + +function(conan_cmake_install) + # Calls "conan install" + # Argument BUILD is equivalant to --build={missing, PkgName,...} or + # --build when argument is 'BUILD all' (which builds all packages from source) + # Argument CONAN_COMMAND, to specify the conan path, e.g. in case of running from source + # cmake does not identify conan as command, even if it is +x and it is in the path + parse_arguments(${ARGV}) + + if(CONAN_CMAKE_MULTI) + set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake_multi) + else() + set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake) + endif() + + set(CONAN_BUILD_POLICY "") + foreach(ARG ${ARGUMENTS_BUILD}) + if(${ARG} STREQUAL "all") + set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build) + break() + else() + set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build=${ARG}) + endif() + endforeach() + if(ARGUMENTS_CONAN_COMMAND) + set(conan_command ${ARGUMENTS_CONAN_COMMAND}) + else() + set(conan_command conan) + endif() + set(CONAN_OPTIONS "") + if(ARGUMENTS_CONANFILE) + set(CONANFILE ${CMAKE_CURRENT_SOURCE_DIR}/${ARGUMENTS_CONANFILE}) + # A conan file has been specified - apply specified options as well if provided + foreach(ARG ${ARGUMENTS_OPTIONS}) + set(CONAN_OPTIONS ${CONAN_OPTIONS} -o=${ARG}) + endforeach() + else() + set(CONANFILE ".") + endif() + if(ARGUMENTS_UPDATE) + set(CONAN_INSTALL_UPDATE --update) + endif() + set(CONAN_INSTALL_FOLDER "") + if(ARGUMENTS_INSTALL_FOLDER) + set(CONAN_INSTALL_FOLDER -if=${ARGUMENTS_INSTALL_FOLDER}) + endif() + foreach(ARG ${ARGUMENTS_GENERATORS}) + set(CONAN_GENERATORS ${CONAN_GENERATORS} -g=${ARG}) + endforeach() + foreach(ARG ${ARGUMENTS_ENV}) + set(CONAN_ENV_VARS ${CONAN_ENV_VARS} -e=${ARG}) + endforeach() + set(conan_args install ${CONANFILE} ${settings} ${CONAN_ENV_VARS} ${CONAN_GENERATORS} ${CONAN_BUILD_POLICY} ${CONAN_INSTALL_UPDATE} ${CONAN_OPTIONS} ${CONAN_INSTALL_FOLDER}) + + string (REPLACE ";" " " _conan_args "${conan_args}") + message(STATUS "Conan executing: ${conan_command} ${_conan_args}") + + if(ARGUMENTS_OUTPUT_QUIET) + set(OUTPUT_CONTROL OUTPUT_QUIET) + endif() + + execute_process(COMMAND ${conan_command} ${conan_args} + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_output + ERROR_VARIABLE conan_output + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + + message(STATUS "${conan_output}") + + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan install failed='${return_code}'") + endif() + +endfunction() + + +function(conan_cmake_setup_conanfile) + parse_arguments(${ARGV}) + if(ARGUMENTS_CONANFILE) + # configure_file will make sure cmake re-runs when conanfile is updated + configure_file(${ARGUMENTS_CONANFILE} ${ARGUMENTS_CONANFILE}.junk) + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${ARGUMENTS_CONANFILE}.junk) + else() + conan_cmake_generate_conanfile(${ARGV}) + endif() +endfunction() + +function(conan_cmake_generate_conanfile) + # Generate, writing in disk a conanfile.txt with the requires, options, and imports + # specified as arguments + # This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) + parse_arguments(${ARGV}) + set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") + + file(WRITE ${_FN} "[generators]\ncmake\n\n[requires]\n") + foreach(ARG ${ARGUMENTS_REQUIRES}) + file(APPEND ${_FN} ${ARG} "\n") + endforeach() + + file(APPEND ${_FN} ${ARG} "\n[options]\n") + foreach(ARG ${ARGUMENTS_OPTIONS}) + file(APPEND ${_FN} ${ARG} "\n") + endforeach() + + file(APPEND ${_FN} ${ARG} "\n[imports]\n") + foreach(ARG ${ARGUMENTS_IMPORTS}) + file(APPEND ${_FN} ${ARG} "\n") + endforeach() +endfunction() + + +macro(conan_load_buildinfo) + if(CONAN_CMAKE_MULTI) + set(_CONANBUILDINFO conanbuildinfo_multi.cmake) + else() + set(_CONANBUILDINFO conanbuildinfo.cmake) + endif() + # Checks for the existence of conanbuildinfo.cmake, and loads it + # important that it is macro, so variables defined at parent scope + if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${_CONANBUILDINFO}") + message(STATUS "Conan: Loading ${_CONANBUILDINFO}") + include(${CMAKE_CURRENT_BINARY_DIR}/${_CONANBUILDINFO}) + else() + message(FATAL_ERROR "${_CONANBUILDINFO} doesn't exist in ${CMAKE_CURRENT_BINARY_DIR}") + endif() +endmacro() + + +macro(conan_cmake_run) + parse_arguments(${ARGV}) + + if(CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE AND NOT CONAN_EXPORTED + AND NOT ARGUMENTS_BUILD_TYPE) + set(CONAN_CMAKE_MULTI ON) + message(STATUS "Conan: Using cmake-multi generator") + else() + set(CONAN_CMAKE_MULTI OFF) + endif() + + if(NOT CONAN_EXPORTED) + conan_cmake_setup_conanfile(${ARGV}) + if(CONAN_CMAKE_MULTI) + foreach(CMAKE_BUILD_TYPE "Release" "Debug") + set(ENV{CONAN_IMPORT_PATH} ${CMAKE_BUILD_TYPE}) + conan_cmake_settings(settings ${ARGV}) + conan_cmake_install(SETTINGS ${settings} ${ARGV}) + endforeach() + set(CMAKE_BUILD_TYPE) + else() + conan_cmake_settings(settings ${ARGV}) + conan_cmake_install(SETTINGS ${settings} ${ARGV}) + endif() + endif() + + conan_load_buildinfo() + + if(ARGUMENTS_BASIC_SETUP) + foreach(_option CMAKE_TARGETS KEEP_RPATHS NO_OUTPUT_DIRS) + if(ARGUMENTS_${_option}) + if(${_option} STREQUAL "CMAKE_TARGETS") + list(APPEND _setup_options "TARGETS") + else() + list(APPEND _setup_options ${_option}) + endif() + endif() + endforeach() + conan_basic_setup(${_setup_options}) + endif() +endmacro() + +macro(conan_check) + # Checks conan availability in PATH + # Arguments REQUIRED and VERSION are optional + # Example usage: + # conan_check(VERSION 1.0.0 REQUIRED) + message(STATUS "Conan: checking conan executable in path") + set(options REQUIRED) + set(oneValueArgs VERSION) + cmake_parse_arguments(CONAN "${options}" "${oneValueArgs}" "" ${ARGN}) + + find_program(CONAN_CMD conan) + if(NOT CONAN_CMD AND CONAN_REQUIRED) + message(FATAL_ERROR "Conan executable not found!") + endif() + message(STATUS "Conan: Found program ${CONAN_CMD}") + execute_process(COMMAND ${CONAN_CMD} --version + OUTPUT_VARIABLE CONAN_VERSION_OUTPUT + ERROR_VARIABLE CONAN_VERSION_OUTPUT) + message(STATUS "Conan: Version found ${CONAN_VERSION_OUTPUT}") + + if(DEFINED CONAN_VERSION) + string(REGEX MATCH ".*Conan version ([0-9]+\.[0-9]+\.[0-9]+)" FOO + "${CONAN_VERSION_OUTPUT}") + if(${CMAKE_MATCH_1} VERSION_LESS ${CONAN_VERSION}) + message(FATAL_ERROR "Conan outdated. Installed: ${CONAN_VERSION}, \ + required: ${CONAN_VERSION_REQUIRED}. Consider updating via 'pip \ + install conan --upgrade'.") + endif() + endif() +endmacro() + +macro(conan_add_remote) + # Adds a remote + # Arguments URL and NAME are required, INDEX is optional + # Example usage: + # conan_add_remote(NAME bincrafters INDEX 1 + # URL https://api.bintray.com/conan/bincrafters/public-conan) + set(oneValueArgs URL NAME INDEX) + cmake_parse_arguments(CONAN "" "${oneValueArgs}" "" ${ARGN}) + + if(DEFINED CONAN_INDEX) + set(CONAN_INDEX_ARG "-i ${CONAN_INDEX}") + endif() + + message(STATUS "Conan: Adding ${CONAN_NAME} remote repositoy (${CONAN_URL})") + execute_process(COMMAND ${CONAN_CMD} remote add ${CONAN_NAME} ${CONAN_URL} + ${CONAN_INDEX_ARG} -f) +endmacro() + From 946ac43e5c4a44f37cef60edf8becf48fa37ee72 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Tue, 29 Jan 2019 14:03:02 +0100 Subject: [PATCH 16/42] Added protoc to conan deps --- conanfile.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/conanfile.txt b/conanfile.txt index 7591bc8..c834ab6 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,5 +1,6 @@ [requires] protobuf/3.6.1@bincrafters/stable +protoc_installer/3.6.1@bincrafters/stable catch2/2.4.2@bincrafters/stable [generators] From 542d2df9923247e171c0e221b46c2e38a406de0c Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Tue, 29 Jan 2019 20:14:24 +0100 Subject: [PATCH 17/42] Removed filename string conversion from loading/saving to avoid codepage problems --- source/DataModel.cpp | 22 ++++++++++++++++++---- source/DataModel.h | 4 ++-- source/mainwindow.cpp | 7 ++----- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/source/DataModel.cpp b/source/DataModel.cpp index 216eb8c..eba7f53 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -1,6 +1,8 @@ #include "DataModel.h" #include "DataModel.pb.h" +#include + #include DataModel::DataModel(QObject *parent) @@ -27,7 +29,7 @@ DataModel::DataModel(QObject *parent) connect(&m_genitiv, &GenitivModel::dataChanged, this, &DataModel::genitivModelChanged); } -void DataModel::write(std::ostream &outStream) const +void DataModel::write(const QString &filename) const { ESGRAF48::DataModel dataModel; @@ -41,13 +43,25 @@ void DataModel::write(std::ostream &outStream) const m_genitiv.write(*dataModel.mutable_lateskillsgenitiv()); m_passiv.write(*dataModel.mutable_lateskillspassiv()); - dataModel.SerializeToOstream(&outStream); + QFile outFile(filename); + if (!outFile.open(QIODevice::WriteOnly)) + { + return; + } + + dataModel.SerializeToFileDescriptor(outFile.handle()); } -void DataModel::read(std::istream &inStream) +void DataModel::read(const QString &filename) { + QFile inFile(filename); + if (!inFile.open(QIODevice::ReadOnly)) + { + return; + } + ESGRAF48::DataModel dataModel; - dataModel.ParseFromIstream(&inStream); + dataModel.ParseFromFileDescriptor(inFile.handle()); m_metaData.read(dataModel.metadata()); m_v2Svk.read(dataModel.v2svk()); diff --git a/source/DataModel.h b/source/DataModel.h index 71a9352..42b5294 100644 --- a/source/DataModel.h +++ b/source/DataModel.h @@ -36,8 +36,8 @@ public: std::string toHtml() const; - void write(std::ostream &outStream) const; - void read(std::istream &inStream); + void write(const QString &filename) const; + void read(const QString &filename); signals: void modelChanged(); diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index e91549a..8f0eab0 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -92,8 +92,7 @@ void MainWindow::openFile(const QString &filename) { closeFile(); - std::fstream protoInFile(filename.toStdString(), std::ios::in | std::ios::binary); - m_dataModel.read(protoInFile); + m_dataModel.read(filename); setWindowModified(false); setWindowTitle(filename + "[*]"); @@ -196,9 +195,7 @@ void MainWindow::closeEvent(QCloseEvent *event) void MainWindow::saveFile(const QString &filename) { - std::fstream protoOutFile(filename.toStdString(), - std::ios::out | std::ios::trunc | std::ios::binary); - m_dataModel.write(protoOutFile); + m_dataModel.write(filename); qDebug() << "Wrote" << filename; From 20901898a853ca898eed1a41c3e2f2024256ea86 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Tue, 29 Jan 2019 20:55:16 +0100 Subject: [PATCH 18/42] Show and handle load and save errors --- source/DataModel.cpp | 4 ++-- source/mainwindow.cpp | 21 +++++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/source/DataModel.cpp b/source/DataModel.cpp index eba7f53..eef2e2f 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -46,7 +46,7 @@ void DataModel::write(const QString &filename) const QFile outFile(filename); if (!outFile.open(QIODevice::WriteOnly)) { - return; + throw std::runtime_error("open failed"); } dataModel.SerializeToFileDescriptor(outFile.handle()); @@ -57,7 +57,7 @@ void DataModel::read(const QString &filename) QFile inFile(filename); if (!inFile.open(QIODevice::ReadOnly)) { - return; + throw std::runtime_error("open failed"); } ESGRAF48::DataModel dataModel; diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 8f0eab0..aa6a915 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -85,7 +85,15 @@ void MainWindow::openFile() return; } - openFile(filename); + try + { + openFile(filename); + } + catch (std::exception &e) + { + QString errorMessage = QString("Error loading \"") + filename + "\": " + e.what(); + QMessageBox::critical(this, "Error", errorMessage); + } } void MainWindow::openFile(const QString &filename) @@ -195,7 +203,16 @@ void MainWindow::closeEvent(QCloseEvent *event) void MainWindow::saveFile(const QString &filename) { - m_dataModel.write(filename); + try + { + m_dataModel.write(filename); + } + catch (std::exception &e) + { + QString errorMessage = QString("Error saving \"") + filename + "\": " + e.what(); + QMessageBox::critical(this, "Error", errorMessage); + return; + } qDebug() << "Wrote" << filename; From f42d7eafb0f4225e51a4601eaee7cbcd7f3c41f9 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Tue, 29 Jan 2019 21:19:05 +0100 Subject: [PATCH 19/42] Label save-file-dialog button "Save" instead of "Open" --- source/mainwindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 8f0eab0..8eaf34a 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -117,6 +117,7 @@ void MainWindow::saveFile() void MainWindow::saveFileAs() { QFileDialog saveFilenameDialog(this); + saveFilenameDialog.setAcceptMode(QFileDialog::AcceptSave); saveFilenameDialog.setDefaultSuffix("esgraf48"); saveFilenameDialog.setFileMode(QFileDialog::AnyFile); saveFilenameDialog.setNameFilter("ESGRAF 4-8 (*.esgraf48)"); From b7beced1e5ce13bc8618b7d334c852ca86b39273 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Wed, 30 Jan 2019 08:53:19 +0100 Subject: [PATCH 20/42] Parse command line options platform (and encoding) independent --- source/ESGRAF48.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/source/ESGRAF48.cpp b/source/ESGRAF48.cpp index 1f15804..40b8801 100644 --- a/source/ESGRAF48.cpp +++ b/source/ESGRAF48.cpp @@ -1,18 +1,31 @@ #include "mainwindow.h" #include +#include int main(int argc, char **argv) { QApplication app(argc, argv); + QCoreApplication::setApplicationName("ESGRAF 4-8"); + QCoreApplication::setApplicationVersion("0.1"); + + QCommandLineParser cmdParser; + cmdParser.setApplicationDescription("ESGRAF 4-8"); + cmdParser.addHelpOption(); + cmdParser.addVersionOption(); + cmdParser.addPositionalArgument("filename", "file to open"); + + cmdParser.process(app); + + const QStringList args = cmdParser.positionalArguments(); std::unique_ptr mainWindow; - if (argc < 2) + if (args.empty()) { mainWindow = std::make_unique(nullptr); } else { - mainWindow = std::make_unique(nullptr, argv[1]); + mainWindow = std::make_unique(nullptr, args.at(0)); } mainWindow->show(); From f3249b8720dde82149e6344a08e0f38d0d5fb2c1 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Wed, 30 Jan 2019 20:41:22 +0100 Subject: [PATCH 21/42] Prevent loading of foreign files --- source/DataModel.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/DataModel.cpp b/source/DataModel.cpp index eef2e2f..0b94963 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -46,10 +46,14 @@ void DataModel::write(const QString &filename) const QFile outFile(filename); if (!outFile.open(QIODevice::WriteOnly)) { - throw std::runtime_error("open failed"); + throw std::runtime_error("failed to open file"); } - dataModel.SerializeToFileDescriptor(outFile.handle()); + bool success = dataModel.SerializeToFileDescriptor(outFile.handle()); + if (success == false) + { + throw std::runtime_error("filed to write file"); + } } void DataModel::read(const QString &filename) @@ -57,11 +61,15 @@ void DataModel::read(const QString &filename) QFile inFile(filename); if (!inFile.open(QIODevice::ReadOnly)) { - throw std::runtime_error("open failed"); + throw std::runtime_error("failed to read file"); } ESGRAF48::DataModel dataModel; - dataModel.ParseFromFileDescriptor(inFile.handle()); + bool success = dataModel.ParseFromFileDescriptor(inFile.handle()); + if (success == false) + { + throw std::runtime_error("invalid file format"); + } m_metaData.read(dataModel.metadata()); m_v2Svk.read(dataModel.v2svk()); From eff3b42cb08062a6154d26f3fc352dd891e5c2ed Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Wed, 30 Jan 2019 21:23:26 +0100 Subject: [PATCH 22/42] Added version number and optional build number to build system --- CMakeLists.txt | 3 ++- source/CMakeLists.txt | 20 +++++++++++++++++++- source/ESGRAF48.cpp | 9 ++++++--- source/version.h.in | 4 ++++ 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 source/version.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a8da5b..a731ba0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) include(cmake/conan.cmake) conan_cmake_run(CONANFILE conanfile.txt BASIC_SETUP - BUILD missing) + BUILD missing +) include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) conan_basic_setup() diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 0a0f40f..75f11e5 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,6 +1,24 @@ cmake_minimum_required(VERSION 3.6) -project(ESGRAF48 LANGUAGES CXX) +set(BUILD_VERSION_MAJOR_MINOR 0.1) + +if ($ENV{BUILD_NUMBER}) + set(BUILD_VERSION_PATCH $ENV{BUILD_NUMBER}) +else() + set(BUILD_VERSION_PATCH 0) +endif() + +project(ESGRAF48 + VERSION ${BUILD_VERSION_MAJOR_MINOR}.${BUILD_VERSION_PATCH} + DESCRIPTION "ESGRAF 4-8" + LANGUAGES CXX +) + +configure_file( + version.h.in + version.h +) + find_package(Qt5Widgets REQUIRED) find_package(Qt5PrintSupport REQUIRED) diff --git a/source/ESGRAF48.cpp b/source/ESGRAF48.cpp index 40b8801..9e39190 100644 --- a/source/ESGRAF48.cpp +++ b/source/ESGRAF48.cpp @@ -1,15 +1,18 @@ #include "mainwindow.h" + +#include "version.h" + #include #include int main(int argc, char **argv) { QApplication app(argc, argv); - QCoreApplication::setApplicationName("ESGRAF 4-8"); - QCoreApplication::setApplicationVersion("0.1"); + QCoreApplication::setApplicationName(ESGRAF48_DESCRIPTION); + QCoreApplication::setApplicationVersion(ESGRAF48_VERSION); QCommandLineParser cmdParser; - cmdParser.setApplicationDescription("ESGRAF 4-8"); + cmdParser.setApplicationDescription(ESGRAF48_DESCRIPTION); cmdParser.addHelpOption(); cmdParser.addVersionOption(); cmdParser.addPositionalArgument("filename", "file to open"); diff --git a/source/version.h.in b/source/version.h.in new file mode 100644 index 0000000..dedd89c --- /dev/null +++ b/source/version.h.in @@ -0,0 +1,4 @@ +#pragma once + +#define ESGRAF48_VERSION "@PROJECT_VERSION@" +#define ESGRAF48_DESCRIPTION "@PROJECT_DESCRIPTION@" From 7c717331847ec7e5e689d6464c5c92d77c3c3f82 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Wed, 30 Jan 2019 21:41:03 +0100 Subject: [PATCH 23/42] Added an about dialog with version info --- source/mainwindow.cpp | 11 +++++++++++ source/mainwindow.h | 1 + source/mainwindow.ui | 12 ++++++++++++ 3 files changed, 24 insertions(+) diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index ea846b0..d5f425a 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -1,6 +1,8 @@ #include "mainwindow.h" #include "ui_mainwindow.h" +#include "version.h" + #include #include #include @@ -58,6 +60,8 @@ void MainWindow::setupUi() connect(ui->actionPrint, &QAction::triggered, this, &MainWindow::print); connect(ui->actionExport_PDF, &QAction::triggered, this, qOverload<>(&MainWindow::savePdf)); + connect(ui->actionAbout, &QAction::triggered, this, &MainWindow::aboutDialog); + connect(&m_dataModel, &DataModel::modelChanged, this, &MainWindow::dataModelChanged); } @@ -235,3 +239,10 @@ void MainWindow::savePdf(const QString &filename) printDoc.print(&printer); } + +void MainWindow::aboutDialog() +{ + QString infoString = + QString::fromUtf8(ESGRAF48_DESCRIPTION) + " Version " + QString::fromUtf8(ESGRAF48_VERSION); + QMessageBox::information(this, ESGRAF48_DESCRIPTION, infoString); +} diff --git a/source/mainwindow.h b/source/mainwindow.h index 9675fb7..e250555 100644 --- a/source/mainwindow.h +++ b/source/mainwindow.h @@ -38,6 +38,7 @@ public slots: void print() const; void dataModelChanged(); void savePdf(); + void aboutDialog(); protected: void closeEvent(QCloseEvent *event) override; diff --git a/source/mainwindow.ui b/source/mainwindow.ui index 9622ce3..d8233be 100644 --- a/source/mainwindow.ui +++ b/source/mainwindow.ui @@ -137,7 +137,14 @@ + + + Help + + + + @@ -237,6 +244,11 @@ Export as PDF file + + + About + + From 4e1f9dda795ebcabab6fd263536aac7f00fcf36d Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Wed, 30 Jan 2019 21:42:25 +0100 Subject: [PATCH 24/42] Incremented version number to 0.2 --- source/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 75f11e5..24df849 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.6) -set(BUILD_VERSION_MAJOR_MINOR 0.1) +set(BUILD_VERSION_MAJOR_MINOR 0.2) if ($ENV{BUILD_NUMBER}) set(BUILD_VERSION_PATCH $ENV{BUILD_NUMBER}) From a09e9a53514dba640728ead4547c10374798bc22 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Wed, 30 Jan 2019 23:07:11 +0100 Subject: [PATCH 25/42] Split subtest 1 into four widgets, extracted TPeModel --- source/DataModel.cpp | 8 ++- source/DataModel.h | 4 ++ source/SubTests/V2Svk/CMakeLists.txt | 1 + source/SubTests/V2Svk/TPeModel.cpp | 95 +++++++++++++++++++++++++++ source/SubTests/V2Svk/TPeModel.h | 18 +++++ source/SubTests/V2Svk/V2SvkModel.cpp | 21 +----- source/SubTests/V2Svk/V2SvkWidget.cpp | 11 +++- source/SubTests/V2Svk/V2SvkWidget.h | 2 + source/SubTests/V2Svk/V2SvkWidget.ui | 11 +++- source/mainwindow.cpp | 1 + 10 files changed, 148 insertions(+), 24 deletions(-) create mode 100644 source/SubTests/V2Svk/TPeModel.cpp create mode 100644 source/SubTests/V2Svk/TPeModel.h diff --git a/source/DataModel.cpp b/source/DataModel.cpp index 0b94963..6f4dee1 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -15,6 +15,7 @@ DataModel::DataModel(QObject *parent) , m_akkusativ(this) , m_dativ(this) , m_v2Svk(this) + , m_tPeModel(this) , m_passiv(this) , m_genitiv(this) { @@ -25,6 +26,7 @@ DataModel::DataModel(QObject *parent) connect(&m_akkusativ, &AkkusativModel::dataChanged, this, &DataModel::akkusativModelChanged); connect(&m_dativ, &DativModel::dataChanged, this, &DataModel::dativModelChanged); connect(&m_v2Svk, &V2SvkModel::dataChanged, this, &DataModel::v2SvkModelChanged); + connect(&m_tPeModel, &TPeModel::dataChanged, this, &DataModel::v2SvkModelChanged); connect(&m_passiv, &PassivModel::dataChanged, this, &DataModel::passivModelChanged); connect(&m_genitiv, &GenitivModel::dataChanged, this, &DataModel::genitivModelChanged); } @@ -35,6 +37,7 @@ void DataModel::write(const QString &filename) const m_metaData.write(*dataModel.mutable_metadata()); m_v2Svk.write(*dataModel.mutable_v2svk()); + m_tPeModel.write(*dataModel.mutable_v2svk()); m_verbEnd.write(*dataModel.mutable_verbend()); m_genus.write(*dataModel.mutable_genus()); m_akkusativ.write(*dataModel.mutable_akkusativ()); @@ -73,6 +76,7 @@ void DataModel::read(const QString &filename) m_metaData.read(dataModel.metadata()); m_v2Svk.read(dataModel.v2svk()); + m_tPeModel.read(dataModel.v2svk()); m_verbEnd.read(dataModel.verbend()); m_genus.read(dataModel.genus()); m_akkusativ.read(dataModel.akkusativ()); @@ -149,8 +153,8 @@ void DataModel::dativModelChanged() void DataModel::v2SvkModelChanged() { - m_results.setV2Result(m_v2Svk.getV2Points()); - m_results.setSvkResult(m_v2Svk.getSvkPoints()); + m_results.setV2Result(m_v2Svk.getV2Points() + m_tPeModel.getV2Points()); + m_results.setSvkResult(m_v2Svk.getSvkPoints() + m_tPeModel.getSvkPoints()); emit modelChanged(); } diff --git a/source/DataModel.h b/source/DataModel.h index 42b5294..61037a3 100644 --- a/source/DataModel.h +++ b/source/DataModel.h @@ -7,6 +7,7 @@ #include "AkkusativModel.h" #include "DativModel.h" #include "V2SvkModel.h" +#include "TPeModel.h" #include "PassivModel.h" #include "GenitivModel.h" @@ -25,7 +26,10 @@ public: PluralModel m_plural; AkkusativModel m_akkusativ; DativModel m_dativ; + V2SvkModel m_v2Svk; + TPeModel m_tPeModel; + PassivModel m_passiv; GenitivModel m_genitiv; diff --git a/source/SubTests/V2Svk/CMakeLists.txt b/source/SubTests/V2Svk/CMakeLists.txt index caf6c8c..0269a26 100644 --- a/source/SubTests/V2Svk/CMakeLists.txt +++ b/source/SubTests/V2Svk/CMakeLists.txt @@ -20,6 +20,7 @@ protobuf_generate_cpp(V2Svk_PROTO_SRCS V2Svk_PROTO_HDRS ${V2Svk_PROTO_FILES}) add_library(${PROJECT_NAME} V2SvkWidget.cpp V2SvkModel.cpp + TPeModel.cpp ${UI_HEADERS} ${V2Svk_PROTO_SRCS} ${V2Svk_PROTO_HDRS} diff --git a/source/SubTests/V2Svk/TPeModel.cpp b/source/SubTests/V2Svk/TPeModel.cpp new file mode 100644 index 0000000..2c17da3 --- /dev/null +++ b/source/SubTests/V2Svk/TPeModel.cpp @@ -0,0 +1,95 @@ +#include "TPeModel.h" + +TPeModel::TPeModel(QObject *parent) + : CheckableTestModel(parent) +{ + m_tests = { + {"Temporaladverb Perfekt", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, + {"Verbtrennung", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, + {"SVK: /-e/ o. Stamm", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, + {"Partizip", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, + }; +} + +unsigned int TPeModel::getV2Points() +{ + unsigned int points = 0; + + for (auto testIndex : {0, 1}) + { + const auto &test = m_tests.at(testIndex); + + for (const auto &item : test.items()) + { + if (item.isChecked()) + { + points++; + } + } + } + + return points; +} + +unsigned int TPeModel::getSvkPoints() +{ + unsigned int points = 0; + + for (auto testIndex : {2, 3}) + { + const auto &test = m_tests.at(testIndex); + + for (const auto &item : test.items()) + { + if (item.isChecked()) + { + points++; + } + } + } + + return points; +} + +void TPeModel::write(ESGRAF48::V2SvkModel &model) const +{ + auto writeTwoVals = [&](ESGRAF48::V2SvkModel::TwoEach *modelData, int testIndex) { + if (modelData != nullptr) + { + const auto &testItems = m_tests.at(testIndex).items(); + + modelData->set_affe1(testItems[0].isChecked()); + modelData->set_affe2(testItems[1].isChecked()); + modelData->set_schwein1(testItems[2].isChecked()); + modelData->set_schwein2(testItems[3].isChecked()); + modelData->set_gans1(testItems[4].isChecked()); + modelData->set_gans2(testItems[5].isChecked()); + } + }; + + writeTwoVals(model.mutable_tempperf(), 0); + writeTwoVals(model.mutable_verbtrennung2(), 1); + writeTwoVals(model.mutable_svke2(), 2); + writeTwoVals(model.mutable_partizip(), 3); +} + +void TPeModel::read(const ESGRAF48::V2SvkModel &model) +{ + auto readTwoVals = [&](const ESGRAF48::V2SvkModel::TwoEach &modelData, int testIndex) { + auto &testItems = m_tests.at(testIndex).items(); + + testItems[0].setState(modelData.affe1()); + testItems[1].setState(modelData.affe2()); + testItems[2].setState(modelData.schwein1()); + testItems[3].setState(modelData.schwein2()); + testItems[4].setState(modelData.gans1()); + testItems[5].setState(modelData.gans2()); + }; + + readTwoVals(model.tempperf(), 0); + readTwoVals(model.verbtrennung2(), 1); + readTwoVals(model.svke2(), 2); + readTwoVals(model.partizip(), 3); + + emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); +} diff --git a/source/SubTests/V2Svk/TPeModel.h b/source/SubTests/V2Svk/TPeModel.h new file mode 100644 index 0000000..19a1c12 --- /dev/null +++ b/source/SubTests/V2Svk/TPeModel.h @@ -0,0 +1,18 @@ +#pragma once + +#include "CheckableTestModel.h" +#include "V2SvkModel.pb.h" + +class TPeModel : public CheckableTestModel +{ + Q_OBJECT + +public: + TPeModel(QObject *parent); + + unsigned int getV2Points(); + unsigned int getSvkPoints(); + + void write(ESGRAF48::V2SvkModel &model) const; + void read(const ESGRAF48::V2SvkModel &model); +}; diff --git a/source/SubTests/V2Svk/V2SvkModel.cpp b/source/SubTests/V2Svk/V2SvkModel.cpp index 2196ba4..716f1d4 100644 --- a/source/SubTests/V2Svk/V2SvkModel.cpp +++ b/source/SubTests/V2Svk/V2SvkModel.cpp @@ -21,11 +21,6 @@ V2SvkModel::V2SvkModel(QObject *parent) {"Temporaladverb Präsens", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, {"SKV: /-e/ o. Stamm", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, - - {"Temporaladverb Perfekt", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, - {"Verbtrennung", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, - {"SVK: /-e/ o. Stamm", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, - {"Partizip", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, }; } @@ -33,7 +28,7 @@ unsigned int V2SvkModel::getV2Points() { unsigned int points = 0; - for (auto testIndex : {0, 1, 3, 5, 7, 8}) + for (auto testIndex : {0, 1, 3, 5}) { const auto &test = m_tests.at(testIndex); @@ -53,7 +48,7 @@ unsigned int V2SvkModel::getSvkPoints() { unsigned int points = 0; - for (auto testIndex : {2, 4, 6, 9, 10}) + for (auto testIndex : {2, 4, 6}) { const auto &test = m_tests.at(testIndex); @@ -77,10 +72,6 @@ bool V2SvkModel::isValidIndex(const QModelIndex &index) const return index.column() == 1 || index.column() == 7 || index.column() == 10; case 5: case 6: - case 7: - case 8: - case 9: - case 10: return index.column() < 6; default: return CheckableTestModel::isValidIndex(index); @@ -141,10 +132,6 @@ void V2SvkModel::write(ESGRAF48::V2SvkModel &model) const writeFourVals(model.mutable_svkstamm(), 4); writeTwoVals(model.mutable_temppraes(), 5); writeTwoVals(model.mutable_svke1(), 6); - writeTwoVals(model.mutable_tempperf(), 7); - writeTwoVals(model.mutable_verbtrennung2(), 8); - writeTwoVals(model.mutable_svke2(), 9); - writeTwoVals(model.mutable_partizip(), 10); } void V2SvkModel::read(const ESGRAF48::V2SvkModel &model) @@ -192,10 +179,6 @@ void V2SvkModel::read(const ESGRAF48::V2SvkModel &model) readFourVals(model.svkstamm(), 4); readTwoVals(model.temppraes(), 5); readTwoVals(model.svke1(), 6); - readTwoVals(model.tempperf(), 7); - readTwoVals(model.verbtrennung2(), 8); - readTwoVals(model.svke2(), 9); - readTwoVals(model.partizip(), 10); emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); } diff --git a/source/SubTests/V2Svk/V2SvkWidget.cpp b/source/SubTests/V2Svk/V2SvkWidget.cpp index d6fe544..10d79b4 100644 --- a/source/SubTests/V2Svk/V2SvkWidget.cpp +++ b/source/SubTests/V2Svk/V2SvkWidget.cpp @@ -2,13 +2,15 @@ #include "ui_V2SvkWidget.h" #include "V2SvkModel.h" +#include "TPeModel.h" V2SvkWidget::V2SvkWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::V2SvkWidget) { ui->setupUi(this); - ui->v2SvkTableView->horizontalHeader()->hide(); + ui->wfTableView->horizontalHeader()->hide(); + ui->tpeTableView->horizontalHeader()->hide(); } V2SvkWidget::~V2SvkWidget() @@ -18,5 +20,10 @@ V2SvkWidget::~V2SvkWidget() void V2SvkWidget::setV2SvkModel(V2SvkModel *model) { - ui->v2SvkTableView->setModel(model); + ui->wfTableView->setModel(model); +} + +void V2SvkWidget::setTPeModel(TPeModel *model) +{ + ui->tpeTableView->setModel(model); } diff --git a/source/SubTests/V2Svk/V2SvkWidget.h b/source/SubTests/V2Svk/V2SvkWidget.h index e23cac5..6256e77 100644 --- a/source/SubTests/V2Svk/V2SvkWidget.h +++ b/source/SubTests/V2Svk/V2SvkWidget.h @@ -3,6 +3,7 @@ #include class V2SvkModel; +class TPeModel; namespace Ui { class V2SvkWidget; @@ -20,4 +21,5 @@ public: ~V2SvkWidget(); void setV2SvkModel(V2SvkModel *model); + void setTPeModel(TPeModel *model); }; diff --git a/source/SubTests/V2Svk/V2SvkWidget.ui b/source/SubTests/V2Svk/V2SvkWidget.ui index 73ee028..83a3b71 100644 --- a/source/SubTests/V2Svk/V2SvkWidget.ui +++ b/source/SubTests/V2Svk/V2SvkWidget.ui @@ -15,7 +15,16 @@ - + + + + + + + + + + diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index d5f425a..cadf73e 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -49,6 +49,7 @@ void MainWindow::setupUi() ui->akkusativDativWidget->setAkkusativModel(&m_dataModel.m_akkusativ); ui->akkusativDativWidget->setDativModel(&m_dataModel.m_dativ); ui->v2SvkWidget->setV2SvkModel(&m_dataModel.m_v2Svk); + ui->v2SvkWidget->setTPeModel(&m_dataModel.m_tPeModel); ui->lateSkillsWidget->setPassivModel(&m_dataModel.m_passiv); ui->lateSkillsWidget->setGenitivModel(&m_dataModel.m_genitiv); ui->resultWidget->setModel(&m_dataModel.m_results); From 8678fdb2075aa7a13d8b9bdf85ca83c42c3edfd1 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 31 Jan 2019 20:14:38 +0100 Subject: [PATCH 26/42] Split subtest 1 in four blocks --- source/DataModel.cpp | 30 +++-- source/DataModel.h | 10 +- source/SubTests/V2Svk/CMakeLists.txt | 4 +- source/SubTests/V2Svk/OTModel.cpp | 105 ++++++++++++++++++ source/SubTests/V2Svk/OTModel.h | 18 +++ source/SubTests/V2Svk/TPrModel.cpp | 89 +++++++++++++++ source/SubTests/V2Svk/TPrModel.h | 18 +++ source/SubTests/V2Svk/V2SvkWidget.cpp | 26 ++++- source/SubTests/V2Svk/V2SvkWidget.h | 8 +- .../V2Svk/{V2SvkModel.cpp => WFModel.cpp} | 75 +++---------- .../V2Svk/{V2SvkModel.h => WFModel.h} | 7 +- source/mainwindow.cpp | 6 +- 12 files changed, 311 insertions(+), 85 deletions(-) create mode 100644 source/SubTests/V2Svk/OTModel.cpp create mode 100644 source/SubTests/V2Svk/OTModel.h create mode 100644 source/SubTests/V2Svk/TPrModel.cpp create mode 100644 source/SubTests/V2Svk/TPrModel.h rename source/SubTests/V2Svk/{V2SvkModel.cpp => WFModel.cpp} (57%) rename source/SubTests/V2Svk/{V2SvkModel.h => WFModel.h} (63%) diff --git a/source/DataModel.cpp b/source/DataModel.cpp index 6f4dee1..ab61bed 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -14,8 +14,10 @@ DataModel::DataModel(QObject *parent) , m_results(this) , m_akkusativ(this) , m_dativ(this) - , m_v2Svk(this) - , m_tPeModel(this) + , m_wfModel(this) + , m_otModel(this) + , m_tPrModel(this) + , m_tPeModel(this) , m_passiv(this) , m_genitiv(this) { @@ -25,8 +27,12 @@ DataModel::DataModel(QObject *parent) connect(&m_verbEnd, &VerbEndModel::dataChanged, this, &DataModel::verbEndModelChanged); connect(&m_akkusativ, &AkkusativModel::dataChanged, this, &DataModel::akkusativModelChanged); connect(&m_dativ, &DativModel::dataChanged, this, &DataModel::dativModelChanged); - connect(&m_v2Svk, &V2SvkModel::dataChanged, this, &DataModel::v2SvkModelChanged); + + connect(&m_wfModel, &WFModel::dataChanged, this, &DataModel::v2SvkModelChanged); + connect(&m_otModel, &OTModel::dataChanged, this, &DataModel::v2SvkModelChanged); + connect(&m_tPrModel, &TPrModel::dataChanged, this, &DataModel::v2SvkModelChanged); connect(&m_tPeModel, &TPeModel::dataChanged, this, &DataModel::v2SvkModelChanged); + connect(&m_passiv, &PassivModel::dataChanged, this, &DataModel::passivModelChanged); connect(&m_genitiv, &GenitivModel::dataChanged, this, &DataModel::genitivModelChanged); } @@ -36,8 +42,12 @@ void DataModel::write(const QString &filename) const ESGRAF48::DataModel dataModel; m_metaData.write(*dataModel.mutable_metadata()); - m_v2Svk.write(*dataModel.mutable_v2svk()); + + m_wfModel.write(*dataModel.mutable_v2svk()); + m_otModel.write(*dataModel.mutable_v2svk()); + m_tPrModel.write(*dataModel.mutable_v2svk()); m_tPeModel.write(*dataModel.mutable_v2svk()); + m_verbEnd.write(*dataModel.mutable_verbend()); m_genus.write(*dataModel.mutable_genus()); m_akkusativ.write(*dataModel.mutable_akkusativ()); @@ -75,8 +85,12 @@ void DataModel::read(const QString &filename) } m_metaData.read(dataModel.metadata()); - m_v2Svk.read(dataModel.v2svk()); + + m_wfModel.read(dataModel.v2svk()); + m_otModel.read(dataModel.v2svk()); + m_tPrModel.read(dataModel.v2svk()); m_tPeModel.read(dataModel.v2svk()); + m_verbEnd.read(dataModel.verbend()); m_genus.read(dataModel.genus()); m_akkusativ.read(dataModel.akkusativ()); @@ -153,8 +167,10 @@ void DataModel::dativModelChanged() void DataModel::v2SvkModelChanged() { - m_results.setV2Result(m_v2Svk.getV2Points() + m_tPeModel.getV2Points()); - m_results.setSvkResult(m_v2Svk.getSvkPoints() + m_tPeModel.getSvkPoints()); + m_results.setV2Result(m_wfModel.getV2Points() + m_otModel.getV2Points() + + m_tPrModel.getV2Points() + m_tPeModel.getV2Points()); + m_results.setSvkResult(m_wfModel.getSvkPoints() + m_otModel.getSvkPoints() + + m_tPrModel.getSvkPoints() + m_tPeModel.getSvkPoints()); emit modelChanged(); } diff --git a/source/DataModel.h b/source/DataModel.h index 61037a3..307a93b 100644 --- a/source/DataModel.h +++ b/source/DataModel.h @@ -6,8 +6,12 @@ #include "PluralModel.h" #include "AkkusativModel.h" #include "DativModel.h" -#include "V2SvkModel.h" + +#include "WFModel.h" +#include "OTModel.h" +#include "TPrModel.h" #include "TPeModel.h" + #include "PassivModel.h" #include "GenitivModel.h" @@ -27,7 +31,9 @@ public: AkkusativModel m_akkusativ; DativModel m_dativ; - V2SvkModel m_v2Svk; + WFModel m_wfModel; + OTModel m_otModel; + TPrModel m_tPrModel; TPeModel m_tPeModel; PassivModel m_passiv; diff --git a/source/SubTests/V2Svk/CMakeLists.txt b/source/SubTests/V2Svk/CMakeLists.txt index 0269a26..441c569 100644 --- a/source/SubTests/V2Svk/CMakeLists.txt +++ b/source/SubTests/V2Svk/CMakeLists.txt @@ -19,7 +19,9 @@ protobuf_generate_cpp(V2Svk_PROTO_SRCS V2Svk_PROTO_HDRS ${V2Svk_PROTO_FILES}) add_library(${PROJECT_NAME} V2SvkWidget.cpp - V2SvkModel.cpp + WFModel.cpp + OTModel.cpp + TPrModel.cpp TPeModel.cpp ${UI_HEADERS} ${V2Svk_PROTO_SRCS} diff --git a/source/SubTests/V2Svk/OTModel.cpp b/source/SubTests/V2Svk/OTModel.cpp new file mode 100644 index 0000000..1c0f477 --- /dev/null +++ b/source/SubTests/V2Svk/OTModel.cpp @@ -0,0 +1,105 @@ +#include "OTModel.h" + +OTModel::OTModel(QObject *parent) + : CheckableTestModel(parent) +{ + m_tests = { + {"Objekt-Topikalisierung", + {"Affe", "Affe", "Affe", "Affe", "Schwein", "Schwein", "Schwein", "Schwein", "Gans", + "Gans", "Gans", "Gans"}}, + {"SVK: Stamm", + {"Affe", "Affe", "Affe", "Affe", "Schwein", "Schwein", "Schwein", "Schwein", "Gans", + "Gans", "Gans", "Gans"}}, + }; +} + +unsigned int OTModel::getV2Points() +{ + unsigned int points = 0; + + for (auto testIndex : {0}) + { + const auto &test = m_tests.at(testIndex); + + for (const auto &item : test.items()) + { + if (item.isChecked()) + { + points++; + } + } + } + + return points; +} + +unsigned int OTModel::getSvkPoints() +{ + unsigned int points = 0; + + for (auto testIndex : {1}) + { + const auto &test = m_tests.at(testIndex); + + for (const auto &item : test.items()) + { + if (item.isChecked()) + { + points++; + } + } + } + + return points; +} + +void OTModel::write(ESGRAF48::V2SvkModel &model) const +{ + auto writeFourVals = [&](ESGRAF48::V2SvkModel::FourEach *modelData, int testIndex) { + if (modelData != nullptr) + { + const auto &testItems = m_tests.at(testIndex).items(); + + modelData->set_affe1(testItems[0].isChecked()); + modelData->set_affe2(testItems[1].isChecked()); + modelData->set_affe3(testItems[2].isChecked()); + modelData->set_affe4(testItems[3].isChecked()); + modelData->set_schwein1(testItems[4].isChecked()); + modelData->set_schwein2(testItems[5].isChecked()); + modelData->set_schwein3(testItems[6].isChecked()); + modelData->set_schwein4(testItems[7].isChecked()); + modelData->set_gans1(testItems[8].isChecked()); + modelData->set_gans2(testItems[9].isChecked()); + modelData->set_gans3(testItems[10].isChecked()); + modelData->set_gans4(testItems[11].isChecked()); + } + }; + + writeFourVals(model.mutable_objtop(), 0); + writeFourVals(model.mutable_svkstamm(), 1); +} + +void OTModel::read(const ESGRAF48::V2SvkModel &model) +{ + auto readFourVals = [&](const ESGRAF48::V2SvkModel::FourEach &modelData, int testIndex) { + auto &testItems = m_tests.at(testIndex).items(); + + testItems[0].setState(modelData.affe1()); + testItems[1].setState(modelData.affe2()); + testItems[2].setState(modelData.affe3()); + testItems[3].setState(modelData.affe4()); + testItems[4].setState(modelData.schwein1()); + testItems[5].setState(modelData.schwein2()); + testItems[6].setState(modelData.schwein3()); + testItems[7].setState(modelData.schwein4()); + testItems[8].setState(modelData.gans1()); + testItems[9].setState(modelData.gans2()); + testItems[10].setState(modelData.gans3()); + testItems[11].setState(modelData.gans4()); + }; + + readFourVals(model.objtop(), 0); + readFourVals(model.svkstamm(), 1); + + emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); +} diff --git a/source/SubTests/V2Svk/OTModel.h b/source/SubTests/V2Svk/OTModel.h new file mode 100644 index 0000000..d4b5a49 --- /dev/null +++ b/source/SubTests/V2Svk/OTModel.h @@ -0,0 +1,18 @@ +#pragma once + +#include "CheckableTestModel.h" +#include "V2SvkModel.pb.h" + +class OTModel : public CheckableTestModel +{ + Q_OBJECT + +public: + OTModel(QObject *parent); + + unsigned int getV2Points(); + unsigned int getSvkPoints(); + + void write(ESGRAF48::V2SvkModel &model) const; + void read(const ESGRAF48::V2SvkModel &model); +}; diff --git a/source/SubTests/V2Svk/TPrModel.cpp b/source/SubTests/V2Svk/TPrModel.cpp new file mode 100644 index 0000000..fcf9c01 --- /dev/null +++ b/source/SubTests/V2Svk/TPrModel.cpp @@ -0,0 +1,89 @@ +#include "TPrModel.h" + +TPrModel::TPrModel(QObject *parent) + : CheckableTestModel(parent) +{ + m_tests = { + {"Temporaladverb Präsens", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, + {"SKV: /-e/ o. Stamm", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, + }; +} + +unsigned int TPrModel::getV2Points() +{ + unsigned int points = 0; + + for (auto testIndex : {0}) + { + const auto &test = m_tests.at(testIndex); + + for (const auto &item : test.items()) + { + if (item.isChecked()) + { + points++; + } + } + } + + return points; +} + +unsigned int TPrModel::getSvkPoints() +{ + unsigned int points = 0; + + for (auto testIndex : {1}) + { + const auto &test = m_tests.at(testIndex); + + for (const auto &item : test.items()) + { + if (item.isChecked()) + { + points++; + } + } + } + + return points; +} + +void TPrModel::write(ESGRAF48::V2SvkModel &model) const +{ + auto writeTwoVals = [&](ESGRAF48::V2SvkModel::TwoEach *modelData, int testIndex) { + if (modelData != nullptr) + { + const auto &testItems = m_tests.at(testIndex).items(); + + modelData->set_affe1(testItems[0].isChecked()); + modelData->set_affe2(testItems[1].isChecked()); + modelData->set_schwein1(testItems[2].isChecked()); + modelData->set_schwein2(testItems[3].isChecked()); + modelData->set_gans1(testItems[4].isChecked()); + modelData->set_gans2(testItems[5].isChecked()); + } + }; + + writeTwoVals(model.mutable_temppraes(), 0); + writeTwoVals(model.mutable_svke1(), 1); +} + +void TPrModel::read(const ESGRAF48::V2SvkModel &model) +{ + auto readTwoVals = [&](const ESGRAF48::V2SvkModel::TwoEach &modelData, int testIndex) { + auto &testItems = m_tests.at(testIndex).items(); + + testItems[0].setState(modelData.affe1()); + testItems[1].setState(modelData.affe2()); + testItems[2].setState(modelData.schwein1()); + testItems[3].setState(modelData.schwein2()); + testItems[4].setState(modelData.gans1()); + testItems[5].setState(modelData.gans2()); + }; + + readTwoVals(model.temppraes(), 0); + readTwoVals(model.svke1(), 1); + + emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); +} diff --git a/source/SubTests/V2Svk/TPrModel.h b/source/SubTests/V2Svk/TPrModel.h new file mode 100644 index 0000000..257a576 --- /dev/null +++ b/source/SubTests/V2Svk/TPrModel.h @@ -0,0 +1,18 @@ +#pragma once + +#include "CheckableTestModel.h" +#include "V2SvkModel.pb.h" + +class TPrModel : public CheckableTestModel +{ + Q_OBJECT + +public: + TPrModel(QObject *parent); + + unsigned int getV2Points(); + unsigned int getSvkPoints(); + + void write(ESGRAF48::V2SvkModel &model) const; + void read(const ESGRAF48::V2SvkModel &model); +}; diff --git a/source/SubTests/V2Svk/V2SvkWidget.cpp b/source/SubTests/V2Svk/V2SvkWidget.cpp index 10d79b4..f8974dc 100644 --- a/source/SubTests/V2Svk/V2SvkWidget.cpp +++ b/source/SubTests/V2Svk/V2SvkWidget.cpp @@ -1,15 +1,19 @@ #include "V2SvkWidget.h" #include "ui_V2SvkWidget.h" -#include "V2SvkModel.h" +#include "WFModel.h" +#include "OTModel.h" +#include "TPrModel.h" #include "TPeModel.h" V2SvkWidget::V2SvkWidget(QWidget *parent) - : QWidget(parent) - , ui(new Ui::V2SvkWidget) + : QWidget(parent) + , ui(new Ui::V2SvkWidget) { ui->setupUi(this); - ui->wfTableView->horizontalHeader()->hide(); + ui->wfTableView->horizontalHeader()->hide(); + ui->otTableView->horizontalHeader()->hide(); + ui->tprTableView->horizontalHeader()->hide(); ui->tpeTableView->horizontalHeader()->hide(); } @@ -18,11 +22,21 @@ V2SvkWidget::~V2SvkWidget() delete ui; } -void V2SvkWidget::setV2SvkModel(V2SvkModel *model) +void V2SvkWidget::setWFModel(WFModel *model) { ui->wfTableView->setModel(model); } - + +void V2SvkWidget::setOTModel(OTModel *model) +{ + ui->otTableView->setModel(model); +} + +void V2SvkWidget::setTPrModel(TPrModel *model) +{ + ui->tprTableView->setModel(model); +} + void V2SvkWidget::setTPeModel(TPeModel *model) { ui->tpeTableView->setModel(model); diff --git a/source/SubTests/V2Svk/V2SvkWidget.h b/source/SubTests/V2Svk/V2SvkWidget.h index 6256e77..82a15c9 100644 --- a/source/SubTests/V2Svk/V2SvkWidget.h +++ b/source/SubTests/V2Svk/V2SvkWidget.h @@ -2,7 +2,9 @@ #include -class V2SvkModel; +class WFModel; +class OTModel; +class TPrModel; class TPeModel; namespace Ui { @@ -20,6 +22,8 @@ public: V2SvkWidget(QWidget *parent = nullptr); ~V2SvkWidget(); - void setV2SvkModel(V2SvkModel *model); + void setWFModel(WFModel *model); + void setOTModel(OTModel *model); + void setTPrModel(TPrModel *model); void setTPeModel(TPeModel *model); }; diff --git a/source/SubTests/V2Svk/V2SvkModel.cpp b/source/SubTests/V2Svk/WFModel.cpp similarity index 57% rename from source/SubTests/V2Svk/V2SvkModel.cpp rename to source/SubTests/V2Svk/WFModel.cpp index 716f1d4..fac9098 100644 --- a/source/SubTests/V2Svk/V2SvkModel.cpp +++ b/source/SubTests/V2Svk/WFModel.cpp @@ -1,6 +1,6 @@ -#include "V2SvkModel.h" +#include "WFModel.h" -V2SvkModel::V2SvkModel(QObject *parent) +WFModel::WFModel(QObject *parent) : CheckableTestModel(parent) { m_tests = { @@ -11,24 +11,14 @@ V2SvkModel::V2SvkModel(QObject *parent) {"SVK: /-st/", {"Affe", "Affe", "Affe", "Affe", "Schwein", "Schwein", "Schwein", "Schwein", "Gans", "Gans", "Gans", "Gans"}}, - - {"Objekt-Topikalisierung", - {"Affe", "Affe", "Affe", "Affe", "Schwein", "Schwein", "Schwein", "Schwein", "Gans", - "Gans", "Gans", "Gans"}}, - {"SVK: Stamm", - {"Affe", "Affe", "Affe", "Affe", "Schwein", "Schwein", "Schwein", "Schwein", "Gans", - "Gans", "Gans", "Gans"}}, - - {"Temporaladverb Präsens", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, - {"SKV: /-e/ o. Stamm", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, }; } -unsigned int V2SvkModel::getV2Points() +unsigned int WFModel::getV2Points() { unsigned int points = 0; - for (auto testIndex : {0, 1, 3, 5}) + for (auto testIndex : {0, 1}) { const auto &test = m_tests.at(testIndex); @@ -44,11 +34,11 @@ unsigned int V2SvkModel::getV2Points() return points; } -unsigned int V2SvkModel::getSvkPoints() +unsigned int WFModel::getSvkPoints() { unsigned int points = 0; - for (auto testIndex : {2, 4, 6}) + for (auto testIndex : {2}) { const auto &test = m_tests.at(testIndex); @@ -64,21 +54,17 @@ unsigned int V2SvkModel::getSvkPoints() return points; } -bool V2SvkModel::isValidIndex(const QModelIndex &index) const +bool WFModel::isValidIndex(const QModelIndex &index) const { - switch (index.row()) + if (index.row() == 1) { - case 1: - return index.column() == 1 || index.column() == 7 || index.column() == 10; - case 5: - case 6: - return index.column() < 6; - default: - return CheckableTestModel::isValidIndex(index); + return index.column() == 1 || index.column() == 7 || index.column() == 10; } + + return CheckableTestModel::isValidIndex(index); } -void V2SvkModel::write(ESGRAF48::V2SvkModel &model) const +void WFModel::write(ESGRAF48::V2SvkModel &model) const { auto writeOneVal = [&](ESGRAF48::V2SvkModel::OneEach *modelData, int testIndex) { if (modelData != nullptr) @@ -91,20 +77,6 @@ void V2SvkModel::write(ESGRAF48::V2SvkModel &model) const } }; - auto writeTwoVals = [&](ESGRAF48::V2SvkModel::TwoEach *modelData, int testIndex) { - if (modelData != nullptr) - { - const auto &testItems = m_tests.at(testIndex).items(); - - modelData->set_affe1(testItems[0].isChecked()); - modelData->set_affe2(testItems[1].isChecked()); - modelData->set_schwein1(testItems[2].isChecked()); - modelData->set_schwein2(testItems[3].isChecked()); - modelData->set_gans1(testItems[4].isChecked()); - modelData->set_gans2(testItems[5].isChecked()); - } - }; - auto writeFourVals = [&](ESGRAF48::V2SvkModel::FourEach *modelData, int testIndex) { if (modelData != nullptr) { @@ -127,14 +99,9 @@ void V2SvkModel::write(ESGRAF48::V2SvkModel &model) const writeFourVals(model.mutable_wfrage(), 0); writeOneVal(model.mutable_verbtrennung1(), 1); - writeFourVals(model.mutable_svkst(), 2); - writeFourVals(model.mutable_objtop(), 3); - writeFourVals(model.mutable_svkstamm(), 4); - writeTwoVals(model.mutable_temppraes(), 5); - writeTwoVals(model.mutable_svke1(), 6); } -void V2SvkModel::read(const ESGRAF48::V2SvkModel &model) +void WFModel::read(const ESGRAF48::V2SvkModel &model) { auto readOneVal = [&](const ESGRAF48::V2SvkModel::OneEach &modelData, int testIndex) { auto &testItems = m_tests.at(testIndex).items(); @@ -144,17 +111,6 @@ void V2SvkModel::read(const ESGRAF48::V2SvkModel &model) testItems[10].setState(modelData.gans()); }; - auto readTwoVals = [&](const ESGRAF48::V2SvkModel::TwoEach &modelData, int testIndex) { - auto &testItems = m_tests.at(testIndex).items(); - - testItems[0].setState(modelData.affe1()); - testItems[1].setState(modelData.affe2()); - testItems[2].setState(modelData.schwein1()); - testItems[3].setState(modelData.schwein2()); - testItems[4].setState(modelData.gans1()); - testItems[5].setState(modelData.gans2()); - }; - auto readFourVals = [&](const ESGRAF48::V2SvkModel::FourEach &modelData, int testIndex) { auto &testItems = m_tests.at(testIndex).items(); @@ -174,11 +130,6 @@ void V2SvkModel::read(const ESGRAF48::V2SvkModel &model) readFourVals(model.wfrage(), 0); readOneVal(model.verbtrennung1(), 1); - readFourVals(model.svkst(), 2); - readFourVals(model.objtop(), 3); - readFourVals(model.svkstamm(), 4); - readTwoVals(model.temppraes(), 5); - readTwoVals(model.svke1(), 6); emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); } diff --git a/source/SubTests/V2Svk/V2SvkModel.h b/source/SubTests/V2Svk/WFModel.h similarity index 63% rename from source/SubTests/V2Svk/V2SvkModel.h rename to source/SubTests/V2Svk/WFModel.h index 519508a..647765a 100644 --- a/source/SubTests/V2Svk/V2SvkModel.h +++ b/source/SubTests/V2Svk/WFModel.h @@ -3,12 +3,12 @@ #include "CheckableTestModel.h" #include "V2SvkModel.pb.h" -class V2SvkModel : public CheckableTestModel +class WFModel : public CheckableTestModel { Q_OBJECT public: - V2SvkModel(QObject *parent); + WFModel(QObject *parent); unsigned int getV2Points(); unsigned int getSvkPoints(); @@ -16,6 +16,5 @@ public: void write(ESGRAF48::V2SvkModel &model) const; void read(const ESGRAF48::V2SvkModel &model); -protected: - bool isValidIndex(const QModelIndex &index) const override; + bool isValidIndex(const QModelIndex &index) const; }; diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index cadf73e..9d90d06 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -48,8 +48,12 @@ void MainWindow::setupUi() ui->pluralWidget->setModel(&m_dataModel.m_plural); ui->akkusativDativWidget->setAkkusativModel(&m_dataModel.m_akkusativ); ui->akkusativDativWidget->setDativModel(&m_dataModel.m_dativ); - ui->v2SvkWidget->setV2SvkModel(&m_dataModel.m_v2Svk); + + ui->v2SvkWidget->setWFModel(&m_dataModel.m_wfModel); + ui->v2SvkWidget->setOTModel(&m_dataModel.m_otModel); + ui->v2SvkWidget->setTPrModel(&m_dataModel.m_tPrModel); ui->v2SvkWidget->setTPeModel(&m_dataModel.m_tPeModel); + ui->lateSkillsWidget->setPassivModel(&m_dataModel.m_passiv); ui->lateSkillsWidget->setGenitivModel(&m_dataModel.m_genitiv); ui->resultWidget->setModel(&m_dataModel.m_results); From af6316d3a21b78690988b1126599e3df37122b79 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 31 Jan 2019 20:23:08 +0100 Subject: [PATCH 27/42] Bumped version number --- source/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 24df849..6c4f314 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.6) -set(BUILD_VERSION_MAJOR_MINOR 0.2) +set(BUILD_VERSION_MAJOR_MINOR 0.3) if ($ENV{BUILD_NUMBER}) set(BUILD_VERSION_PATCH $ENV{BUILD_NUMBER}) From baf0cb8dbe14b86bb186c72e555117a76ea89700 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 2 Feb 2019 14:44:01 +0100 Subject: [PATCH 28/42] Set equal size for all row headers --- .../CheckableTestModel/CheckableTestModel.cpp | 63 +++++++++++-------- source/SubTests/Plural/PluralModel.cpp | 12 +--- source/SubTests/Plural/PluralModel.h | 3 - source/SubTests/Plural/PluralWidget.cpp | 3 +- source/SubTests/Plural/PluralWidget.ui | 12 +--- 5 files changed, 42 insertions(+), 51 deletions(-) diff --git a/source/CheckableTestModel/CheckableTestModel.cpp b/source/CheckableTestModel/CheckableTestModel.cpp index 493bd76..9c46e03 100644 --- a/source/CheckableTestModel/CheckableTestModel.cpp +++ b/source/CheckableTestModel/CheckableTestModel.cpp @@ -5,13 +5,13 @@ #include CheckableTestModel::CheckableTestModel(QObject *parent) - : QAbstractTableModel(parent) + : QAbstractTableModel(parent) { } int CheckableTestModel::rowCount(const QModelIndex &) const { - return static_cast(m_tests.size()); + return static_cast(m_tests.size()); } int CheckableTestModel::columnCount(const QModelIndex &) const @@ -20,7 +20,7 @@ int CheckableTestModel::columnCount(const QModelIndex &) const for (const auto &test : m_tests) { - columnCount = std::max(columnCount, static_cast(test.size())); + columnCount = std::max(columnCount, static_cast(test.size())); } return columnCount; @@ -37,17 +37,17 @@ QVariant CheckableTestModel::data(const QModelIndex &index, int role) const { auto &item = getItem(index); - switch (role) - { - case Qt::DisplayRole: - { - return item.getText().c_str(); - } - case Qt::CheckStateRole: - { - return item.isChecked() ? Qt::Checked : Qt::Unchecked; - } - } + switch (role) + { + case Qt::DisplayRole: + { + return item.getText().c_str(); + } + case Qt::CheckStateRole: + { + return item.isChecked() ? Qt::Checked : Qt::Unchecked; + } + } } catch (std::runtime_error &e) { @@ -67,8 +67,7 @@ Qt::ItemFlags CheckableTestModel::flags(const QModelIndex &index) const return Qt::NoItemFlags; } -bool CheckableTestModel::setData( - const QModelIndex &index, const QVariant &value, int role) +bool CheckableTestModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!isValidIndex(index)) { @@ -93,18 +92,33 @@ bool CheckableTestModel::setData( return false; } -QVariant CheckableTestModel::headerData( - int section, Qt::Orientation orientation, int role) const +QVariant CheckableTestModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (role == Qt::DisplayRole && orientation == Qt::Vertical) + switch (orientation) { - if (section < m_tests.size()) + case Qt::Vertical: { - return m_tests.at(section).name(); + switch (role) + { + case Qt::DisplayRole: + { + if (section < m_tests.size()) + { + return m_tests.at(section).name(); + } + } + case Qt::SizeHintRole: + { + return QSize(200, 0); + } + } + break; } + default: + break; } - return QAbstractTableModel::headerData(section, orientation, role); + return QAbstractTableModel::headerData(section, orientation, role); } void CheckableTestModel::write(QJsonObject &json) const @@ -151,8 +165,7 @@ CheckableItems &CheckableTestModel::getItems(const QModelIndex &index) throw std::runtime_error("invalid index"); } -const CheckableItems &CheckableTestModel::getItems( - const QModelIndex &index) const +const CheckableItems &CheckableTestModel::getItems(const QModelIndex &index) const { if (index.row() < m_tests.size()) { @@ -186,7 +199,7 @@ const CheckableItem &CheckableTestModel::getItem(const QModelIndex &index) const unsigned int CheckableTestModel::getPoints() const { - unsigned int points = 0; + unsigned int points = 0; for (const auto &test : m_tests) { diff --git a/source/SubTests/Plural/PluralModel.cpp b/source/SubTests/Plural/PluralModel.cpp index 0ade859..dcd0959 100644 --- a/source/SubTests/Plural/PluralModel.cpp +++ b/source/SubTests/Plural/PluralModel.cpp @@ -5,21 +5,11 @@ PluralModel::PluralModel(QObject *parent) : CheckableTestModel(parent) { - m_tests = {{"", + m_tests = {{"Plural", {"Fisch /-e/", "Banane /-n/", "Bonbon /-s/", "Ei /-er/", "Eimer /-ø/", "Korn UML+/-er/", "Nuss UML+/-e/", "Bär /-en/", "Apfel UML"}}}; } -QVariant PluralModel::data(const QModelIndex &index, int role) const -{ - if (role == Qt::SizeHintRole) - { - return QSize(180, 0); - } - - return CheckableTestModel::data(index, role); -} - void PluralModel::read(const ESGRAF48::PluralModel &model) { auto &testItems = m_tests.at(0).items(); diff --git a/source/SubTests/Plural/PluralModel.h b/source/SubTests/Plural/PluralModel.h index cadeae9..ef1381f 100644 --- a/source/SubTests/Plural/PluralModel.h +++ b/source/SubTests/Plural/PluralModel.h @@ -10,9 +10,6 @@ class PluralModel : public CheckableTestModel public: PluralModel(QObject *parent); - QVariant data( - const QModelIndex &index, int role = Qt::DisplayRole) const override; - void read(const ESGRAF48::PluralModel &model); void write(ESGRAF48::PluralModel &model) const; }; diff --git a/source/SubTests/Plural/PluralWidget.cpp b/source/SubTests/Plural/PluralWidget.cpp index 4776e52..cf78939 100644 --- a/source/SubTests/Plural/PluralWidget.cpp +++ b/source/SubTests/Plural/PluralWidget.cpp @@ -8,6 +8,8 @@ PluralWidget::PluralWidget(QWidget *parent) , ui(new Ui::PluralWidget) { ui->setupUi(this); + + ui->pluralTableView->horizontalHeader()->hide(); } PluralWidget::~PluralWidget() @@ -18,5 +20,4 @@ PluralWidget::~PluralWidget() void PluralWidget::setModel(PluralModel *model) { ui->pluralTableView->setModel(model); - ui->pluralTableView->resizeColumnsToContents(); } diff --git a/source/SubTests/Plural/PluralWidget.ui b/source/SubTests/Plural/PluralWidget.ui index ec1230f..7e78ce4 100644 --- a/source/SubTests/Plural/PluralWidget.ui +++ b/source/SubTests/Plural/PluralWidget.ui @@ -15,17 +15,7 @@ - - - false - - - 120 - - - false - - + From ab862aeaf10fe0caabfd089584c22ec26d596c5c Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 3 Feb 2019 19:53:51 +0100 Subject: [PATCH 29/42] Print most of the table structures --- source/CheckableTestModel/CMakeLists.txt | 3 +- .../CheckableTestModel/CheckableTestModel.cpp | 5 + .../CheckableTestModel/CheckableTestModel.h | 11 +- source/DataModel.cpp | 29 +++- source/DataModel.h | 6 +- source/MetaData/MetaDataModel.cpp | 2 +- source/MetaData/MetaDataModel.h | 2 +- source/PrintableModel/CMakeLists.txt | 2 + source/PrintableModel/PrintableModel.cpp | 87 +++++++++++- source/PrintableModel/PrintableModel.h | 20 ++- source/SubTests/Genus/CMakeLists.txt | 4 +- source/SubTests/Genus/GenusModel.cpp | 4 +- source/SubTests/Genus/GenusModel.h | 4 +- source/SubTests/Plural/CMakeLists.txt | 4 +- source/SubTests/Plural/PluralModel.cpp | 4 +- source/SubTests/Plural/PluralModel.h | 4 +- source/SubTests/V2Svk/CMakeLists.txt | 4 +- source/SubTests/V2Svk/OTModel.cpp | 16 ++- source/SubTests/V2Svk/OTModel.h | 18 ++- source/SubTests/V2Svk/TPeModel.cpp | 16 ++- source/SubTests/V2Svk/TPeModel.h | 18 ++- source/SubTests/V2Svk/TPrModel.cpp | 16 ++- source/SubTests/V2Svk/TPrModel.h | 18 ++- source/SubTests/V2Svk/V2SvkModel.cpp | 126 ++++++++++++++++++ source/SubTests/V2Svk/V2SvkModel.h | 27 ++++ source/SubTests/V2Svk/WFModel.cpp | 121 ++--------------- source/SubTests/V2Svk/WFModel.h | 19 ++- source/SubTests/VerbEnd/CMakeLists.txt | 1 + source/SubTests/VerbEnd/VerbEndModel.cpp | 5 +- source/SubTests/VerbEnd/VerbEndModel.h | 4 +- source/mainwindow.cpp | 14 +- 31 files changed, 411 insertions(+), 203 deletions(-) create mode 100644 source/SubTests/V2Svk/V2SvkModel.cpp create mode 100644 source/SubTests/V2Svk/V2SvkModel.h diff --git a/source/CheckableTestModel/CMakeLists.txt b/source/CheckableTestModel/CMakeLists.txt index 2ce7c3b..c7426fc 100644 --- a/source/CheckableTestModel/CMakeLists.txt +++ b/source/CheckableTestModel/CMakeLists.txt @@ -18,8 +18,9 @@ target_include_directories(${PROJECT_NAME} ) target_link_libraries(${PROJECT_NAME} - PRIVATE + PUBLIC CheckableItem CheckableTest + PRIVATE Qt5::Core ) diff --git a/source/CheckableTestModel/CheckableTestModel.cpp b/source/CheckableTestModel/CheckableTestModel.cpp index aafc5f9..685ea1a 100644 --- a/source/CheckableTestModel/CheckableTestModel.cpp +++ b/source/CheckableTestModel/CheckableTestModel.cpp @@ -187,3 +187,8 @@ unsigned int CheckableTestModel::getPoints() const return points; } + +QString CheckableTestModel::getTitle() const +{ + return m_title; +} diff --git a/source/CheckableTestModel/CheckableTestModel.h b/source/CheckableTestModel/CheckableTestModel.h index 2fd5434..2201cec 100644 --- a/source/CheckableTestModel/CheckableTestModel.h +++ b/source/CheckableTestModel/CheckableTestModel.h @@ -8,6 +8,7 @@ class CheckableTestModel : public QAbstractTableModel Q_OBJECT protected: + QString m_title; CheckableTests m_tests; public: @@ -16,17 +17,17 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data( - const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; - bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole) override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const override; + int role = Qt::DisplayRole) const override; unsigned int getPoints() const; + QString getTitle() const; + protected: virtual bool isValidIndex(const QModelIndex &index) const; diff --git a/source/DataModel.cpp b/source/DataModel.cpp index 8eebb89..0d33a13 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -99,15 +99,38 @@ void DataModel::read(const QString &filename) m_genitiv.read(dataModel.lateskillsgenitiv()); m_passiv.read(dataModel.lateskillspassiv()); } - -void DataModel::printTo(QPainter &painter) const + +void DataModel::printTo(QPrinter &printer) const { - painter.setFont(h1Font()); + QPainter painter; + painter.begin(&printer); + + + painter.setFont(PrintableModel::h1Font()); painter.drawText(0, painter.fontMetrics().lineSpacing(), "ESGRAF 4-8 Auswertungsbogen"); painter.translate(0, 3 * painter.fontMetrics().lineSpacing()); m_metaData.printTo(painter); + m_wfModel.printTo(painter); + m_otModel.printTo(painter); + m_tPrModel.printTo(painter); + m_tPeModel.printTo(painter); + V2SvkModel::printSummary(painter, + m_wfModel.getV2Points() + m_otModel.getV2Points() + + m_tPrModel.getV2Points() + m_tPeModel.getV2Points(), + m_wfModel.getSvkPoints() + m_otModel.getSvkPoints() + + m_tPrModel.getSvkPoints() + m_tPeModel.getSvkPoints()); + + m_verbEnd.printTo(painter); + m_genus.printTo(painter); + + printer.newPage(); + painter.resetTransform(); + + m_plural.printTo(painter); + + painter.end(); } void DataModel::pluralModelChanged() diff --git a/source/DataModel.h b/source/DataModel.h index f99fcc4..aa0fbf3 100644 --- a/source/DataModel.h +++ b/source/DataModel.h @@ -19,9 +19,9 @@ #include "ResultModel.h" -#include +#include -class DataModel : public QObject, public PrintableModel +class DataModel : public QObject { Q_OBJECT @@ -49,7 +49,7 @@ public: void write(const QString &filename) const; void read(const QString &filename); - void printTo(QPainter &painter) const override; + void printTo(QPrinter &printer) const; signals: void modelChanged(); diff --git a/source/MetaData/MetaDataModel.cpp b/source/MetaData/MetaDataModel.cpp index 24efdbd..2342b17 100644 --- a/source/MetaData/MetaDataModel.cpp +++ b/source/MetaData/MetaDataModel.cpp @@ -5,7 +5,7 @@ #include MetaDataModel::MetaDataModel(QObject *parent) - : QAbstractTableModel(parent) + : PrintableModel(parent) { m_dateOfBirth = QDate::currentDate().addYears(-9); m_dateOfTest = QDate::currentDate(); diff --git a/source/MetaData/MetaDataModel.h b/source/MetaData/MetaDataModel.h index 136b463..4ab5f4b 100644 --- a/source/MetaData/MetaDataModel.h +++ b/source/MetaData/MetaDataModel.h @@ -10,7 +10,7 @@ #include #include -class MetaDataModel : public QAbstractTableModel, public PrintableModel +class MetaDataModel : public PrintableModel { Q_OBJECT diff --git a/source/PrintableModel/CMakeLists.txt b/source/PrintableModel/CMakeLists.txt index 0a09f00..842b0f2 100644 --- a/source/PrintableModel/CMakeLists.txt +++ b/source/PrintableModel/CMakeLists.txt @@ -19,6 +19,8 @@ target_include_directories(${PROJECT_NAME} ) target_link_libraries(${PROJECT_NAME} + PUBLIC + CheckableTestModel PRIVATE Qt5::Core Qt5::Widgets diff --git a/source/PrintableModel/PrintableModel.cpp b/source/PrintableModel/PrintableModel.cpp index 21d57a2..85b6ed4 100644 --- a/source/PrintableModel/PrintableModel.cpp +++ b/source/PrintableModel/PrintableModel.cpp @@ -1,5 +1,17 @@ #include "PrintableModel.h" +PrintableModel::PrintableModel(QObject *parent) + : CheckableTestModel(parent) +{ +} + +void PrintableModel::printTo(QPainter &painter) const +{ + printHeader(painter); + printTests(painter); + printSummary(painter); +} + QFont PrintableModel::h1Font() { return QFont("Helvetica", 16); @@ -7,7 +19,7 @@ QFont PrintableModel::h1Font() QFont PrintableModel::h2Font() { - return QFont("Helvetica", 12); + return QFont("Helvetica", 10); } QFont PrintableModel::tableFont() @@ -44,17 +56,12 @@ void PrintableModel::PrintableModel::drawCheckSquare(QPainter &painter, const QR void PrintableModel::drawResultSquare(QPainter &painter, double y, bool rightCell, unsigned int value) { - auto prevPen = painter.pen(); - painter.setPen(tablePen()); - double pageWidth = painter.device()->width(); double cellWidth = 0.03 * pageWidth; - double cellHeight = painter.fontMetrics().lineSpacing(); + double cellHeight = 1.5 * painter.fontMetrics().lineSpacing(); double x = pageWidth - cellWidth - (rightCell ? 0 : 0.04 * pageWidth); drawTextSquare(painter, {x, y, cellWidth, cellHeight}, QString::number(value)); - - painter.setPen(prevPen); } void PrintableModel::drawGreySquare(QPainter &painter, const QRectF &cell) @@ -76,3 +83,69 @@ void PrintableModel::drawGreySquare(QPainter &painter, const QRectF &cell) painter.setBrush(prevBrush); painter.setPen(prevPen); } + +void PrintableModel::drawHeader2(QPainter &painter, const QString &text) +{ + painter.setFont(h2Font()); + painter.drawText(0, 0, text); + painter.translate(0, 0.5 * painter.fontMetrics().lineSpacing()); +} + +void PrintableModel::printHeader(QPainter &painter) const +{ + auto title = getTitle(); + if (!title.isEmpty()) + { + drawHeader2(painter, getTitle()); + } +} + +void PrintableModel::printTests(QPainter &painter) const +{ + painter.setFont(tableFont()); + painter.setPen(tablePen()); + + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); + + double headerWidth = 0.2 * width; + double cellWidth = 0.08 * width; + double rowHeight = height; + + double x = 0; + double y = 0; + for (const auto &test : m_tests) + { + drawTextSquare(painter, {0, y, headerWidth, 2 * rowHeight}, test.name()); + x = headerWidth; + + for (const auto &item : test.items()) + { + drawTextSquare(painter, {x, y, cellWidth, rowHeight}, item.getText().c_str()); + drawCheckSquare(painter, {x, y + rowHeight, cellWidth, rowHeight}, item.isChecked()); + + x += cellWidth; + } + y += rowHeight; + + drawResultSquare(painter, y, true, test.getPoints()); + y += rowHeight; + } + + painter.translate(0, y + rowHeight); +} + +void PrintableModel::printSummary(QPainter &painter) const +{ + painter.setFont(tableFont()); + painter.setPen(tablePen()); + + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); + + painter.drawText(0, 0, 0.85 * width, height, Qt::AlignRight | Qt::AlignVCenter, + "Rohwertpunkte Total:"); + drawResultSquare(painter, 0, true, getPoints()); + + painter.translate(0, 3 * height); +} diff --git a/source/PrintableModel/PrintableModel.h b/source/PrintableModel/PrintableModel.h index ab08433..8dba378 100644 --- a/source/PrintableModel/PrintableModel.h +++ b/source/PrintableModel/PrintableModel.h @@ -1,17 +1,22 @@ #pragma once +#include "CheckableTestModel.h" + #include #include #include #include #include -class PrintableModel +class PrintableModel : public CheckableTestModel { -public: - virtual void printTo(QPainter &painter) const = 0; + Q_OBJECT + +public: + PrintableModel(QObject *parent); + + virtual void printTo(QPainter &painter) const; -protected: static QFont h1Font(); static QFont h2Font(); static QFont tableFont(); @@ -22,4 +27,11 @@ protected: static void drawCheckSquare(QPainter &painter, const QRectF &cell, bool checked); static void drawResultSquare(QPainter &painter, double y, bool rightCell, unsigned int value); static void drawGreySquare(QPainter &painter, const QRectF &cell); + +protected: + static void drawHeader2(QPainter &painter, const QString &text); + + virtual void printHeader(QPainter &painter) const; + virtual void printTests(QPainter &painter) const; + virtual void printSummary(QPainter &painter) const; }; diff --git a/source/SubTests/Genus/CMakeLists.txt b/source/SubTests/Genus/CMakeLists.txt index 5b29b68..b3f1ae3 100644 --- a/source/SubTests/Genus/CMakeLists.txt +++ b/source/SubTests/Genus/CMakeLists.txt @@ -39,9 +39,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE - CheckableItem - CheckableTest - CheckableTestModel + PrintableModel Qt5::Widgets ${Protobuf_LIBRARIES} ) diff --git a/source/SubTests/Genus/GenusModel.cpp b/source/SubTests/Genus/GenusModel.cpp index 3f2278b..faa7460 100644 --- a/source/SubTests/Genus/GenusModel.cpp +++ b/source/SubTests/Genus/GenusModel.cpp @@ -1,8 +1,10 @@ #include "GenusModel.h" GenusModel::GenusModel(QObject *parent) - : CheckableTestModel(parent) + : PrintableModel(parent) { + m_title = "Subtest 3: Genus"; + m_tests = {{"Tiere", {"Tiger", "Bär", "Katze", "Pferd", "Gans", "Elefant", "Affe", "Hund"}}, {"Futter", {"Salat", "Fleisch", "Knochen", "Banane", "Apfel", "Karotte", "Honig", "Zucker"}}, diff --git a/source/SubTests/Genus/GenusModel.h b/source/SubTests/Genus/GenusModel.h index 8261779..fd3faba 100644 --- a/source/SubTests/Genus/GenusModel.h +++ b/source/SubTests/Genus/GenusModel.h @@ -1,9 +1,9 @@ #pragma once -#include "CheckableTestModel.h" +#include "PrintableModel.h" #include "GenusModel.pb.h" -class GenusModel : public CheckableTestModel +class GenusModel : public PrintableModel { Q_OBJECT diff --git a/source/SubTests/Plural/CMakeLists.txt b/source/SubTests/Plural/CMakeLists.txt index 7a6aa58..978e936 100644 --- a/source/SubTests/Plural/CMakeLists.txt +++ b/source/SubTests/Plural/CMakeLists.txt @@ -39,9 +39,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE - CheckableItem - CheckableTest - CheckableTestModel + PrintableModel Qt5::Widgets ${Protobuf_LIBRARIES} ) diff --git a/source/SubTests/Plural/PluralModel.cpp b/source/SubTests/Plural/PluralModel.cpp index dcd0959..5448ed3 100644 --- a/source/SubTests/Plural/PluralModel.cpp +++ b/source/SubTests/Plural/PluralModel.cpp @@ -3,8 +3,10 @@ #include PluralModel::PluralModel(QObject *parent) - : CheckableTestModel(parent) + : PrintableModel(parent) { + m_title = "Subtest 5: Plural"; + m_tests = {{"Plural", {"Fisch /-e/", "Banane /-n/", "Bonbon /-s/", "Ei /-er/", "Eimer /-ø/", "Korn UML+/-er/", "Nuss UML+/-e/", "Bär /-en/", "Apfel UML"}}}; diff --git a/source/SubTests/Plural/PluralModel.h b/source/SubTests/Plural/PluralModel.h index ef1381f..728258d 100644 --- a/source/SubTests/Plural/PluralModel.h +++ b/source/SubTests/Plural/PluralModel.h @@ -1,9 +1,9 @@ #pragma once -#include "CheckableTestModel.h" +#include "PrintableModel.h" #include "PluralModel.pb.h" -class PluralModel : public CheckableTestModel +class PluralModel : public PrintableModel { Q_OBJECT diff --git a/source/SubTests/V2Svk/CMakeLists.txt b/source/SubTests/V2Svk/CMakeLists.txt index 2f758ce..2690a7b 100644 --- a/source/SubTests/V2Svk/CMakeLists.txt +++ b/source/SubTests/V2Svk/CMakeLists.txt @@ -19,6 +19,7 @@ protobuf_generate_cpp(V2Svk_PROTO_SRCS V2Svk_PROTO_HDRS ${V2Svk_PROTO_FILES}) add_library(${PROJECT_NAME} V2SvkWidget.cpp + V2SvkModel.cpp WFModel.cpp OTModel.cpp TPrModel.cpp @@ -42,9 +43,6 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE - CheckableItem - CheckableTest - CheckableTestModel PrintableModel Qt5::Widgets ${Protobuf_LIBRARIES} diff --git a/source/SubTests/V2Svk/OTModel.cpp b/source/SubTests/V2Svk/OTModel.cpp index 1c0f477..6760255 100644 --- a/source/SubTests/V2Svk/OTModel.cpp +++ b/source/SubTests/V2Svk/OTModel.cpp @@ -1,7 +1,7 @@ #include "OTModel.h" OTModel::OTModel(QObject *parent) - : CheckableTestModel(parent) + : V2SvkModel(parent) { m_tests = { {"Objekt-Topikalisierung", @@ -13,7 +13,7 @@ OTModel::OTModel(QObject *parent) }; } -unsigned int OTModel::getV2Points() +unsigned int OTModel::getV2Points() const { unsigned int points = 0; @@ -33,7 +33,7 @@ unsigned int OTModel::getV2Points() return points; } -unsigned int OTModel::getSvkPoints() +unsigned int OTModel::getSvkPoints() const { unsigned int points = 0; @@ -103,3 +103,13 @@ void OTModel::read(const ESGRAF48::V2SvkModel &model) emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); } + +std::set OTModel::v2Tests() const +{ + return {0}; +}; + +std::set OTModel::svkTests() const +{ + return {1}; +}; diff --git a/source/SubTests/V2Svk/OTModel.h b/source/SubTests/V2Svk/OTModel.h index d4b5a49..c9d9e2b 100644 --- a/source/SubTests/V2Svk/OTModel.h +++ b/source/SubTests/V2Svk/OTModel.h @@ -1,18 +1,24 @@ #pragma once -#include "CheckableTestModel.h" +#include "V2SvkModel.h" #include "V2SvkModel.pb.h" -class OTModel : public CheckableTestModel +class OTModel : public V2SvkModel { Q_OBJECT public: OTModel(QObject *parent); - unsigned int getV2Points(); - unsigned int getSvkPoints(); + unsigned int getV2Points() const override; + unsigned int getSvkPoints() const override; - void write(ESGRAF48::V2SvkModel &model) const; - void read(const ESGRAF48::V2SvkModel &model); + void write(ESGRAF48::V2SvkModel &model) const override; + void read(const ESGRAF48::V2SvkModel &model) override; + +protected: + void printHeader(QPainter &) const override {}; + + std::set v2Tests() const override; + std::set svkTests() const override; }; diff --git a/source/SubTests/V2Svk/TPeModel.cpp b/source/SubTests/V2Svk/TPeModel.cpp index 2c17da3..5f66aab 100644 --- a/source/SubTests/V2Svk/TPeModel.cpp +++ b/source/SubTests/V2Svk/TPeModel.cpp @@ -1,7 +1,7 @@ #include "TPeModel.h" TPeModel::TPeModel(QObject *parent) - : CheckableTestModel(parent) + : V2SvkModel(parent) { m_tests = { {"Temporaladverb Perfekt", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, @@ -11,7 +11,7 @@ TPeModel::TPeModel(QObject *parent) }; } -unsigned int TPeModel::getV2Points() +unsigned int TPeModel::getV2Points() const { unsigned int points = 0; @@ -31,7 +31,7 @@ unsigned int TPeModel::getV2Points() return points; } -unsigned int TPeModel::getSvkPoints() +unsigned int TPeModel::getSvkPoints() const { unsigned int points = 0; @@ -93,3 +93,13 @@ void TPeModel::read(const ESGRAF48::V2SvkModel &model) emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); } + +std::set TPeModel::v2Tests() const +{ + return {0, 1}; +}; + +std::set TPeModel::svkTests() const +{ + return {2, 3}; +}; diff --git a/source/SubTests/V2Svk/TPeModel.h b/source/SubTests/V2Svk/TPeModel.h index 19a1c12..60eb7ba 100644 --- a/source/SubTests/V2Svk/TPeModel.h +++ b/source/SubTests/V2Svk/TPeModel.h @@ -1,18 +1,24 @@ #pragma once -#include "CheckableTestModel.h" +#include "V2SvkModel.h" #include "V2SvkModel.pb.h" -class TPeModel : public CheckableTestModel +class TPeModel : public V2SvkModel { Q_OBJECT public: TPeModel(QObject *parent); - unsigned int getV2Points(); - unsigned int getSvkPoints(); + unsigned int getV2Points() const override; + unsigned int getSvkPoints() const override; - void write(ESGRAF48::V2SvkModel &model) const; - void read(const ESGRAF48::V2SvkModel &model); + void write(ESGRAF48::V2SvkModel &model) const override; + void read(const ESGRAF48::V2SvkModel &model) override; + +protected: + void printHeader(QPainter &) const override {}; + + std::set v2Tests() const override; + std::set svkTests() const override; }; diff --git a/source/SubTests/V2Svk/TPrModel.cpp b/source/SubTests/V2Svk/TPrModel.cpp index fcf9c01..995b584 100644 --- a/source/SubTests/V2Svk/TPrModel.cpp +++ b/source/SubTests/V2Svk/TPrModel.cpp @@ -1,7 +1,7 @@ #include "TPrModel.h" TPrModel::TPrModel(QObject *parent) - : CheckableTestModel(parent) + : V2SvkModel(parent) { m_tests = { {"Temporaladverb Präsens", {"Affe", "Affe", "Schwein", "Schwein", "Gans", "Gans"}}, @@ -9,7 +9,7 @@ TPrModel::TPrModel(QObject *parent) }; } -unsigned int TPrModel::getV2Points() +unsigned int TPrModel::getV2Points() const { unsigned int points = 0; @@ -29,7 +29,7 @@ unsigned int TPrModel::getV2Points() return points; } -unsigned int TPrModel::getSvkPoints() +unsigned int TPrModel::getSvkPoints() const { unsigned int points = 0; @@ -87,3 +87,13 @@ void TPrModel::read(const ESGRAF48::V2SvkModel &model) emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); } + +std::set TPrModel::v2Tests() const +{ + return {0}; +}; + +std::set TPrModel::svkTests() const +{ + return {1}; +}; diff --git a/source/SubTests/V2Svk/TPrModel.h b/source/SubTests/V2Svk/TPrModel.h index 257a576..9047cbf 100644 --- a/source/SubTests/V2Svk/TPrModel.h +++ b/source/SubTests/V2Svk/TPrModel.h @@ -1,18 +1,24 @@ #pragma once -#include "CheckableTestModel.h" +#include "V2SvkModel.h" #include "V2SvkModel.pb.h" -class TPrModel : public CheckableTestModel +class TPrModel : public V2SvkModel { Q_OBJECT public: TPrModel(QObject *parent); - unsigned int getV2Points(); - unsigned int getSvkPoints(); + unsigned int getV2Points() const override; + unsigned int getSvkPoints() const override; - void write(ESGRAF48::V2SvkModel &model) const; - void read(const ESGRAF48::V2SvkModel &model); + void write(ESGRAF48::V2SvkModel &model) const override; + void read(const ESGRAF48::V2SvkModel &model) override; + +protected: + void printHeader(QPainter &) const override{}; + + std::set v2Tests() const override; + std::set svkTests() const override; }; diff --git a/source/SubTests/V2Svk/V2SvkModel.cpp b/source/SubTests/V2Svk/V2SvkModel.cpp new file mode 100644 index 0000000..5db51d4 --- /dev/null +++ b/source/SubTests/V2Svk/V2SvkModel.cpp @@ -0,0 +1,126 @@ +#include "V2SvkModel.h" + +V2SvkModel::V2SvkModel(QObject *parent) + : PrintableModel(parent) +{ +} + +void V2SvkModel::printTests(QPainter &painter) const +{ + painter.setFont(tableFont()); + painter.setPen(tablePen()); + + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); + + auto v2TestIndices = v2Tests(); + auto svkTestIndices = svkTests(); + + double x = 0; + double y = 0; + auto testIndex = 0; + for (const auto &test : m_tests) + { + double rowHeaderWidth = 0.2 * width; + double resultCellWidth = test.size() > 8 ? 0.04 * width : 0.08 * width; + double rowHeight = height; + + if (testIndex == 0) + { + drawTextSquare(painter, {x, y, rowHeaderWidth, 2 * rowHeight}, test.name()); + x += rowHeaderWidth; + + std::vector> columnHeaders; + for (const auto &item : test.items()) + { + const auto &itemText = item.getText(); + if (!columnHeaders.empty() && columnHeaders.back().first == itemText) + { + columnHeaders.back().second++; + } + else + { + columnHeaders.emplace_back(itemText, 1); + } + } + + for (const auto &columnHeader : columnHeaders) + { + double cellWidth = columnHeader.second * resultCellWidth; + drawTextSquare(painter, {x, y, cellWidth, rowHeight}, columnHeader.first.c_str()); + x += cellWidth; + } + x = rowHeaderWidth; + y += rowHeight; + } + else + { + drawTextSquare(painter, {x, y, rowHeaderWidth, rowHeight}, test.name()); + x += rowHeaderWidth; + } + + unsigned int emptyItemsStack = 0; + for (const auto &item : test.items()) + { + if (item.getText().empty()) + { + emptyItemsStack++; + } + else + { + if (emptyItemsStack > 0) + { + drawGreySquare(painter, {x - emptyItemsStack * resultCellWidth, y, + emptyItemsStack * resultCellWidth, rowHeight}); + emptyItemsStack = 0; + } + + drawCheckSquare(painter, {x, y, resultCellWidth, rowHeight}, item.isChecked()); + } + x += resultCellWidth; + } + if (emptyItemsStack > 0) + { + drawGreySquare(painter, {x - emptyItemsStack * resultCellWidth, y, + emptyItemsStack * resultCellWidth, rowHeight}); + emptyItemsStack = 0; + } + + if (v2TestIndices.find(testIndex) != v2TestIndices.end()) + { + drawResultSquare(painter, y, false, test.getPoints()); + } + + if (svkTestIndices.find(testIndex) != svkTestIndices.end()) + { + drawResultSquare(painter, y, true, test.getPoints()); + } + + x = 0; + y += rowHeight; + + testIndex++; + } + + x = 0; + y += height; + + painter.translate(0, y); +} + +void V2SvkModel::printSummary(QPainter &painter, unsigned int v2Points, unsigned int svkPoints) +{ + painter.setFont(PrintableModel::tableFont()); + painter.setPen(PrintableModel::tablePen()); + + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); + + painter.drawText(0, 0, 0.85 * width, height, Qt::AlignRight | Qt::AlignVCenter, + "Rohwertpunkte Total:"); + PrintableModel::drawResultSquare(painter, 0, false, v2Points); + PrintableModel::drawResultSquare(painter, 0, true, svkPoints); + + painter.translate(0, 3 * height); +} + diff --git a/source/SubTests/V2Svk/V2SvkModel.h b/source/SubTests/V2Svk/V2SvkModel.h new file mode 100644 index 0000000..87af510 --- /dev/null +++ b/source/SubTests/V2Svk/V2SvkModel.h @@ -0,0 +1,27 @@ +#pragma once + +#include "PrintableModel.h" +#include "V2SvkModel.pb.h" + +class V2SvkModel : public PrintableModel +{ + Q_OBJECT + +public: + V2SvkModel(QObject *parent); + + virtual unsigned int getV2Points() const = 0; + virtual unsigned int getSvkPoints() const = 0; + + virtual void write(ESGRAF48::V2SvkModel &model) const = 0; + virtual void read(const ESGRAF48::V2SvkModel &model) = 0; + + static void printSummary(QPainter &painter, unsigned int v2Points, unsigned int svkPoints); + +protected: + void printTests(QPainter &painter) const override; + void printSummary(QPainter &painter) const override {}; + + virtual std::set v2Tests() const = 0; + virtual std::set svkTests() const = 0; +}; diff --git a/source/SubTests/V2Svk/WFModel.cpp b/source/SubTests/V2Svk/WFModel.cpp index dde665a..487a5dc 100644 --- a/source/SubTests/V2Svk/WFModel.cpp +++ b/source/SubTests/V2Svk/WFModel.cpp @@ -1,8 +1,10 @@ #include "WFModel.h" WFModel::WFModel(QObject *parent) - : CheckableTestModel(parent) + : V2SvkModel(parent) { + m_title = "Subtest 1: Verbzweitstellungsregel (V2) und Subjekt-Verb-Kontrollregel (SVK)"; + m_tests = { {"W-Frage", {"Affe", "Affe", "Affe", "Affe", "Schwein", "Schwein", "Schwein", "Schwein", "Gans", @@ -134,115 +136,12 @@ void WFModel::read(const ESGRAF48::V2SvkModel &model) emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); } -void WFModel::printTo(QPainter &painter) const +std::set WFModel::v2Tests() const { - painter.setFont(h2Font()); + return {0, 1}; +}; - painter.drawText( - 0, 0, "Subtest 1: Verbzweitstellungsregel (V2) und Subjekt-Verb-Kontrollregel (SVK)"); - - painter.setFont(tableFont()); - painter.setPen(tablePen()); - - auto width = painter.device()->width(); - auto height = 1.5 * painter.fontMetrics().lineSpacing(); - - std::set blockStarters = {0, 3, 5, 7}; - std::set v2Tests = {0, 1, 3, 5, 7, 8}; - std::set svkTests = {2, 4, 6, 9, 10}; - - double x = 0; - double y = 0; - auto testIndex = 0; - for (const auto &test : m_tests) - { - double rowHeaderWidth = 0.2 * width; - double resultCellWidth = test.size() > 8 ? 0.05 * width : 0.1 * width; - double rowHeight = height; - - if (blockStarters.find(testIndex) != blockStarters.end()) - { - y += rowHeight; - drawTextSquare(painter, {x, y, rowHeaderWidth, 2 * rowHeight}, test.name()); - x += rowHeaderWidth; - - std::vector> columnHeaders; - for (const auto &item : test.items()) - { - const auto &itemText = item.getText(); - if (!columnHeaders.empty() && columnHeaders.back().first == itemText) - { - columnHeaders.back().second++; - } - else - { - columnHeaders.emplace_back(itemText, 1); - } - } - - for (const auto &columnHeader : columnHeaders) - { - double cellWidth = columnHeader.second * resultCellWidth; - drawTextSquare(painter, {x, y, cellWidth, rowHeight}, columnHeader.first.c_str()); - x += cellWidth; - } - x = rowHeaderWidth; - y += rowHeight; - } - else - { - drawTextSquare(painter, {x, y, rowHeaderWidth, rowHeight}, test.name()); - x += rowHeaderWidth; - } - - unsigned int emptyItemsStack = 0; - for (const auto &item : test.items()) - { - if (item.getText().empty()) - { - emptyItemsStack++; - } - else - { - if (emptyItemsStack > 0) - { - drawGreySquare(painter, {x - emptyItemsStack * resultCellWidth, y, - emptyItemsStack * resultCellWidth, rowHeight}); - emptyItemsStack = 0; - } - - drawCheckSquare(painter, {x, y, resultCellWidth, rowHeight}, item.isChecked()); - } - x += resultCellWidth; - } - if (emptyItemsStack > 0) - { - drawGreySquare(painter, {x - emptyItemsStack * resultCellWidth, y, - emptyItemsStack * resultCellWidth, rowHeight}); - emptyItemsStack = 0; - } - - if (v2Tests.find(testIndex) != v2Tests.end()) - { - drawResultSquare(painter, y, false, test.getPoints()); - } - - if (svkTests.find(testIndex) != svkTests.end()) - { - drawResultSquare(painter, y, true, test.getPoints()); - } - - x = 0; - y += rowHeight; - - testIndex++; - } - - x = 0; - y += height; - - painter.drawText(x, y, 0.85 * width, height, Qt::AlignRight | Qt::AlignVCenter, - "Rohwertpunkte Total:"); - drawResultSquare(painter, y, false, getV2Points()); - drawResultSquare(painter, y, true, getSvkPoints()); -} +std::set WFModel::svkTests() const +{ + return {2}; +}; diff --git a/source/SubTests/V2Svk/WFModel.h b/source/SubTests/V2Svk/WFModel.h index 9f2fa28..a3d801d 100644 --- a/source/SubTests/V2Svk/WFModel.h +++ b/source/SubTests/V2Svk/WFModel.h @@ -1,25 +1,24 @@ #pragma once -#include "PrintableModel.h" - -#include "CheckableTestModel.h" +#include "V2SvkModel.h" #include "V2SvkModel.pb.h" -class WFModel : public CheckableTestModel, public PrintableModel +class WFModel : public V2SvkModel { Q_OBJECT public: WFModel(QObject *parent); - unsigned int getV2Points() const; - unsigned int getSvkPoints() const; + unsigned int getV2Points() const override; + unsigned int getSvkPoints() const override; - void write(ESGRAF48::V2SvkModel &model) const; - void read(const ESGRAF48::V2SvkModel &model); - - void printTo(QPainter &painter) const override; + void write(ESGRAF48::V2SvkModel &model) const override; + void read(const ESGRAF48::V2SvkModel &model) override; protected: + std::set v2Tests() const override; + std::set svkTests() const override; + bool isValidIndex(const QModelIndex &index) const override; }; diff --git a/source/SubTests/VerbEnd/CMakeLists.txt b/source/SubTests/VerbEnd/CMakeLists.txt index 1302223..135ab66 100644 --- a/source/SubTests/VerbEnd/CMakeLists.txt +++ b/source/SubTests/VerbEnd/CMakeLists.txt @@ -42,6 +42,7 @@ target_link_libraries(${PROJECT_NAME} CheckableItem CheckableTest CheckableTestModel + PrintableModel Qt5::Widgets ${Protobuf_LIBRARIES} ) diff --git a/source/SubTests/VerbEnd/VerbEndModel.cpp b/source/SubTests/VerbEnd/VerbEndModel.cpp index dea4d95..6aa3503 100644 --- a/source/SubTests/VerbEnd/VerbEndModel.cpp +++ b/source/SubTests/VerbEnd/VerbEndModel.cpp @@ -1,8 +1,10 @@ #include "VerbEndModel.h" VerbEndModel::VerbEndModel(QObject *parent) - : CheckableTestModel(parent) + : PrintableModel(parent) { + m_title = "Subtest 2: Verbendstellungsregel (VE)"; + m_tests = { { "Telefonat", { "Kausal", "Kausal", "Relativ", "Kausal", "Final", "Temporal", "Temporal" } }, @@ -98,3 +100,4 @@ void VerbEndModel::read(const ESGRAF48::VerbEndModel &model) emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); } + diff --git a/source/SubTests/VerbEnd/VerbEndModel.h b/source/SubTests/VerbEnd/VerbEndModel.h index cf6342a..8baee48 100644 --- a/source/SubTests/VerbEnd/VerbEndModel.h +++ b/source/SubTests/VerbEnd/VerbEndModel.h @@ -1,9 +1,9 @@ #pragma once -#include "CheckableTestModel.h" +#include "PrintableModel.h" #include "VerbEndModel.pb.h" -class VerbEndModel : public CheckableTestModel +class VerbEndModel : public PrintableModel { Q_OBJECT diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 7e96907..3a29063 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -178,12 +178,7 @@ void MainWindow::print() const return; } - QPainter painter; - painter.begin(&printer); - - m_dataModel.printTo(painter); - - painter.end(); + m_dataModel.printTo(printer); } void MainWindow::dataModelChanged() @@ -242,12 +237,7 @@ void MainWindow::savePdf(const QString &filename) printer.setPageMargins(20, 20, 20, 20, QPrinter::Millimeter); printer.setOutputFileName(filename); - QPainter painter; - painter.begin(&printer); - - m_dataModel.printTo(painter); - - painter.end(); + m_dataModel.printTo(printer); } void MainWindow::aboutDialog() From 1695174303adb50c98cd0be6e3ac8926c227d674 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Tue, 5 Feb 2019 21:32:13 +0100 Subject: [PATCH 30/42] Added fat lines around summary squares --- source/PrintableModel/PrintableModel.cpp | 24 +++++++++++-- source/PrintableModel/PrintableModel.h | 2 ++ source/SubTests/V2Svk/V2SvkModel.cpp | 8 +++-- source/SubTests/VerbEnd/VerbEndModel.cpp | 43 +++++++++++++++++++----- source/SubTests/VerbEnd/VerbEndModel.h | 5 +++ 5 files changed, 67 insertions(+), 15 deletions(-) diff --git a/source/PrintableModel/PrintableModel.cpp b/source/PrintableModel/PrintableModel.cpp index 85b6ed4..97b3fd8 100644 --- a/source/PrintableModel/PrintableModel.cpp +++ b/source/PrintableModel/PrintableModel.cpp @@ -32,6 +32,11 @@ QPen PrintableModel::tablePen() return QPen(Qt::black, 1, Qt::SolidLine); } +QPen PrintableModel::resultPen() +{ + return QPen(Qt::black, 2, Qt::SolidLine); +} + void PrintableModel::drawTextSquare(QPainter &painter, const QRectF &cell, const QString &text) { auto prevPen = painter.pen(); @@ -47,6 +52,19 @@ void PrintableModel::drawTextSquare(QPainter &painter, const QRectF &cell, const painter.setPen(prevPen); } +void PrintableModel::drawNumberSquare(QPainter &painter, double x, double y, int number) +{ + QRectF cell = {x, y, 0.03 * painter.device()->width(), + 1.5 * painter.fontMetrics().lineSpacing()}; + + painter.drawText(cell, Qt::AlignCenter, QString::number(number)); + + painter.drawLine(cell.topLeft(), cell.topRight()); + painter.drawLine(cell.topRight(), cell.bottomRight()); + painter.drawLine(cell.bottomRight(), cell.bottomLeft()); + painter.drawLine(cell.bottomLeft(), cell.topLeft()); +} + void PrintableModel::PrintableModel::drawCheckSquare(QPainter &painter, const QRectF &cell, bool checked) { @@ -138,14 +156,14 @@ void PrintableModel::printTests(QPainter &painter) const void PrintableModel::printSummary(QPainter &painter) const { painter.setFont(tableFont()); - painter.setPen(tablePen()); auto width = painter.device()->width(); auto height = 1.5 * painter.fontMetrics().lineSpacing(); - painter.drawText(0, 0, 0.85 * width, height, Qt::AlignRight | Qt::AlignVCenter, + painter.drawText(0, 0, 0.95 * width, height, Qt::AlignRight | Qt::AlignVCenter, "Rohwertpunkte Total:"); - drawResultSquare(painter, 0, true, getPoints()); + painter.setPen(resultPen()); + drawNumberSquare(painter, 0.97 * width, 0, getPoints()); painter.translate(0, 3 * height); } diff --git a/source/PrintableModel/PrintableModel.h b/source/PrintableModel/PrintableModel.h index 8dba378..e647585 100644 --- a/source/PrintableModel/PrintableModel.h +++ b/source/PrintableModel/PrintableModel.h @@ -22,8 +22,10 @@ public: static QFont tableFont(); static QPen tablePen(); + static QPen resultPen(); static void drawTextSquare(QPainter &painter, const QRectF &cell, const QString &text); + static void drawNumberSquare(QPainter &painter, double x, double y, int number); static void drawCheckSquare(QPainter &painter, const QRectF &cell, bool checked); static void drawResultSquare(QPainter &painter, double y, bool rightCell, unsigned int value); static void drawGreySquare(QPainter &painter, const QRectF &cell); diff --git a/source/SubTests/V2Svk/V2SvkModel.cpp b/source/SubTests/V2Svk/V2SvkModel.cpp index 5db51d4..5416064 100644 --- a/source/SubTests/V2Svk/V2SvkModel.cpp +++ b/source/SubTests/V2Svk/V2SvkModel.cpp @@ -116,10 +116,12 @@ void V2SvkModel::printSummary(QPainter &painter, unsigned int v2Points, unsigned auto width = painter.device()->width(); auto height = 1.5 * painter.fontMetrics().lineSpacing(); - painter.drawText(0, 0, 0.85 * width, height, Qt::AlignRight | Qt::AlignVCenter, + painter.drawText(0, 0, 0.91 * width, height, Qt::AlignRight | Qt::AlignVCenter, "Rohwertpunkte Total:"); - PrintableModel::drawResultSquare(painter, 0, false, v2Points); - PrintableModel::drawResultSquare(painter, 0, true, svkPoints); + + painter.setPen(resultPen()); + drawNumberSquare(painter, 0.93 * width, 0, v2Points); + drawNumberSquare(painter, 0.97 * width, 0, svkPoints); painter.translate(0, 3 * height); } diff --git a/source/SubTests/VerbEnd/VerbEndModel.cpp b/source/SubTests/VerbEnd/VerbEndModel.cpp index 6aa3503..afc21cc 100644 --- a/source/SubTests/VerbEnd/VerbEndModel.cpp +++ b/source/SubTests/VerbEnd/VerbEndModel.cpp @@ -1,17 +1,14 @@ #include "VerbEndModel.h" VerbEndModel::VerbEndModel(QObject *parent) - : PrintableModel(parent) + : PrintableModel(parent) { m_title = "Subtest 2: Verbendstellungsregel (VE)"; - m_tests = { { "Telefonat", - { "Kausal", "Kausal", "Relativ", "Kausal", - "Final", "Temporal", "Temporal" } }, - { "Zaubertrick", { "Relativ", "Final", "Kausal", "Final", - "Temporal", "Kausal", "Temporal" } }, - { "Zauberregel", { "Temporal", "Kausal", "Final", "Relativ", - "Temporal", "Relativ" } } }; + m_tests = { + {"Telefonat", {"Kausal", "Kausal", "Relativ", "Kausal", "Final", "Temporal", "Temporal"}}, + {"Zaubertrick", {"Relativ", "Final", "Kausal", "Final", "Temporal", "Kausal", "Temporal"}}, + {"Zauberregel", {"Temporal", "Kausal", "Final", "Relativ", "Temporal", "Relativ"}}}; } void VerbEndModel::write(ESGRAF48::VerbEndModel &model) const @@ -100,4 +97,32 @@ void VerbEndModel::read(const ESGRAF48::VerbEndModel &model) emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); } - + +unsigned int VerbEndModel::getKausalPoints() const +{ + auto points = [&](unsigned int testId, unsigned int itemId) { + return m_tests.at(testId).items().at(itemId).points(); + }; + + return points(0, 0) + points(0, 1) + points(0, 3) + points(1, 2) + points(1, 5) + points(2, 1); +} + +void VerbEndModel::printSummary(QPainter &painter) const +{ + painter.setFont(tableFont()); + + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); + + painter.drawText(0, 0, 0.71 * width, height, Qt::AlignRight | Qt::AlignVCenter, + "Rohwertpunkte Kausalsätze:"); + painter.drawText(0, 0, 0.95 * width, height, Qt::AlignRight | Qt::AlignVCenter, + "Rohwertpunkte Total:"); + + drawNumberSquare(painter, 0.73 * width, 0, getKausalPoints()); + + painter.setPen(resultPen()); + drawNumberSquare(painter, 0.97 * width, 0, getKausalPoints()); + + painter.translate(0, 3 * height); +} diff --git a/source/SubTests/VerbEnd/VerbEndModel.h b/source/SubTests/VerbEnd/VerbEndModel.h index 8baee48..0211e4f 100644 --- a/source/SubTests/VerbEnd/VerbEndModel.h +++ b/source/SubTests/VerbEnd/VerbEndModel.h @@ -12,4 +12,9 @@ public: void write(ESGRAF48::VerbEndModel &model) const; void read(const ESGRAF48::VerbEndModel &model); + + unsigned int getKausalPoints() const; + +protected: + void printSummary(QPainter &painter) const override; }; From 57fe4256e2905fc4bbd6fdb6717acbb5a3995314 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Tue, 5 Feb 2019 22:06:43 +0100 Subject: [PATCH 31/42] Print akkusativ and dativ model --- source/DataModel.cpp | 2 ++ source/SubTests/AkkusativDativ/AkkusativModel.cpp | 7 ++++++- source/SubTests/AkkusativDativ/AkkusativModel.h | 7 +++++-- source/SubTests/AkkusativDativ/CMakeLists.txt | 4 +--- source/SubTests/AkkusativDativ/DativModel.cpp | 2 +- source/SubTests/AkkusativDativ/DativModel.h | 7 +++++-- 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/source/DataModel.cpp b/source/DataModel.cpp index 0d33a13..b674978 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -128,6 +128,8 @@ void DataModel::printTo(QPrinter &printer) const printer.newPage(); painter.resetTransform(); + m_akkusativ.printTo(painter); + m_dativ.printTo(painter); m_plural.printTo(painter); painter.end(); diff --git a/source/SubTests/AkkusativDativ/AkkusativModel.cpp b/source/SubTests/AkkusativDativ/AkkusativModel.cpp index 79d2c31..368d297 100644 --- a/source/SubTests/AkkusativDativ/AkkusativModel.cpp +++ b/source/SubTests/AkkusativDativ/AkkusativModel.cpp @@ -1,7 +1,7 @@ #include "AkkusativModel.h" AkkusativModel::AkkusativModel(QObject *parent) - : CheckableTestModel(parent) + : PrintableModel(parent) { m_tests = {{"Akkusativ Nominalphrase", {"Tiger", "Katze", "Affe", "Gans", "Bär", "Pferd", "Hund", "Elefant"}}, @@ -105,3 +105,8 @@ void AkkusativModel::write(ESGRAF48::AkkusativModel &model) const futterModel->set_zucker(testItems[7].isChecked()); } } + +void AkkusativModel::printHeader(QPainter &painter) const +{ + drawHeader2(painter, "Subtest 4: Akkusativ und Dativ"); +} diff --git a/source/SubTests/AkkusativDativ/AkkusativModel.h b/source/SubTests/AkkusativDativ/AkkusativModel.h index 43a4881..e790ad9 100644 --- a/source/SubTests/AkkusativDativ/AkkusativModel.h +++ b/source/SubTests/AkkusativDativ/AkkusativModel.h @@ -1,9 +1,9 @@ #pragma once -#include "CheckableTestModel.h" +#include "PrintableModel.h" #include "AkkusativModel.pb.h" -class AkkusativModel : public CheckableTestModel +class AkkusativModel : public PrintableModel { Q_OBJECT @@ -12,4 +12,7 @@ public: void read(const ESGRAF48::AkkusativModel &model); void write(ESGRAF48::AkkusativModel &model) const; + +protected: + void printHeader(QPainter &painter) const override; }; diff --git a/source/SubTests/AkkusativDativ/CMakeLists.txt b/source/SubTests/AkkusativDativ/CMakeLists.txt index a543ee7..da3a956 100644 --- a/source/SubTests/AkkusativDativ/CMakeLists.txt +++ b/source/SubTests/AkkusativDativ/CMakeLists.txt @@ -43,9 +43,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE - CheckableItem - CheckableTest - CheckableTestModel + PrintableModel Qt5::Widgets ${Protobuf_LIBRARIES} ) diff --git a/source/SubTests/AkkusativDativ/DativModel.cpp b/source/SubTests/AkkusativDativ/DativModel.cpp index 3741833..9a7cfa5 100644 --- a/source/SubTests/AkkusativDativ/DativModel.cpp +++ b/source/SubTests/AkkusativDativ/DativModel.cpp @@ -1,7 +1,7 @@ #include "DativModel.h" DativModel::DativModel(QObject *parent) - : CheckableTestModel(parent) + : PrintableModel(parent) { m_tests = {{"Dativ Nominalphrase", {"Affe", "Gans", "Tiger", "Hund", "Elefant", "Pferd", "Bär", "Katze"}}, diff --git a/source/SubTests/AkkusativDativ/DativModel.h b/source/SubTests/AkkusativDativ/DativModel.h index 6a9a323..c6c83f0 100644 --- a/source/SubTests/AkkusativDativ/DativModel.h +++ b/source/SubTests/AkkusativDativ/DativModel.h @@ -1,9 +1,9 @@ #pragma once -#include "CheckableTestModel.h" +#include "PrintableModel.h" #include "DativModel.pb.h" -class DativModel : public CheckableTestModel +class DativModel : public PrintableModel { Q_OBJECT @@ -12,4 +12,7 @@ public: void read(const ESGRAF48::DativModel &model); void write(ESGRAF48::DativModel &model) const; + +protected: + void printHeader(QPainter &) const override {}; }; From 1f5c0de80a6567260eb61805bf7b7e1f6ae0e113 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Tue, 5 Feb 2019 22:16:30 +0100 Subject: [PATCH 32/42] Added line-break to test names --- source/PrintableModel/PrintableModel.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/PrintableModel/PrintableModel.cpp b/source/PrintableModel/PrintableModel.cpp index 97b3fd8..baabe85 100644 --- a/source/PrintableModel/PrintableModel.cpp +++ b/source/PrintableModel/PrintableModel.cpp @@ -1,5 +1,7 @@ #include "PrintableModel.h" +#include + PrintableModel::PrintableModel(QObject *parent) : CheckableTestModel(parent) { @@ -134,7 +136,10 @@ void PrintableModel::printTests(QPainter &painter) const double y = 0; for (const auto &test : m_tests) { - drawTextSquare(painter, {0, y, headerWidth, 2 * rowHeight}, test.name()); + QString testName = QString::fromStdString( + std::regex_replace(test.name().toStdString(), std::regex("\\s"), "\n")); + + drawTextSquare(painter, {0, y, headerWidth, 2 * rowHeight}, testName); x = headerWidth; for (const auto &item : test.items()) From 189c24cf6180d0526ec13a2f657d50303d0501f6 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 7 Feb 2019 20:03:22 +0100 Subject: [PATCH 33/42] Wrap long row headers --- source/PrintableModel/PrintableModel.cpp | 14 ++++++-- source/PrintableModel/PrintableModel.h | 3 ++ source/SubTests/Plural/PluralModel.cpp | 41 ++++++++++++++++++++++++ source/SubTests/Plural/PluralModel.h | 3 ++ source/SubTests/V2Svk/V2SvkModel.cpp | 17 +++++++--- 5 files changed, 72 insertions(+), 6 deletions(-) diff --git a/source/PrintableModel/PrintableModel.cpp b/source/PrintableModel/PrintableModel.cpp index baabe85..3107942 100644 --- a/source/PrintableModel/PrintableModel.cpp +++ b/source/PrintableModel/PrintableModel.cpp @@ -39,6 +39,16 @@ QPen PrintableModel::resultPen() return QPen(Qt::black, 2, Qt::SolidLine); } +double PrintableModel::headerWidthFactor() +{ + return 0.17; +} + +double PrintableModel::cellWidthFactor() +{ + return 0.085; +} + void PrintableModel::drawTextSquare(QPainter &painter, const QRectF &cell, const QString &text) { auto prevPen = painter.pen(); @@ -128,8 +138,8 @@ void PrintableModel::printTests(QPainter &painter) const auto width = painter.device()->width(); auto height = 1.5 * painter.fontMetrics().lineSpacing(); - double headerWidth = 0.2 * width; - double cellWidth = 0.08 * width; + double headerWidth = headerWidthFactor() * width; + double cellWidth = cellWidthFactor() * width; double rowHeight = height; double x = 0; diff --git a/source/PrintableModel/PrintableModel.h b/source/PrintableModel/PrintableModel.h index e647585..eb1daeb 100644 --- a/source/PrintableModel/PrintableModel.h +++ b/source/PrintableModel/PrintableModel.h @@ -24,6 +24,9 @@ public: static QPen tablePen(); static QPen resultPen(); + static double headerWidthFactor(); + static double cellWidthFactor(); + static void drawTextSquare(QPainter &painter, const QRectF &cell, const QString &text); static void drawNumberSquare(QPainter &painter, double x, double y, int number); static void drawCheckSquare(QPainter &painter, const QRectF &cell, bool checked); diff --git a/source/SubTests/Plural/PluralModel.cpp b/source/SubTests/Plural/PluralModel.cpp index 5448ed3..b310ae2 100644 --- a/source/SubTests/Plural/PluralModel.cpp +++ b/source/SubTests/Plural/PluralModel.cpp @@ -2,6 +2,8 @@ #include +#include + PluralModel::PluralModel(QObject *parent) : PrintableModel(parent) { @@ -43,3 +45,42 @@ void PluralModel::write(ESGRAF48::PluralModel &model) const model.set_baer(testItems[7].isChecked()); model.set_apfel(testItems[8].isChecked()); } + +void PluralModel::printTests(QPainter &painter) const +{ + painter.setFont(tableFont()); + painter.setPen(tablePen()); + + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); + + double headerWidth = headerWidthFactor() * width; + double cellWidth = cellWidthFactor() * width; + double rowHeight = height; + + double x = 0; + double y = 0; + for (const auto &test : m_tests) + { + drawTextSquare(painter, {0, y, headerWidth, 3 * rowHeight}, test.name()); + x = headerWidth; + + for (const auto &item : test.items()) + { + QString itemText = + QString::fromStdString(std::regex_replace(item.getText(), std::regex("\\s"), "\n")); + + drawTextSquare(painter, {x, y, cellWidth, 2 * rowHeight}, itemText); + drawCheckSquare(painter, {x, y + 2 * rowHeight, cellWidth, rowHeight}, + item.isChecked()); + + x += cellWidth; + } + y += rowHeight; + + drawResultSquare(painter, y, true, test.getPoints()); + y += rowHeight; + } + + painter.translate(0, y + 2 * rowHeight); +} diff --git a/source/SubTests/Plural/PluralModel.h b/source/SubTests/Plural/PluralModel.h index 728258d..f7c3543 100644 --- a/source/SubTests/Plural/PluralModel.h +++ b/source/SubTests/Plural/PluralModel.h @@ -12,4 +12,7 @@ public: void read(const ESGRAF48::PluralModel &model); void write(ESGRAF48::PluralModel &model) const; + +protected: + virtual void printTests(QPainter &painter) const; }; diff --git a/source/SubTests/V2Svk/V2SvkModel.cpp b/source/SubTests/V2Svk/V2SvkModel.cpp index 5416064..ff0ab00 100644 --- a/source/SubTests/V2Svk/V2SvkModel.cpp +++ b/source/SubTests/V2Svk/V2SvkModel.cpp @@ -1,5 +1,7 @@ #include "V2SvkModel.h" +#include + V2SvkModel::V2SvkModel(QObject *parent) : PrintableModel(parent) { @@ -21,13 +23,20 @@ void V2SvkModel::printTests(QPainter &painter) const auto testIndex = 0; for (const auto &test : m_tests) { - double rowHeaderWidth = 0.2 * width; - double resultCellWidth = test.size() > 8 ? 0.04 * width : 0.08 * width; + double rowHeaderWidth = headerWidthFactor() * width; + double resultCellWidth = (test.size() > 8 ? 0.5 : 1) * cellWidthFactor() * width; double rowHeight = height; + QString testName = test.name(); + if (testName.length() > 20) + { + testName = QString::fromStdString( + std::regex_replace(testName.toStdString(), std::regex("[\\s-]"), "\n")); + } + if (testIndex == 0) { - drawTextSquare(painter, {x, y, rowHeaderWidth, 2 * rowHeight}, test.name()); + drawTextSquare(painter, {x, y, rowHeaderWidth, 2 * rowHeight}, testName); x += rowHeaderWidth; std::vector> columnHeaders; @@ -55,7 +64,7 @@ void V2SvkModel::printTests(QPainter &painter) const } else { - drawTextSquare(painter, {x, y, rowHeaderWidth, rowHeight}, test.name()); + drawTextSquare(painter, {x, y, rowHeaderWidth, rowHeight}, testName); x += rowHeaderWidth; } From 51271e959529a25985ca634fd378d0ea444ab65a Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 7 Feb 2019 22:36:39 +0100 Subject: [PATCH 34/42] Print subtest 6 and results --- source/DataModel.cpp | 6 +- source/PrintableModel/PrintableModel.cpp | 2 +- source/PrintableModel/PrintableModel.h | 2 +- source/ResultWidget/CMakeLists.txt | 1 + source/ResultWidget/ResultModel.cpp | 82 +++++++++++++++---- source/ResultWidget/ResultModel.h | 4 + source/SubTests/AkkusativDativ/DativModel.cpp | 5 ++ source/SubTests/AkkusativDativ/DativModel.h | 2 +- source/SubTests/LateSkills/CMakeLists.txt | 5 +- source/SubTests/LateSkills/GenitivModel.cpp | 7 +- source/SubTests/LateSkills/GenitivModel.h | 7 +- .../SubTests/LateSkills/LateSkillsModel.cpp | 64 +++++++++++++++ source/SubTests/LateSkills/LateSkillsModel.h | 15 ++++ source/SubTests/LateSkills/PassivModel.cpp | 7 +- source/SubTests/LateSkills/PassivModel.h | 10 ++- source/SubTests/Plural/PluralModel.cpp | 5 +- 16 files changed, 187 insertions(+), 37 deletions(-) create mode 100644 source/SubTests/LateSkills/LateSkillsModel.cpp create mode 100644 source/SubTests/LateSkills/LateSkillsModel.h diff --git a/source/DataModel.cpp b/source/DataModel.cpp index b674978..0b7332b 100644 --- a/source/DataModel.cpp +++ b/source/DataModel.cpp @@ -105,7 +105,6 @@ void DataModel::printTo(QPrinter &printer) const QPainter painter; painter.begin(&printer); - painter.setFont(PrintableModel::h1Font()); painter.drawText(0, painter.fontMetrics().lineSpacing(), "ESGRAF 4-8 Auswertungsbogen"); painter.translate(0, 3 * painter.fontMetrics().lineSpacing()); @@ -132,6 +131,11 @@ void DataModel::printTo(QPrinter &printer) const m_dativ.printTo(painter); m_plural.printTo(painter); + m_passiv.printTo(painter); + m_genitiv.printTo(painter); + + m_results.printTo(painter); + painter.end(); } diff --git a/source/PrintableModel/PrintableModel.cpp b/source/PrintableModel/PrintableModel.cpp index 3107942..2423ba0 100644 --- a/source/PrintableModel/PrintableModel.cpp +++ b/source/PrintableModel/PrintableModel.cpp @@ -46,7 +46,7 @@ double PrintableModel::headerWidthFactor() double PrintableModel::cellWidthFactor() { - return 0.085; + return headerWidthFactor() / 2; } void PrintableModel::drawTextSquare(QPainter &painter, const QRectF &cell, const QString &text) diff --git a/source/PrintableModel/PrintableModel.h b/source/PrintableModel/PrintableModel.h index eb1daeb..3cbced8 100644 --- a/source/PrintableModel/PrintableModel.h +++ b/source/PrintableModel/PrintableModel.h @@ -33,9 +33,9 @@ public: static void drawResultSquare(QPainter &painter, double y, bool rightCell, unsigned int value); static void drawGreySquare(QPainter &painter, const QRectF &cell); -protected: static void drawHeader2(QPainter &painter, const QString &text); +protected: virtual void printHeader(QPainter &painter) const; virtual void printTests(QPainter &painter) const; virtual void printSummary(QPainter &painter) const; diff --git a/source/ResultWidget/CMakeLists.txt b/source/ResultWidget/CMakeLists.txt index bfdd22c..437eeab 100644 --- a/source/ResultWidget/CMakeLists.txt +++ b/source/ResultWidget/CMakeLists.txt @@ -30,6 +30,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE + PrintableModel Age Qt5::Widgets ) diff --git a/source/ResultWidget/ResultModel.cpp b/source/ResultWidget/ResultModel.cpp index c905346..85cf097 100644 --- a/source/ResultWidget/ResultModel.cpp +++ b/source/ResultWidget/ResultModel.cpp @@ -10,13 +10,14 @@ #include "PassivPR.h" #include "GenitivPR.h" +#include "PrintableModel.h" + #include ResultModel::ResultModel(QObject *parent) - : QAbstractTableModel(parent) + : QAbstractTableModel(parent) { - m_results = { { "V2", "SVK", "VE", "Passiv", "Genus", "Akkusativ", "Dativ", - "Genitiv", "Plural" } }; + m_results = {{"V2", "SVK", "VE", "Passiv", "Genus", "Akkusativ", "Dativ", "Genitiv", "Plural"}}; } int ResultModel::rowCount(const QModelIndex &parent) const @@ -81,8 +82,7 @@ QVariant ResultModel::data(const QModelIndex &index, int role) const return {}; } -QVariant ResultModel::headerData( - int section, Qt::Orientation orientation, int role) const +QVariant ResultModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) { @@ -170,7 +170,7 @@ void ResultModel::setDativResult(unsigned int points) emit dataChanged(index(0, 6), index(4, 6)); } } - + void ResultModel::setV2Result(unsigned int points) { if (m_results[0].points() != points) @@ -193,20 +193,66 @@ void ResultModel::setSvkResult(unsigned int points) void ResultModel::setPassivResult(unsigned int points) { - if (m_results[3].points() != points) - { - m_results[3].setPoints(points); - m_results[3].setPR(PassivPR().lookup(m_age, points)); - emit dataChanged(index(0, 3), index(4, 3)); - } + if (m_results[3].points() != points) + { + m_results[3].setPoints(points); + m_results[3].setPR(PassivPR().lookup(m_age, points)); + emit dataChanged(index(0, 3), index(4, 3)); + } } void ResultModel::setGenitivResult(unsigned int points) { - if (m_results[7].points() != points) - { - m_results[7].setPoints(points); - m_results[7].setPR(GenitivPR().lookup(m_age, points)); - emit dataChanged(index(0, 7), index(4, 7)); - } + if (m_results[7].points() != points) + { + m_results[7].setPoints(points); + m_results[7].setPR(GenitivPR().lookup(m_age, points)); + emit dataChanged(index(0, 7), index(4, 7)); + } +} + +void ResultModel::printTo(QPainter &painter) const +{ + PrintableModel::drawHeader2(painter, "Prozentränge (PR)"); + + painter.setFont(PrintableModel::tableFont()); + painter.setPen(PrintableModel::tablePen()); + + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); + + double cellWidth = width / (m_results.size() + 1); + double rowHeight = 2 * height; + + double x = 0; + double y = 0; + + PrintableModel::drawTextSquare(painter, {x, y + 0 * rowHeight, cellWidth, rowHeight}, ""); + PrintableModel::drawTextSquare(painter, {x, y + 1 * rowHeight, cellWidth, rowHeight}, + "\u2265 PR 84"); + PrintableModel::drawTextSquare(painter, {x, y + 2 * rowHeight, cellWidth, rowHeight}, + "< PR 84"); + + PrintableModel::drawGreySquare(painter, {x, y + 3 * rowHeight, cellWidth, rowHeight}); + PrintableModel::drawTextSquare(painter, {x, y + 3 * rowHeight, cellWidth, rowHeight}, + "\u2264 PR 16"); + + x += cellWidth; + for (const auto &result : m_results) + { + PrintableModel::drawTextSquare(painter, {x, y + 0 * rowHeight, cellWidth, rowHeight}, + result.name()); + const auto pr = result.pr(); + + PrintableModel::drawTextSquare(painter, {x, y + 1 * rowHeight, cellWidth, rowHeight}, + pr >= 84 ? QString::number(pr) : "-"); + PrintableModel::drawTextSquare(painter, {x, y + 2 * rowHeight, cellWidth, rowHeight}, + pr < 84 && pr > 16 ? QString::number(pr) : "-"); + + PrintableModel::drawGreySquare(painter, {x, y + 3 * rowHeight, cellWidth, rowHeight}); + PrintableModel::drawTextSquare(painter, {x, y + 3 * rowHeight, cellWidth, rowHeight}, + pr <= 16 ? QString::number(pr) : "-"); + + x += cellWidth; + } } diff --git a/source/ResultWidget/ResultModel.h b/source/ResultWidget/ResultModel.h index ae6dd78..2430f62 100644 --- a/source/ResultWidget/ResultModel.h +++ b/source/ResultWidget/ResultModel.h @@ -1,7 +1,9 @@ #pragma once #include "Age.h" + #include +#include class TestResult { @@ -72,4 +74,6 @@ public: void setSvkResult(unsigned int points); void setPassivResult(unsigned int points); void setGenitivResult(unsigned int points); + + void printTo(QPainter &painter) const; }; diff --git a/source/SubTests/AkkusativDativ/DativModel.cpp b/source/SubTests/AkkusativDativ/DativModel.cpp index 9a7cfa5..c0a7560 100644 --- a/source/SubTests/AkkusativDativ/DativModel.cpp +++ b/source/SubTests/AkkusativDativ/DativModel.cpp @@ -105,3 +105,8 @@ void DativModel::write(ESGRAF48::DativModel &model) const nomTiereModel->set_katze(testItems[7].isChecked()); } } + +void DativModel::printHeader(QPainter &painter) const +{ + painter.translate(0, -1.5 * painter.fontMetrics().lineSpacing()); +} diff --git a/source/SubTests/AkkusativDativ/DativModel.h b/source/SubTests/AkkusativDativ/DativModel.h index c6c83f0..9b21add 100644 --- a/source/SubTests/AkkusativDativ/DativModel.h +++ b/source/SubTests/AkkusativDativ/DativModel.h @@ -14,5 +14,5 @@ public: void write(ESGRAF48::DativModel &model) const; protected: - void printHeader(QPainter &) const override {}; + void printHeader(QPainter &painter) const override; }; diff --git a/source/SubTests/LateSkills/CMakeLists.txt b/source/SubTests/LateSkills/CMakeLists.txt index 7fef071..a32a4d9 100644 --- a/source/SubTests/LateSkills/CMakeLists.txt +++ b/source/SubTests/LateSkills/CMakeLists.txt @@ -22,6 +22,7 @@ protobuf_generate_cpp(LateSkills_PROTO_SRCS LateSkills_PROTO_HDRS add_library(${PROJECT_NAME} LateSkillsWidget.cpp + LateSkillsModel.cpp PassivModel.cpp GenitivModel.cpp ${UI_HEADERS} @@ -43,9 +44,7 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE - CheckableItem - CheckableTest - CheckableTestModel + PrintableModel Qt5::Widgets ${Protobuf_LIBRARIES} ) diff --git a/source/SubTests/LateSkills/GenitivModel.cpp b/source/SubTests/LateSkills/GenitivModel.cpp index 9ebf423..6fcf26c 100644 --- a/source/SubTests/LateSkills/GenitivModel.cpp +++ b/source/SubTests/LateSkills/GenitivModel.cpp @@ -1,7 +1,7 @@ #include "GenitivModel.h" GenitivModel::GenitivModel(QObject *parent) - : CheckableTestModel(parent) + : LateSkillsModel(parent) { m_tests = { {"Genitiv Präpositionen", @@ -107,3 +107,8 @@ void GenitivModel::write(ESGRAF48::LateSkillsGenitivModel &model) const attributierungModel->set_guertel2(testItems[9].isChecked()); } } + +void GenitivModel::printHeader(QPainter &painter) const +{ + painter.translate(0, -1.5 * painter.fontMetrics().lineSpacing()); +} diff --git a/source/SubTests/LateSkills/GenitivModel.h b/source/SubTests/LateSkills/GenitivModel.h index 2346e94..4923828 100644 --- a/source/SubTests/LateSkills/GenitivModel.h +++ b/source/SubTests/LateSkills/GenitivModel.h @@ -1,9 +1,9 @@ #pragma once -#include "CheckableTestModel.h" +#include "LateSkillsModel.h" #include "LateSkillsGenitivModel.pb.h" -class GenitivModel : public CheckableTestModel +class GenitivModel : public LateSkillsModel { Q_OBJECT @@ -14,4 +14,7 @@ public: void read(const ESGRAF48::LateSkillsGenitivModel &model); void write(ESGRAF48::LateSkillsGenitivModel &model) const; + +protected: + void printHeader(QPainter &painter) const override; }; diff --git a/source/SubTests/LateSkills/LateSkillsModel.cpp b/source/SubTests/LateSkills/LateSkillsModel.cpp new file mode 100644 index 0000000..1f441ce --- /dev/null +++ b/source/SubTests/LateSkills/LateSkillsModel.cpp @@ -0,0 +1,64 @@ +#include "LateSkillsModel.h" + +#include + +LateSkillsModel::LateSkillsModel(QObject *parent) + : PrintableModel(parent) +{ +} + +void LateSkillsModel::printTests(QPainter &painter) const +{ + painter.setFont(tableFont()); + painter.setPen(tablePen()); + + auto width = painter.device()->width(); + auto height = 1.5 * painter.fontMetrics().lineSpacing(); + + double headerWidth = headerWidthFactor() * width; + double cellHeaderWidth = cellWidthFactor() * width; + double cellWidth = 0.5 * cellHeaderWidth; + double rowHeight = height; + + double x = 0; + double y = 0; + for (const auto &test : m_tests) + { + QString testName = QString::fromStdString( + std::regex_replace(test.name().toStdString(), std::regex("\\s"), "\n")); + + drawTextSquare(painter, {0, y, headerWidth, 3 * rowHeight}, testName); + + const auto &items = test.items(); + + x = headerWidth; + for (unsigned int i = 0; i < items.size(); i += 2) + { + const auto &item = test.items().at(i); + QString itemText = QString::fromStdString(item.getText()).split(" ").at(0); + + drawTextSquare(painter, {x, y, cellHeaderWidth, rowHeight}, itemText); + + x += cellHeaderWidth; + } + y += rowHeight; + + x = headerWidth; + for (const auto &item : items) + { + drawTextSquare(painter, {x, y, cellWidth, rowHeight}, QString::number(item.value())); + drawCheckSquare(painter, {x, y + rowHeight, cellWidth, rowHeight}, item.isChecked()); + + x += cellWidth; + } + + if (m_tests.size() > 1) + { + drawResultSquare(painter, y + rowHeight, true, test.getPoints()); + } + + y += 2 * rowHeight; + } + + painter.translate(0, y + rowHeight); +} diff --git a/source/SubTests/LateSkills/LateSkillsModel.h b/source/SubTests/LateSkills/LateSkillsModel.h new file mode 100644 index 0000000..8049f51 --- /dev/null +++ b/source/SubTests/LateSkills/LateSkillsModel.h @@ -0,0 +1,15 @@ +#pragma once + +#include "PrintableModel.h" +#include "LateSkillsPassivModel.pb.h" + +class LateSkillsModel : public PrintableModel +{ + Q_OBJECT + +public: + LateSkillsModel(QObject *parent); + +protected: + void printTests(QPainter &painter) const override; +}; diff --git a/source/SubTests/LateSkills/PassivModel.cpp b/source/SubTests/LateSkills/PassivModel.cpp index 6f1d3a8..d54d1c3 100644 --- a/source/SubTests/LateSkills/PassivModel.cpp +++ b/source/SubTests/LateSkills/PassivModel.cpp @@ -1,7 +1,7 @@ #include "PassivModel.h" PassivModel::PassivModel(QObject *parent) - : CheckableTestModel(parent) + : LateSkillsModel(parent) { m_tests = {{"Passiv", {"Elefant (1)", "Elefant (2)", "Pferde (1)", "Pferde (2)", "Bälle (1)", "Bälle (2)", @@ -65,3 +65,8 @@ void PassivModel::write(ESGRAF48::LateSkillsPassivModel &model) const model.set_fleisch1(testItems[8].isChecked()); model.set_fleisch2(testItems[9].isChecked()); } + +void PassivModel::printHeader(QPainter &painter) const +{ + drawHeader2(painter, "Subtest 6: Späte Fähigkeiten (7;0-8;11)"); +} diff --git a/source/SubTests/LateSkills/PassivModel.h b/source/SubTests/LateSkills/PassivModel.h index e0671bb..d6aabfd 100644 --- a/source/SubTests/LateSkills/PassivModel.h +++ b/source/SubTests/LateSkills/PassivModel.h @@ -1,17 +1,19 @@ #pragma once -#include "CheckableTestModel.h" +#include "LateSkillsModel.h" #include "LateSkillsPassivModel.pb.h" -class PassivModel : public CheckableTestModel +class PassivModel : public LateSkillsModel { Q_OBJECT public: PassivModel(QObject *parent); - bool setData(const QModelIndex &index, const QVariant &value, - int role = Qt::EditRole) override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; void read(const ESGRAF48::LateSkillsPassivModel &model); void write(ESGRAF48::LateSkillsPassivModel &model) const; + +protected: + void printHeader(QPainter &painter) const override; }; diff --git a/source/SubTests/Plural/PluralModel.cpp b/source/SubTests/Plural/PluralModel.cpp index b310ae2..cc9568e 100644 --- a/source/SubTests/Plural/PluralModel.cpp +++ b/source/SubTests/Plural/PluralModel.cpp @@ -76,10 +76,7 @@ void PluralModel::printTests(QPainter &painter) const x += cellWidth; } - y += rowHeight; - - drawResultSquare(painter, y, true, test.getPoints()); - y += rowHeight; + y += 2 * rowHeight; } painter.translate(0, y + 2 * rowHeight); From 468006a416dde420360fac01e296378efba3a91d Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 7 Feb 2019 22:40:18 +0100 Subject: [PATCH 35/42] Bumped version to 0.4 --- source/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 063ff65..bd5bc26 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.6) -set(BUILD_VERSION_MAJOR_MINOR 0.3) +set(BUILD_VERSION_MAJOR_MINOR 0.4) if ($ENV{BUILD_NUMBER}) set(BUILD_VERSION_PATCH $ENV{BUILD_NUMBER}) From a95943ec6662af47857b01e065c00514e933c66d Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 7 Feb 2019 22:42:07 +0100 Subject: [PATCH 36/42] added save, export and swap files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e42f4b6..b1a9f41 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ _*/ build-* *.user tags +*.esgraf48 +*.swp +*.pdf From 390e97c7bf7d9f055ff7bbb3c66f241df96e045f Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Fri, 8 Feb 2019 21:03:52 +0100 Subject: [PATCH 37/42] Use unicode strings --- source/PrintableModel/PrintableModel.cpp | 2 +- source/ResultWidget/ResultModel.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/PrintableModel/PrintableModel.cpp b/source/PrintableModel/PrintableModel.cpp index 2423ba0..5d9be53 100644 --- a/source/PrintableModel/PrintableModel.cpp +++ b/source/PrintableModel/PrintableModel.cpp @@ -80,7 +80,7 @@ void PrintableModel::drawNumberSquare(QPainter &painter, double x, double y, int void PrintableModel::PrintableModel::drawCheckSquare(QPainter &painter, const QRectF &cell, bool checked) { - drawTextSquare(painter, cell, checked ? "\u2612" : "\u2610"); + drawTextSquare(painter, cell, checked ? u8"\u2612" : u8"\u2610"); } void PrintableModel::drawResultSquare(QPainter &painter, double y, bool rightCell, diff --git a/source/ResultWidget/ResultModel.cpp b/source/ResultWidget/ResultModel.cpp index 85cf097..907662b 100644 --- a/source/ResultWidget/ResultModel.cpp +++ b/source/ResultWidget/ResultModel.cpp @@ -229,13 +229,13 @@ void ResultModel::printTo(QPainter &painter) const PrintableModel::drawTextSquare(painter, {x, y + 0 * rowHeight, cellWidth, rowHeight}, ""); PrintableModel::drawTextSquare(painter, {x, y + 1 * rowHeight, cellWidth, rowHeight}, - "\u2265 PR 84"); + u8"\u2265 PR 84"); PrintableModel::drawTextSquare(painter, {x, y + 2 * rowHeight, cellWidth, rowHeight}, "< PR 84"); PrintableModel::drawGreySquare(painter, {x, y + 3 * rowHeight, cellWidth, rowHeight}); PrintableModel::drawTextSquare(painter, {x, y + 3 * rowHeight, cellWidth, rowHeight}, - "\u2264 PR 16"); + u8"\u2264 PR 16"); x += cellWidth; for (const auto &result : m_results) From f5d8b3f3d51ab5c21b15390c12ef9c6af99dba3f Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Fri, 8 Feb 2019 21:46:11 +0100 Subject: [PATCH 38/42] Sorted results by test order --- source/ResultWidget/ResultModel.cpp | 49 +++++++++++++++-------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/source/ResultWidget/ResultModel.cpp b/source/ResultWidget/ResultModel.cpp index 907662b..b4eebb9 100644 --- a/source/ResultWidget/ResultModel.cpp +++ b/source/ResultWidget/ResultModel.cpp @@ -18,6 +18,7 @@ ResultModel::ResultModel(QObject *parent) : QAbstractTableModel(parent) { m_results = {{"V2", "SVK", "VE", "Passiv", "Genus", "Akkusativ", "Dativ", "Genitiv", "Plural"}}; + m_results = {{"V2", "SVK", "VE", "Genus", "Akkusativ", "Dativ", "Plural", "Passiv", "Genitiv"}}; } int ResultModel::rowCount(const QModelIndex &parent) const @@ -123,21 +124,21 @@ void ResultModel::setAge(const Age &age) void ResultModel::setPluralResult(unsigned int points) { - if (m_results[8].points() != points) + if (m_results[6].points() != points) { - m_results[8].setPoints(points); - m_results[8].setPR(PluralPR().lookup(m_age, points)); - emit dataChanged(index(0, 8), index(4, 8)); + m_results[6].setPoints(points); + m_results[6].setPR(PluralPR().lookup(m_age, points)); + emit dataChanged(index(0, 6), index(4, 6)); } } void ResultModel::setGenusResult(unsigned int points) { - if (m_results[4].points() != points) + if (m_results[3].points() != points) { - m_results[4].setPoints(points); - m_results[4].setPR(GenusPR().lookup(m_age, points)); - emit dataChanged(index(0, 4), index(4, 4)); + m_results[3].setPoints(points); + m_results[3].setPR(GenusPR().lookup(m_age, points)); + emit dataChanged(index(0, 3), index(4, 3)); } } @@ -153,21 +154,21 @@ void ResultModel::setVerbEndResult(unsigned int points) void ResultModel::setAkkusativResult(unsigned int points) { - if (m_results[5].points() != points) + if (m_results[4].points() != points) { - m_results[5].setPoints(points); - m_results[5].setPR(AkkusativPR().lookup(m_age, points)); - emit dataChanged(index(0, 5), index(4, 5)); + m_results[4].setPoints(points); + m_results[4].setPR(AkkusativPR().lookup(m_age, points)); + emit dataChanged(index(0, 4), index(4, 4)); } } void ResultModel::setDativResult(unsigned int points) { - if (m_results[6].points() != points) + if (m_results[5].points() != points) { - m_results[6].setPoints(points); - m_results[6].setPR(DativPR().lookup(m_age, points)); - emit dataChanged(index(0, 6), index(4, 6)); + m_results[5].setPoints(points); + m_results[5].setPR(DativPR().lookup(m_age, points)); + emit dataChanged(index(0, 5), index(4, 5)); } } @@ -193,21 +194,21 @@ void ResultModel::setSvkResult(unsigned int points) void ResultModel::setPassivResult(unsigned int points) { - if (m_results[3].points() != points) + if (m_results[7].points() != points) { - m_results[3].setPoints(points); - m_results[3].setPR(PassivPR().lookup(m_age, points)); - emit dataChanged(index(0, 3), index(4, 3)); + m_results[7].setPoints(points); + m_results[7].setPR(PassivPR().lookup(m_age, points)); + emit dataChanged(index(0, 7), index(4, 7)); } } void ResultModel::setGenitivResult(unsigned int points) { - if (m_results[7].points() != points) + if (m_results[8].points() != points) { - m_results[7].setPoints(points); - m_results[7].setPR(GenitivPR().lookup(m_age, points)); - emit dataChanged(index(0, 7), index(4, 7)); + m_results[8].setPoints(points); + m_results[8].setPR(GenitivPR().lookup(m_age, points)); + emit dataChanged(index(0, 8), index(4, 8)); } } From edc7aca7252632b7212bdd34bd40233d597cdc55 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Fri, 8 Feb 2019 21:48:11 +0100 Subject: [PATCH 39/42] Bumped version number --- source/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index bd5bc26..a5c5666 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.6) -set(BUILD_VERSION_MAJOR_MINOR 0.4) +set(BUILD_VERSION_MAJOR_MINOR 0.5) if ($ENV{BUILD_NUMBER}) set(BUILD_VERSION_PATCH $ENV{BUILD_NUMBER}) From 24bc4dbd8b73fc828d03705c33a305d9a8333a28 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 17 Feb 2019 16:01:42 +0100 Subject: [PATCH 40/42] Use qt conan package instead of local install --- .gitignore | 1 + conanfile.txt | 2 ++ source/CMakeLists.txt | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/.gitignore b/.gitignore index b1a9f41..e027351 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ compile_commands.json _*/ +build/ build-* *.user tags diff --git a/conanfile.txt b/conanfile.txt index c834ab6..2d9562b 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -1,4 +1,5 @@ [requires] +qt/5.12.0@bincrafters/stable protobuf/3.6.1@bincrafters/stable protoc_installer/3.6.1@bincrafters/stable catch2/2.4.2@bincrafters/stable @@ -8,3 +9,4 @@ cmake [options] protobuf:shared=False +qt:qttools=True diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index a5c5666..ebf0f1b 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -92,6 +92,25 @@ target_link_libraries(${PROJECT_NAME} ${Protobuf_LIBRARIES} ) +if (WIN32) + get_target_property(_qmake_executable Qt5::qmake IMPORTED_LOCATION) + message(STATUS "_qmake_executable: ${_qmake_executable}") + + get_filename_component(_qt_bin_dir "${_qmake_executable}" DIRECTORY) + message(STATUS "_qt_bin_dir: ${_qt_bin_dir}") + + find_program(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}") + + if (WINDEPLOYQT_EXECUTABLE) + message(STATUS "Found ${WINDEPLOYQT_EXECUTABLE}") + else() + message(FATAL_ERROR "Unable to find windeployqt") + endif() + + add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD + COMMAND ${WINDEPLOYQT_EXECUTABLE} $) +endif() + add_subdirectory(Age) add_subdirectory(CheckableItem) add_subdirectory(CheckableTest) From e888f5c59dafd462c891855bfd934ba93bef01f7 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 17 Feb 2019 17:33:43 +0100 Subject: [PATCH 41/42] Bumped version number to 0.6 --- source/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index ebf0f1b..f13a6d5 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.6) -set(BUILD_VERSION_MAJOR_MINOR 0.5) +set(BUILD_VERSION_MAJOR_MINOR 0.6) if ($ENV{BUILD_NUMBER}) set(BUILD_VERSION_PATCH $ENV{BUILD_NUMBER}) From 505b2d9007b538864849f0cc82206b54504e3501 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sun, 17 Feb 2019 19:49:52 +0100 Subject: [PATCH 42/42] Re-added translations --- conanfile.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/conanfile.txt b/conanfile.txt index 2d9562b..e405607 100644 --- a/conanfile.txt +++ b/conanfile.txt @@ -10,3 +10,4 @@ cmake [options] protobuf:shared=False qt:qttools=True +qt:qttranslations=True