diff src/printing.cpp @ 157:325e7590f93e

Move most of the printing related code to printing.cpp
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 12 Sep 2017 15:56:40 +0300
parents
children f5c1861b48aa
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/printing.cpp	Tue Sep 12 15:56:40 2017 +0300
@@ -0,0 +1,242 @@
+//
+// Syntilista - debt list/management database program
+// Programmed and designed by Matti Hämäläinen <ccr@tnsp.org>
+// (C) Copyright 2017 Tecnic Software productions (TNSP)
+//
+// Distributed under 3-clause BSD style license, refer to
+// included file "COPYING" for exact terms.
+//
+#include <QPrintDialog>
+#include <QPrintPreviewDialog>
+#include "main.h"
+
+
+void SyntilistaMainWindow::on_button_Print_clicked()
+{
+    // Create a printer object and force some basic settings
+    QPrinter printer(QPrinter::HighResolution);
+    printer.setPageSize(QPageSize(QPageSize::A4));
+    printer.setColorMode(QPrinter::GrayScale);
+    printer.setResolution(300);
+
+    // We need to get the page count here, and also need it again in
+    // printDocument(), but there is no sane way to pass that there,
+    // so some code duplication is unfortunately necessary
+    SLPageInfo pinfo;
+    pinfo.npages = 0;
+    pinfo.nlinesPerPage = 0;
+
+    QPixmap tmpPixmap(1000, 1300);
+    QPainter tmpPainter;
+    tmpPainter.begin(&tmpPixmap);
+    bool ret = printDocumentPage(pinfo, true, -1, &tmpPainter, &printer);
+    tmpPainter.end();
+
+    if (!ret)
+    {
+        // Some kind of error occured
+        return;
+    }
+
+
+    // Set available pages
+    printer.setFromTo(1, pinfo.npages);
+
+    // Create print preview dialog and show it
+    QPrintPreviewDialog preview(&printer, this);
+    preview.setWindowModality(Qt::ApplicationModal);
+    preview.setSizeGripEnabled(true);
+
+    connect(
+        &preview,
+        SIGNAL(paintRequested(QPrinter *)),
+        this,
+        SLOT(printDocument(QPrinter *)));
+
+    preview.exec();
+}
+
+
+void SyntilistaMainWindow::printDocument(QPrinter *printer)
+{
+    // Create progress dialog
+    QProgressDialog progress(
+        tr("Tulostetaan ..."),
+        tr("Peruuta"),
+        0,
+        1,
+        this);
+
+    progress.setWindowModality(Qt::ApplicationModal);
+
+    // Again, get the page info here .. we need the number of lines per page
+    SLPageInfo pinfo;
+    pinfo.npages = 0;
+    pinfo.nlinesPerPage = 0;
+
+    QPixmap tmpPixmap(1000, 1300);
+    QPainter tmpPainter;
+    tmpPainter.begin(&tmpPixmap);
+    bool ret = printDocumentPage(pinfo, true, -1, &tmpPainter, printer);
+    tmpPainter.end();
+
+    if (!ret)
+        return;
+
+    // If from and to are 0, we are supposed to print all pages
+    if (printer->fromPage() == 0 && printer->toPage() == 0)
+        printer->setFromTo(1, pinfo.npages);
+
+    // Setup rest of the progress dialog here
+    progress.setMinimum(printer->fromPage() - 1);
+    progress.setMaximum(printer->toPage());
+
+    // Begin painting to the printer (or preview)
+    QPainter painter;
+    painter.begin(printer);
+
+    bool firstPage = true;
+    for (int page = printer->fromPage(); page <= printer->toPage(); page++)
+    {
+        if (!firstPage)
+            printer->newPage();
+
+        qApp->processEvents();
+        if (progress.wasCanceled())
+            break;
+
+        printDocumentPage(pinfo, false, page, &painter, printer);
+        progress.setValue(page);
+        firstPage = false;
+    }
+
+    painter.end();
+}
+
+
+bool SyntilistaMainWindow::printDocumentPage(SLPageInfo &pinfo, const bool getPageInfo, const int npage, QPainter *pt, QPrinter *printer)
+{
+    // Form the SQL query for list of users
+    QString querystr = QStringLiteral(
+        "SELECT id,first_name,last_name,extra_info,added,updated, "
+        "(SELECT TOTAL(value) FROM transactions WHERE transactions.person=people.id) AS balance "
+        "FROM people ORDER BY last_name ASC,first_name ASC");
+
+    // If we are fetching page info, we need to process all entries
+    if (!getPageInfo)
+    {
+        // Otherwise we can limit to given page number
+        querystr += QStringLiteral(" LIMIT %1 OFFSET %2").
+            arg(pinfo.nlinesPerPage).
+            arg((npage - 1) * pinfo.nlinesPerPage);
+    }
+
+    QSqlQuery query;
+    query.prepare(querystr);
+    query.setForwardOnly(true);
+    query.exec();
+
+    if (!slCheckAndReportSQLError("printDocumentPage()", query.lastError()))
+    {
+        slErrorMsg(
+            tr("SQL-tietokantavirhe"),
+            tr("Tietokantaa selattaessa tapahtui virhe."));
+
+        return false;
+    }
+
+    pt->save();
+    if (!getPageInfo)
+    {
+        pt->scale(
+            printer->pageRect().width() / 1000.0f,
+            printer->pageRect().height() / 1300.0f);
+    }
+
+    QFont font1("Arial", 5);
+    SLDrawContext ctx(pt);
+    ctx.setFont(font1);
+
+    int nline = 0;
+    while (query.next())
+    {
+        PersonInfo info;
+        slGetPersonInfoRec(query, info);
+
+        // Check for end of page
+        // KLUDGE for now
+        if (getPageInfo && ctx.lfq(10) >= 1300.0f)
+        {
+            if (nline > pinfo.nlinesPerPage)
+                pinfo.nlinesPerPage = nline;
+
+            pinfo.npages++;
+            nline = 0;
+        }
+
+        if (nline == 0)
+        {
+            // If we are at the start of the page, we shall draw a header
+            pt->setBrush(QBrush(Qt::black));
+            pt->setPen(QPen(Qt::black, 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
+
+            ctx.setPos(0, 0);
+            ctx.drawText(   5,  180, tr("Etunimi"));
+            ctx.drawText( 200,  230, tr("Sukunimi"));
+            ctx.drawText( 450,  190, tr("Lisätty"));
+            ctx.drawText( 650,  190, tr("Päivitetty"));
+            ctx.drawText( 870,  120, tr("Tase"));
+            ctx.lf();
+
+            pt->drawLine(0, ctx.m_pos.y(), 1000, ctx.m_pos.y());
+
+            ctx.move(0, 5);
+        }
+
+        // Draw a gray bar under every second line
+        if (nline % 2 == 0)
+        {
+            pt->fillRect(
+                0,
+                ctx.m_pos.y() - 1,
+                1000,
+                ctx.boundRect().height() + 4,
+                QColor(0, 0, 0, 40));
+        }
+
+        ctx.drawText(   5,  180, info.firstName);
+        ctx.drawText( 200,  230, info.lastName);
+        ctx.drawText( 450,  190, slDateTimeToStr(info.added));
+        ctx.drawText( 650,  190, slDateTimeToStr(info.updated));
+        ctx.drawText( 870,  120, slMoneyValueToStr(info.balance), Qt::AlignRight);
+
+        ctx.lf(10);
+        nline++;
+    }
+
+    query.finish();
+
+    if (getPageInfo)
+    {
+        if (nline > pinfo.nlinesPerPage)
+            pinfo.nlinesPerPage = nline;
+
+        pinfo.npages++;
+    }
+    else
+    {
+        ctx.setPos(0, 1240);
+        ctx.drawText(0, 1000,
+            tr("Sivu %1 / %2 (%3 / %4)").
+            arg(npage - printer->fromPage() + 1).
+            arg(printer->toPage() - printer->fromPage() + 1).
+            arg(npage).
+            arg(printer->toPage()),
+            Qt::AlignHCenter);
+    }
+
+    pt->restore();
+    return true;
+}
+
+