Compare commits

...
This repository has been archived on 2024-12-15. You can view files and clone it, but cannot push or open issues or pull requests.

18 Commits

Author SHA1 Message Date
e64ef375fb Increased print resolution to get thinner table borders 2018-12-15 17:10:21 +01:00
c8bd1bbdb8 Paint empty result cells gray 2018-12-15 16:31:51 +01:00
6eb585b08c Use central table format for printing 2018-12-15 16:12:20 +01:00
a718113747 Print subtest 1 2018-12-13 20:46:38 +01:00
be3a3f453d WIP V2/Svk printing 2018-12-12 22:19:42 +01:00
cc20d46a76 Print causal sentence points 2018-12-12 21:40:26 +01:00
8ef56f1855 Display causal sentence point count below subtest 2 2018-12-12 21:33:44 +01:00
98196e05d6 Implemented printing for late skills tests 2018-12-10 22:29:49 +01:00
f6c2da5edc Implemented plural-test printing 2018-12-10 21:11:46 +01:00
2570d5d5b5 Print results 2018-12-09 12:49:12 +01:00
c065b04cbe Use std::accumulate instead of manually adding 2018-12-09 11:27:13 +01:00
e89f157bac Merge branch 'develop' into feature/print-as-qtextdocument 2018-12-09 11:14:41 +01:00
49b52f1dbc Print subtests 2, 3 and 4 2018-12-08 21:02:35 +01:00
e2237110cf Merge branch 'develop' into feature/print-as-qtextdocument 2018-12-08 17:02:46 +01:00
b06e717575 Very basic subtest 2 print output 2018-12-02 22:57:56 +01:00
bcd0b17caa Removed html output 2018-11-28 22:43:32 +01:00
bf08d0c5e4 Print formatting 2018-11-28 22:39:51 +01:00
bf963adeb5 Print metadata and v2svk header 2018-11-26 21:47:42 +01:00
45 changed files with 872 additions and 282 deletions

View File

@ -36,6 +36,7 @@ protobuf_generate_cpp(DataModel_PROTO_SRCS DataModel_PROTO_HDRS
add_executable(${PROJECT_NAME} WIN32
ESGRAF48.cpp
DataModel.cpp
PrintableModel.cpp
mainwindow.cpp
${LOGO_TEST_UI}
${LOGO_TEST_QRC}

View File

@ -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();
}
}

View File

@ -24,7 +24,4 @@ public:
void setValue(unsigned int value);
unsigned int points() const;
void write(QJsonObject &json) const;
void read(const QJsonObject &json);
};

View File

@ -2,6 +2,8 @@
#include <QJsonArray>
#include <numeric>
CheckableItems::CheckableItems(std::initializer_list<std::string> itemNames)
{
for (const auto &itemName : itemNames)
@ -10,27 +12,9 @@ CheckableItems::CheckableItems(std::initializer_list<std::string> 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();
});
}

View File

@ -10,6 +10,5 @@ class CheckableItems : public std::vector<CheckableItem>
public:
CheckableItems(std::initializer_list<std::string> itemNames);
void write(QJsonArray &json) const;
void read(const QJsonArray &json);
unsigned int getPoints() const;
};

View File

@ -1,5 +1,7 @@
#include "CheckableTest.h"
#include <numeric>
CheckableTest::CheckableTest(
const char *name, std::initializer_list<std::string> items)
: m_name(name)
@ -26,3 +28,8 @@ CheckableItems &CheckableTest::items()
{
return m_items;
}
unsigned int CheckableTest::getPoints() const
{
return m_items.getPoints();
}

View File

@ -17,6 +17,8 @@ public:
const QString &name() const;
const CheckableItems &items() const;
CheckableItems &items();
unsigned int getPoints() const;
};
using CheckableTests = std::vector<CheckableTest>;

View File

@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.6)
project(CheckableTestModel LANGUAGES CXX)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
add_library(${PROJECT_NAME}
CheckableTestModel.cpp
@ -22,4 +23,5 @@ target_link_libraries(${PROJECT_NAME}
CheckableItem
CheckableTest
Qt5::Core
Qt5::Gui
)

View File

@ -2,6 +2,7 @@
#include <QJsonArray>
#include <QSize>
#include <QTextTable>
#include <QDebug>
CheckableTestModel::CheckableTestModel(QObject *parent)
@ -67,8 +68,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,8 +93,7 @@ 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)
{
@ -107,30 +106,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())
@ -141,6 +116,81 @@ bool CheckableTestModel::isValidIndex(const QModelIndex &index) const
return false;
}
void CheckableTestModel::printTo(QTextCursor &cursor) const
{
QTextCharFormat headerFormat;
headerFormat.setFontPointSize(10);
cursor.insertBlock();
cursor.insertText("\n");
cursor.insertText(getName().c_str(), headerFormat);
printTableTo(cursor);
cursor.movePosition(QTextCursor::End);
cursor.insertBlock();
cursor.insertText("\n");
printSummaryTo(cursor);
cursor.movePosition(QTextCursor::End);
}
void CheckableTestModel::printTableTo(QTextCursor &cursor) const
{
QTextTableFormat tableFormat = defaultTableFormat();
tableFormat.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 20),
QTextLength(QTextLength::PercentageLength, 9),
QTextLength(QTextLength::PercentageLength, 9),
QTextLength(QTextLength::PercentageLength, 9),
QTextLength(QTextLength::PercentageLength, 9),
QTextLength(QTextLength::PercentageLength, 9),
QTextLength(QTextLength::PercentageLength, 9),
QTextLength(QTextLength::PercentageLength, 9),
QTextLength(QTextLength::PercentageLength, 9),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3)});
QTextTable *table = cursor.insertTable(m_tests.size() * 2, 13, tableFormat);
int currentRow = 0;
for (const auto &test : m_tests)
{
table->mergeCells(currentRow, 0, 2, 1);
int currentColumn = 0;
setCellText(*table, currentRow, currentColumn, test.name());
currentColumn++;
for (const auto &item : test.items())
{
setCellText(*table, currentRow, currentColumn, item.getText().c_str());
setCellChecked(*table, currentRow + 1, currentColumn, item.isChecked());
currentColumn++;
}
setCellNumber(*table, currentRow + 1, 12, test.getPoints());
currentRow += 2;
}
}
void CheckableTestModel::printSummaryTo(QTextCursor &cursor) const
{
QTextTableFormat tableFormat = defaultTableFormat();
tableFormat.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 76),
QTextLength(QTextLength::PercentageLength, 20),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3)});
QTextTable *table = cursor.insertTable(1, 4, tableFormat);
setCellText(*table, 0, 1, "Rohwertpunkte Total:");
setCellNumber(*table, 0, 3, getPoints());
}
CheckableItems &CheckableTestModel::getItems(const QModelIndex &index)
{
if (index.row() < m_tests.size())
@ -151,8 +201,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,15 +235,7 @@ const CheckableItem &CheckableTestModel::getItem(const QModelIndex &index) const
unsigned int CheckableTestModel::getPoints() const
{
unsigned int points = 0;
for (const auto &test : m_tests)
{
for (const auto &item : test.items())
{
points += item.points();
}
}
return points;
return std::accumulate(
std::begin(m_tests), std::end(m_tests), 0,
[](int base, const CheckableTest &test) { return base + test.getPoints(); });
}

View File

@ -1,9 +1,12 @@
#pragma once
#include "../PrintableModel.h"
#include "CheckableTest.h"
#include <QAbstractTableModel>
class CheckableTestModel : public QAbstractTableModel
#include <QAbstractTableModel>
#include <QTextCursor>
class CheckableTestModel : public QAbstractTableModel, protected PrintableModel
{
Q_OBJECT
@ -25,14 +28,18 @@ 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;
void printTo(QTextCursor &cursor) const override;
protected:
virtual bool isValidIndex(const QModelIndex &index) const;
virtual std::string getName() const = 0;
virtual void printTableTo(QTextCursor &cursor) const;
virtual void printSummaryTo(QTextCursor &cursor) const;
private:
CheckableItems &getItems(const QModelIndex &index);
const CheckableItems &getItems(const QModelIndex &index) const;

View File

@ -60,27 +60,27 @@ void DataModel::read(std::istream &inStream)
m_passiv.read(dataModel.lateskillspassiv());
}
std::string DataModel::toHtml() const
void DataModel::printTo(QTextCursor &cursor) const
{
std::stringstream out;
QTextCharFormat titleFormat;
titleFormat.setFontPointSize(14);
out << "<html>" << std::endl;
out << "<head>" << std::endl;
out << "<style>" << std::endl;
out << "body {" << std::endl;
out << "font-family:sans-serif;" << std::endl;
out << "}" << std::endl;
out << "</style>" << std::endl;
out << "</head>" << std::endl;
out << "<body>" << std::endl;
out << "<h2>ESGRAF 4-8 Auswertungsbogen</h2>" << std::endl;
out << "<p>" << std::endl;
out << m_metaData.toHtml();
out << "</p>" << std::endl;
out << "</body>" << std::endl;
out << "</html>" << std::endl;
cursor.insertText("ESGRAF 4-8 Auswertungsbogen", titleFormat);
cursor.insertText("\n", titleFormat);
return out.str();
m_metaData.printTo(cursor);
m_v2Svk.printTo(cursor);
m_verbEnd.printTo(cursor);
m_genus.printTo(cursor);
m_akkusativ.printTo(cursor);
m_dativ.printTo(cursor);
m_plural.printTo(cursor);
m_passiv.printTo(cursor);
m_genitiv.printTo(cursor);
m_results.printTo(cursor);
}
void DataModel::pluralModelChanged()

View File

@ -13,6 +13,7 @@
#include "ResultModel.h"
#include <QJsonObject>
#include <QTextCursor>
class DataModel : public QObject
{
@ -34,35 +35,13 @@ public:
public:
DataModel(QObject *parent);
std::string toHtml() const;
void write(std::ostream &outStream) const;
void printTo(QTextCursor &cursor) const;
void write(std::ostream &outStream) const;
void read(std::istream &inStream);
signals:
void modelChanged();
private:
template <class ModelType>
void write(
const ModelType &model, QJsonObject &target, const char *name) const
{
QJsonObject jsonObject;
model.write(jsonObject);
target[name] = jsonObject;
}
template <class ModelType>
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();

View File

@ -1,5 +1,6 @@
#include "MetaDataModel.h"
#include <QTextTable>
#include <QDebug>
#include <sstream>
@ -130,39 +131,52 @@ void MetaDataModel::write(ESGRAF48::MetaDataModel &model) const
model.set_remarks(m_remarks.toStdString());
}
std::string MetaDataModel::toHtml() const
void MetaDataModel::printTo(QTextCursor &cursor) const
{
std::ostringstream out;
cursor.insertBlock();
out << "<table border=\"1\" cellspacing=\"0\" cellpadding=\"2\" frame=\"box\" rules=\"all\">"
<< std::endl;
out << "<tr>" << std::endl;
out << "<td width=\"25%\">Name, Vorname</td>" << std::endl;
out << "<td width=\"25%\">" << m_participant.toHtmlEscaped().toStdString() << "</td>"
<< std::endl;
out << "<td width=\"25%\">Untersucher(in)</td>" << std::endl;
out << "<td width=\"25%\">" << m_instructor.toHtmlEscaped().toStdString() << "</td>"
<< std::endl;
out << "</tr>" << std::endl;
out << "<tr>" << std::endl;
out << "<td>Geburtsdatum</td>" << std::endl;
out << "<td>" << m_dateOfBirth.toString("dd.MM.yyyy").toHtmlEscaped().toStdString() << "</td>"
<< std::endl;
out << "<td colspan=\"2\">Bemerkungen</td>" << std::endl;
out << "</tr>" << std::endl;
out << "<tr>" << std::endl;
out << "<td>Untersuchungsdatum</td>" << std::endl;
out << "<td>" << m_dateOfTest.toString("dd.MM.yyyy").toHtmlEscaped().toStdString() << "</td>"
<< std::endl;
out << "<td colspan=\"2\" rowspan=\"2\">"
<< m_remarks.trimmed().toHtmlEscaped().replace("\n", "<br>").toStdString() << "</td>"
<< std::endl;
out << "</tr>" << std::endl;
out << "<tr>" << std::endl;
out << "<td>Alter am Testtag</td>" << std::endl;
out << "<td>" << getAge().toString() << "</td>" << std::endl;
out << "</tr>" << std::endl;
out << "</table>" << std::endl;
QTextTableFormat tableFormat = defaultTableFormat();
tableFormat.setBorderStyle(QTextTableFormat::BorderStyle_None);
return out.str();
tableFormat.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 25),
QTextLength(QTextLength::PercentageLength, 25),
QTextLength(QTextLength::PercentageLength, 25),
QTextLength(QTextLength::PercentageLength, 25)});
QTextTable *table = cursor.insertTable(4, 4, tableFormat);
table->mergeCells(1, 2, 1, 2);
table->mergeCells(2, 2, 2, 2);
cursor.insertText("Name, Vorname");
cursor.movePosition(QTextCursor::NextCell);
cursor.insertText(m_participant);
cursor.movePosition(QTextCursor::NextCell);
cursor.insertText("Untersucher(in)");
cursor.movePosition(QTextCursor::NextCell);
cursor.insertText(m_instructor);
cursor.movePosition(QTextCursor::NextRow);
cursor.insertText("Geburtsdatum");
cursor.movePosition(QTextCursor::NextCell);
cursor.insertText(m_dateOfBirth.toString("dd.MM.yyyy"));
cursor.movePosition(QTextCursor::NextCell);
if (!m_remarks.trimmed().isEmpty())
{
cursor.insertText("Bemerkungen:");
}
cursor.movePosition(QTextCursor::NextRow);
cursor.insertText("Untersuchungsdatum");
cursor.movePosition(QTextCursor::NextCell);
cursor.insertText(m_dateOfTest.toString("dd.MM.yyyy"));
cursor.movePosition(QTextCursor::NextCell);
cursor.insertText(m_remarks.trimmed());
cursor.movePosition(QTextCursor::NextRow);
cursor.insertText("Alter am Testtag");
cursor.movePosition(QTextCursor::NextCell);
cursor.insertText(getAge().toString().c_str());
cursor.movePosition(QTextCursor::End);
}

View File

@ -1,5 +1,6 @@
#pragma once
#include "../PrintableModel.h"
#include "Age.h"
#include "MetaDataModel.pb.h"
@ -8,8 +9,9 @@
#include <QString>
#include <QDate>
#include <QJsonObject>
#include <QTextCursor>
class MetaDataModel : public QAbstractTableModel
class MetaDataModel : public QAbstractTableModel, protected PrintableModel
{
Q_OBJECT
@ -24,19 +26,17 @@ 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;
void printTo(QTextCursor &cursor) const override;
Age getAge() const
{
return { m_dateOfBirth, m_dateOfTest };
return {m_dateOfBirth, m_dateOfTest};
}
};

46
source/PrintableModel.cpp Normal file
View File

@ -0,0 +1,46 @@
#include "PrintableModel.h"
QTextTableFormat PrintableModel::defaultTableFormat()
{
QTextTableFormat tableFormat;
tableFormat.setCellPadding(2);
tableFormat.setCellSpacing(0);
return tableFormat;
}
void PrintableModel::setCellText(QTextTable &table, int row, int column, const QString &text)
{
auto cell = table.cellAt(row, column);
auto textCursor = cell.firstCursorPosition();
auto blockFormat = textCursor.blockFormat();
blockFormat.setAlignment(Qt::AlignCenter);
textCursor.setBlockFormat(blockFormat);
auto cellFormat = cell.format();
cellFormat.setVerticalAlignment(QTextCharFormat::AlignMiddle);
cell.setFormat(cellFormat);
auto charFormat = textCursor.charFormat();
charFormat.setVerticalAlignment(QTextCharFormat::AlignMiddle);
charFormat.setFontPointSize(8);
textCursor.setCharFormat(charFormat);
textCursor.insertText(text);
}
void PrintableModel::setCellChecked(QTextTable &table, int row, int column, bool check)
{
setCellText(table, row, column, check ? "x" : "\u2610");
}
void PrintableModel::setCellBackground(QTextTable &table, int row, int column, const QColor &color)
{
auto cell = table.cellAt(row, column);
auto cellFormat = cell.format();
cellFormat.setBackground(QBrush(color));
cell.setFormat(cellFormat);
}

23
source/PrintableModel.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <QTextTableFormat>
#include <QTextTable>
class PrintableModel
{
public:
virtual void printTo(QTextCursor &cursor) const = 0;
protected:
static QTextTableFormat defaultTableFormat();
static void setCellText(QTextTable &table, int row, int column, const QString &text);
static void setCellChecked(QTextTable &table, int row, int column, bool check);
static void setCellBackground(QTextTable &table, int row, int column, const QColor &color);
template<typename NumberType>
static void setCellNumber(QTextTable &table, int row, int column, const NumberType &number)
{
setCellText(table, row, column, QString::number(number));
}
};

View File

@ -12,6 +12,7 @@ qt5_wrap_ui(GENUS_UI
add_library(${PROJECT_NAME}
ResultWidget.cpp
TestResult.cpp
ResultModel.cpp
PRMap.cpp
${GENUS_UI}

View File

@ -10,13 +10,13 @@
#include "PassivPR.h"
#include "GenitivPR.h"
#include <QTextTable>
#include <QDebug>
ResultModel::ResultModel(QObject *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 +81,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)
{
@ -102,11 +101,11 @@ QVariant ResultModel::headerData(
case 0:
return "RP";
case 1:
return ">= PR 84";
return "\u2265 PR 84";
case 2:
return "< PR 84";
case 3:
return "<= PR 16";
return "\u2264 PR 16";
default:
return {};
}
@ -210,3 +209,75 @@ void ResultModel::setGenitivResult(unsigned int points)
emit dataChanged(index(0, 7), index(4, 7));
}
}
void ResultModel::printTo(QTextCursor &cursor) const
{
QTextCharFormat headerFormat;
headerFormat.setFontPointSize(10);
cursor.insertBlock();
cursor.insertText("\nProzentränge (PR)");
QTextTableFormat tableFormat = defaultTableFormat();
const unsigned int columnCount = 10;
tableFormat.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10)});
QTextTable *table = cursor.insertTable(4, columnCount, tableFormat);
auto insertText = [&table](int row, int column, const QString &text) {
auto cell = table->cellAt(row, column);
auto textCursor = cell.firstCursorPosition();
auto blockFormat = textCursor.blockFormat();
blockFormat.setAlignment(Qt::AlignCenter);
textCursor.setBlockFormat(blockFormat);
auto cellFormat = cell.format();
cellFormat.setVerticalAlignment(QTextCharFormat::AlignMiddle);
if (row == 3)
{
QBrush backgroundBrush(QColor(192, 192, 192));
cellFormat.setBackground(backgroundBrush);
}
cell.setFormat(cellFormat);
auto charFormat = textCursor.charFormat();
charFormat.setVerticalAlignment(QTextCharFormat::AlignMiddle);
charFormat.setFontPointSize(8);
if (row == 0 || column == 0)
{
charFormat.setFontWeight(QFont::Bold);
}
textCursor.setCharFormat(charFormat);
textCursor.insertText(text);
};
insertText(1, 0, "\u2265 PR 84");
insertText(2, 0, "< PR 84");
insertText(3, 0, "\u2264 PR 16");
for (size_t index = 0; index < m_results.size(); ++index)
{
insertText(0, index + 1, m_results[index].name());
int pr = m_results[index].pr();
insertText(1, index + 1, pr >= 84 ? QString::number(pr) : "-");
insertText(2, index + 1, pr < 84 && pr > 16 ? QString::number(pr) : "-");
insertText(3, index + 1, pr <= 16 ? QString::number(pr) : "-");
}
}

View File

@ -1,48 +1,13 @@
#pragma once
#include "../PrintableModel.h"
#include "Age.h"
#include "TestResult.h"
#include <QAbstractTableModel>
#include <QTextCursor>
class TestResult
{
private:
QString m_name;
size_t m_points = 0;
size_t m_pr = 0;
public:
TestResult(const char *name)
: m_name(name)
{
}
void setPoints(const size_t &points)
{
m_points = points;
}
void setPR(const unsigned int &pr)
{
m_pr = pr;
}
const QString &name() const
{
return m_name;
}
const size_t points() const
{
return m_points;
}
const size_t pr() const
{
return m_pr;
}
};
class ResultModel : public QAbstractTableModel
class ResultModel : public QAbstractTableModel, protected PrintableModel
{
Q_OBJECT
@ -56,8 +21,7 @@ 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;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const override;
@ -72,4 +36,6 @@ public:
void setSvkResult(unsigned int points);
void setPassivResult(unsigned int points);
void setGenitivResult(unsigned int points);
void printTo(QTextCursor &cursor) const override;
};

View File

@ -0,0 +1,31 @@
#include "TestResult.h"
TestResult::TestResult(const char *name)
: m_name(name)
{
}
void TestResult::setPoints(const size_t &points)
{
m_points = points;
}
void TestResult::setPR(const unsigned int &pr)
{
m_pr = pr;
}
QString TestResult::name() const
{
return m_name;
}
size_t TestResult::points() const
{
return m_points;
}
size_t TestResult::pr() const
{
return m_pr;
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <QString>
class TestResult
{
private:
QString m_name;
size_t m_points = 0;
size_t m_pr = 0;
public:
TestResult(const char *name);
void setPoints(const size_t &points);
void setPR(const unsigned int &pr);
QString name() const;
size_t points() const;
size_t pr() const;
};

View File

@ -105,3 +105,8 @@ void AkkusativModel::write(ESGRAF48::AkkusativModel &model) const
futterModel->set_zucker(testItems[7].isChecked());
}
}
std::string AkkusativModel::getName() const
{
return "Subtest 4: Akkusativ und Dativ";
}

View File

@ -12,4 +12,7 @@ public:
void read(const ESGRAF48::AkkusativModel &model);
void write(ESGRAF48::AkkusativModel &model) const;
protected:
std::string getName() const override;
};

View File

@ -105,3 +105,8 @@ void DativModel::write(ESGRAF48::DativModel &model) const
futterModel->set_zucker(testItems[7].isChecked());
}
}
std::string DativModel::getName() const
{
return "";
}

View File

@ -12,4 +12,7 @@ public:
void read(const ESGRAF48::DativModel &model);
void write(ESGRAF48::DativModel &model) const;
protected:
std::string getName() const override;
};

View File

@ -95,3 +95,8 @@ void GenusModel::write(ESGRAF48::GenusModel &model) const
zirkusModel->set_baum(testItems[3].isChecked());
}
}
std::string GenusModel::getName() const
{
return "Subtest 3: Genus";
}

View File

@ -12,4 +12,7 @@ public:
void read(const ESGRAF48::GenusModel &model);
void write(ESGRAF48::GenusModel &model) const;
protected:
std::string getName() const override;
};

View File

@ -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}

View File

@ -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());
}
}
std::string GenitivModel::getName() const
{
return "";
}

View File

@ -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:
std::string getName() const override;
};

View File

@ -0,0 +1,65 @@
#include "LateSkillsModel.h"
#include <QTextTable>
#include <regex>
LateSkillsModel::LateSkillsModel(QObject *parent)
: CheckableTestModel(parent)
{
}
void LateSkillsModel::printTableTo(QTextCursor &cursor) const
{
QTextTableFormat tableFormat = defaultTableFormat();
tableFormat.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 20),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 26),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3)});
QTextTable *table = cursor.insertTable(m_tests.size() * 3, 14, tableFormat);
int currentRow = 0;
for (const auto &test : m_tests)
{
table->mergeCells(currentRow, 0, 3, 1);
int currentColumn = 0;
setCellText(*table, currentRow, currentColumn, test.name());
currentColumn++;
for (auto it = std::begin(test.items()); it != std::end(test.items()); std::advance(it, 2))
{
const auto &item = *it;
const auto &nextItem = *std::next(it);
table->mergeCells(currentRow, currentColumn, 1, 2);
auto itemName = std::regex_replace(item.getText(), std::regex(R"((\S+).*)"), "$1");
setCellText(*table, currentRow, currentColumn, itemName.c_str());
setCellText(*table, currentRow + 1, currentColumn, "1");
setCellText(*table, currentRow + 1, currentColumn + 1, "2");
setCellChecked(*table, currentRow + 2, currentColumn, item.isChecked());
setCellChecked(*table, currentRow + 2, currentColumn + 1, nextItem.isChecked());
currentColumn += 2;
}
setCellNumber(*table, currentRow + 2, 13, test.getPoints());
currentRow += 3;
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "CheckableTestModel.h"
class LateSkillsModel : public CheckableTestModel
{
Q_OBJECT
public:
LateSkillsModel(QObject *parent);
protected:
void printTableTo(QTextCursor &cursor) const override;
};

View File

@ -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());
}
std::string PassivModel::getName() const
{
return "Subtest 6: Späte Fähigkeiten (7;0 - 8;11)";
}

View File

@ -1,9 +1,9 @@
#pragma once
#include "CheckableTestModel.h"
#include "LateSkillsModel.h"
#include "LateSkillsPassivModel.pb.h"
class PassivModel : public CheckableTestModel
class PassivModel : public LateSkillsModel
{
Q_OBJECT
@ -14,4 +14,7 @@ public:
void read(const ESGRAF48::LateSkillsPassivModel &model);
void write(ESGRAF48::LateSkillsPassivModel &model) const;
protected:
std::string getName() const override;
};

View File

@ -1,6 +1,10 @@
#include "PluralModel.h"
#include <QSize>
#include <QTextTable>
#include <QDebug>
#include <regex>
PluralModel::PluralModel(QObject *parent)
: CheckableTestModel(parent)
@ -51,3 +55,41 @@ void PluralModel::write(ESGRAF48::PluralModel &model) const
model.set_baer(testItems[7].isChecked());
model.set_apfel(testItems[8].isChecked());
}
std::string PluralModel::getName() const
{
return "Subtest 5: Plural";
}
void PluralModel::printTableTo(QTextCursor &cursor) const
{
QTextTableFormat tableFormat = defaultTableFormat();
tableFormat.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10)});
QTextTable *table = cursor.insertTable(2, 10, tableFormat);
const auto &test = m_tests.front();
int currentColumn = 0;
for (const auto &item : test.items())
{
std::string itemName = std::regex_replace(item.getText(), std::regex("\\s"), "\n",
std::regex_constants::format_first_only);
setCellText(*table, 0, currentColumn, itemName.c_str());
setCellChecked(*table, 1, currentColumn, item.isChecked());
currentColumn++;
}
}

View File

@ -15,4 +15,9 @@ public:
void read(const ESGRAF48::PluralModel &model);
void write(ESGRAF48::PluralModel &model) const;
protected:
std::string getName() const override;
void printTableTo(QTextCursor &cursor) const override;
};

View File

@ -1,10 +1,12 @@
#include "V2SvkModel.h"
#include <QTextTable>
V2SvkModel::V2SvkModel(QObject *parent)
: CheckableTestModel(parent)
{
m_tests = {
{"W-Frage",
{"W-Fragen",
{"Affe", "Affe", "Affe", "Affe", "Schwein", "Schwein", "Schwein", "Schwein", "Gans",
"Gans", "Gans", "Gans"}},
{"Verbtrennung", {"", "Affe", "", "", "", "", "", "Schwein", "", "", "Gans", ""}},
@ -29,7 +31,7 @@ V2SvkModel::V2SvkModel(QObject *parent)
};
}
unsigned int V2SvkModel::getV2Points()
unsigned int V2SvkModel::getV2Points() const
{
unsigned int points = 0;
@ -49,7 +51,7 @@ unsigned int V2SvkModel::getV2Points()
return points;
}
unsigned int V2SvkModel::getSvkPoints()
unsigned int V2SvkModel::getSvkPoints() const
{
unsigned int points = 0;
@ -199,3 +201,147 @@ void V2SvkModel::read(const ESGRAF48::V2SvkModel &model)
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
}
std::string V2SvkModel::getName() const
{
return "Subtest 1: Verbzweitstellungsregel (V2) und Subjekt-Verb-Kontrollregel (SVK)";
}
void V2SvkModel::printTableTo(QTextCursor &cursor) const
{
QTextTableFormat tableFormat12 = defaultTableFormat();
tableFormat12.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 20),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 5),
QTextLength(QTextLength::PercentageLength, 13),
QTextLength(QTextLength::PercentageLength, 3),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3)});
QTextTableFormat tableFormat6 = defaultTableFormat();
tableFormat6.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 20),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 10),
QTextLength(QTextLength::PercentageLength, 13),
QTextLength(QTextLength::PercentageLength, 3),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3)});
auto writeHeader = [](QTextTable *table, const CheckableTest &test, int colSpan) {
table->mergeCells(0, 0, 2, 1);
int column = 1;
for (auto it = std::begin(test.items()); it != std::end(test.items());
std::advance(it, colSpan))
{
table->mergeCells(0, column, 1, colSpan);
setCellText(*table, 0, column, it->getText().c_str());
column += colSpan;
}
};
auto writeLine = [](QTextTable *table, const CheckableTest &test, int row, int resultColumn) {
int column = 0;
setCellText(*table, row, column, test.name());
for (const auto item : test.items())
{
column++;
if (item.getText().empty())
{
setCellBackground(*table, row, column, QColor(92, 92, 92));
}
else
{
setCellChecked(*table, row, column, item.isChecked());
}
}
setCellNumber(*table, row, resultColumn, test.getPoints());
};
{
QTextTable *table = cursor.insertTable(4, 17, tableFormat12);
writeHeader(table, m_tests[0], 4);
writeLine(table, m_tests[0], 1, 14);
writeLine(table, m_tests[1], 2, 14);
writeLine(table, m_tests[2], 3, 16);
}
cursor.movePosition(QTextCursor::End);
cursor.insertBlock();
cursor.insertText("\n");
{
QTextTable *table = cursor.insertTable(3, 17, tableFormat12);
writeHeader(table, m_tests[3], 4);
writeLine(table, m_tests[3], 1, 14);
writeLine(table, m_tests[4], 2, 16);
}
cursor.movePosition(QTextCursor::End);
cursor.insertBlock();
cursor.insertText("\n");
{
QTextTable *table = cursor.insertTable(3, 11, tableFormat6);
writeHeader(table, m_tests[5], 2);
writeLine(table, m_tests[5], 1, 8);
writeLine(table, m_tests[6], 2, 10);
}
cursor.movePosition(QTextCursor::End);
cursor.insertBlock();
cursor.insertText("\n");
{
QTextTable *table = cursor.insertTable(5, 11, tableFormat6);
writeHeader(table, m_tests[7], 2);
writeLine(table, m_tests[7], 1, 8);
writeLine(table, m_tests[8], 2, 8);
writeLine(table, m_tests[9], 3, 10);
writeLine(table, m_tests[10], 4, 10);
}
}
void V2SvkModel::printSummaryTo(QTextCursor &cursor) const
{
QTextTableFormat tableFormat = defaultTableFormat();
tableFormat.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 72),
QTextLength(QTextLength::PercentageLength, 20),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3)});
QTextTable *table = cursor.insertTable(1, 6, tableFormat);
setCellText(*table, 0, 1, "Rohwertpunkte Total:");
setCellNumber(*table, 0, 3, getV2Points());
setCellNumber(*table, 0, 5, getSvkPoints());
}

View File

@ -3,6 +3,8 @@
#include "CheckableTestModel.h"
#include "V2SvkModel.pb.h"
#include <QTextCursor>
class V2SvkModel : public CheckableTestModel
{
Q_OBJECT
@ -10,12 +12,16 @@ class V2SvkModel : public CheckableTestModel
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);
protected:
bool isValidIndex(const QModelIndex &index) const override;
std::string getName() const override;
void printTableTo(QTextCursor &cursor) const override;
void printSummaryTo(QTextCursor &cursor) const override;
};

View File

@ -1,15 +1,17 @@
#include "VerbEndModel.h"
#include <QTextTable>
#include <QDebug>
VerbEndModel::VerbEndModel(QObject *parent)
: CheckableTestModel(parent)
{
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"}}};
connect(this, &VerbEndModel::dataChanged, this, &VerbEndModel::modelChanged);
}
void VerbEndModel::write(ESGRAF48::VerbEndModel &model) const
@ -98,3 +100,52 @@ void VerbEndModel::read(const ESGRAF48::VerbEndModel &model)
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
}
unsigned int VerbEndModel::getCausalPoints() const
{
unsigned int points = 0;
for (const auto &test : m_tests)
{
for (const auto &item : test.items())
{
if (item.getText() == "Kausal")
{
points += item.points();
}
}
}
return points;
}
void VerbEndModel::modelChanged()
{
emit causalPointsChanged(getCausalPoints());
}
std::string VerbEndModel::getName() const
{
return "Subtest 2: Verbendstellungsregel (VE)";
};
void VerbEndModel::printSummaryTo(QTextCursor &cursor) const
{
QTextTableFormat tableFormat = defaultTableFormat();
tableFormat.setColumnWidthConstraints({QTextLength(QTextLength::PercentageLength, 46),
QTextLength(QTextLength::PercentageLength, 25),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 20),
QTextLength(QTextLength::PercentageLength, 1),
QTextLength(QTextLength::PercentageLength, 3)});
QTextTable *table = cursor.insertTable(1, 8, tableFormat);
setCellText(*table, 0, 1, "Rohwertpunkte Kausalsätze:");
setCellNumber(*table, 0, 3, getCausalPoints());
setCellText(*table, 0, 5, "Rohwertpunkte Total:");
setCellNumber(*table, 0, 7, getPoints());
}

View File

@ -3,6 +3,8 @@
#include "CheckableTestModel.h"
#include "VerbEndModel.pb.h"
#include <QTextCursor>
class VerbEndModel : public CheckableTestModel
{
Q_OBJECT
@ -12,4 +14,16 @@ public:
void write(ESGRAF48::VerbEndModel &model) const;
void read(const ESGRAF48::VerbEndModel &model);
unsigned int getCausalPoints() const;
protected:
std::string getName() const override;
void printSummaryTo(QTextCursor &cursor) const override;
private slots:
void modelChanged();
signals:
void causalPointsChanged(unsigned int points);
};

View File

@ -20,4 +20,11 @@ VerbEndWidget::~VerbEndWidget()
void VerbEndWidget::setModel(VerbEndModel *model)
{
ui->verbEndTableView->setModel(model);
connect(model, &VerbEndModel::causalPointsChanged, this, &VerbEndWidget::causalPointsChanged);
}
void VerbEndWidget::causalPointsChanged(unsigned int points)
{
ui->causalPointsLabel->setText(QString::number(points));
}

View File

@ -20,4 +20,7 @@ public:
~VerbEndWidget();
void setModel(VerbEndModel *model);
public slots:
void causalPointsChanged(unsigned int points);
};

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>556</width>
<height>210</height>
<width>732</width>
<height>381</height>
</rect>
</property>
<property name="windowTitle">
@ -17,6 +17,30 @@
<item>
<widget class="QTableView" name="verbEndTableView"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="maximumSize">
<size>
<width>80</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Kausalsätze: </string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="causalPointsLabel">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>

View File

@ -150,10 +150,8 @@ void MainWindow::closeFile()
void MainWindow::print() const
{
//std::ofstream htmlfile("print.html");
//htmlfile << m_dataModel.toHtml();
QPrinter printer;
printer.setResolution(1200);
QPrintDialog dialog(&printer);
if (dialog.exec() != QDialog::Accepted)
@ -162,7 +160,8 @@ void MainWindow::print() const
}
QTextDocument printDoc;
printDoc.setHtml(QString::fromStdString(m_dataModel.toHtml()));
QTextCursor printCursor(&printDoc);
m_dataModel.printTo(printCursor);
printDoc.print(&printer);
}
@ -211,12 +210,14 @@ void MainWindow::saveFile(const QString &filename)
void MainWindow::savePdf(const QString &filename)
{
QPrinter printer;
printer.setResolution(1200);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setPaperSize(QPrinter::A4);
printer.setOutputFileName(filename);
QTextDocument printDoc;
printDoc.setHtml(QString::fromStdString(m_dataModel.toHtml()));
QTextCursor printCursor(&printDoc);
m_dataModel.printTo(printCursor);
printDoc.print(&printer);
}

View File

@ -5,7 +5,6 @@
#include <QMainWindow>
#include <QString>
class DataModel;
class QDataWidgetMapper;