Merge branch 'custom-print' of github.com:neolit123/subsurface

This commit is contained in:
Dirk Hohndel 2015-08-23 07:38:11 -07:00
commit 2f540b56a8
13 changed files with 479 additions and 133 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -2711,8 +2711,9 @@ process could be used for the Cloud-based storage of dive logs.
[[S_PrintDivelog]]
== Printing a dive log
_Subsurface_ provides a simple interface to print a whole dive log or only a
few selected dives, including dive profiles and other contextual information.
_Subsurface_ provides a simple interface to print a whole dive log or only a few selected dives.
Pre-installed templates or a custom written template can be used to choose where the data will
be fitted into the page.
Before printing, two decisions are required:
@ -2727,15 +2728,10 @@ below).
image::images/PrintDiveLog.jpg["FIGURE: Print dialogue",align="center"]
Under _Print type_ users need to select one of three options:
Under _Print type_ users need to select one of two options:
- Print the complete Dive List: to do this, _Table Print_ should be selected.
- Print the selected dives (dive profiles and all other information) at 6
dives per printed page: to do this, users should select _6 dives per page_.
- Print the selected dives (dive profiles and all other information) at 2
dives per printed page: to do this, users should select _2 dives per page_.
- Print the selected dives (dive profiles and all other information) at 1
dive per printed page: to do this, users should select _1 dive per page_.
- _Dive list_ print: print dives from the list with profiles and other information.
- _Statistics_ print: print yearly statistics of the dives.
Under _Print options_ users need to select:
@ -2744,12 +2740,20 @@ Under _Print options_ users need to select:
selected dives_.
- Printing in colour, achieved by checking the box with _Print in colour_.
The _Ordering_ affects the layout of the page (or part of it) for each dive.
The dive profile could be printed at the top of each dive, with the textual
information underneath, or it could be printed with the textual information at
the top with the dive profile underneath. Users should select the appropriate option in the
print dialogue. See the image below which has a layout with
text below the dive profile.
Under _Template_ users can select:
- A template to be used as the page layout.
- _Delete_ a template from the template list
- _Import_ a new template to the template list
- _Export_ a template from the template list
- _Edit_ a template (choose colors, fonts, font-type)
When editing a template the following options are available:
- _Style_: edit font type, size, choose color palette; this will not affect the template HTML code
- _Template_: edit the template HTML code; by saving, the "Custom" template in the template list will be replaced
- _Colors_: edit the current color palette; the new color palette will overwrite the "Custom" color palette
Users can _Preview_ the printed page by selecting the _Preview_ button on the
dialogue. After preview, changes to the options in the print dialogue can be
@ -2767,6 +2771,11 @@ the output for one particular page.
image::images/Printpreview.jpg["FIGURE: Print preview page",align="center"]
=== Write a custom printing template (advanced)
Writing a custom template is an effective way to produce highly customized printouts. Subsurface uses HTML templates with Grantlee as the printing backend.
See <<_appendix_f_write_a_custom_printing_template ,APPENDIX F>> for information on how to write your own template.
[[S_Configure]]
== Configuring a dive computer
@ -4137,3 +4146,134 @@ If you have downloaded your dives to different dive logging software
before they were overwritten, there is a high change that Subsurface can
import these. However, if the logs are only on your dive computer, they
cannot be salvaged after being over written by new dives.
== APPENDIX F: Write a custom printing template
_Subsurface_ provides a customizable printing support which is based on templates that are transformed by the _Grantlee_
backend to correct _HTML_ syntax, The _HTML_ output is then rendered by _Subsurface_.
To write a custom template the following elements must exist so that the template will be correctly handled and rendered.
=== Main dive loop
_Subsurface_ exports a dive list called (*dives*) to the _Grantlee_ backend. It is possible to iterate over the list as follows:
.template.html
....
{% for dive in dives %}
<h1> {{ dive.number }} </h1>
{% endfor %}
....
.output.html
....
<h1> 1 </h1>
<h1> 2 </h1>
<h1> 3 </h1>
....
Additional information about _Grantlee_ can be found http://www.grantlee.org/apidox/for_themers.html[here]
=== Grantlee exported variables
Only a subset of the dive data is exported:
|====================
|*Name*|*Description*
|number| (*int*) dive number
|id| (*int*) unique dive ID, should be used to fetch the dive profile
|date| (*string*) data of the dive
|time| (*string*) time of the dive
|location| (*string*) location of the dive
|duration| (*string*) duration of the dive
|depth| (*string*) depth of the dive
|divemaster| (*string*) divemaster data
|buddy| (*string*) buddy data
|airTemp| (*string*) air temperature of dive
|waterTemp| (*string*) water temperature of dive
|notes| (*string*) dive notes
|rating| (*int*) dive rating ranges from 0 to 5
|sac| (*string*) sac value
|tags| (*string*) all dive tags concatenate together
|gas| (*string*) used gas cylinder
|=====================
_Subsurface_ also exports *template_options* data. This data must be used as _CSS_ values to provide a dynamically
editable template. The exported data is shown in the following table:
|====================
|*Name*|*Description*
|font| (*string*) font family
|borderwidth| (*int*) border-width value dynamically calculated as 0.1% of the page width with minimum value of 1px
|font_size| (*double*) size of fonts in vw, ranges between 1.0 and 2.0
|line_spacing| (*double*) distance between text lines, ranges between 1.0 and 3.0
|color1| (*string*) background color
|color2| (*string*) primary table cell color
|color3| (*string*) secondary table cell color
|color4| (*string*) primary text color
|color5| (*string*) secondary text color
|color6| (*string*) border colors
|=====================
.template.html
....
border-width: {{ template_options.borderwidth }}px;
....
.output.html
....
border-width: 3px;
....
Another variable that _Subsurface_ exports is *print_options*. This variable contains a single member:
|=====================
|*Name*|*Description*
|grayscale | Use _CSS_ filters to convert the page into grayscale (should be added to body style to enable printing grayscale prints)
|=====================
.template.html
....
body {
{{ print_options.grayscale }};
}
....
.output.html
....
body {
-webkit-filter: grayscale(100%);
}
....
=== Defined CSS selectors
As the dive profile is placed after rendering, _Subsurface_ uses a special _CSS_ selectors to do some searches
in the HTML output. The _CSS_ selectors in the following table should be added.
|====================
|*Selector*|*Type*|*Description*
|dive_{{ dive.id }} | id | is used to fetch the relevant dive profile
|diveProfile | class | each div that will contain a dive profile should have this class selector in addition to the dive_{{ dive.id }} id selector
|dontbreak | class | prevents the div with this class to be divided into two pages, this can be used
in flow layout templates only (when data-numberofdives = 0)
|=====================
IMPORTANT: Rendering dive profiles is not supported for flow layout templates (when data-numberofdives = 0).
=== Special attributes
There are two ways of rendering- either rendering a specific number of dives in each page or make _Subsurface_ try to
fit as much dives as possible into one page (_flow_ rendering).
The *data-numberofdives* data attribute is added to the body tag to set the rendering mode
- render 6 dives per page:
....
<body data-numberofdives = 6>
....
- render as much dives as possible:
....
<body data-numberofdives = 0>
....
IMPORTANT: All CSS units should be in relative lengths only, to support printing on any page size.

View file

@ -59,6 +59,11 @@ void Printer::putProfileImage(QRect profilePlaceholder, QRect viewPort, QPainter
void Printer::flowRender()
{
// add extra padding at the bottom to pages with height not divisible by view port
int paddingBottom = pageSize.height() - (webView->page()->mainFrame()->contentsSize().height() % pageSize.height());
QString styleString = QString::fromUtf8("padding-bottom: ") + QString::number(paddingBottom) + "px;";
webView->page()->mainFrame()->findFirstElement("body").setAttribute("style", styleString);
// render the Qwebview
QPainter painter;
QRect viewPort(0, 0, 0, 0);
@ -90,7 +95,14 @@ void Printer::flowRender()
// rendering progress is 4/5 of total work
emit(progessUpdated((end * 80.0 / fullPageResolution) + done));
static_cast<QPrinter*>(paintDevice)->newPage();
// add new pages only in print mode, while previewing we don't add new pages
if (printMode == Printer::PRINT)
static_cast<QPrinter*>(paintDevice)->newPage();
else {
painter.end();
return;
}
start = dontbreakElement.geometry().y();
}
}
@ -187,6 +199,7 @@ void Printer::print()
return;
}
QPrinter *printerPtr;
printerPtr = static_cast<QPrinter*>(paintDevice);
@ -194,18 +207,17 @@ void Printer::print()
connect(&t, SIGNAL(progressUpdated(int)), this, SLOT(templateProgessUpdated(int)));
dpi = printerPtr->resolution();
//rendering resolution = selected paper size in inchs * printer dpi
#if QT_VERSION >= 0x050300
pageSize.setHeight(printerPtr->pageLayout().paintRectPixels(dpi).height());
pageSize.setWidth(printerPtr->pageLayout().paintRectPixels(dpi).width());
#else
pageSize.setHeight(printerPtr->pageRect(QPrinter::Inch).height() * dpi);
pageSize.setWidth(printerPtr->pageRect(QPrinter::Inch).width() * dpi);
#endif
pageSize.setHeight(qCeil(printerPtr->pageRect(QPrinter::Inch).height() * dpi));
pageSize.setWidth(qCeil(printerPtr->pageRect(QPrinter::Inch).width() * dpi));
webView->page()->setViewportSize(pageSize);
webView->page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
// export border width with at least 1 pixel
templateOptions->border_width = std::max(1, pageSize.width() / 1000);
webView->setHtml(t.generate());
if (printOptions->type == print_options::DIVELIST) {
webView->setHtml(t.generate());
} else if (printOptions->type == print_options::STATISTICS ) {
webView->setHtml(t.generateStatistics());
}
if (printOptions->color_selected && printerPtr->colorMode()) {
printerPtr->setColorMode(QPrinter::Color);
} else {
@ -223,71 +235,13 @@ void Printer::print()
}
int Pages;
if (divesPerPage == 0) {
// add extra padding at the bottom to pages with height not divisible by view port
int paddingBottom = pageSize.height() - (webView->page()->mainFrame()->contentsSize().height() % pageSize.height());
QString styleString = QString::fromUtf8("padding-bottom: ") + QString::number(paddingBottom) + "px;";
webView->page()->mainFrame()->findFirstElement("body").setAttribute("style", styleString);
flowRender();
} else {
Pages = ceil(getTotalWork(printOptions) / (float)divesPerPage);
Pages = qCeil(getTotalWork(printOptions) / (float)divesPerPage);
render(Pages);
}
}
void Printer::print_statistics()
{
QPrinter *printerPtr;
printerPtr = static_cast<QPrinter*>(paintDevice);
stats_t total_stats;
total_stats.selection_size = 0;
total_stats.total_time.seconds = 0;
QString html;
html += "<table border=1>";
html += "<tr>";
html += "<td>Year</td>";
html += "<td>Dives</td>";
html += "<td>Total Time</td>";
html += "<td>Avg Time</td>";
html += "<td>Shortest Time</td>";
html += "<td>Longest Time</td>";
html += "<td>Avg Depth</td>";
html += "<td>Min Depth</td>";
html += "<td>Max Depth</td>";
html += "<td>Avg SAC</td>";
html += "<td>Min SAC</td>";
html += "<td>Max SAC</td>";
html += "<td>Min Temp</td>";
html += "<td>Max Temp</td>";
html += "</tr>";
int i = 0;
while (stats_yearly != NULL && stats_yearly[i].period) {
html += "<tr>";
html += "<td>" + QString::number(stats_yearly[i].period) + "</td>";
html += "<td>" + QString::number(stats_yearly[i].selection_size) + "</td>";
html += "<td>" + QString::fromUtf8(get_time_string(stats_yearly[i].total_time.seconds, 0)) + "</td>";
html += "<td>" + QString::fromUtf8(get_minutes(stats_yearly[i].total_time.seconds / stats_yearly[i].selection_size)) + "</td>";
html += "<td>" + QString::fromUtf8(get_minutes(stats_yearly[i].shortest_time.seconds)) + "</td>";
html += "<td>" + QString::fromUtf8(get_minutes(stats_yearly[i].longest_time.seconds)) + "</td>";
html += "<td>" + get_depth_string(stats_yearly[i].avg_depth) + "</td>";
html += "<td>" + get_depth_string(stats_yearly[i].min_depth) + "</td>";
html += "<td>" + get_depth_string(stats_yearly[i].max_depth) + "</td>";
html += "<td>" + get_volume_string(stats_yearly[i].avg_sac) + "</td>";
html += "<td>" + get_volume_string(stats_yearly[i].min_sac) + "</td>";
html += "<td>" + get_volume_string(stats_yearly[i].max_sac) + "</td>";
html += "<td>" + QString::number(stats_yearly[i].min_temp == 0 ? 0 : get_temp_units(stats_yearly[i].min_temp, NULL)) + "</td>";
html += "<td>" + QString::number(stats_yearly[i].max_temp == 0 ? 0 : get_temp_units(stats_yearly[i].max_temp, NULL)) + "</td>";
html += "</tr>";
total_stats.selection_size += stats_yearly[i].selection_size;
total_stats.total_time.seconds += stats_yearly[i].total_time.seconds;
i++;
}
html += "</table>";
webView->setHtml(html);
webView->print(printerPtr);
}
void Printer::previewOnePage()
{
if (printMode == PREVIEW) {
@ -296,9 +250,24 @@ void Printer::previewOnePage()
pageSize.setHeight(paintDevice->height());
pageSize.setWidth(paintDevice->width());
webView->page()->setViewportSize(pageSize);
webView->setHtml(t.generate());
// initialize the border settings
templateOptions->border_width = std::max(1, pageSize.width() / 1000);
if (printOptions->type == print_options::DIVELIST) {
webView->setHtml(t.generate());
} else if (printOptions->type == print_options::STATISTICS ) {
webView->setHtml(t.generateStatistics());
}
// render only one page
render(1);
bool ok;
int divesPerPage = webView->page()->mainFrame()->findFirstElement("body").attribute("data-numberofdives").toInt(&ok);
if (!ok) {
divesPerPage = 1; // print each dive in a single page if the attribute is missing or malformed
//TODO: show warning
}
if (divesPerPage == 0) {
flowRender();
} else {
render(1);
}
}
}

View file

@ -39,7 +39,6 @@ public:
Printer(QPaintDevice *paintDevice, print_options *printOptions, template_options *templateOptions, PrintMode printMode);
~Printer();
void print();
void print_statistics();
void previewOnePage();
signals:

View file

@ -40,11 +40,11 @@
.mainContainer {
width: 50%;
height: 33.333333%;
height: 33.333%;
margin-left: 0%;
margin-right: 0%;
margin-top: 0;
margin-bottom: 0;
margin-top: 0%;
margin-bottom: 0%;
overflow: hidden;
page-break-inside: avoid;
float: left;
@ -111,12 +111,20 @@
text-overflow: ellipsis;
line-height: {{ template_options.line_spacing }};
}
#sixdivespack {
width: 100%;
height: 100%;
}
</style>
</head>
<body data-numberofdives = 6>
<div id="body_div">
{% block main_rows %}
{% for dive in dives %}
{% if forloop.counter|divisibleby:6 %}
<div id = "sixdivespack">
{% endif %}
<div class="mainContainer">
<div class="innerContainer">
<div class="diveDetails">
@ -173,6 +181,9 @@
</div>
</div>
</div>
{% if forloop.counter|divisibleby:6 %}
</div>
{% endif %}
{% endfor %}
{% endblock %}
<div id="footer">

View file

@ -0,0 +1,97 @@
<html>
<head>
<style>
body {
{{ print_options.grayscale }};
padding: 0;
margin: 0;
font-size: {{ template_options.font_size }}vw;
line-height: {{ template_options.line_spacing }};
font-family: {{ template_options.font }};
}
h1 {
float: left;
font-size: {{ template_options.font_size }}vw;
}
th {
font-size: {{ template_options.font_size }}vw;
page-break-inside: avoid;
-webkit-column-break-inside: avoid;
padding-top: 1vh;
padding-bottom: 1vh;
-webkit-box-sizing: border-box;
box-sizing: border-box;
border-width: {{ template_options.borderwidth }}px;
border-style:solid;
border-color: {{ template_options.color6 }};
}
#body_div {
background-color: {{ template_options.color1 }};
}
.mainContainer {
width: 99%;
height: 100%;
margin-left: 0.5%;
margin-right: 0.5%;
margin-top: 0%;
margin-bottom: 0%;
overflow: hidden;
border-width: 0;
page-break-inside: avoid;
}
.table_class {
overflow: hidden;
width: 100%;
margin: 0%;
}
</style>
</head>
<body data-numberofdives = 0>
<div id="body_div">
<table class="table_class">
<tr style="background-color: {{ template_options.color2 }}; color: {{ template_options.color4 }}">
<td>Year</td>
<td>Dives</td>
<td>Total Time</td>
<td>Avg Time</td>
<td>Shortest Time</td>
<td>Longest Time</td>
<td>Avg Depth</td>
<td>Min Depth</td>
<td>Max Depth</td>
<td>Avg SAC</td>
<td>Min SAC</td>
<td>Max SAC</td>
<td>Min Temp</td>
<td>Max Temp</td>
</tr>
{% block main_rows %}
{% for year in years %}
<tr class="dontbreak" style="background-color: {{ template_options.color3 }}; color: {{ template_options.color5 }};">
<td> {{ year.year }} </td>
<td> {{ year.dives }} </td>
<td> {{ year.total_time }} </td>
<td> {{ year.avg_time }} </td>
<td> {{ year.shortest_time }} </td>
<td> {{ year.longest_time }} </td>
<td> {{ year.avg_depth }} </td>
<td> {{ year.min_depth }} </td>
<td> {{ year.max_depth }} </td>
<td> {{ year.avg_sac }} </td>
<td> {{ year.min_sac }} </td>
<td> {{ year.max_sac }} </td>
<td> {{ year.min_temp }} </td>
<td> {{ year.max_temp }} </td>
</tr>
{% endfor %}
{% endblock %}
</table>
</div>
</body>
</html>

View file

@ -178,15 +178,8 @@ void PrintDialog::printClicked(void)
{
QPrintDialog printDialog(&qprinter, this);
if (printDialog.exec() == QDialog::Accepted) {
switch (printOptions.type) {
case print_options::DIVELIST:
connect(printer, SIGNAL(progessUpdated(int)), progressBar, SLOT(setValue(int)));
printer->print();
break;
case print_options::STATISTICS:
printer->print_statistics();
break;
}
connect(printer, SIGNAL(progessUpdated(int)), progressBar, SLOT(setValue(int)));
printer->print();
close();
}
}
@ -194,14 +187,7 @@ void PrintDialog::printClicked(void)
void PrintDialog::onPaintRequested(QPrinter *printerPtr)
{
connect(printer, SIGNAL(progessUpdated(int)), progressBar, SLOT(setValue(int)));
switch (printOptions.type) {
case print_options::DIVELIST:
printer->print();
break;
case print_options::STATISTICS:
printer->print_statistics();
break;
}
printer->print();
progressBar->setValue(0);
disconnect(printer, SIGNAL(progessUpdated(int)), progressBar, SLOT(setValue(int)));
}

View file

@ -31,21 +31,7 @@ void PrintOptions::setup()
break;
}
// insert existing templates in the UI and select the current template
qSort(grantlee_templates);
int current_index = 0, index = 0;
for (QList<QString>::iterator i = grantlee_templates.begin(); i != grantlee_templates.end(); ++i) {
if ((*i).compare(printOptions->p_template) == 0) {
current_index = index;
break;
}
index++;
}
ui.printTemplate->clear();
for (QList<QString>::iterator i = grantlee_templates.begin(); i != grantlee_templates.end(); ++i) {
ui.printTemplate->addItem((*i).split('.')[0], QVariant::fromValue(*i));
}
ui.printTemplate->setCurrentIndex(current_index);
setupTemplates();
// general print option checkboxes
if (printOptions->color_selected)
@ -63,6 +49,43 @@ void PrintOptions::setup()
hasSetupSlots = true;
}
void PrintOptions::setupTemplates()
{
if (printOptions->type == print_options::DIVELIST) {
// insert dive list templates in the UI and select the current template
qSort(grantlee_templates);
int current_index = 0, index = 0;
for (QList<QString>::iterator i = grantlee_templates.begin(); i != grantlee_templates.end(); ++i) {
if ((*i).compare(printOptions->p_template) == 0) {
current_index = index;
break;
}
index++;
}
ui.printTemplate->clear();
for (QList<QString>::iterator i = grantlee_templates.begin(); i != grantlee_templates.end(); ++i) {
ui.printTemplate->addItem((*i).split('.')[0], QVariant::fromValue(*i));
}
ui.printTemplate->setCurrentIndex(current_index);
} else if (printOptions->type == print_options::STATISTICS) {
// insert statistics templates in the UI and select the current template
qSort(grantlee_statistics_templates);
int current_index = 0, index = 0;
for (QList<QString>::iterator i = grantlee_statistics_templates.begin(); i != grantlee_statistics_templates.end(); ++i) {
if ((*i).compare(printOptions->p_template) == 0) {
current_index = index;
break;
}
index++;
}
ui.printTemplate->clear();
for (QList<QString>::iterator i = grantlee_statistics_templates.begin(); i != grantlee_statistics_templates.end(); ++i) {
ui.printTemplate->addItem((*i).split('.')[0], QVariant::fromValue(*i));
}
ui.printTemplate->setCurrentIndex(current_index);
}
}
// print type radio buttons
void PrintOptions::on_radioDiveListPrint_toggled(bool check)
{
@ -70,15 +93,14 @@ void PrintOptions::on_radioDiveListPrint_toggled(bool check)
printOptions->type = print_options::DIVELIST;
// print options
ui.printInColor->setEnabled(true);
ui.printSelected->setEnabled(true);
// print template
ui.deleteButton->setEnabled(true);
ui.editButton->setEnabled(true);
ui.exportButton->setEnabled(true);
ui.importButton->setEnabled(true);
ui.printTemplate->setEnabled(true);
setupTemplates();
}
}
@ -88,15 +110,14 @@ void PrintOptions::on_radioStatisticsPrint_toggled(bool check)
printOptions->type = print_options::STATISTICS;
// print options
ui.printInColor->setEnabled(false);
ui.printSelected->setEnabled(false);
// print template
ui.deleteButton->setEnabled(false);
ui.editButton->setEnabled(false);
ui.exportButton->setEnabled(false);
ui.importButton->setEnabled(false);
ui.printTemplate->setEnabled(false);
setupTemplates();
}
}

View file

@ -70,6 +70,7 @@ private:
struct print_options *printOptions;
struct template_options *templateOptions;
bool hasSetupSlots;
void setupTemplates();
private
slots:

View file

@ -35,6 +35,9 @@ TemplateEdit::TemplateEdit(QWidget *parent, struct print_options *printOptions,
ui->plainTextEdit->setPlainText(grantlee_template);
editingCustomColors = false;
if (printOptions->type == print_options::STATISTICS) {
ui->plainTextEdit->setEnabled(false);
}
updatePreview();
}
@ -125,8 +128,8 @@ void TemplateEdit::saveSettings()
if (msgBox.exec() == QMessageBox::Save) {
memcpy(templateOptions, &newTemplateOptions, sizeof(struct template_options));
if (grantlee_template.compare(ui->plainTextEdit->toPlainText())) {
printOptions->p_template = "custom.html";
TemplateLayout::writeTemplate("custom.html", ui->plainTextEdit->toPlainText());
printOptions->p_template = "Custom.html";
TemplateLayout::writeTemplate("Custom.html", ui->plainTextEdit->toPlainText());
}
if (templateOptions->color_palette_index == CUSTOM) {
custom_colors = templateOptions->color_palette;

View file

@ -4,7 +4,7 @@
#include "helpers.h"
#include "display.h"
QList<QString> grantlee_templates;
QList<QString> grantlee_templates, grantlee_statistics_templates;
int getTotalWork(print_options *printOptions)
{
@ -24,6 +24,7 @@ int getTotalWork(print_options *printOptions)
void find_all_templates()
{
grantlee_templates.clear();
grantlee_statistics_templates.clear();
QDir dir(getSubsurfaceDataPath("printing_templates"));
QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
foreach (QFileInfo finfo, list) {
@ -32,6 +33,15 @@ void find_all_templates()
grantlee_templates.append(finfo.fileName());
}
}
// find statistics templates
dir.setPath(getSubsurfaceDataPath("printing_templates") + QDir::separator() + "statistics");
list = dir.entryInfoList(QDir::Files | QDir::NoDotAndDotDot);
foreach (QFileInfo finfo, list) {
QString filename = finfo.fileName();
if (filename.at(filename.size() - 1) != '~') {
grantlee_statistics_templates.append(finfo.fileName());
}
}
}
TemplateLayout::TemplateLayout(print_options *PrintOptions, template_options *templateOptions) :
@ -98,6 +108,53 @@ QString TemplateLayout::generate()
return htmlContent;
}
QString TemplateLayout::generateStatistics()
{
QString htmlContent;
m_engine = new Grantlee::Engine(this);
QSharedPointer<Grantlee::FileSystemTemplateLoader> m_templateLoader =
QSharedPointer<Grantlee::FileSystemTemplateLoader>(new Grantlee::FileSystemTemplateLoader());
m_templateLoader->setTemplateDirs(QStringList() << getSubsurfaceDataPath("printing_templates/statistics"));
m_engine->addTemplateLoader(m_templateLoader);
Grantlee::registerMetaType<YearInfo>();
Grantlee::registerMetaType<template_options>();
Grantlee::registerMetaType<print_options>();
QVariantHash mapping;
QVariantList years;
int i = 0;
while (stats_yearly != NULL && stats_yearly[i].period) {
YearInfo year(stats_yearly[i]);
years.append(QVariant::fromValue(year));
i++;
}
mapping.insert("years", years);
mapping.insert("template_options", QVariant::fromValue(*templateOptions));
mapping.insert("print_options", QVariant::fromValue(*PrintOptions));
Grantlee::Context c(mapping);
Grantlee::Template t = m_engine->loadByName(PrintOptions->p_template);
if (!t || t->error()) {
qDebug() << "Can't load template";
return htmlContent;
}
htmlContent = t->render(&c);
if (t->error()) {
qDebug() << "Can't render template";
return htmlContent;
}
emit progressUpdated(100);
return htmlContent;
}
QString TemplateLayout::readTemplate(QString template_name)
{
QFile qfile(getSubsurfaceDataPath("printing_templates") + QDir::separator() + template_name);
@ -306,3 +363,13 @@ void Dive::put_sac()
m_sac = QString::number(value, 'f', decimal).append(unit);
}
}
YearInfo::YearInfo()
{
}
YearInfo::~YearInfo()
{
}

View file

@ -4,11 +4,13 @@
#include <grantlee_templates.h>
#include "mainwindow.h"
#include "printoptions.h"
#include "statistics.h"
#include "helpers.h"
int getTotalWork(print_options *printOptions);
void find_all_templates();
extern QList<QString> grantlee_templates;
extern QList<QString> grantlee_templates, grantlee_statistics_templates;
class TemplateLayout : public QObject {
Q_OBJECT
@ -16,6 +18,7 @@ public:
TemplateLayout(print_options *PrintOptions, template_options *templateOptions);
~TemplateLayout();
QString generate();
QString generateStatistics();
static QString readTemplate(QString template_name);
static void writeTemplate(QString template_name, QString grantlee_template);
@ -98,9 +101,22 @@ public:
QString sac() const;
};
class YearInfo {
public:
stats_t *year;
YearInfo(stats_t& year)
:year(&year)
{
}
YearInfo();
~YearInfo();
};
Q_DECLARE_METATYPE(Dive)
Q_DECLARE_METATYPE(template_options)
Q_DECLARE_METATYPE(print_options)
Q_DECLARE_METATYPE(YearInfo)
GRANTLEE_BEGIN_LOOKUP(Dive)
if (property == "number")
@ -182,4 +198,40 @@ if (property == "grayscale") {
}
GRANTLEE_END_LOOKUP
GRANTLEE_BEGIN_LOOKUP(YearInfo)
if (property == "year") {
return object.year->period;
} else if (property == "dives") {
return object.year->selection_size;
} else if (property == "min_temp") {
const char *unit;
double temp = get_temp_units(object.year->min_temp, &unit);
return object.year->min_temp == 0 ? "0" : QString::number(temp, 'g', 2) + unit;
} else if (property == "max_temp") {
const char *unit;
double temp = get_temp_units(object.year->max_temp, &unit);
return object.year->max_temp == 0 ? "0" : QString::number(temp, 'g', 2) + unit;
} else if (property == "total_time") {
return get_time_string(object.year->total_time.seconds, 0);
} else if (property == "avg_time") {
return get_minutes(object.year->total_time.seconds / object.year->selection_size);
} else if (property == "shortest_time") {
return get_minutes(object.year->shortest_time.seconds);
} else if (property == "longest_time") {
return get_minutes(object.year->longest_time.seconds);
} else if (property == "avg_depth") {
return get_depth_string(object.year->avg_depth);
} else if (property == "min_depth") {
return get_depth_string(object.year->min_depth);
} else if (property == "max_depth") {
return get_depth_string(object.year->max_depth);
} else if (property == "avg_sac") {
return get_volume_string(object.year->avg_sac);
} else if (property == "min_sac") {
return get_volume_string(object.year->min_sac);
} else if (property == "max_sac") {
return get_volume_string(object.year->max_sac);
}
GRANTLEE_END_LOOKUP
#endif