diff options
33 files changed, 949 insertions, 314 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7b7f783b9..deec8b397 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,17 @@ include_directories(. qt-ui/profile ) +# get the version string -- this is only used for Mac Bundle at this point +# the other version data gets updated when running make - this is set when running cmake +execute_process( + COMMAND sh scripts/get-version linux + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE SSRF_VERSION_STRING + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +message(STATUS "Creating build files for Subsurface ${SSRF_VERSION_STRING}") + # compiler specific settings if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 ") @@ -147,7 +158,7 @@ else() set(WEBKIT_LIB Qt5::WebKitWidgets) 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} ${LIBUSB_LIBRARIES}) # handle out of tree build correctly string(COMPARE EQUAL "${${PROJECT_NAME}_SOURCE_DIR}" "${${PROJECT_NAME}_BINARY_DIR}" insource) @@ -260,9 +271,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") set(MACOSX_BUNDLE_ICON_FILE Subsurface.icns) set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.subsurface-divelog") set(MACOSX_BUNDLE_BUNDLE_NAME "Subsurface") - set(MACOSX_BUNDLE_BUNDLE_VERSION "4.4.1") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "4.4.1") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "4.4.1") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${SSRF_VERSION_STRING}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${SSRF_VERSION_STRING}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${SSRF_VERSION_STRING}") set(MACOSX_BUNDLE_COPYRIGHT "Linus Torvalds, Dirk Hohndel, Tomaz Canabrava, and others") set_source_files_properties(${ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") set(SUBSURFACE_PKG MACOSX_BUNDLE ${ICON_FILE}) @@ -364,6 +375,7 @@ set(SUBSURFACE_MODELS_LIB_SRCS qt-models/divepicturemodel.cpp qt-models/diveplotdatamodel.cpp qt-models/divelocationmodel.cpp + qt-models/divesitepicturesmodel.cpp ) source_group("Subsurface Models" FILES ${SUBSURFACE_MODELS}) @@ -93,7 +93,7 @@ like this: mkdir -p ~/src cd ~/src -git clone -b v4.4.2 git://subsurface-divelog.org/subsurface +git clone git://subsurface-divelog.org/subsurface ./subsurface/scripts/build.sh # <- this step will take quite a while as it # compiles a handful of libraries before # building Subsurface @@ -133,75 +133,56 @@ $ xcode-select --install 1) Install Homebrew -$ ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go/install)" +$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 2) Install needed dependencies -$ brew install asciidoc libzip sqlite cmake libusb pkg-config +$ brew install asciidoc libzip sqlite cmake libusb pkg-config automake libtool 3) Make the brew version of sqlite the default $ brew link --force sqlite -4) Download Qt from http://www.qt.io/download-open-source/ +4) Download and install Qt -In the installer, chose an install folder (e.g., /home/username/Qt5), in -"Select components" select the most recent version and be sure you also -install the "Source Components". +You can build Qt from source or use the prebuilt binaries for Mac. Start +by downloading the online installer: -Build it (takes a long time) +$ curl -L -o ~/Downloads/qt-unified-mac-x64-online.dmg \ + http://download.qt.io/official_releases/online_installers/qt-unified-mac-x64-online.dmg +$ open ~/Downloads/qt-unified-mac-x64-online.dmg -$ cd ~/Qt5/5.4/Src/ +Double click on the Qt installer shown in the Finder window. -$ ./configure -prefix /usr/local -opensource +In the installer, chose an install folder (the build script we are using +below assumes that you accept the default of /home/<your username>/Qt), in +"Select components" select the most recent version and (if you want to +build Qt from source) be sure you also install the "Source Components". +To save time and disk space you can unselect Android and IOS packages +as well as QtWebEngine, Qt3D, Qt Canvas 3D and the Qt Extras. -$ make -j4 +If you want to build from source (which takes a very long time and a lot of disk) -$ make install +$ cd ~/Qt/5.5/Src/ -5) Install custom subsurface Marble +$ ./configure -prefix /usr/local -opensource -$ cd ~/src -$ git clone -b Subsurface-4.4 git://subsurface-divelog.org/marble marble-source -$ cd marble-source -$ mkdir marble-build -$ cd marble-build -$ cmake -DCMAKE_BUILD_TYPE=Debug -DQTONLY=TRUE \ - -DQT5BUILD=ON -DCMAKE_INSTALL_PREFIX=/usr/local ../../marble-source -$ cd src/lib/marble $ make -j4 -$ make install -5) Install Libdivecomputer - -$ brew install automake libtool -$ cd ~/src -$ git clone -b Subsurface-4.4 git://subsurface-divelog.org/libdc libdivecomputer - # -> when not building a release version of Subsurface but the - # latest master, it may be necessary to build against the - # Subsurface-testing branch -$ cd libdivecomputer -$ autoreconf --install -$ ./configure --disable-shared -$ make -j4 $ make install +5) run the build script -6) Compile Subsurface - -$ cd ~/src -$ git clone git://subsurface-divelog.org/subsurface.git -$ cd subsurface -$ mkdir build -$ cd build -$ cmake -DCMAKE_BUILD_TYPE=Release .. -$ make -j4 -$ make install +cd ~/src +bash subsurface/scripts/build.sh After the above is done, Subsurface.app will be available in the -subsurface/build/staging directory. This folder can then be moved -to /Applications install Subsurface for every user. +subsurface/build directory. You can run Subsurface with the command + +$ open subsurface/build/Subsurface.app +or you can move this folder to /Applications to install Subsurface for +every user. Cross-building Subsurface on Linux for Windows @@ -19,6 +19,7 @@ #include <string.h> #include "dive.h" #include <assert.h> +#include <planner.h> //! Option structure for Buehlmann decompression. struct buehlmann_config { @@ -147,43 +148,55 @@ static double tissue_tolerance_calc(const struct dive *dive) double lowest_ceiling = 0.0; double tissue_lowest_ceiling[16]; - for (ci = 0; ci < 16; ci++) { - tissue_inertgas_saturation[ci] = tissue_n2_sat[ci] + tissue_he_sat[ci]; - buehlmann_inertgas_a[ci] = ((buehlmann_N2_a[ci] * tissue_n2_sat[ci]) + (buehlmann_He_a[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci]; - buehlmann_inertgas_b[ci] = ((buehlmann_N2_b[ci] * tissue_n2_sat[ci]) + (buehlmann_He_b[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci]; + if (prefs.deco_mode != VPMB || !in_planner) { + for (ci = 0; ci < 16; ci++) { + tissue_inertgas_saturation[ci] = tissue_n2_sat[ci] + tissue_he_sat[ci]; + buehlmann_inertgas_a[ci] = ((buehlmann_N2_a[ci] * tissue_n2_sat[ci]) + (buehlmann_He_a[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci]; + buehlmann_inertgas_b[ci] = ((buehlmann_N2_b[ci] * tissue_n2_sat[ci]) + (buehlmann_He_b[ci] * tissue_he_sat[ci])) / tissue_inertgas_saturation[ci]; - /* tolerated = (tissue_inertgas_saturation - buehlmann_inertgas_a) * buehlmann_inertgas_b; */ + /* tolerated = (tissue_inertgas_saturation - buehlmann_inertgas_a) * buehlmann_inertgas_b; */ - tissue_lowest_ceiling[ci] = (buehlmann_inertgas_b[ci] * tissue_inertgas_saturation[ci] - gf_low * buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci]) / - ((1.0 - buehlmann_inertgas_b[ci]) * gf_low + buehlmann_inertgas_b[ci]); - if (tissue_lowest_ceiling[ci] > lowest_ceiling) - lowest_ceiling = tissue_lowest_ceiling[ci]; - if (!buehlmann_config.gf_low_at_maxdepth) { - if (lowest_ceiling > gf_low_pressure_this_dive) - gf_low_pressure_this_dive = lowest_ceiling; + tissue_lowest_ceiling[ci] = (buehlmann_inertgas_b[ci] * tissue_inertgas_saturation[ci] - gf_low * buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci]) / + ((1.0 - buehlmann_inertgas_b[ci]) * gf_low + buehlmann_inertgas_b[ci]); + if (tissue_lowest_ceiling[ci] > lowest_ceiling) + lowest_ceiling = tissue_lowest_ceiling[ci]; + if (!buehlmann_config.gf_low_at_maxdepth) { + if (lowest_ceiling > gf_low_pressure_this_dive) + gf_low_pressure_this_dive = lowest_ceiling; + } } - } - for (ci = 0; ci <16; ci++) { - double tolerated; - - if ((surface / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - surface) * gf_high + surface < - (gf_low_pressure_this_dive / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - gf_low_pressure_this_dive) * gf_low + gf_low_pressure_this_dive) - tolerated = (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high * gf_low_pressure_this_dive - gf_low * surface) - - (1.0 - buehlmann_inertgas_b[ci]) * (gf_high - gf_low) * gf_low_pressure_this_dive * surface + - buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface) * tissue_inertgas_saturation[ci]) / - (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high - gf_low) + - (1.0 - buehlmann_inertgas_b[ci]) * (gf_low * gf_low_pressure_this_dive - gf_high * surface) + - buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface)); - else - tolerated = ret_tolerance_limit_ambient_pressure; - - - tolerated_by_tissue[ci] = tolerated; - - if (tolerated >= ret_tolerance_limit_ambient_pressure) { - ci_pointing_to_guiding_tissue = ci; - ret_tolerance_limit_ambient_pressure = tolerated; + for (ci = 0; ci < 16; ci++) { + double tolerated; + + if ((surface / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - surface) * gf_high + surface < + (gf_low_pressure_this_dive / buehlmann_inertgas_b[ci] + buehlmann_inertgas_a[ci] - gf_low_pressure_this_dive) * gf_low + gf_low_pressure_this_dive) + tolerated = (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high * gf_low_pressure_this_dive - gf_low * surface) - + (1.0 - buehlmann_inertgas_b[ci]) * (gf_high - gf_low) * gf_low_pressure_this_dive * surface + + buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface) * tissue_inertgas_saturation[ci]) / + (-buehlmann_inertgas_a[ci] * buehlmann_inertgas_b[ci] * (gf_high - gf_low) + + (1.0 - buehlmann_inertgas_b[ci]) * (gf_low * gf_low_pressure_this_dive - gf_high * surface) + + buehlmann_inertgas_b[ci] * (gf_low_pressure_this_dive - surface)); + else + tolerated = ret_tolerance_limit_ambient_pressure; + + + tolerated_by_tissue[ci] = tolerated; + + if (tolerated >= ret_tolerance_limit_ambient_pressure) { + ci_pointing_to_guiding_tissue = ci; + ret_tolerance_limit_ambient_pressure = tolerated; + } + } + } else { + // VPM-B ceiling + for (ci = 0; ci < 16; ci++) { + double tolerated = tissue_n2_sat[ci] + tissue_he_sat[ci] + vpmb_config.other_gases_pressure - total_gradient[ci]; + if (tolerated >= ret_tolerance_limit_ambient_pressure) { + ci_pointing_to_guiding_tissue = ci; + ret_tolerance_limit_ambient_pressure = tolerated; + } + tolerated_by_tissue[ci] = tolerated; } } return ret_tolerance_limit_ambient_pressure; @@ -552,6 +552,7 @@ int parse_txt_file(const char *filename, const char *csv) bool has_depth = false, has_setpoint = false, has_ndl = false; char *lineptr, *key, *value; int o2cylinder_pressure = 0, cylinder_pressure = 0, cur_cylinder_index = 0; + unsigned int prev_time = 0; struct dive *dive; struct divecomputer *dc; @@ -651,7 +652,14 @@ int parse_txt_file(const char *filename, const char *csv) has_setpoint = false; has_ndl = false; sample = prepare_sample(dc); - sample->time.seconds = cur_sampletime; + + /* + * There was a bug in MKVI download tool that resulted in erroneous sample + * times. This fix should work similarly as the vendor's own. + */ + + sample->time.seconds = cur_sampletime < 0xFFFF * 3 / 4 ? cur_sampletime : prev_time; + prev_time = sample->time.seconds; do { int i = sscanf(lineptr, "%d,%d,%d", &sampletime, &type, &value); diff --git a/git-access.c b/git-access.c index 82f761710..c6a1648b1 100644 --- a/git-access.c +++ b/git-access.c @@ -143,7 +143,7 @@ int certificate_check_cb(git_cert *cert, int valid, const char *host, void *payl SHA1_Update(&ctx, cert509->data, cert509->len); SHA1_Final(hash, &ctx); hash[20] = 0; - if (same_string(hash, KNOWN_CERT)) { + if (same_string((char *)hash, KNOWN_CERT)) { fprintf(stderr, "cloud certificate considered %s, forcing it valid\n", valid ? "valid" : "not valid"); return 1; @@ -33,6 +33,14 @@ int decostoplevels_imperial[] = { 0, 3048, 6096, 9144, 12192, 15240, 18288, 2133 double plangflow, plangfhigh; bool plan_verbatim, plan_display_runtime, plan_display_duration, plan_display_transitions; +/* This is a bit round about: Currently, we only support VPM-B in the planner, + * so, when we compute ceilings we have to know if we are in planning mode since + * the maximally allowed gradient in the tissues is determined by the critical volume algorithm for + * which we currently have no version for logged dives. But the information about the application state + * is only available in the C++/Qt part. So this global variable is a way to leak this info. */ + +bool in_planner = false; + const char *disclaimer; #if DEBUG_PLAN @@ -879,7 +887,7 @@ bool trial_ascent(int trial_depth, int stoplevel, int avg_depth, int bottom_time tissue_tolerance = add_segment(depth_to_mbar(trial_depth, &displayed_dive) / 1000.0, gasmix, TIMESTEP, po2, &displayed_dive, prefs.decosac); - if (prefs.deco_mode != VPMB && deco_allowed_depth(tissue_tolerance, surface_pressure, &displayed_dive, 1) > trial_depth - deltad) { + if (deco_allowed_depth(tissue_tolerance, surface_pressure, &displayed_dive, 1) > trial_depth - deltad) { /* We should have stopped */ clear_to_ascend = false; break; @@ -25,7 +25,7 @@ extern struct dive *planned_dive; extern char *cache_data; extern const char *disclaimer; extern double plangflow, plangfhigh; - +extern bool in_planner; #ifdef __cplusplus } diff --git a/printer.cpp b/printer.cpp index fc18c9afe..b0caa0815 100644 --- a/printer.cpp +++ b/printer.cpp @@ -1,6 +1,9 @@ #include "printer.h" #include "templatelayout.h" +#include "statistics.h" +#include "helpers.h" +#include <algorithm> #include <QtWebKitWidgets> #include <QPainter> #include <QWebElementCollection> @@ -54,6 +57,53 @@ void Printer::putProfileImage(QRect profilePlaceholder, QRect viewPort, QPainter } } +void Printer::flowRender() +{ + // render the Qwebview + QPainter painter; + QRect viewPort(0, 0, 0, 0); + painter.begin(paintDevice); + painter.setRenderHint(QPainter::Antialiasing); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + + // get all references to dontbreak divs + int start = 0, end = 0; + int fullPageResolution = webView->page()->mainFrame()->contentsSize().height(); + QWebElementCollection dontbreak = webView->page()->mainFrame()->findAllElements(".dontbreak"); + foreach (QWebElement dontbreakElement, dontbreak) { + if ((dontbreakElement.geometry().y() + dontbreakElement.geometry().height()) - start < pageSize.height()) { + // One more element can be placed + end = dontbreakElement.geometry().y() + dontbreakElement.geometry().height(); + } else { + // fill the page with background color + QRect fullPage(0, 0, pageSize.width(), pageSize.height()); + QBrush fillBrush(templateOptions->color_palette.color1); + painter.fillRect(fullPage, fillBrush); + QRegion reigon(0, 0, pageSize.width(), end - start); + viewPort.setRect(0, start, pageSize.width(), end - start); + + // render the base Html template + webView->page()->mainFrame()->render(&painter, QWebFrame::ContentsLayer, reigon); + + // scroll the webview to the next page + webView->page()->mainFrame()->scroll(0, dontbreakElement.geometry().y() - start); + + // rendering progress is 4/5 of total work + emit(progessUpdated((end * 80.0 / fullPageResolution) + done)); + static_cast<QPrinter*>(paintDevice)->newPage(); + start = dontbreakElement.geometry().y(); + } + } + // render the remianing page + QRect fullPage(0, 0, pageSize.width(), pageSize.height()); + QBrush fillBrush(templateOptions->color_palette.color1); + painter.fillRect(fullPage, fillBrush); + QRegion reigon(0, 0, pageSize.width(), end - start); + webView->page()->mainFrame()->render(&painter, QWebFrame::ContentsLayer, reigon); + + painter.end(); +} + void Printer::render(int Pages = 0) { // keep original preferences @@ -144,9 +194,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 - pageSize.setHeight(printerPtr->pageLayout().paintRect(QPageLayout::Inch).height() * dpi); - pageSize.setWidth(printerPtr->pageLayout().paintRect(QPageLayout::Inch).width() * 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 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->color_selected && printerPtr->colorMode()) { printerPtr->setColorMode(QPrinter::Color); @@ -165,11 +223,69 @@ void Printer::print() } int Pages; if (divesPerPage == 0) { - Pages = ceil(webView->page()->mainFrame()->contentsSize().height() / (float)pageSize.height()); + // 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); + 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++; } - render(Pages); + html += "</table>"; + webView->setHtml(html); + webView->print(printerPtr); } void Printer::previewOnePage() @@ -29,6 +29,7 @@ private: int done; int dpi; void render(int Pages); + void flowRender(); void putProfileImage(QRect box, QRect viewPort, QPainter *painter, struct dive *dive, QPointer<ProfileWidget2> profile); private slots: @@ -38,6 +39,7 @@ 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/Flowlayout.html b/printing_templates/Flowlayout.html index a3f7951d9..2615c35a8 100644 --- a/printing_templates/Flowlayout.html +++ b/printing_templates/Flowlayout.html @@ -15,11 +15,17 @@ font-size: {{ template_options.font_size }}vw; } + p { + float: left; + font-size: {{ template_options.font_size }}vw; + } + table { -webkit-box-sizing: border-box; box-sizing: border-box; - border:max(1px, 0.1vw); + border-width: {{ template_options.borderwidth }}px; border-style:solid; + border-color: {{ template_options.color6 }}; } td { @@ -32,57 +38,59 @@ } .mainContainer { - width: 96%; - margin-left: 2%; - margin-right: 2%; + width: 100%; + margin-left: 0%; + margin-right: 0%; margin-top: 0%; - margin-bottom: 0%; + margin-bottom: 2%; overflow: hidden; border-width: 0; page-break-inside: avoid; } .innerContainer { - width: 98%; - padding: 1%; + width: 100%; + padding: 0%; overflow: hidden; } .diveDetails { - width: 98%; - -webkit-box-sizing: border-box; - box-sizing: border-box; - border:max(1px, 0.1vw); - border-style:solid; + width: 100%; float: left; } .dataSection { - width: 98%; - margin: 1%; + width: 100%; } .fieldTitle { background-color: {{ template_options.color2 }}; overflow: hidden; + color: {{ template_options.color4 }}; + } + + .fieldData { + color: {{ template_options.color5 }}; + background-color: {{ template_options.color3 }}; } .table_class { float: left; - margin: 1%; - width: 48%; + width: 49.25%; + margin: 0.5%; } .notes_table_class { overflow: hidden; - width: 98%; - margin: 1%; + width: 99%; + margin: 0.5%; } .textArea { line-height: {{ template_options.line_spacing }}; max-height: 19vh; overflow: hidden; + color: {{ template_options.color4 }}; } </style> </head> @@ -90,7 +98,7 @@ <div id="body_div"> {% block main_rows %} {% for dive in dives %} - <div class="mainContainer"> + <div class="mainContainer dontbreak"> <div class="innerContainer"> <div class="diveDetails"> <div class="dataSection"> @@ -99,39 +107,40 @@ <td class="fieldTitle"> <h1> Dive No. </h1> </td> - <td> - <h1> {{ dive.number }} </h1> + <td class="fieldData"> + <p> {{ dive.number }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Date </h1> </td> - <td><h1> {{ dive.date }} </h1> + <td class="fieldData"> + <p> {{ dive.date }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Location </h1> </td> - <td> - <h1> {{ dive.location }} </h1> + <td class="fieldData"> + <p> {{ dive.location }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Max depth </h1> </td> - <td> - <h1> {{ dive.depth }} </h1> + <td class="fieldData"> + <p> {{ dive.depth }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Duration </h1> </td> - <td> - <h1> {{ dive.duration }} </h1> + <td class="fieldData"> + <p> {{ dive.duration }} </p> </td> </tr> </tbody></table> @@ -140,39 +149,40 @@ <td class="fieldTitle"> <h1> Time. </h1> </td> - <td> - <h1> {{ dive.time }} </h1> + <td class="fieldData"> + <p> {{ dive.time }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Air Temp. </h1> </td> - <td><h1> {{ dive.airTemp }} </h1> + <td class="fieldData"> + <p> {{ dive.airTemp }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Water Temp. </h1> </td> - <td> - <h1> {{ dive.waterTemp }} </h1> + <td class="fieldData"> + <p> {{ dive.waterTemp }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Buddy </h1> </td> - <td> - <h1> {{ dive.buddy }} </h1> + <td class="fieldData"> + <p> {{ dive.buddy }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Dive Master </h1> </td> - <td> - <h1> {{ dive.divemaster }} </h1> + <td class="fieldData"> + <p> {{ dive.divemaster }} </p> </td> </tr> </tbody> @@ -185,9 +195,9 @@ </td> </tr> <tr> - <td> + <td class="fieldData"> <div class="textArea"> - <h1> {{ dive.notes }} </h1> + <p> {{ dive.notes }} </p> </div> </td> </tr> diff --git a/printing_templates/One Dive.html b/printing_templates/One Dive.html index 40c02b395..020c67b30 100644 --- a/printing_templates/One Dive.html +++ b/printing_templates/One Dive.html @@ -15,11 +15,17 @@ font-size: {{ template_options.font_size }}vw; } + p { + float: left; + font-size: {{ template_options.font_size }}vw; + } + table { -webkit-box-sizing: border-box; box-sizing: border-box; - border:max(1px, 0.1vw); + border-width: {{ template_options.borderwidth }}px; border-style:solid; + border-color: {{ template_options.color6 }}; } td { @@ -32,10 +38,10 @@ } .mainContainer { - width: 96%; + width: 98%; height: 100%; - margin-left: 2%; - margin-right: 2%; + margin-left: 1%; + margin-right: 1%; margin-top: 0%; margin-bottom: 0%; overflow: hidden; @@ -44,53 +50,56 @@ } .innerContainer { - width: 98%; - height: 98%; - padding: 1%; + width: 100%; + height: 99%; + padding-top: 1%; overflow: hidden; } .diveDetails { - width: 98%; + width: 100%; height: 98%; - -webkit-box-sizing: border-box; - box-sizing: border-box; - border:max(1px, 0.1vw); - border-style:solid; float: left; } .diveProfile { - width: 96%; + width: 99%; height: 40%; - margin: 2%; + margin: 0.5%; } .dataSection { - width: 98%; + width: 100%; height: 40%; - margin: 1%; + margin: 0%; } .fieldTitle { background-color: {{ template_options.color2 }}; overflow: hidden; + color: {{ template_options.color4 }}; + } + + .fieldData { + background-color: {{ template_options.color3 }}; + color: {{ template_options.color5 }}; } .table_class { float: left; - margin: 1%; - width: 48%; + margin: 0.5%; + width: 49%; } .notes_table_class { overflow: hidden; - width: 98%; - margin: 1%; + width: 99%; + margin: 0.5%; } .textArea { line-height: {{ template_options.line_spacing }}; + color: {{ template_options.color5 }}; max-height: 19vh; overflow: hidden; } @@ -111,39 +120,40 @@ <td class="fieldTitle"> <h1> Dive No. </h1> </td> - <td> - <h1> {{ dive.number }} </h1> + <td class="fieldData"> + <p> {{ dive.number }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Date </h1> </td> - <td><h1> {{ dive.date }} </h1> + <td class="fieldData"> + <p> {{ dive.date }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Location </h1> </td> - <td> - <h1> {{ dive.location }} </h1> + <td class="fieldData"> + <p> {{ dive.location }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Max depth </h1> </td> - <td> - <h1> {{ dive.depth }} </h1> + <td class="fieldData"> + <p> {{ dive.depth }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Duration </h1> </td> - <td> - <h1> {{ dive.duration }} </h1> + <td class="fieldData"> + <p> {{ dive.duration }} </p> </td> </tr> </tbody></table> @@ -152,39 +162,40 @@ <td class="fieldTitle"> <h1> Time. </h1> </td> - <td> - <h1> {{ dive.time }} </h1> + <td class="fieldData"> + <p> {{ dive.time }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Air Temp. </h1> </td> - <td><h1> {{ dive.airTemp }} </h1> + <td class="fieldData"> + <p> {{ dive.airTemp }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Water Temp. </h1> </td> - <td> - <h1> {{ dive.waterTemp }} </h1> + <td class="fieldData"> + <p> {{ dive.waterTemp }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Buddy </h1> </td> - <td> - <h1> {{ dive.buddy }} </h1> + <td class="fieldData"> + <p> {{ dive.buddy }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Dive Master </h1> </td> - <td> - <h1> {{ dive.divemaster }} </h1> + <td class="fieldData"> + <p> {{ dive.divemaster }} </p> </td> </tr> </tbody> @@ -197,9 +208,9 @@ </td> </tr> <tr> - <td> + <td class="fieldData"> <div class="textArea"> - <h1> {{ dive.notes }} </h1> + <p> {{ dive.notes }} </p> </div> </td> </tr> diff --git a/printing_templates/Six Dives.html b/printing_templates/Six Dives.html new file mode 100644 index 000000000..3f2c7b95e --- /dev/null +++ b/printing_templates/Six Dives.html @@ -0,0 +1,182 @@ +<html> +<head> + <style> + body { + {{ print_options.grayscale }}; + padding: 0px; + margin: 0px; + font-size: {{ template_options.font_size }}vw; + line-height: {{ template_options.line_spacing }}; + font-family: {{ template_options.font }}; + color: {{ template_options.color4 }}; + } + + h1 { + font-size: {{ template_options.font_size }}vw; + float: left; + margin: 0px; + } + + p { + font-size: {{ template_options.font_size }}vw; + float: left; + margin: 0px; + } + + td { + margin:0px; + } + + #footer { + height: 100%; + width: 100%; + float: left; + } + + #body_div { + background-color: {{ template_options.color1 }}; + float: left; + } + + .mainContainer { + width: 50%; + height: 33.333333%; + margin-left: 0%; + margin-right: 0%; + margin-top: 0; + margin-bottom: 0; + overflow: hidden; + page-break-inside: avoid; + float: left; + } + + .innerContainer { + height: 99%; + width: 98%; + padding-left: 1%; + padding-right: 1%; + padding-top: 1%; + overflow: hidden; + } + + .table_class { + overflow: hidden; + width: 100%; + margin: 0%; + float: left; + -webkit-box-sizing: border-box; + box-sizing: border-box; + border-width: {{ template_options.borderwidth }}px; + border-style:solid; + border-color: {{ template_options.color6 }}; + font-size: {{ template_options.font_size }}vw; + background-color: {{ template_options.color3 }}; + color: {{ template_options.color4 }}; + } + + .notes_table_class { + overflow: hidden; + max-width: 100%; + min-width: 100%; + margin: 0.5%; + float: left; + } + + .diveProfile { + width: 100%; + height: 95%; + margin-left: 0%; + margin-right: 0%; + margin-bottom: 0%; + margin-top: 0%; + float: right; + } + + .diveDetails { + width: 100%; + float: left; + } + + .dataPart { + height: 45%; + max-height: 60%; + } + + .dataSection{ + width: 100%; + } + + .textArea { + overflow: hidden !important; + text-overflow: ellipsis; + line-height: {{ template_options.line_spacing }}; + } + </style> +</head> +<body data-numberofdives = 6> +<div id="body_div"> +{% block main_rows %} + {% for dive in dives %} + <div class="mainContainer"> + <div class="innerContainer"> + <div class="diveDetails"> + <div class="dataPart"> + <div class="diveProfile" id="dive_{{ dive.id }}"> + </div> + <div class="dataSection"> + <table style="float:left;width:100%;"> + <tr> + <td> + <h1> Dive # {{ dive.number }} - {{ dive.date }} {{ dive.time }}</h1> + <p style="float:right;"> Max depth: {{ dive.depth }} </p> + </td> + </tr> + <tr> + <td> + <p> {{ dive.location }} </p> + <p style="float:right;"> Duration: {{ dive.duration }} </p> + </td> + </tr> + </table> + <table class="table_class"> + <tr> + <td> Gas used: {{ dive.gas }}</td> + <td> Tags: {{ dive.tags }}</td> + <td> SAC: {{ dive.sac }}</td> + </tr> + <tr> + <td> Divemaster: {{ dive.divemaster }}</td> + <td> Buddy: {{ dive.buddy }}</td> + <td> Rating: {{ dive.rating }}/5</td> + </tr> + </table> + </div> + </div> + <div class="notesPart"> + <table class="notes_table_class"> + <tbody> + <tr> + <td> + <p> Notes: </p> + </td> + </tr> + <tr> + <td> + <div class="textArea"> + <p> {{ dive.notes }} </p> + </div> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </div> + </div> + {% endfor %} +{% endblock %} +<div id="footer"> +</div> +</div> +</body> +</html> diff --git a/printing_templates/Table.html b/printing_templates/Table.html index c97267405..e4d921fae 100644 --- a/printing_templates/Table.html +++ b/printing_templates/Table.html @@ -21,6 +21,11 @@ -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 { @@ -28,10 +33,10 @@ } .mainContainer { - width: 96%; + width: 99%; height: 100%; - margin-left: 2%; - margin-right: 2%; + margin-left: 0.5%; + margin-right: 0.5%; margin-top: 0%; margin-bottom: 0%; overflow: hidden; @@ -41,13 +46,8 @@ .table_class { overflow: hidden; - width: 97%; - margin: 1.5%; - -webkit-box-sizing: border-box; - box-sizing: border-box; - border:max(0.1vw, 1px); - border-style:solid; - border-color: color: {{ template_options.color5 }}; + width: 100%; + margin: 0%; } </style> @@ -55,7 +55,7 @@ <body data-numberofdives = 0> <div id="body_div"> <table class="table_class"> - <tr style="background-color: {{ template_options.color2 }}; color: {{ template_options.color3 }}"> + <tr style="background-color: {{ template_options.color2 }}; color: {{ template_options.color4 }}"> <th>Dive #</th> <th>Date</th> <th>Time</th> @@ -66,7 +66,7 @@ </tr> {% block main_rows %} {% for dive in dives %} - <tr style="color: {{ template_options.color4 }}"> + <tr class="dontbreak" style="background-color: {{ template_options.color3 }}; color: {{ template_options.color5 }};"> <th>{{ dive.number }}</th> <th>{{ dive.date }}</th> <th>{{ dive.time }}</th> diff --git a/printing_templates/Two Dives.html b/printing_templates/Two Dives.html index 5dba74303..95cc9a088 100644 --- a/printing_templates/Two Dives.html +++ b/printing_templates/Two Dives.html @@ -15,15 +15,20 @@ float: left; } + p { + font-size: {{ template_options.font_size }}vw; + float: left; + } + #body_div { background-color: {{ template_options.color1 }}; } .mainContainer { - width: 96%; + width: 99%; height: 50%; - margin-left: 2%; - margin-right: 2%; + margin-left: 0.5%; + margin-right: 0.5%; margin-top: 0; margin-bottom: 0; overflow: hidden; @@ -32,68 +37,70 @@ .innerContainer { height: 85%; - padding: 0.5%; margin-top: 1%; margin-bottom: 1%; overflow: hidden; - -webkit-box-sizing: border-box; - box-sizing: border-box; - border:max(0.1vw, 1px); - border-style:solid; } .table_class { overflow: hidden; - max-width: 25%; - min-width: 25%; + width: 25%; + height: 99%; margin: 0.5%; float: left; -webkit-box-sizing: border-box; box-sizing: border-box; - border:max(0.1vw, 1px); + border-width: {{ template_options.borderwidth }}px; border-style:solid; + border-color: {{ template_options.color6 }}; } .notes_table_class { overflow: hidden; - max-width: 100%; - min-width: 100%; + width: 99%; margin: 0.5%; - float: left; -webkit-box-sizing: border-box; box-sizing: border-box; - border:max(0.1vw, 1px); + border-width: {{ template_options.borderwidth }}px; border-style:solid; + border-color: {{ template_options.color6 }}; } .fieldTitle { background-color: {{ template_options.color2 }}; - overflow: hidden; - padding:0; + color: {{ template_options.color4 }}; + padding-left: 2%; + } + + .fieldData { + color: {{ template_options.color5 }}; + background-color: {{ template_options.color3 }}; + padding-left: 2%; } .diveProfile { - width: 48%; - height: 95%; - margin-left: 0%; - margin-right: 0%; - margin-bottom: 0%; - margin-top: 0.5%; - float: right; + float: left; + height: 99%; + width: 47%; + margin: 0.5%; } .diveDetails { - width: 98.5%; + width: 100%; float: left; } .dataPart { - height: 45%; - max-height: 60%; + height: 64%; + padding-bottom: 1%; + width: 100%; + float: left; } .notesPart { height: 35%; + width: 100%; + float: left; } .textArea { @@ -122,39 +129,40 @@ <td class="fieldTitle"> <h1> Dive No. </h1> </td> - <td> - <h1> {{ dive.number }} </h1> + <td class="fieldData"> + <p> {{ dive.number }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Date </h1> </td> - <td><h1> {{ dive.date }} </h1> + <td class="fieldData"> + <p> {{ dive.date }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Location </h1> </td> - <td> - <h1> {{ dive.location }} </h1> + <td class="fieldData"> + <p> {{ dive.location }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Max depth </h1> </td> - <td> - <h1> {{ dive.depth }} </h1> + <td class="fieldData"> + <p> {{ dive.depth }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Duration </h1> </td> - <td> - <h1> {{ dive.duration }} </h1> + <td class="fieldData"> + <p> {{ dive.duration }} </p> </td> </tr> </tbody></table> @@ -163,39 +171,40 @@ <td class="fieldTitle"> <h1> Time. </h1> </td> - <td> - <h1> {{ dive.time }} </h1> + <td class="fieldData"> + <p> {{ dive.time }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Air Temp. </h1> </td> - <td><h1> {{ dive.airTemp }} </h1> + <td class="fieldData"> + <p> {{ dive.airTemp }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Water Temp. </h1> </td> - <td> - <h1> {{ dive.waterTemp }} </h1> + <td class="fieldData"> + <p> {{ dive.waterTemp }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Buddy </h1> </td> - <td> - <h1> {{ dive.buddy }} </h1> + <td class="fieldData"> + <p> {{ dive.buddy }} </p> </td> </tr> <tr> <td class="fieldTitle"> <h1> Dive Master </h1> </td> - <td> - <h1> {{ dive.divemaster }} </h1> + <td class="fieldData"> + <p> {{ dive.divemaster }} </p> </td> </tr> </tbody></table> @@ -205,14 +214,14 @@ <div class="notesPart"> <table class="notes_table_class"> <tbody><tr> - <td class="fieldTitle"> + <td style="padding-left:1%" class="fieldTitle"> <h1> Notes </h1> </td> </tr> <tr> - <td> + <td class="fieldData"> <div class="textArea"> - <h1> {{ dive.notes }} </h1> + <p> {{ dive.notes }} </p> </div> </td> </tr> @@ -224,7 +233,7 @@ {% endfor %} {% endblock %} <div id="footer"> -<div> +</div> </div> </body> </html> diff --git a/qt-models/divepicturemodel.cpp b/qt-models/divepicturemodel.cpp index 9e60404ed..06051dd28 100644 --- a/qt-models/divepicturemodel.cpp +++ b/qt-models/divepicturemodel.cpp @@ -5,12 +5,7 @@ #include <QtConcurrent> -typedef QList<struct picture *> SPictureList; -typedef struct picture *picturepointer; -typedef QPair<picturepointer, QImage> SPixmap; - - -static SPixmap scaleImages(picturepointer picture) +SPixmap scaleImages(picturepointer picture) { static QHash <QString, QImage > cache; SPixmap ret; @@ -126,4 +121,4 @@ void DivePictureModel::removePicture(const QString &fileUrl) int DivePictureModel::rowCount(const QModelIndex &parent) const { return numberOfPictures; -}
\ No newline at end of file +} diff --git a/qt-models/divepicturemodel.h b/qt-models/divepicturemodel.h index edcddd7a2..d6393e45f 100644 --- a/qt-models/divepicturemodel.h +++ b/qt-models/divepicturemodel.h @@ -12,12 +12,18 @@ public: SHashedImage(struct picture *picture); }; - struct PhotoHelper { QImage image; int offsetSeconds; }; +typedef QList<struct picture *> SPictureList; +typedef struct picture *picturepointer; +typedef QPair<picturepointer, QImage> SPixmap; + +// function that will scale the pixmap, used inside the QtConcurrent thread. +SPixmap scaleImages(picturepointer picture); + class DivePictureModel : public QAbstractTableModel { Q_OBJECT public: @@ -25,11 +31,11 @@ public: virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; - void updateDivePictures(); + virtual void updateDivePictures(); void updateDivePicturesWhenDone(QList<QFuture<void> >); void removePicture(const QString& fileUrl); -private: +protected: DivePictureModel(); int numberOfPictures; // Currently, load the images on the fly @@ -38,4 +44,4 @@ private: QHash<QString, PhotoHelper> stringPixmapCache; }; -#endif
\ No newline at end of file +#endif diff --git a/qt-models/divesitepicturesmodel.cpp b/qt-models/divesitepicturesmodel.cpp new file mode 100644 index 000000000..3777f1d36 --- /dev/null +++ b/qt-models/divesitepicturesmodel.cpp @@ -0,0 +1,45 @@ +#include "divesitepicturesmodel.h" +#include "dive.h" +#include "stdint.h" + +#include <QtConcurrent> +#include <QPixmap> + +DiveSitePicturesModel* DiveSitePicturesModel::instance() { + static DiveSitePicturesModel *self = new DiveSitePicturesModel(); + return self; +} + +DiveSitePicturesModel::DiveSitePicturesModel() { + +} + +void DiveSitePicturesModel::updateDivePictures() { + beginResetModel(); + numberOfPictures = 0; + endResetModel(); + + const uint32_t ds_uuid = displayed_dive_site.uuid; + struct dive *d; + int i; + + stringPixmapCache.clear(); + SPictureList pictures; + + for_each_dive (i, d) { + if (d->dive_site_uuid == ds_uuid && dive_get_picture_count(d)) { + FOR_EACH_PICTURE(d) { + stringPixmapCache[QString(picture->filename)].offsetSeconds = picture->offset.seconds; + pictures.push_back(picture); + } + } + } + + QList<SPixmap> list = QtConcurrent::blockingMapped(pictures, scaleImages); + Q_FOREACH (const SPixmap &pixmap, list) + stringPixmapCache[pixmap.first->filename].image = pixmap.second; + + numberOfPictures = list.count(); + beginInsertRows(QModelIndex(), 0, numberOfPictures - 1); + endInsertRows(); +} diff --git a/qt-models/divesitepicturesmodel.h b/qt-models/divesitepicturesmodel.h new file mode 100644 index 000000000..f19f57cc2 --- /dev/null +++ b/qt-models/divesitepicturesmodel.h @@ -0,0 +1,15 @@ +#ifndef DIVESITEPICTURESMODEL_H +#define DIVESITEPICTURESMODEL_H + +#include "divepicturemodel.h" + +class DiveSitePicturesModel : public DivePictureModel { + Q_OBJECT +public: + static DiveSitePicturesModel *instance(); + void updateDivePictures(); +private: + DiveSitePicturesModel(); +}; + +#endif diff --git a/qt-ui/groupedlineedit.cpp b/qt-ui/groupedlineedit.cpp index ed2428fd7..9ce5e175c 100644 --- a/qt-ui/groupedlineedit.cpp +++ b/qt-ui/groupedlineedit.cpp @@ -31,6 +31,10 @@ #include <QScrollBar> #include <QTextBlock> #include <QPainter> +#include <QApplication> +#include <QStyle> +#include <QStyleOptionFocusRect> +#include <QDebug> struct GroupedLineEdit::Private { struct Block { @@ -159,9 +163,6 @@ void GroupedLineEdit::keyPressEvent(QKeyEvent *e) void GroupedLineEdit::paintEvent(QPaintEvent *e) { - // for reasons we don't understand, touching the painter - // here (even drawing the fill rect) causes the QPlainTextEdit - // paintEvent to not draw the text on Qt4 & MacOS. QTextLine line = document()->findBlock(0).layout()->lineAt(0); QPainter painter(viewport()); diff --git a/qt-ui/locationInformation.ui b/qt-ui/locationInformation.ui index cb9ddb829..ad33b2a90 100644 --- a/qt-ui/locationInformation.ui +++ b/qt-ui/locationInformation.ui @@ -14,7 +14,7 @@ <string>GroupBox</string> </property> <property name="title"> - <string>Dive Site</string> + <string/> </property> <layout class="QGridLayout" name="gridLayout"> <property name="horizontalSpacing"> diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index 09814e9c0..0a2f66262 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -51,6 +51,6 @@ signals: void setLineEditText(const QString& text); private: uint32_t last_uuid; - }; + #endif diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index db1d8c8b7..f22884a84 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -1716,6 +1716,8 @@ void MainWindow::setApplicationState(const QByteArray& state) { return; currentApplicationState = state; + in_planner = (state == "PlanDive" || state == "EditPlannedDive"); + #define SET_CURRENT_INDEX( X ) \ if (applicationState[state].X) { \ ui.X->setCurrentWidget( applicationState[state].X); \ diff --git a/qt-ui/printdialog.cpp b/qt-ui/printdialog.cpp index 6c50ae99b..002f9b9f4 100644 --- a/qt-ui/printdialog.cpp +++ b/qt-ui/printdialog.cpp @@ -17,21 +17,24 @@ template_options::color_palette_struct ssrf_colors, almond_colors, blueshades_co PrintDialog::PrintDialog(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) { // initialize const colors - ssrf_colors.color1 = QColor::fromRgb(0xef, 0xf7, 0xff); + ssrf_colors.color1 = QColor::fromRgb(0xff, 0xff, 0xff); ssrf_colors.color2 = QColor::fromRgb(0xa6, 0xbc, 0xd7); - ssrf_colors.color3 = QColor::fromRgb(0x34, 0x65, 0xa4); - ssrf_colors.color4 = QColor::fromRgb(0x20, 0x4a, 0x87); - ssrf_colors.color5 = QColor::fromRgb(0x17, 0x37, 0x64); - almond_colors.color1 = QColor::fromRgb(243, 234, 207); + ssrf_colors.color3 = QColor::fromRgb(0xef, 0xf7, 0xff); + ssrf_colors.color4 = QColor::fromRgb(0x34, 0x65, 0xa4); + ssrf_colors.color5 = QColor::fromRgb(0x20, 0x4a, 0x87); + ssrf_colors.color6 = QColor::fromRgb(0x17, 0x37, 0x64); + almond_colors.color1 = QColor::fromRgb(255, 255, 255); almond_colors.color2 = QColor::fromRgb(253, 204, 156); - almond_colors.color3 = QColor::fromRgb(136, 160, 150); - almond_colors.color4 = QColor::fromRgb(187, 171, 139); - almond_colors.color5 = QColor::fromRgb(239, 130, 117); - blueshades_colors.color1 = QColor::fromRgb(182, 192, 206); + almond_colors.color3 = QColor::fromRgb(243, 234, 207); + almond_colors.color4 = QColor::fromRgb(136, 160, 150); + almond_colors.color5 = QColor::fromRgb(187, 171, 139); + almond_colors.color6 = QColor::fromRgb(0, 0, 0); + blueshades_colors.color1 = QColor::fromRgb(255, 255, 255); blueshades_colors.color2 = QColor::fromRgb(142, 152, 166); - blueshades_colors.color3 = QColor::fromRgb(31, 49, 75); - blueshades_colors.color4 = QColor::fromRgb(21, 45, 84); - blueshades_colors.color5 = QColor::fromRgb(5, 25, 56); + blueshades_colors.color3 = QColor::fromRgb(182, 192, 206); + blueshades_colors.color4 = QColor::fromRgb(31, 49, 75); + blueshades_colors.color5 = QColor::fromRgb(21, 45, 84); + blueshades_colors.color6 = QColor::fromRgb(0, 0, 0); // check if the options were previously stored in the settings; if not use some defaults. QSettings s; @@ -164,13 +167,6 @@ void PrintDialog::onFinished() void PrintDialog::previewClicked(void) { - if (printOptions.type == print_options::STATISTICS) { - QMessageBox msgBox; - msgBox.setText("This feature is not implemented yet"); - msgBox.exec(); - return; - } - QPrintPreviewDialog previewDialog(&qprinter, this, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint | Qt::WindowTitleHint); @@ -180,13 +176,6 @@ void PrintDialog::previewClicked(void) void PrintDialog::printClicked(void) { - if (printOptions.type == print_options::STATISTICS) { - QMessageBox msgBox; - msgBox.setText("This feature is not implemented yet"); - msgBox.exec(); - return; - } - QPrintDialog printDialog(&qprinter, this); if (printDialog.exec() == QDialog::Accepted) { switch (printOptions.type) { @@ -195,6 +184,7 @@ void PrintDialog::printClicked(void) printer->print(); break; case print_options::STATISTICS: + printer->print_statistics(); break; } close(); @@ -204,7 +194,14 @@ void PrintDialog::printClicked(void) void PrintDialog::onPaintRequested(QPrinter *printerPtr) { connect(printer, SIGNAL(progessUpdated(int)), progressBar, SLOT(setValue(int))); - printer->print(); + switch (printOptions.type) { + case print_options::DIVELIST: + printer->print(); + break; + case print_options::STATISTICS: + printer->print_statistics(); + break; + } 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 1da95a94d..419098cf8 100644 --- a/qt-ui/printoptions.cpp +++ b/qt-ui/printoptions.cpp @@ -64,17 +64,39 @@ void PrintOptions::setup() } // print type radio buttons -void PrintOptions::on_radioDiveListPrint_clicked(bool check) +void PrintOptions::on_radioDiveListPrint_toggled(bool check) { if (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); } } -void PrintOptions::on_radioStatisticsPrint_clicked(bool check) +void PrintOptions::on_radioStatisticsPrint_toggled(bool check) { if (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); } } diff --git a/qt-ui/printoptions.h b/qt-ui/printoptions.h index 4903da09f..6d7ffffee 100644 --- a/qt-ui/printoptions.h +++ b/qt-ui/printoptions.h @@ -19,6 +19,7 @@ struct print_options { struct template_options { int font_index; int color_palette_index; + int border_width; double font_size; double line_spacing; struct color_palette_struct { @@ -27,12 +28,14 @@ struct template_options { QColor color3; QColor color4; QColor color5; + QColor color6; bool operator!=(const color_palette_struct &other) const { return other.color1 != color1 || other.color2 != color2 || other.color3 != color3 || other.color4 != color4 - || other.color5 != color5; + || other.color5 != color5 + || other.color6 != color6; } } color_palette; bool operator!=(const template_options &other) const { @@ -72,8 +75,8 @@ private slots: void printInColorClicked(bool check); void printSelectedClicked(bool check); - void on_radioStatisticsPrint_clicked(bool check); - void on_radioDiveListPrint_clicked(bool check); + void on_radioStatisticsPrint_toggled(bool check); + void on_radioDiveListPrint_toggled(bool check); void on_printTemplate_currentIndexChanged(int index); void on_editButton_clicked(); void on_importButton_clicked(); diff --git a/qt-ui/profile/profilewidget2.cpp b/qt-ui/profile/profilewidget2.cpp index 400401655..c776f9fea 100644 --- a/qt-ui/profile/profilewidget2.cpp +++ b/qt-ui/profile/profilewidget2.cpp @@ -627,6 +627,17 @@ void ProfileWidget2::plotDive(struct dive *d, bool force) eventItems.clear(); struct event *event = currentdc->events; while (event) { + // if print mode is selected only draw headings, SP change, gas events or bookmark event + if (printMode) { + if (same_string(event->name, "") || + !(strcmp(event->name, "heading") == 0 || + (same_string(event->name, "SP change") && event->time.seconds == 0) || + event_is_gaschange(event) || + event->type == SAMPLE_EVENT_BOOKMARK)) { + event = event->next; + continue; + } + } DiveEventItem *item = new DiveEventItem(); item->setHorizontalAxis(timeAxis); item->setVerticalAxis(profileYAxis); diff --git a/qt-ui/starwidget.cpp b/qt-ui/starwidget.cpp index 508d9a746..d959ed3b9 100644 --- a/qt-ui/starwidget.cpp +++ b/qt-ui/starwidget.cpp @@ -17,6 +17,25 @@ const QImage& StarWidget::starInactive() return inactiveStar; } +QImage focusedImage(const QImage& coloredImg) +{ + QImage img = coloredImg; + for (int i = 0; i < img.width(); ++i) { + for (int j = 0; j < img.height(); ++j) { + QRgb rgb = img.pixel(i, j); + if (!rgb) + continue; + + QColor c(rgb); + c = c.dark(); + img.setPixel(i, j, c.rgb()); + } + } + + return img; +} + + int StarWidget::currentStars() const { return current; @@ -44,13 +63,14 @@ void StarWidget::mouseReleaseEvent(QMouseEvent *event) void StarWidget::paintEvent(QPaintEvent *event) { QPainter p(this); - QPixmap active = QPixmap::fromImage(starActive()); + QImage star = hasFocus() ? focusedImage(starActive()) : starActive(); + QPixmap selected = QPixmap::fromImage(star); QPixmap inactive = QPixmap::fromImage(starInactive()); - const IconMetrics& metrics = defaultIconMetrics(); + for (int i = 0; i < current; i++) - p.drawPixmap(i * metrics.sz_small + metrics.spacing, 0, active); + p.drawPixmap(i * metrics.sz_small + metrics.spacing, 0, selected); for (int i = current; i < TOTALSTARS; i++) p.drawPixmap(i * metrics.sz_small + metrics.spacing, 0, inactive); @@ -132,16 +152,13 @@ void StarWidget::focusOutEvent(QFocusEvent *event) QWidget::focusOutEvent(event); } - void StarWidget::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Up || event->key() == Qt::Key_Right) { - if (currentStars() < TOTALSTARS) { + if (currentStars() < TOTALSTARS) setCurrentStars(currentStars() + 1); - } } else if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Left) { - if (currentStars() > 0) { + if (currentStars() > 0) setCurrentStars(currentStars() - 1); - } } } diff --git a/qt-ui/templateedit.cpp b/qt-ui/templateedit.cpp index 94ed276b5..e4e6453ac 100644 --- a/qt-ui/templateedit.cpp +++ b/qt-ui/templateedit.cpp @@ -30,9 +30,11 @@ TemplateEdit::TemplateEdit(QWidget *parent, struct print_options *printOptions, btnGroup->addButton(ui->editButton3, 3); btnGroup->addButton(ui->editButton4, 4); btnGroup->addButton(ui->editButton5, 5); + btnGroup->addButton(ui->editButton6, 6); connect(btnGroup, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(colorSelect(QAbstractButton*))); ui->plainTextEdit->setPlainText(grantlee_template); + editingCustomColors = false; updatePreview(); } @@ -59,12 +61,14 @@ void TemplateEdit::updatePreview() ui->colorLable3->setStyleSheet("QLabel { background-color : \"" + newTemplateOptions.color_palette.color3.name() + "\";}"); ui->colorLable4->setStyleSheet("QLabel { background-color : \"" + newTemplateOptions.color_palette.color4.name() + "\";}"); ui->colorLable5->setStyleSheet("QLabel { background-color : \"" + newTemplateOptions.color_palette.color5.name() + "\";}"); + ui->colorLable6->setStyleSheet("QLabel { background-color : \"" + newTemplateOptions.color_palette.color6.name() + "\";}"); ui->colorLable1->setText(newTemplateOptions.color_palette.color1.name()); ui->colorLable2->setText(newTemplateOptions.color_palette.color2.name()); ui->colorLable3->setText(newTemplateOptions.color_palette.color3.name()); ui->colorLable4->setText(newTemplateOptions.color_palette.color4.name()); ui->colorLable5->setText(newTemplateOptions.color_palette.color5.name()); + ui->colorLable6->setText(newTemplateOptions.color_palette.color6.name()); // update critical UI elements ui->colorpalette->setCurrentIndex(newTemplateOptions.color_palette_index); @@ -102,7 +106,10 @@ void TemplateEdit::on_colorpalette_currentIndexChanged(int index) newTemplateOptions.color_palette = blueshades_colors; break; case CUSTOM: // custom - newTemplateOptions.color_palette = custom_colors; + if (!editingCustomColors) + newTemplateOptions.color_palette = custom_colors; + else + editingCustomColors = false; break; } updatePreview(); @@ -121,7 +128,7 @@ void TemplateEdit::saveSettings() printOptions->p_template = "custom.html"; TemplateLayout::writeTemplate("custom.html", ui->plainTextEdit->toPlainText()); } - if (templateOptions->color_palette_index == 2) { + if (templateOptions->color_palette_index == CUSTOM) { custom_colors = templateOptions->color_palette; } } @@ -148,6 +155,7 @@ void TemplateEdit::on_buttonBox_clicked(QAbstractButton *button) void TemplateEdit::colorSelect(QAbstractButton *button) { + editingCustomColors = true; // reset custom colors palette switch (newTemplateOptions.color_palette_index) { case SSRF_COLORS: // subsurface derived default colors @@ -155,11 +163,11 @@ void TemplateEdit::colorSelect(QAbstractButton *button) break; case ALMOND: // almond newTemplateOptions.color_palette = almond_colors; - custom_colors = newTemplateOptions.color_palette; break; case BLUESHADES: // blueshades newTemplateOptions.color_palette = blueshades_colors; - custom_colors = newTemplateOptions.color_palette; + break; + default: break; } @@ -168,24 +176,35 @@ void TemplateEdit::colorSelect(QAbstractButton *button) switch (btnGroup->id(button)) { case 1: color = QColorDialog::getColor(newTemplateOptions.color_palette.color1, this); - newTemplateOptions.color_palette.color1 = color; + if (color.isValid()) { + newTemplateOptions.color_palette.color1 = color; + } break; case 2: color = QColorDialog::getColor(newTemplateOptions.color_palette.color2, this); - newTemplateOptions.color_palette.color2 = color; - break; + if (color.isValid()) { + newTemplateOptions.color_palette.color2 = color; + } break; case 3: color = QColorDialog::getColor(newTemplateOptions.color_palette.color3, this); - newTemplateOptions.color_palette.color3 = color; - break; + if (color.isValid()) { + newTemplateOptions.color_palette.color3 = color; + } break; case 4: color = QColorDialog::getColor(newTemplateOptions.color_palette.color4, this); - newTemplateOptions.color_palette.color4 = color; - break; + if (color.isValid()) { + newTemplateOptions.color_palette.color4 = color; + } break; case 5: color = QColorDialog::getColor(newTemplateOptions.color_palette.color5, this); - newTemplateOptions.color_palette.color5 = color; - break; + if (color.isValid()) { + newTemplateOptions.color_palette.color5 = color; + } break; + case 6: + color = QColorDialog::getColor(newTemplateOptions.color_palette.color6, this); + if (color.isValid()) { + newTemplateOptions.color_palette.color6 = color; + } break; } newTemplateOptions.color_palette_index = CUSTOM; updatePreview(); diff --git a/qt-ui/templateedit.h b/qt-ui/templateedit.h index 15b717f78..5e548ae19 100644 --- a/qt-ui/templateedit.h +++ b/qt-ui/templateedit.h @@ -31,6 +31,7 @@ private slots: private: Ui::TemplateEdit *ui; QButtonGroup *btnGroup; + bool editingCustomColors; struct template_options *templateOptions; struct template_options newTemplateOptions; struct print_options *printOptions; diff --git a/qt-ui/templateedit.ui b/qt-ui/templateedit.ui index 238e69290..322193cc6 100644 --- a/qt-ui/templateedit.ui +++ b/qt-ui/templateedit.ui @@ -317,7 +317,7 @@ </sizepolicy> </property> <property name="text"> - <string>Table cells</string> + <string>Table cells 1</string> </property> </widget> </item> @@ -347,9 +347,9 @@ </layout> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_7"> + <layout class="QHBoxLayout" name="horizontalLayout_13"> <item> - <widget class="QLabel" name="label_7"> + <widget class="QLabel" name="label_6"> <property name="sizePolicy"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> <horstretch>0</horstretch> @@ -357,7 +357,7 @@ </sizepolicy> </property> <property name="text"> - <string>Text 1</string> + <string>Table cells 2</string> </property> </widget> </item> @@ -387,9 +387,9 @@ </layout> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_9"> + <layout class="QHBoxLayout" name="horizontalLayout_7"> <item> - <widget class="QLabel" name="label_11"> + <widget class="QLabel" name="label_7"> <property name="sizePolicy"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> <horstretch>0</horstretch> @@ -397,7 +397,7 @@ </sizepolicy> </property> <property name="text"> - <string>Text 2</string> + <string>Text 1</string> </property> </widget> </item> @@ -427,9 +427,9 @@ </layout> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_6"> + <layout class="QHBoxLayout" name="horizontalLayout_9"> <item> - <widget class="QLabel" name="label_4"> + <widget class="QLabel" name="label_11"> <property name="sizePolicy"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> <horstretch>0</horstretch> @@ -437,7 +437,7 @@ </sizepolicy> </property> <property name="text"> - <string>Borders</string> + <string>Text 2</string> </property> </widget> </item> @@ -467,6 +467,46 @@ </layout> </item> <item> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QLabel" name="label_4"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Borders</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="colorLable6"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>color6</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="editButton6"> + <property name="text"> + <string>Edit</string> + </property> + </widget> + </item> + </layout> + </item> + <item> <spacer name="verticalSpacer_2"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/scripts/build.sh b/scripts/build.sh index b18b1197d..64a92f678 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -141,6 +141,9 @@ if ! git checkout Subsurface-testing ; then fi mkdir -p build cd build +if [ $PLATFORM = Darwin ] ; then + export CMAKE_PREFIX_PATH=~/Qt/5.5/clang_64/lib/cmake +fi cmake -DCMAKE_BUILD_TYPE=Release -DQTONLY=TRUE -DQT5BUILD=ON \ -DCMAKE_INSTALL_PREFIX=$INSTALL_ROOT \ -DBUILD_MARBLE_TESTS=NO \ @@ -151,6 +154,16 @@ cd src/lib/marble make -j4 make install +if [ $PLATFORM = Darwin ] ; then + # in order for macdeployqt to do its job correctly, we need the full path in the dylib ID + cd $INSTALL_ROOT/lib + NAME=$(otool -L libssrfmarblewidget.dylib | grep -v : | head -1 | cut -f1 -d\ | tr -d '\t' | cut -f3 -d/ ) + echo $NAME | grep / > /dev/null 2>&1 + if [ $? -eq 1 ] ; then + install_name_tool -id "$INSTALL_ROOT/lib/$NAME" "$INSTALL_ROOT/lib/$NAME" + fi +fi + # build grantlee cd $SRC @@ -201,5 +214,5 @@ if [ $PLATFORM = Darwin ] ; then rm -rf Subsurface.app fi -make -j4 -make install +LIBRARY_PATH=$INSTALL_ROOT/lib make -j4 +LIBRARY_PATH=$INSTALL_ROOT/lib make install diff --git a/templatelayout.cpp b/templatelayout.cpp index 1da88249b..b0098fbd9 100644 --- a/templatelayout.cpp +++ b/templatelayout.cpp @@ -188,10 +188,30 @@ QString Dive::notes() const return m_notes; } +QString Dive::tags() const +{ + return m_tags; +} + +QString Dive::gas() const +{ + return m_gas; +} + +QString Dive::sac() const +{ + return m_sac; +} + +int Dive::rating() const +{ + return m_rating; +} + void Dive::put_divemaster() { if (!dive->divemaster) - m_divemaster = ""; + m_divemaster = "--"; else m_divemaster = dive->divemaster; } @@ -207,6 +227,9 @@ void Dive::put_date_time() void Dive::put_location() { m_location = QString::fromUtf8(get_dive_location(dive)); + if (m_location.isEmpty()) { + m_location = "--"; + } } void Dive::put_depth() @@ -222,7 +245,7 @@ void Dive::put_duration() void Dive::put_buddy() { if (!dive->buddy) - m_buddy = ""; + m_buddy = "--"; else m_buddy = dive->buddy; } @@ -231,9 +254,55 @@ void Dive::put_temp() { m_airTemp = get_temperature_string(dive->airtemp, true); m_waterTemp = get_temperature_string(dive->watertemp, true); + if (m_airTemp.isEmpty()) { + m_airTemp = "--"; + } + if (m_waterTemp.isEmpty()) { + m_waterTemp = "--"; + } } void Dive::put_notes() { m_notes = QString::fromUtf8(dive->notes); + if (m_notes.isEmpty()) { + m_notes = "--"; + } +} + +void Dive::put_tags() +{ + char buffer[256]; + taglist_get_tagstring(dive->tag_list, buffer, 256); + m_tags = QString(buffer); +} + +void Dive::put_gas() +{ + int added = 0; + QString gas, gases; + for (int i = 0; i < MAX_CYLINDERS; i++) { + if (!is_cylinder_used(dive, i)) + continue; + gas = dive->cylinder[i].type.description; + gas += QString(!gas.isEmpty() ? " " : "") + gasname(&dive->cylinder[i].gasmix); + // if has a description and if such gas is not already present + if (!gas.isEmpty() && gases.indexOf(gas) == -1) { + if (added > 0) + gases += QString(" / "); + gases += gas; + added++; + } + } + m_gas = gases; +} + +void Dive::put_sac() +{ + if (dive->sac) { + const char *unit; + int decimal; + double value = get_volume_units(dive->sac, &decimal, &unit); + m_sac = QString::number(value, 'f', decimal).append(unit); + } } diff --git a/templatelayout.h b/templatelayout.h index c545f5a05..41a3cbfa9 100644 --- a/templatelayout.h +++ b/templatelayout.h @@ -32,6 +32,7 @@ class Dive { private: int m_number; int m_id; + int m_rating; QString m_date; QString m_time; QString m_location; @@ -42,6 +43,9 @@ private: QString m_airTemp; QString m_waterTemp; QString m_notes; + QString m_tags; + QString m_gas; + QString m_sac; struct dive *dive; void put_date_time(); void put_location(); @@ -51,6 +55,9 @@ private: void put_buddy(); void put_temp(); void put_notes(); + void put_tags(); + void put_gas(); + void put_sac(); public: Dive(struct dive *dive) @@ -58,6 +65,7 @@ public: { m_number = dive->number; m_id = dive->id; + m_rating = dive->rating; put_date_time(); put_location(); put_duration(); @@ -66,11 +74,15 @@ public: put_buddy(); put_temp(); put_notes(); + put_tags(); + put_gas(); + put_sac(); } Dive(); ~Dive(); int number() const; int id() const; + int rating() const; QString date() const; QString time() const; QString location() const; @@ -81,6 +93,9 @@ public: QString airTemp() const; QString waterTemp() const; QString notes() const; + QString tags() const; + QString gas() const; + QString sac() const; }; Q_DECLARE_METATYPE(Dive) @@ -112,6 +127,14 @@ else if (property == "waterTemp") return object.waterTemp(); else if (property == "notes") return object.notes(); +else if (property == "rating") + return object.rating(); +else if (property == "sac") + return object.sac(); +else if (property == "tags") + return object.tags(); +else if (property == "gas") + return object.gas(); GRANTLEE_END_LOOKUP GRANTLEE_BEGIN_LOOKUP(template_options) @@ -128,6 +151,8 @@ if (property == "font") { case 4: return "Verdana, Geneva, sans-serif"; } +} else if (property == "borderwidth") { + return object.border_width; } else if (property == "font_size") { return object.font_size / 9.0; } else if (property == "line_spacing") { @@ -142,6 +167,8 @@ if (property == "font") { return object.color_palette.color4.name(); } else if (property == "color5") { return object.color_palette.color5.name(); +} else if (property == "color6") { + return object.color_palette.color6.name(); } GRANTLEE_END_LOOKUP |