This commit is contained in:
Dirk Hohndel 2015-06-19 20:33:54 -07:00
commit 56d701dfff
11 changed files with 374 additions and 47 deletions

View file

@ -99,7 +99,11 @@ endif()
# setup Grantlee
if(NOT NO_PRINTING)
if(NO_PRINTING)
message(STATUS "building without printing support")
add_definitions(-DNO_PRINTING)
set(GRANTLEE_LIBRARIES "")
else()
if(LIBGRANTLEE_FROM_PKGCONFIG)
pkg_config_library(GRANTLEE libgrantlee REQUIRED)
set(GRANTLEE_LIBRARIES "")
@ -113,12 +117,6 @@ if(NOT NO_PRINTING)
)
endif()
if(NO_PRINTING)
message(STATUS "building without printing support")
add_definitions(-DNO_PRINTING)
set(GRANTLEE_LIBRARIES "")
endif()
set(SUBSURFACE_LINK_LIBRARIES ${SUBSURFACE_LINK_LIBRARIES} ${LIBDIVECOMPUTER_LIBRARIES} ${LIBGIT2_LIBRARIES} ${GRANTLEE_LIBRARIES} -lusb-1.0)
# handle out of tree build correctly

View file

@ -3,43 +3,102 @@
#include <QtWebKitWidgets>
#include <QPainter>
#include <QWebElementCollection>
#include <QWebElement>
#define A4_300DPI_WIDTH 2480
#define A4_300DPI_HIGHT 3508
Printer::Printer(QPrinter *printer)
Printer::Printer(QPrinter *printer, print_options *printOptions)
{
this->printer = printer;
//override these settings for now.
printer->setFullPage(true);
printer->setOrientation(QPrinter::Portrait);
printer->setPaperSize(QPrinter::A4);
printer->setPrintRange(QPrinter::AllPages);
printer->setResolution(300);
this->printOptions = printOptions;
done = 0;
}
void Printer::putProfileImage(QRect profilePlaceholder, QRect viewPort, QPainter *painter, struct dive *dive, QPointer<ProfileWidget2> profile)
{
int x = profilePlaceholder.x() - viewPort.x();
int y = profilePlaceholder.y() - viewPort.y();
// use the placeHolder and the viewPort position to calculate the relative position of the dive profile.
QRect pos(x, y, profilePlaceholder.width(), profilePlaceholder.height());
profile->plotDive(dive, true);
profile->render(painter, pos);
}
void Printer::render()
{
QPointer<ProfileWidget2> profile = MainWindow::instance()->graphics();
// keep original preferences
int profileFrameStyle = profile->frameStyle();
int animationOriginal = prefs.animation_speed;
double fontScale = profile->getFontPrintScale();
// apply printing settings to profile
profile->setFrameStyle(QFrame::NoFrame);
profile->setPrintMode(true, !printOptions->color_selected);
profile->setFontPrintScale(0.6);
profile->setToolTipVisibile(false);
prefs.animation_speed = 0;
// render the Qwebview
QPainter painter;
QSize size(A4_300DPI_WIDTH, A4_300DPI_HIGHT);
QRect viewPort(0, 0, pageSize.width(), pageSize.height());
painter.begin(printer);
painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
webView->page()->setViewportSize(size);
int divesPerPage;
switch (printOptions->p_template) {
case print_options::ONE_DIVE:
divesPerPage = 1;
break;
case print_options::TWO_DIVE:
divesPerPage = 2;
break;
}
int Pages = ceil(getTotalWork() / (float)divesPerPage);
int Pages = ceil((float)webView->page()->mainFrame()->contentsSize().rheight() / A4_300DPI_HIGHT);
// get all refereces to diveprofile class in the Html template
QWebElementCollection collection = webView->page()->mainFrame()->findAllElements(".diveprofile");
QSize originalSize = profile->size();
if (collection.count() > 0) {
profile->resize(collection.at(0).geometry().size());
}
int elemNo = 0;
for (int i = 0; i < Pages; i++) {
// render the base Html template
webView->page()->mainFrame()->render(&painter, QWebFrame::ContentsLayer);
webView->page()->mainFrame()->scroll(0, A4_300DPI_HIGHT);
//rendering progress is 4/5 of total work
// render all the dive profiles in the current page
while (elemNo < collection.count() && collection.at(elemNo).geometry().y() < viewPort.y() + viewPort.height()) {
// dive id field should be dive_{{dive_no}} se we remove the first 5 characters
int diveNo = collection.at(elemNo).attribute("id").remove(0, 5).toInt(0, 10);
putProfileImage(collection.at(elemNo).geometry(), viewPort, &painter, get_dive(diveNo - 1), profile);
elemNo++;
}
// scroll the webview to the next page
webView->page()->mainFrame()->scroll(0, pageSize.height());
viewPort.adjust(0, pageSize.height(), 0, pageSize.height());
// rendering progress is 4/5 of total work
emit(progessUpdated((i * 80.0 / Pages) + done));
if (i < Pages - 1)
printer->newPage();
}
painter.end();
// return profle settings
profile->setFrameStyle(profileFrameStyle);
profile->setPrintMode(false);
profile->setFontPrintScale(fontScale);
profile->setToolTipVisibile(true);
profile->resize(originalSize);
prefs.animation_speed = animationOriginal;
//replot the dive after returning the settings
profile->plotDive(0, true);
}
//value: ranges from 0 : 100 and shows the progress of the templating engine
@ -51,9 +110,15 @@ void Printer::templateProgessUpdated(int value)
void Printer::print()
{
TemplateLayout t;
connect(&t, SIGNAL(progressUpdated(int)), this, SLOT(templateProgessUpdated(int)));
TemplateLayout t(printOptions);
webView = new QWebView();
connect(&t, SIGNAL(progressUpdated(int)), this, SLOT(templateProgessUpdated(int)));
dpi = printer->resolution();
//rendering resolution = selected paper size in inchs * printer dpi
pageSize.setHeight(printer->pageLayout().paintRect(QPageLayout::Inch).height() * dpi);
pageSize.setWidth(printer->pageLayout().paintRect(QPageLayout::Inch).width() * dpi);
webView->page()->setViewportSize(pageSize);
webView->setHtml(t.generate());
render();
}

View file

@ -3,6 +3,11 @@
#include <QPrinter>
#include <QWebView>
#include <QRect>
#include <QPainter>
#include "profile/profilewidget2.h"
#include "printoptions.h"
class Printer : public QObject {
Q_OBJECT
@ -10,14 +15,18 @@ class Printer : public QObject {
private:
QPrinter *printer;
QWebView *webView;
void render();
print_options *printOptions;
QSize pageSize;
int done;
int dpi;
void render();
void putProfileImage(QRect box, QRect viewPort, QPainter *painter, struct dive *dive, QPointer<ProfileWidget2> profile);
private slots:
void templateProgessUpdated(int value);
public:
Printer(QPrinter *printer);
Printer(QPrinter *printer, print_options *printOptions);
void print();
signals:

View file

@ -0,0 +1,204 @@
<html>
<head>
<style>
body {
background-color: white;
padding: 0;
margin: 0;
font-size: 1.2vw;
}
h1 {
font-size: 1.2vw;
float: left;
}
table {
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box;
border:max(1px, 0.1vw);
border-style:solid;
}
.mainContainer {
width: 96%;
height: 100%;
margin-left: 2%;
margin-right: 2%;
margin-top: 0%;
margin-bottom: 0%;
overflow: hidden;
border-width: 0;
page-break-inside: avoid;
}
.innerContainer {
width: 98%;
height: 98%;
padding: 1%;
overflow: hidden;
}
.diveDetails {
width: 98%;
height: 98%;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box;
border:max(1px, 0.1vw);
border-style:solid;
float: left;
}
.diveProfile {
width: 97%;
height: 40%;
margin: 1.5%;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box;
border:max(1px, 0.1vw);
border-style:solid;
}
.dataSection {
width: 97%;
height: 40%;
margin: 1.5%;
}
.fieldTitle {
background-color: #CfC7C5;
overflow: hidden;
}
.table_class {
float: left;
margin: 1.5%;
}
.notes_table_class {
overflow: hidden;
width: 97%;
margin: 1.5%;
float: left;
}
</style>
</head>
<body>
{% block main_rows %}
{% for dive in dives %}
<div class="mainContainer">
<div class="innerContainer">
<div class="diveDetails">
<div class="diveProfile" id="dive_{{ dive.number }}">
</div>
<div class="dataSection">
<table class="table_class">
<tbody><tr>
<td class="fieldTitle">
<h1> Dive No. </h1>
</td>
<td>
<h1> {{ dive.number }} </h1>
</td>
</tr>
<tr>
<td class="fieldTitle">
<h1> Date </h1>
</td>
<td><h1> {{ dive.date }} </h1>
</td>
</tr>
<tr>
<td class="fieldTitle">
<h1> Location </h1>
</td>
<td>
<h1> {{ dive.location }} </h1>
</td>
</tr>
<tr>
<td class="fieldTitle">
<h1> Max depth </h1>
</td>
<td>
<h1> {{ dive.depth }} </h1>
</td>
</tr>
<tr>
<td class="fieldTitle">
<h1> Duration </h1>
</td>
<td>
<h1> {{ dive.duration }} </h1>
</td>
</tr>
</tbody></table>
<table class="table_class">
<tbody><tr>
<td class="fieldTitle">
<h1> Time. </h1>
</td>
<td>
<h1> {{ dive.time }} </h1>
</td>
</tr>
<tr>
<td class="fieldTitle">
<h1> Air Temp. </h1>
</td>
<td><h1> {{ dive.airTemp }} </h1>
</td>
</tr>
<tr>
<td class="fieldTitle">
<h1> Water Temp. </h1>
</td>
<td>
<h1> {{ dive.waterTemp }} </h1>
</td>
</tr>
<tr>
<td class="fieldTitle">
<h1> Buddy </h1>
</td>
<td>
<h1> {{ dive.buddy }} </h1>
</td>
</tr>
<tr>
<td class="fieldTitle">
<h1> Dive Master </h1>
</td>
<td>
<h1> {{ dive.divemaster }} </h1>
</td>
</tr>
</tbody>
</table>
<table class="notes_table_class">
<tbody>
<tr>
<td class="fieldTitle">
<h1> Notes </h1>
</td>
</tr>
<tr>
<td>
<div class="textArea">
<h1> {{ dive.notes }} </h1>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
</body>
</html>

View file

@ -84,6 +84,11 @@
overflow: hidden !important;
text-overflow: ellipsis;
}
#footer {
width: 96%;
height: 50%;
}
</style>
</head>
<body>
@ -175,8 +180,7 @@
</td>
</tr>
</tbody></table>
<div class="diveProfile">
<h1> Dive profile area </h1>
<div class="diveProfile" id="dive_{{ dive.number }}">
</div>
</div>
<div class="notesPart">
@ -200,5 +204,7 @@
</div>
{% endfor %}
{% endblock %}
<div id="footer">
<div>
</body>
</html>

View file

@ -20,12 +20,14 @@ PrintDialog::PrintDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f
printOptions.print_selected = true;
printOptions.color_selected = true;
printOptions.landscape = false;
printOptions.p_template = print_options::ONE_DIVE;
} else {
s.beginGroup(SETTINGS_GROUP);
printOptions.type = (print_options::print_type)s.value("type").toInt();
printOptions.print_selected = s.value("print_selected").toBool();
printOptions.color_selected = s.value("color_selected").toBool();
printOptions.landscape = s.value("landscape").toBool();
printOptions.p_template = (print_options::print_template)s.value("template_selected").toInt();
qprinter.setOrientation((QPrinter::Orientation)printOptions.landscape);
}
@ -33,7 +35,7 @@ PrintDialog::PrintDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f
optionsWidget = new PrintOptions(this, &printOptions);
// create a new printer object
printer = new Printer(&qprinter);
printer = new Printer(&qprinter, &printOptions);
QVBoxLayout *layout = new QVBoxLayout(this);
setLayout(layout);
@ -85,6 +87,7 @@ void PrintDialog::onFinished()
s.setValue("type", printOptions.type);
s.setValue("print_selected", printOptions.print_selected);
s.setValue("color_selected", printOptions.color_selected);
s.setValue("template_selected", printOptions.p_template);
}
void PrintDialog::previewClicked(void)

View file

@ -1,4 +1,5 @@
#include "printoptions.h"
#include <QDebug>
PrintOptions::PrintOptions(QWidget *parent, struct print_options *printOpt)
{
@ -26,6 +27,14 @@ void PrintOptions::setup(struct print_options *printOpt)
ui.radioStatisticsPrint->setChecked(true);
break;
}
switch (printOptions->p_template) {
case print_options::ONE_DIVE:
ui.printTemplate->setCurrentIndex(0);
break;
case print_options::TWO_DIVE:
ui.printTemplate->setCurrentIndex(1);
break;
}
// general print option checkboxes
if (printOptions->color_selected)
@ -75,3 +84,16 @@ void PrintOptions::printSelectedClicked(bool check)
{
printOptions->print_selected = check;
}
void PrintOptions::on_printTemplate_currentIndexChanged(int index)
{
switch(index){
case 0:
printOptions->p_template = print_options::ONE_DIVE;
break;
case 1:
printOptions->p_template = print_options::TWO_DIVE;
break;
}
}

View file

@ -11,6 +11,10 @@ struct print_options {
TABLE,
STATISTICS
} type;
enum print_template {
ONE_DIVE,
TWO_DIVE
} p_template;
bool print_selected;
bool color_selected;
bool landscape;
@ -36,6 +40,7 @@ slots:
void on_radioStatisticsPrint_clicked(bool check);
void on_radioTablePrint_clicked(bool check);
void on_radioDiveListPrint_clicked(bool check);
void on_printTemplate_currentIndexChanged(int index);
};
#endif // PRINTOPTIONS_H

View file

@ -38,7 +38,7 @@
</sizepolicy>
</property>
<property name="text">
<string>&amp;Dive list Print</string>
<string>&amp;Dive list print</string>
</property>
<property name="checked">
<bool>true</bool>
@ -54,7 +54,7 @@
</sizepolicy>
</property>
<property name="text">
<string>&amp;Table Print</string>
<string>&amp;Table print</string>
</property>
</widget>
</item>
@ -67,7 +67,7 @@
</sizepolicy>
</property>
<property name="text">
<string>&amp;Statistics Print</string>
<string>&amp;Statistics print</string>
</property>
</widget>
</item>
@ -132,7 +132,12 @@
<widget class="QComboBox" name="printTemplate">
<item>
<property name="text">
<string>2 Dives per page</string>
<string>One dive per page</string>
</property>
</item>
<item>
<property name="text">
<string>Two dives per page</string>
</property>
</item>
</widget>

View file

@ -3,16 +3,7 @@
#include "templatelayout.h"
#include "helpers.h"
TemplateLayout::TemplateLayout()
{
}
TemplateLayout::~TemplateLayout()
{
delete m_engine;
}
int TemplateLayout::getTotalWork()
int getTotalWork()
{
int dives = 0, i;
struct dive *dive;
@ -25,10 +16,21 @@ int TemplateLayout::getTotalWork()
return dives;
}
TemplateLayout::TemplateLayout(print_options *PrintOptions)
{
this->PrintOptions = PrintOptions;
}
TemplateLayout::~TemplateLayout()
{
delete m_engine;
}
QString TemplateLayout::generate()
{
int progress = 0;
int totalWork = getTotalWork();
QString templateName;
QString htmlContent;
m_engine = new Grantlee::Engine(this);
@ -58,7 +60,12 @@ QString TemplateLayout::generate()
Grantlee::Context c(mapping);
Grantlee::Template t = m_engine->loadByName("base.html");
if (PrintOptions->p_template == print_options::ONE_DIVE) {
templateName = "one_dive.html";
} else if (PrintOptions->p_template == print_options::TWO_DIVE) {
templateName = "two_dives.html";
}
Grantlee::Template t = m_engine->loadByName(templateName);
if (!t || t->error()) {
qDebug() << "Can't load template";
return htmlContent;

View file

@ -3,17 +3,20 @@
#include <grantlee_templates.h>
#include "mainwindow.h"
#include "printoptions.h"
int getTotalWork();
class TemplateLayout : public QObject {
Q_OBJECT
public:
TemplateLayout();
TemplateLayout(print_options *PrintOptions);
~TemplateLayout();
QString generate();
private:
Grantlee::Engine *m_engine;
int getTotalWork();
print_options *PrintOptions;
signals:
void progressUpdated(int value);