summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2015-08-23 07:38:11 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-08-23 07:38:11 -0700
commit2f540b56a8e42c8a0722dec3676297024f31eb74 (patch)
treed5c34830520481fccef873a3cbc5b9f60aae8d07
parentfbce8a0378f5ebcd36dbc08b3b5771ccf5cad830 (diff)
parentcc864794753eb586e89470d87196e13568cb9031 (diff)
downloadsubsurface-2f540b56a8e42c8a0722dec3676297024f31eb74.tar.gz
Merge branch 'custom-print' of github.com:neolit123/subsurface
-rw-r--r--Documentation/images/PrintDiveLog.jpgbin35196 -> 33884 bytes
-rw-r--r--Documentation/images/Printpreview.jpgbin23664 -> 30041 bytes
-rw-r--r--Documentation/user-manual.txt172
-rw-r--r--printer.cpp111
-rw-r--r--printer.h1
-rw-r--r--printing_templates/Six Dives.html17
-rw-r--r--printing_templates/statistics/Default.html97
-rw-r--r--qt-ui/printdialog.cpp20
-rw-r--r--qt-ui/printoptions.cpp63
-rw-r--r--qt-ui/printoptions.h1
-rw-r--r--qt-ui/templateedit.cpp7
-rw-r--r--templatelayout.cpp69
-rw-r--r--templatelayout.h54
13 files changed, 479 insertions, 133 deletions
diff --git a/Documentation/images/PrintDiveLog.jpg b/Documentation/images/PrintDiveLog.jpg
index 7a485c4ff..8ff972dd7 100644
--- a/Documentation/images/PrintDiveLog.jpg
+++ b/Documentation/images/PrintDiveLog.jpg
Binary files differ
diff --git a/Documentation/images/Printpreview.jpg b/Documentation/images/Printpreview.jpg
index ab5db7fa5..7297d80cc 100644
--- a/Documentation/images/Printpreview.jpg
+++ b/Documentation/images/Printpreview.jpg
Binary files differ
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index 815bb9b2a..943d2268d 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -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.
diff --git a/printer.cpp b/printer.cpp
index b0caa0815..f0197d446 100644
--- a/printer.cpp
+++ b/printer.cpp
@@ -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);
+ }
}
}
diff --git a/printer.h b/printer.h
index 5c7652a8d..979cacd6a 100644
--- a/printer.h
+++ b/printer.h
@@ -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:
diff --git a/printing_templates/Six Dives.html b/printing_templates/Six Dives.html
index 3f2c7b95e..9d4d1341e 100644
--- a/printing_templates/Six Dives.html
+++ b/printing_templates/Six Dives.html
@@ -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">
diff --git a/printing_templates/statistics/Default.html b/printing_templates/statistics/Default.html
new file mode 100644
index 000000000..4ec02766a
--- /dev/null
+++ b/printing_templates/statistics/Default.html
@@ -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>
diff --git a/qt-ui/printdialog.cpp b/qt-ui/printdialog.cpp
index 002f9b9f4..cf08062d2 100644
--- a/qt-ui/printdialog.cpp
+++ b/qt-ui/printdialog.cpp
@@ -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)));
}
diff --git a/qt-ui/printoptions.cpp b/qt-ui/printoptions.cpp
index 419098cf8..cb944f9d7 100644
--- a/qt-ui/printoptions.cpp
+++ b/qt-ui/printoptions.cpp
@@ -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();
}
}
diff --git a/qt-ui/printoptions.h b/qt-ui/printoptions.h
index 6d7ffffee..9c50b10f3 100644
--- a/qt-ui/printoptions.h
+++ b/qt-ui/printoptions.h
@@ -70,6 +70,7 @@ private:
struct print_options *printOptions;
struct template_options *templateOptions;
bool hasSetupSlots;
+ void setupTemplates();
private
slots:
diff --git a/qt-ui/templateedit.cpp b/qt-ui/templateedit.cpp
index e4e6453ac..b50338090 100644
--- a/qt-ui/templateedit.cpp
+++ b/qt-ui/templateedit.cpp
@@ -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;
diff --git a/templatelayout.cpp b/templatelayout.cpp
index b0098fbd9..c52968f09 100644
--- a/templatelayout.cpp
+++ b/templatelayout.cpp
@@ -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()
+{
+
+}
diff --git a/templatelayout.h b/templatelayout.h
index 41a3cbfa9..d9fa29295 100644
--- a/templatelayout.h
+++ b/templatelayout.h
@@ -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