File indexing completed on 2024-12-01 03:32:26

0001 // SPDX-FileCopyrightText: 2002-2010 Peter Hedlund <peter.hedlund@kdemail.net>
0002 // SPDX-FileCopyrightText: 2023 Carl Schwan <carl@carlschwan.eu>
0003 // SPDX-License-Identifier: GPL-2.0-or-later
0004 
0005 #include "exporter.h"
0006 
0007 #include <KLocalizedString>
0008 #include <QPrintDialog>
0009 #include <QPrintPreviewDialog>
0010 #include <QPrinter>
0011 #include <QTextDocument>
0012 #include <QTextTable>
0013 #include <array>
0014 #include <qstringliteral.h>
0015 
0016 #include "kwordquiz_version.h"
0017 
0018 using namespace Qt::Literals::StringLiterals;
0019 
0020 void Exporter::print(const PrintStyle printStyle)
0021 {
0022     QPrinter printer;
0023     QPrintDialog printDialog(&printer, nullptr);
0024 
0025     if (printDialog.exec() == QDialog::Accepted) {
0026         QTextDocument td;
0027         createPages(&printer, &td, true, printStyle);
0028     }
0029 }
0030 
0031 void Exporter::printPreview(const PrintStyle printStyle)
0032 {
0033     QPrinter printer;
0034     QPrintPreviewDialog preview(&printer);
0035 
0036     connect(&preview, &QPrintPreviewDialog::paintRequested, this, [this, printStyle](QPrinter *printer) {
0037         printPreviewRequested(printer, printStyle);
0038     });
0039 
0040     preview.exec();
0041 }
0042 
0043 void Exporter::printPreviewRequested(QPrinter *printer, const PrintStyle printStyle)
0044 {
0045     QTextDocument td;
0046     createPages(printer, &td, true, printStyle);
0047 }
0048 
0049 void Exporter::createPages(QPrinter *printer, QTextDocument *textDoc, bool sendToPrinter, const PrintStyle printStyle)
0050 {
0051     printer->setFullPage(true);
0052     int myDpi = printer->logicalDpiY();
0053 
0054     if (printStyle == Flashcard) {
0055         printer->setPageOrientation(QPageLayout::Landscape);
0056 
0057         int cardWidth = qRound(5 * qreal(myDpi));
0058         int cardHeight = qRound(3 * qreal(myDpi));
0059 
0060         QTextTable *table = textDoc->rootFrame()->lastCursorPosition().insertTable(m_cardModel->rowCount(), 2);
0061 
0062         QTextTableFormat tableFormat = table->format();
0063         tableFormat.setHeaderRowCount(0);
0064         tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_None);
0065         tableFormat.setCellSpacing(0);
0066         tableFormat.setCellPadding(0);
0067 
0068         QList<QTextLength> constraints;
0069         constraints.append(QTextLength(QTextLength::FixedLength, cardWidth));
0070         constraints.append(QTextLength(QTextLength::FixedLength, cardWidth));
0071 
0072         tableFormat.setColumnWidthConstraints(constraints);
0073         table->setFormat(tableFormat);
0074 
0075         QTextBlockFormat headerFormat;
0076         headerFormat.setAlignment(Qt::AlignLeft);
0077 
0078         QTextCharFormat headerCharFormat;
0079         headerCharFormat.setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont));
0080 
0081         QTextBlockFormat cellFormat;
0082         cellFormat.setAlignment(Qt::AlignCenter);
0083 
0084         QTextCharFormat cellCharFormat;
0085         cellCharFormat.setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont));
0086 
0087         QTextFrameFormat cardFormat;
0088         cardFormat.setBorder(1);
0089         cardFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
0090         cardFormat.setBorderBrush(QBrush(Qt::black));
0091         cardFormat.setWidth(QTextLength(QTextLength::FixedLength, cardWidth));
0092         cardFormat.setHeight(QTextLength(QTextLength::FixedLength, cardHeight));
0093         cardFormat.setPadding(qRound(0.25 * myDpi));
0094 
0095         QTextFrameFormat lineFormat;
0096         lineFormat.setBorder(1);
0097         lineFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
0098         lineFormat.setBorderBrush(QBrush(Qt::black));
0099         lineFormat.setWidth(QTextLength(QTextLength::FixedLength, qRound(4.5 * myDpi)));
0100         lineFormat.setHeight(1.1); // 1 is drawn as a box whereas this is drawn as a line. Strange...
0101         lineFormat.setPadding(0);
0102 
0103         QTextFrame *card;
0104         for (int i = 0; i < m_cardModel->rowCount(); i++) {
0105             const std::array<int, 2> roles = {
0106                 KWQCardModel::QuestionRole,
0107                 KWQCardModel::AnswerRole,
0108             };
0109             int j = 0;
0110             for (const auto role : roles) {
0111                 cardFormat.setPosition(QTextFrameFormat::FloatLeft);
0112                 card = table->cellAt(i, j).firstCursorPosition().insertFrame(cardFormat);
0113                 card->lastCursorPosition().insertText(m_cardModel->headerData(j, Qt::Horizontal, Qt::DisplayRole).toString(), headerCharFormat);
0114                 card->lastCursorPosition().insertFrame(lineFormat);
0115                 card->lastCursorPosition().insertBlock();
0116                 card->lastCursorPosition().insertBlock();
0117                 card->lastCursorPosition().insertBlock(cellFormat, cellCharFormat);
0118                 card->lastCursorPosition().insertText(m_cardModel->data(m_cardModel->index(i, 0), role).toString(), cellCharFormat);
0119             }
0120         }
0121     } else {
0122         textDoc->rootFrame()->lastCursorPosition().insertText(QStringLiteral("kwordquiz %1").arg(QStringLiteral(KWORDQUIZ_VERSION_STRING)));
0123 
0124         if (printStyle == Exam)
0125             textDoc->rootFrame()->lastCursorPosition().insertText(QLatin1Char(' ') + i18n("Name:_____________________________ Date:__________"));
0126 
0127         QTextTable *table;
0128         if (printStyle == Exam)
0129             table = textDoc->rootFrame()->lastCursorPosition().insertTable(m_cardModel->rowCount() + 1, 4);
0130         else
0131             table = textDoc->rootFrame()->lastCursorPosition().insertTable(m_cardModel->rowCount() + 1, 3);
0132 
0133         QTextTableFormat tableFormat = table->format();
0134         tableFormat.setHeaderRowCount(1);
0135         tableFormat.setBorder(1);
0136         tableFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Solid);
0137         tableFormat.setCellSpacing(0);
0138         tableFormat.setBorderBrush(QBrush(Qt::black));
0139         tableFormat.setCellPadding(2);
0140 
0141         QList<QTextLength> constraints;
0142         // constraints.append(QTextLength(QTextLength::FixedLength,
0143         // verticalHeader()->width()));
0144         constraints.append(QTextLength(QTextLength::FixedLength, 100));
0145         constraints.append(QTextLength(QTextLength::FixedLength, 100));
0146         if (printStyle == Exam)
0147             constraints.append(QTextLength(QTextLength::FixedLength, 50));
0148         tableFormat.setColumnWidthConstraints(constraints);
0149 
0150         table->setFormat(tableFormat);
0151 
0152         QTextBlockFormat headerFormat;
0153         headerFormat.setAlignment(Qt::AlignHCenter);
0154 
0155         QTextCharFormat headerCharFormat;
0156         headerCharFormat.setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont));
0157 
0158         QTextCursor cellCursor;
0159         cellCursor = table->cellAt(0, 1).firstCursorPosition();
0160         cellCursor.mergeBlockFormat(headerFormat);
0161         cellCursor.mergeCharFormat(headerCharFormat);
0162         cellCursor.insertText(m_cardModel->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString());
0163 
0164         cellCursor = table->cellAt(0, 2).firstCursorPosition();
0165         cellCursor.mergeBlockFormat(headerFormat);
0166         cellCursor.mergeCharFormat(headerCharFormat);
0167         cellCursor.insertText(m_cardModel->headerData(1, Qt::Horizontal, Qt::DisplayRole).toString());
0168 
0169         if (printStyle == Exam) {
0170             cellCursor = table->cellAt(0, 3).firstCursorPosition();
0171             cellCursor.mergeBlockFormat(headerFormat);
0172             cellCursor.mergeCharFormat(headerCharFormat);
0173             cellCursor.insertText(i18n("Score"));
0174         }
0175 
0176         headerCharFormat = cellCursor.charFormat();
0177         QTextCharFormat cellCharFormat = cellCursor.charFormat();
0178         cellCharFormat.setFont(QFontDatabase::systemFont(QFontDatabase::GeneralFont));
0179 
0180         for (int i = 0; i < m_cardModel->rowCount(); i++) {
0181             table->cellAt(i + 1, 0).firstCursorPosition().insertText(m_cardModel->headerData(i, Qt::Vertical, Qt::DisplayRole).toString(), headerCharFormat);
0182             table->cellAt(i + 1, 1).firstCursorPosition().insertText(m_cardModel->data(m_cardModel->index(i, 0), KWQCardModel::QuestionRole).toString(),
0183                                                                      cellCharFormat);
0184             if (printStyle == List)
0185                 table->cellAt(i + 1, 2).firstCursorPosition().insertText(m_cardModel->data(m_cardModel->index(i, 0), KWQCardModel::AnswerRole).toString(),
0186                                                                          cellCharFormat);
0187         }
0188     }
0189 
0190     if (sendToPrinter) {
0191         textDoc->print(printer);
0192     }
0193 }
0194 
0195 #include "moc_exporter.cpp"