Mercurial > hg > syntilista
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; +} + +