# HG changeset patch # User Matti Hamalainen # Date 1505221000 -10800 # Node ID 325e7590f93eacd66f3860aca422ba89421dabf9 # Parent afadc1380fb12bb752b75047cee9c80794ac39ec Move most of the printing related code to printing.cpp diff -r afadc1380fb1 -r 325e7590f93e Makefile.gen --- a/Makefile.gen Fri Sep 08 03:22:54 2017 +0300 +++ b/Makefile.gen Tue Sep 12 15:56:40 2017 +0300 @@ -20,7 +20,7 @@ APP_SRC=src/ APP_IMG=img/ APP_BIN=$(BINPATH)Syntilista$(EXEEXT) -APP_OBJS=main.o resources.o moc_main.o +APP_OBJS=main.o printing.o resources.o moc_main.o APP_VERSION := $(shell cat VERSION) comma:= , APP_VERSION_COM := $(subst .,$(comma),$(APP_VERSION)) diff -r afadc1380fb1 -r 325e7590f93e src/main.cpp --- a/src/main.cpp Fri Sep 08 03:22:54 2017 +0300 +++ b/src/main.cpp Tue Sep 12 15:56:40 2017 +0300 @@ -9,8 +9,6 @@ #include #include #include -#include -#include #include #include "main.h" #include "ui_mainwindow.h" @@ -131,7 +129,7 @@ // report it to stdout if so. Return "false" if error has occured, // true otherwise. // -bool slCheckAndReportSQLError(const QString where, const QSqlError &err, bool report = false) +bool slCheckAndReportSQLError(const QString where, const QSqlError &err, bool report) { if (err.isValid()) { @@ -784,235 +782,6 @@ } -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; -} - - void SyntilistaMainWindow::on_button_DeletePerson_clicked() { if (currPerson.id <= 0) diff -r afadc1380fb1 -r 325e7590f93e src/main.h --- a/src/main.h Fri Sep 08 03:22:54 2017 +0300 +++ b/src/main.h Tue Sep 12 15:56:40 2017 +0300 @@ -44,8 +44,9 @@ #define BACKUP_HTTP 1 // HTTP(s) POST to a PHP script + // -// Custom SQL models +// Person information record // class PersonInfo : public QObject { @@ -74,7 +75,25 @@ }; +// +// Global functions +// +double slMoneyStrToValue(const QString &str); +QString slMoneyValueToStr(double val); +QString slCleanupStr(const QString &str); +const QDateTime slDateTimeToLocal(const QDateTime &val); +const QString slDateTimeToStr(const QDateTime &val); +void slLog(const QString &mtype, const QString &msg); +int slErrorMsg(QString title, QString msg); +bool slCheckAndReportSQLError(const QString where, const QSqlError &err, bool report = false); + +void slGetPersonInfoRec(QSqlQuery &query, PersonInfo &info); + + +// +// Custom SQL models +// class PersonSQLModel : public QSqlQueryModel { Q_OBJECT diff -r afadc1380fb1 -r 325e7590f93e src/printing.cpp --- /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 +// (C) Copyright 2017 Tecnic Software productions (TNSP) +// +// Distributed under 3-clause BSD style license, refer to +// included file "COPYING" for exact terms. +// +#include +#include +#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; +} + +