Hi, I did some progress in exporting photos, I attached two patches. I am still working on improving the photos slider style and adding additional dive data to the dive status.
Also do you think adding a Google map or some kind of maps to show the dive location will be needed? waiting for your feedback. Regards, Gehad On Fri, Jul 11, 2014 at 6:28 AM, Miika Turkia <[email protected]> wrote: > Here are the latest patches with my SOB. This includes also the Rick's > patch that was missed. > > > On Fri, Jul 11, 2014 at 5:05 AM, Gehad Elrobey <[email protected]> > wrote: > >> I attached two patches with some fixes to the dive profile view. >> >> additionally, I am still can't view the thumbnails when I add photos to >> dives, I think I am doing something wrong when adding photos. >> does any type of export save Images? >> > > This was fixed a few days ago on master. Anyway, I'll send you a sample > log along with an image in a separate email so you can skip the image > loading part. > > Currently the picture is ignored by other exports. Reinhart is just > implementing support for pictures on divelogs.de. I'll take a look in > adding this to UDDF export this weekend. > >> >> Also there is a patch that Rick has sent 5 days ago which is not applied >> till now, should I forward it? >> > > Included here... > > miika >
From 9cd627e14b68344d6174fa05d063742d2be73a7f Mon Sep 17 00:00:00 2001 From: Gehad elrobey <[email protected]> Date: Sun, 13 Jul 2014 23:36:35 +0200 Subject: [PATCH 2/2] HTML: Add dive photos to the detailed view Export dive photos if exisit in dive. Dive photos are copied to the photos directory in the attached files with the export. the photos section appears only if photos exist. QT helper functions are added to copy images to the photos directory, Additionally the photos directory must be passed as a parameter to the write_one_dive function to save photos to it. Some options structure may be needed instead of passing many arguments. Signed-off-by: Gehad elrobey <[email protected]> --- qt-ui/divelogexportdialog.cpp | 7 +++++-- qthelper.cpp | 20 ++++++++++++++++++++ qthelper.h | 1 + save-html.c | 39 ++++++++++++++++++++++++++------------- save-html.h | 4 +++- theme/dive_export.html | 9 +++++++++ theme/light.css | 14 ++++++++++++++ theme/list_lib.js | 41 ++++++++++++++++++++++++++++++++++++++++- theme/sand.css | 14 ++++++++++++++ 9 files changed, 132 insertions(+), 17 deletions(-) diff --git a/qt-ui/divelogexportdialog.cpp b/qt-ui/divelogexportdialog.cpp index f896235..2221802 100644 --- a/qt-ui/divelogexportdialog.cpp +++ b/qt-ui/divelogexportdialog.cpp @@ -81,13 +81,16 @@ void DiveLogExportDialog::exportHtmlInit(const QString &filename) QFileInfo info(file); QDir mainDir = info.absoluteDir(); mainDir.mkdir(file.fileName() + "_files"); - QString exportFiles = file.fileName() + "_files/"; + QString exportFiles = file.fileName() + "_files"; QString json_dive_data = exportFiles + QDir::separator() + "file.json"; QString json_settings = exportFiles + QDir::separator() + "settings.json"; + QString photos_directory = exportFiles + QDir::separator() + "photos" + QDir::separator(); + mainDir.mkdir(photos_directory); + exportFiles += "/"; exportHTMLsettings(json_settings); - export_HTML(json_dive_data.toUtf8().data(), ui->exportSelectedDives->isChecked(), ui->exportListOnly->isChecked()); + export_HTML(json_dive_data.toUtf8().data(), photos_directory.toUtf8().data(), ui->exportSelectedDives->isChecked(), ui->exportListOnly->isChecked()); QString searchPath = getSubsurfaceDataPath("theme"); if (searchPath.isEmpty()) diff --git a/qthelper.cpp b/qthelper.cpp index c8738b2..a961d64 100644 --- a/qthelper.cpp +++ b/qthelper.cpp @@ -4,6 +4,7 @@ #include "statistics.h" #include <exif.h> #include "file.h" +#include <QFile> #include <QRegExp> #include <QDir> #include <QMap> @@ -283,6 +284,25 @@ picture_load_exit: return; } +extern "C" const char* get_file_name(const char *fileName) +{ + QFile file(fileName); + QFileInfo fileInfo(file.fileName()); + QString filename(fileInfo.fileName()); + return filename.toStdString().c_str(); +} + +extern "C" void copy_image_and_overwrite(const char *cfileName, const char *cnewName) +{ + QString fileName = QString::fromUtf8(cfileName); + QString newName = QString::fromUtf8(cnewName); + newName += get_file_name(cfileName); + QFile file(newName); + if (file.exists()) + file.remove(); + QFile::copy(fileName, newName); +} + static bool lessThan(const QPair<QString, int> &a, const QPair<QString, int> &b) { return a.second < b.second; diff --git a/qthelper.h b/qthelper.h index 528c636..ccc57bc 100644 --- a/qthelper.h +++ b/qthelper.h @@ -16,4 +16,5 @@ bool gpsHasChanged(struct dive *dive, struct dive *master, const QString &gps_te QString printGPSCoords(int lat, int lon); QList<int> getDivesInTrip(dive_trip_t *trip); QString gasToStr(struct gasmix gas); + #endif // QTHELPER_H diff --git a/save-html.c b/save-html.c index 2d03bca..324d543 100644 --- a/save-html.c +++ b/save-html.c @@ -11,6 +11,18 @@ void write_attribute(struct membuffer *b, const char *att_name, const char *valu put_string(b, "\","); } +void save_photos(struct membuffer *b, const char *photos_dir, struct dive *dive) +{ + struct picture *pic = dive->picture_list; + put_string(b, "\"photos\":["); + while (pic) { + put_format(b, "{\"filename\":\"%s\"},", get_file_name(pic->filename)); + copy_image_and_overwrite(pic->filename, photos_dir); + pic = pic->next; + } + put_string(b, "],"); +} + void write_dive_status(struct membuffer *b, struct dive *dive) { put_format(b, "\"sac\":\"%d\",", dive->sac); @@ -162,7 +174,7 @@ void put_HTML_tags(struct membuffer *b, struct dive *dive, const char *pre, cons } /* if exporting list_only mode, we neglect exporting the samples, bookmarks and cylinders */ -void write_one_dive(struct membuffer *b, struct dive *dive, int *dive_no, const bool list_only) +void write_one_dive(struct membuffer *b, struct dive *dive, const char *photos_dir, int *dive_no, const bool list_only) { put_string(b, "{"); put_format(b, "\"number\":%d,", *dive_no); @@ -180,6 +192,7 @@ void write_one_dive(struct membuffer *b, struct dive *dive, int *dive_no, const write_attribute(b, "divemaster", dive->divemaster); write_attribute(b, "suit", dive->suit); write_dive_status(b, dive); + save_photos(b, photos_dir, dive); put_HTML_tags(b, dive, "\"tags\":", ","); put_HTML_notes(b, dive, "\"notes\":\"", "\","); if (!list_only) { @@ -191,7 +204,7 @@ void write_one_dive(struct membuffer *b, struct dive *dive, int *dive_no, const (*dive_no)++; } -void write_no_trip(struct membuffer *b, int *dive_no, const bool list_only) +void write_no_trip(struct membuffer *b, int *dive_no, const char *photos_dir, const bool list_only) { int i; struct dive *dive; @@ -202,12 +215,12 @@ void write_no_trip(struct membuffer *b, int *dive_no, const bool list_only) for_each_dive (i, dive) { if (!dive->divetrip) - write_one_dive(b, dive, dive_no, list_only); + write_one_dive(b, dive, photos_dir, dive_no, list_only); } put_format(b, "]},\n\n"); } -void write_trip(struct membuffer *b, dive_trip_t *trip, int *dive_no, const bool list_only) +void write_trip(struct membuffer *b, dive_trip_t *trip, int *dive_no, const char *photos_dir, const bool list_only) { struct dive *dive; @@ -216,13 +229,13 @@ void write_trip(struct membuffer *b, dive_trip_t *trip, int *dive_no, const bool put_format(b, "\"dives\":["); for (dive = trip->dives; dive != NULL; dive = dive->next) { - write_one_dive(b, dive, dive_no, list_only); + write_one_dive(b, dive, photos_dir, dive_no, list_only); } put_format(b, "]},\n\n"); } -void write_trips(struct membuffer *b, bool selected_only, const bool list_only) +void write_trips(struct membuffer *b, const char *photos_dir, bool selected_only, const bool list_only) { int i, dive_no = 0; struct dive *dive; @@ -239,7 +252,7 @@ void write_trips(struct membuffer *b, bool selected_only, const bool list_only) for_each_dive (i, dive) { if (!dive->selected) continue; - write_one_dive(b, dive, &dive_no, list_only); + write_one_dive(b, dive, photos_dir, &dive_no, list_only); } put_format(b, "]},\n\n"); } else { @@ -253,27 +266,27 @@ void write_trips(struct membuffer *b, bool selected_only, const bool list_only) /* We haven't seen this trip before - save it and all dives */ trip->index = 1; - write_trip(b, trip, &dive_no, list_only); + write_trip(b, trip, &dive_no, photos_dir, list_only); } /*Save all remaining trips into Others*/ - write_no_trip(b, &dive_no, list_only); + write_no_trip(b, &dive_no, photos_dir, list_only); } } -void export_list(struct membuffer *b, bool selected_only, const bool list_only) +void export_list(struct membuffer *b, const char *photos_dir, bool selected_only, const bool list_only) { put_string(b, "trips=["); - write_trips(b, selected_only, list_only); + write_trips(b, photos_dir, selected_only, list_only); put_string(b, "]"); } -void export_HTML(const char *file_name, const bool selected_only, const bool list_only) +void export_HTML(const char *file_name, const char *photos_dir, const bool selected_only, const bool list_only) { FILE *f; struct membuffer buf = { 0 }; - export_list(&buf, selected_only, list_only); + export_list(&buf, photos_dir, selected_only, list_only); f = subsurface_fopen(file_name, "w+"); if (!f) diff --git a/save-html.h b/save-html.h index 432231d..2981961 100644 --- a/save-html.h +++ b/save-html.h @@ -15,8 +15,10 @@ void put_HTML_time(struct membuffer *b, struct dive *dive, const char *pre, cons void put_HTML_notes(struct membuffer *b, struct dive *dive, const char *pre, const char *post); void put_HTML_quoted(struct membuffer *b, const char *text); -void export_HTML(const char *file_name, const bool selected_only, const bool list_only); +void export_HTML(const char *file_name, const char *photos_dir, const bool selected_only, const bool list_only); +extern void copy_image_and_overwrite(const char *cfileName, const char *cnewName); +extern const char* get_file_name(const char *fileName); #ifdef __cplusplus } #endif diff --git a/theme/dive_export.html b/theme/dive_export.html index ec08e86..d9417e2 100644 --- a/theme/dive_export.html +++ b/theme/dive_export.html @@ -203,6 +203,15 @@ function changeAdvSearch(e){ <div id="divestats"> <h2 class="det_hed">Dive stats</h2> </div> + <div id="divephotos"> + <h2 class="det_hed">Dive Photos</h2> + <div id="slider_container"> + <button onclick="prev_photo()" style="width:7%;margin:1%;float:left;"><-</button> + <div id="slider"> + </div> + <button onclick="next_photo()" style="width:7%;margin:1%;float:left">-></button> + </div> + </div> </div> </body> </html> diff --git a/theme/light.css b/theme/light.css index 1dc5f6d..6f69880 100644 --- a/theme/light.css +++ b/theme/light.css @@ -210,6 +210,20 @@ ul:hover{ box-shadow: 10px 10px 5px #888888; } +#slider_container{ + height:240px; + margin-bottom:20px; +} + +#slider{ + float:left; + width:80%; + min-width:350px; + height:240px; + border-style:solid; + overflow:hidden; +} + .Cyl{ padding-right:25px; } diff --git a/theme/list_lib.js b/theme/list_lib.js index 0a61ed7..74cfce0 100644 --- a/theme/list_lib.js +++ b/theme/list_lib.js @@ -724,7 +724,8 @@ function get_bookmark_HTML(event) */ function get_bookmarks_HTML(dive) { - if (dive.events <= 0) return ""; + if (dive.events <= 0) + return ""; var result = ""; result += '<h2 class="det_hed">Events</h2><table><tr><td class="words">Name</td><td class="words">Time</td></tr>'; for (var i in dive.events) { @@ -766,6 +767,43 @@ function get_status_HTML(dive) '</td></tr></table>'; }; +function get_dive_photos(dive) +{ + if (dive.photos.length <= 0) { + document.getElementById("divephotos").style.display = 'none'; + return ""; + } + var slider = ""; + document.getElementById("divephotos").style.display = 'block'; + for (var i = 0; i < dive.photos.length; i++) { + slider += '<img src="'+location.pathname + +'_files/photos/'+dive.photos[i].filename+'" alt="" height="240" width="240">'; + } + return slider; +} + +function prev_photo() +{ + var temp = items[dive_id].photos[0]; + var i; + for (i = 0; i < items[dive_id].photos.length - 1; i++) { + items[dive_id].photos[i] = items[dive_id].photos[i + 1] + } + items[dive_id].photos[i] = temp; + document.getElementById("slider").innerHTML = get_dive_photos(items[dive_id]); +} + +function next_photo() +{ + var temp = items[dive_id].photos[items[dive_id].photos.length - 1]; + var i; + for (i = items[dive_id].photos.length - 1; i > 0; i--) { + items[dive_id].photos[i] = items[dive_id].photos[i - 1] + } + items[dive_id].photos[0] = temp; + document.getElementById("slider").innerHTML = get_dive_photos(items[dive_id]); +} + function mkelvin_to_C(mkelvin) { return (mkelvin - ZERO_C_IN_MKELVIN) / 1000.0; @@ -948,6 +986,7 @@ function showDiveDetails(dive) document.getElementById("dive_equipments").innerHTML = get_cylinders_HTML(items[dive_id]); document.getElementById("bookmarks").innerHTML = get_bookmarks_HTML(items[dive_id]); document.getElementById("divestats").innerHTML = get_status_HTML(items[dive_id]); + document.getElementById("slider").innerHTML = get_dive_photos(items[dive_id]); setDiveTitle(items[dive_id]); //hide the list of dives and show the canvas. diff --git a/theme/sand.css b/theme/sand.css index 1ccde77..d17824c 100644 --- a/theme/sand.css +++ b/theme/sand.css @@ -212,6 +212,20 @@ ul:hover{ box-shadow: 7px 7px 5px rgba(215, 107, 27, 0.43); } +#slider_container{ + height:240px; + margin-bottom:20px; +} + +#slider{ + float:left; + width:80%; + min-width:350px; + height:240px; + border-style:solid; + overflow:hidden; +} + .det_hed{ background-color:#EFC15F; padding:3px; -- 1.9.1
From c39edf08f2069bad8108f295e9954d0f093530b2 Mon Sep 17 00:00:00 2001 From: Gehad elrobey <[email protected]> Date: Fri, 11 Jul 2014 03:26:21 +0200 Subject: [PATCH 1/2] HTML: save dive status in dive detailed view Add dive status in the dive detailed view. Signed-off-by: Gehad elrobey <[email protected]> --- save-html.c | 8 ++++++++ theme/list_lib.js | 13 ++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/save-html.c b/save-html.c index 13bf70c..2d03bca 100644 --- a/save-html.c +++ b/save-html.c @@ -11,6 +11,13 @@ void write_attribute(struct membuffer *b, const char *att_name, const char *valu put_string(b, "\","); } +void write_dive_status(struct membuffer *b, struct dive *dive) +{ + put_format(b, "\"sac\":\"%d\",", dive->sac); + put_format(b, "\"otu\":\"%d\",", dive->otu); + put_format(b, "\"cns\":\"%d\",", dive->cns); +} + void put_HTML_bookmarks(struct membuffer *b, struct dive *dive) { struct event *ev = dive->dc.events; @@ -172,6 +179,7 @@ void write_one_dive(struct membuffer *b, struct dive *dive, int *dive_no, const write_attribute(b, "buddy", dive->buddy); write_attribute(b, "divemaster", dive->divemaster); write_attribute(b, "suit", dive->suit); + write_dive_status(b, dive); put_HTML_tags(b, dive, "\"tags\":", ","); put_HTML_notes(b, dive, "\"notes\":\"", "\","); if (!list_only) { diff --git a/theme/list_lib.js b/theme/list_lib.js index 7135369..0a61ed7 100644 --- a/theme/list_lib.js +++ b/theme/list_lib.js @@ -734,7 +734,6 @@ function get_bookmarks_HTML(dive) return result; } - /** *Return HTML main data of a dive */ @@ -756,6 +755,17 @@ function get_dive_HTML(dive) '</td></tr></table><div style="margin:10px;"><p class="words">Notes: </p>' + dive.notes + '</div>'; }; +/** +*Return HTML dive status data +*/ +function get_status_HTML(dive) +{ + return '<h2 class="det_hed">Dive Status</h2><table><tr><td class="words">Sac: </td><td>' + dive.sac + + '</td><td class="words">     Otu: </td><td>' + dive.otu + + '</td><td class="words">     Cns: </td><td>' + dive.cns + + '</td></tr></table>'; +}; + function mkelvin_to_C(mkelvin) { return (mkelvin - ZERO_C_IN_MKELVIN) / 1000.0; @@ -937,6 +947,7 @@ function showDiveDetails(dive) document.getElementById("diveinfo").innerHTML = get_dive_HTML(items[dive_id]); document.getElementById("dive_equipments").innerHTML = get_cylinders_HTML(items[dive_id]); document.getElementById("bookmarks").innerHTML = get_bookmarks_HTML(items[dive_id]); + document.getElementById("divestats").innerHTML = get_status_HTML(items[dive_id]); setDiveTitle(items[dive_id]); //hide the list of dives and show the canvas. -- 1.9.1
_______________________________________________ subsurface mailing list [email protected] http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface
