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 # 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) if(LIBGRANTLEE_FROM_PKGCONFIG)
pkg_config_library(GRANTLEE libgrantlee REQUIRED) pkg_config_library(GRANTLEE libgrantlee REQUIRED)
set(GRANTLEE_LIBRARIES "") set(GRANTLEE_LIBRARIES "")
@ -113,12 +117,6 @@ if(NOT NO_PRINTING)
) )
endif() 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) set(SUBSURFACE_LINK_LIBRARIES ${SUBSURFACE_LINK_LIBRARIES} ${LIBDIVECOMPUTER_LIBRARIES} ${LIBGIT2_LIBRARIES} ${GRANTLEE_LIBRARIES} -lusb-1.0)
# handle out of tree build correctly # handle out of tree build correctly

View file

@ -3,43 +3,102 @@
#include <QtWebKitWidgets> #include <QtWebKitWidgets>
#include <QPainter> #include <QPainter>
#include <QWebElementCollection>
#include <QWebElement>
#define A4_300DPI_WIDTH 2480 Printer::Printer(QPrinter *printer, print_options *printOptions)
#define A4_300DPI_HIGHT 3508
Printer::Printer(QPrinter *printer)
{ {
this->printer = printer; this->printer = printer;
this->printOptions = printOptions;
//override these settings for now.
printer->setFullPage(true);
printer->setOrientation(QPrinter::Portrait);
printer->setPaperSize(QPrinter::A4);
printer->setPrintRange(QPrinter::AllPages);
printer->setResolution(300);
done = 0; 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() 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; QPainter painter;
QSize size(A4_300DPI_WIDTH, A4_300DPI_HIGHT); QRect viewPort(0, 0, pageSize.width(), pageSize.height());
painter.begin(printer); painter.begin(printer);
painter.setRenderHint(QPainter::Antialiasing); painter.setRenderHint(QPainter::Antialiasing);
painter.setRenderHint(QPainter::SmoothPixmapTransform); 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++) { for (int i = 0; i < Pages; i++) {
// render the base Html template
webView->page()->mainFrame()->render(&painter, QWebFrame::ContentsLayer); 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)); emit(progessUpdated((i * 80.0 / Pages) + done));
if (i < Pages - 1) if (i < Pages - 1)
printer->newPage(); printer->newPage();
} }
painter.end(); 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 //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() void Printer::print()
{ {
TemplateLayout t; TemplateLayout t(printOptions);
connect(&t, SIGNAL(progressUpdated(int)), this, SLOT(templateProgessUpdated(int)));
webView = new QWebView(); 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()); webView->setHtml(t.generate());
render(); render();
} }

View file

@ -3,6 +3,11 @@
#include <QPrinter> #include <QPrinter>
#include <QWebView> #include <QWebView>
#include <QRect>
#include <QPainter>
#include "profile/profilewidget2.h"
#include "printoptions.h"
class Printer : public QObject { class Printer : public QObject {
Q_OBJECT Q_OBJECT
@ -10,14 +15,18 @@ class Printer : public QObject {
private: private:
QPrinter *printer; QPrinter *printer;
QWebView *webView; QWebView *webView;
void render(); print_options *printOptions;
QSize pageSize;
int done; int done;
int dpi;
void render();
void putProfileImage(QRect box, QRect viewPort, QPainter *painter, struct dive *dive, QPointer<ProfileWidget2> profile);
private slots: private slots:
void templateProgessUpdated(int value); void templateProgessUpdated(int value);
public: public:
Printer(QPrinter *printer); Printer(QPrinter *printer, print_options *printOptions);
void print(); void print();
signals: 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; overflow: hidden !important;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
#footer {
width: 96%;
height: 50%;
}
</style> </style>
</head> </head>
<body> <body>
@ -175,8 +180,7 @@
</td> </td>
</tr> </tr>
</tbody></table> </tbody></table>
<div class="diveProfile"> <div class="diveProfile" id="dive_{{ dive.number }}">
<h1> Dive profile area </h1>
</div> </div>
</div> </div>
<div class="notesPart"> <div class="notesPart">
@ -200,5 +204,7 @@
</div> </div>
{% endfor %} {% endfor %}
{% endblock %} {% endblock %}
<div id="footer">
<div>
</body> </body>
</html> </html>

View file

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

View file

@ -1,4 +1,5 @@
#include "printoptions.h" #include "printoptions.h"
#include <QDebug>
PrintOptions::PrintOptions(QWidget *parent, struct print_options *printOpt) PrintOptions::PrintOptions(QWidget *parent, struct print_options *printOpt)
{ {
@ -26,6 +27,14 @@ void PrintOptions::setup(struct print_options *printOpt)
ui.radioStatisticsPrint->setChecked(true); ui.radioStatisticsPrint->setChecked(true);
break; 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 // general print option checkboxes
if (printOptions->color_selected) if (printOptions->color_selected)
@ -75,3 +84,16 @@ void PrintOptions::printSelectedClicked(bool check)
{ {
printOptions->print_selected = 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, TABLE,
STATISTICS STATISTICS
} type; } type;
enum print_template {
ONE_DIVE,
TWO_DIVE
} p_template;
bool print_selected; bool print_selected;
bool color_selected; bool color_selected;
bool landscape; bool landscape;
@ -36,6 +40,7 @@ slots:
void on_radioStatisticsPrint_clicked(bool check); void on_radioStatisticsPrint_clicked(bool check);
void on_radioTablePrint_clicked(bool check); void on_radioTablePrint_clicked(bool check);
void on_radioDiveListPrint_clicked(bool check); void on_radioDiveListPrint_clicked(bool check);
void on_printTemplate_currentIndexChanged(int index);
}; };
#endif // PRINTOPTIONS_H #endif // PRINTOPTIONS_H

View file

@ -38,7 +38,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Dive list Print</string> <string>&amp;Dive list print</string>
</property> </property>
<property name="checked"> <property name="checked">
<bool>true</bool> <bool>true</bool>
@ -54,7 +54,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Table Print</string> <string>&amp;Table print</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -67,7 +67,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Statistics Print</string> <string>&amp;Statistics print</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -132,7 +132,12 @@
<widget class="QComboBox" name="printTemplate"> <widget class="QComboBox" name="printTemplate">
<item> <item>
<property name="text"> <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> </property>
</item> </item>
</widget> </widget>

View file

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

View file

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