mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	HTML list exporter
Exporting the raw dive list into JSON format for later viewing with html and js files. Also some worldmap code organizations. Signed-off-by: Gehad elrobey <gehadelrobey@gmail.com> Signed-off-by: Miika Turkia <miika.turkia@gmail.com> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
		
							parent
							
								
									b37422c447
								
							
						
					
					
						commit
						a3dbb5865c
					
				
					 6 changed files with 232 additions and 98 deletions
				
			
		|  | @ -2,7 +2,6 @@ | |||
| #include <QString> | ||||
| #include <QShortcut> | ||||
| #include <QAbstractButton> | ||||
| #include <QDebug> | ||||
| #include <QSettings> | ||||
| 
 | ||||
| #include "mainwindow.h" | ||||
|  | @ -10,6 +9,7 @@ | |||
| #include "ui_divelogexportdialog.h" | ||||
| #include "subsurfacewebservices.h" | ||||
| #include "worldmap-save.h" | ||||
| #include "save-html.h" | ||||
| 
 | ||||
| DiveLogExportDialog::DiveLogExportDialog(QWidget *parent) : QDialog(parent), | ||||
| 	ui(new Ui::DiveLogExportDialog) | ||||
|  | @ -39,6 +39,8 @@ void DiveLogExportDialog::showExplanation() | |||
| 		ui->description->setText("HTML export of the dive locations, visualized on a world map."); | ||||
| 	} else if (ui->exportSubsurfaceXML->isChecked()) { | ||||
| 		ui->description->setText("Subsurface native XML format."); | ||||
| 	} else if (ui->exportHtml->isChecked()) { | ||||
| 		ui->description->setText("Html export of dive list can be viewed in any web browser."); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -84,7 +86,13 @@ void DiveLogExportDialog::on_buttonBox_accepted() | |||
| 			QByteArray bt = QFile::encodeName(filename); | ||||
| 			save_dives_logic(bt.data(), true); | ||||
| 		} | ||||
| 	} else if (ui->exportHtml->isChecked()) { | ||||
| 		filename = QFileDialog::getSaveFileName(this, tr("Export HTML"), lastDir, | ||||
| 							tr("HTML files (*.html)")); | ||||
| 		if (!filename.isNull() && !filename.isEmpty()) | ||||
| 			export_HTML(filename.toUtf8().data(), ui->exportSelected->isChecked()); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!filename.isNull() && !filename.isEmpty()) { | ||||
| 		// remember the last export path
 | ||||
| 		QFileInfo fileInfo(filename); | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ | |||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>448</width> | ||||
|     <height>473</height> | ||||
|     <height>522</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|  | @ -17,7 +17,7 @@ | |||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>20</x> | ||||
|      <y>420</y> | ||||
|      <y>450</y> | ||||
|      <width>341</width> | ||||
|      <height>32</height> | ||||
|     </rect> | ||||
|  | @ -62,7 +62,7 @@ | |||
|      <x>20</x> | ||||
|      <y>70</y> | ||||
|      <width>201</width> | ||||
|      <height>211</height> | ||||
|      <height>241</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <property name="title"> | ||||
|  | @ -166,6 +166,35 @@ | |||
|      <string notr="true">exportGroup</string> | ||||
|     </attribute> | ||||
|    </widget> | ||||
|    <widget class="QRadioButton" name="exportHtml"> | ||||
|     <property name="geometry"> | ||||
|      <rect> | ||||
|       <x>10</x> | ||||
|       <y>190</y> | ||||
|       <width>117</width> | ||||
|       <height>22</height> | ||||
|      </rect> | ||||
|     </property> | ||||
|     <property name="text"> | ||||
|      <string>HTML</string> | ||||
|     </property> | ||||
|     <attribute name="buttonGroup"> | ||||
|      <string notr="true">exportGroup</string> | ||||
|     </attribute> | ||||
|    </widget> | ||||
|    <widget class="Line" name="line"> | ||||
|     <property name="geometry"> | ||||
|      <rect> | ||||
|       <x>40</x> | ||||
|       <y>230</y> | ||||
|       <width>231</width> | ||||
|       <height>16</height> | ||||
|      </rect> | ||||
|     </property> | ||||
|     <property name="orientation"> | ||||
|      <enum>Qt::Horizontal</enum> | ||||
|     </property> | ||||
|    </widget> | ||||
|   </widget> | ||||
|   <widget class="QGroupBox" name="exportSelection"> | ||||
|    <property name="geometry"> | ||||
|  | @ -212,24 +241,11 @@ | |||
|     </property> | ||||
|    </widget> | ||||
|   </widget> | ||||
|   <widget class="Line" name="line"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>60</x> | ||||
|      <y>280</y> | ||||
|      <width>231</width> | ||||
|      <height>16</height> | ||||
|     </rect> | ||||
|    </property> | ||||
|    <property name="orientation"> | ||||
|     <enum>Qt::Horizontal</enum> | ||||
|    </property> | ||||
|   </widget> | ||||
|   <widget class="QLabel" name="description"> | ||||
|    <property name="geometry"> | ||||
|     <rect> | ||||
|      <x>30</x> | ||||
|      <y>310</y> | ||||
|      <y>330</y> | ||||
|      <width>341</width> | ||||
|      <height>91</height> | ||||
|     </rect> | ||||
|  |  | |||
							
								
								
									
										154
									
								
								save-html.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								save-html.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,154 @@ | |||
| #include "save-html.h" | ||||
| #include "gettext.h" | ||||
| 
 | ||||
| void put_HTML_date(struct membuffer *b, struct dive *dive, const char *pre, const char *post) | ||||
| { | ||||
| 	struct tm tm; | ||||
| 	utc_mkdate(dive->when, &tm); | ||||
| 	put_format(b, "%s%04u-%02u-%02u%s", pre, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, post); | ||||
| } | ||||
| 
 | ||||
| char *replace_char(char *str, char replace, char *replace_by) | ||||
| { | ||||
| 	/*
 | ||||
| 		this function can't replace a character with a substring | ||||
| 		where the substring contains the character, infinite loop. | ||||
| 	*/ | ||||
| 
 | ||||
| 	if (!str) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	int i = 0, char_count = 0, new_size; | ||||
| 
 | ||||
| 	while (str[i] != '\0') { | ||||
| 		if (str[i] == replace) | ||||
| 			char_count++; | ||||
| 		i++; | ||||
| 	} | ||||
| 
 | ||||
| 	new_size = strlen(str) + char_count * strlen(replace_by) + 1; | ||||
| 	char *result = malloc(new_size); | ||||
| 	char *temp = strdup(str); | ||||
| 	char *p0, *p1; | ||||
| 	if (!result || !temp) | ||||
| 		return 0; | ||||
| 	result[0] = '\0'; | ||||
| 	p0 = temp; | ||||
| 	p1 = strchr(temp, replace); | ||||
| 	while (p1) { | ||||
| 		*p1 = '\0'; | ||||
| 		strcat(result, p0); | ||||
| 		strcat(result, replace_by); | ||||
| 		p0 = p1 + 1; | ||||
| 		p1 = strchr(p0, replace); | ||||
| 	} | ||||
| 	strcat(result, p0); /*concat the rest of the string*/ | ||||
| 	free(temp); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| char *quote(char *string) | ||||
| { | ||||
| 	char *new_line_removed = replace_char(string, '\n', "<br>"); | ||||
| 	char *single_quotes_removed = replace_char(new_line_removed, '\'', "'"); | ||||
| 	free(new_line_removed); | ||||
| 	return single_quotes_removed; | ||||
| } | ||||
| 
 | ||||
| void put_HTML_notes(struct membuffer *b, struct dive *dive, const char *pre, const char *post) | ||||
| { | ||||
| 	if (dive->notes) { | ||||
| 		char *notes = quote(dive->notes); | ||||
| 		put_format(b, "%s: %s %s", pre, notes, post); | ||||
| 		free(notes); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void put_HTML_time(struct membuffer *b, struct dive *dive, const char *pre, const char *post) | ||||
| { | ||||
| 	struct tm tm; | ||||
| 	utc_mkdate(dive->when, &tm); | ||||
| 	put_format(b, "%s%02u:%02u:%02u%s", pre, tm.tm_hour, tm.tm_min, tm.tm_sec, post); | ||||
| } | ||||
| 
 | ||||
| void put_HTML_airtemp(struct membuffer *b, struct dive *dive, const char *pre, const char *post) | ||||
| { | ||||
| 	const char *unit; | ||||
| 	double value; | ||||
| 
 | ||||
| 	value = get_temp_units(dive->airtemp.mkelvin, &unit); | ||||
| 	put_format(b, "%s%.1f %s%s",pre, value, unit, post); | ||||
| } | ||||
| 
 | ||||
| void put_HTML_watertemp(struct membuffer *b, struct dive *dive, const char *pre, const char *post) | ||||
| { | ||||
| 	const char *unit; | ||||
| 	double value; | ||||
| 
 | ||||
| 	value = get_temp_units(dive->watertemp.mkelvin, &unit); | ||||
| 	put_format(b, "%s%.1f %s%s",pre, value, unit, post); | ||||
| } | ||||
| 
 | ||||
| void put_HTML_tags(struct membuffer *b, struct dive *dive, const char *pre, const char *post) | ||||
| { | ||||
| 	put_string(b, pre); | ||||
| 	struct tag_entry *tag = dive->tag_list; | ||||
| 	while(tag){ | ||||
| 		put_format(b, "%s ", tag->tag->name); | ||||
| 		tag = tag->next; | ||||
| 	} | ||||
| 	put_string(b, post); | ||||
| } | ||||
| 
 | ||||
| void write_dives(struct membuffer *b,bool selected_only) | ||||
| { | ||||
| 	int i, dive_no = 0; | ||||
| 	struct dive *dive; | ||||
| 
 | ||||
| 	for_each_dive(i, dive) { | ||||
| 		if (selected_only) { | ||||
| 			if (!dive->selected) | ||||
| 				continue; | ||||
| 		} | ||||
| 		put_string(b, "{"); | ||||
| 		put_format(b, "\"number\":%d,", dive_no); | ||||
| 		put_HTML_date(b, dive, "\"date\":\"", "\","); | ||||
| 		put_HTML_time(b, dive, "\"time\":\"", "\","); | ||||
| 		put_format(b, "\"location\":\"%s\",", dive->location); | ||||
| 		put_format(b, "\"rating\":%d,", dive->rating); | ||||
| 		put_format(b, "\"visibility\":%d,", dive->visibility); | ||||
| 		put_string(b, "\"temperature\":{"); | ||||
| 		put_HTML_airtemp(b, dive, "\"air\":\"", "\","); | ||||
| 		put_HTML_watertemp(b, dive, "\"water\":\"", "\","); | ||||
| 		put_string(b, "	},"); | ||||
| 		put_format(b, "\"buddy\":\"%s\",", dive->buddy); | ||||
| 		put_format(b, "\"divemaster\":\"%s\",", dive->divemaster); | ||||
| 		put_format(b, "\"suit\":\"%s\",", dive->suit); | ||||
| 		put_HTML_tags(b, dive, "\"tags\":\"", "\","); | ||||
| 		put_HTML_notes(b, dive ,"\"notes\":\"" ,"\","); | ||||
| 		put_string(b, "},\n"); | ||||
| 		dive_no++; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void export_dives(struct membuffer *b,bool selected_only){ | ||||
| 	put_string(b, "items=["); | ||||
| 	write_dives(b, selected_only); | ||||
| 	put_string(b, "]"); | ||||
| } | ||||
| 
 | ||||
| void export_HTML(const char *file_name, const bool selected_only) | ||||
| { | ||||
| 	FILE *f; | ||||
| 
 | ||||
| 	struct membuffer buf = { 0 }; | ||||
| 	export_dives(&buf, selected_only); | ||||
| 
 | ||||
| 	f = fopen(file_name, "w+"); | ||||
| 	if (!f) | ||||
| 		printf("error"); /*report error*/ | ||||
| 
 | ||||
| 	flush_buffer(&buf, f); /*check for writing errors? */ | ||||
| 	free_buffer(&buf); | ||||
| 	fclose(f); | ||||
| } | ||||
							
								
								
									
										26
									
								
								save-html.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								save-html.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | |||
| #ifndef HTML_SAVE_H | ||||
| #define HTML_SAVE_H | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| #include "dive.h" | ||||
| #include "membuffer.h" | ||||
| 
 | ||||
| void put_HTML_date(struct membuffer *b, struct dive *dive, const char *pre, const char *post); | ||||
| void put_HTML_airtemp(struct membuffer *b, struct dive *dive, const char *pre, const char *post); | ||||
| void put_HTML_watertemp(struct membuffer *b, struct dive *dive, const char *pre, const char *post); | ||||
| void put_HTML_time(struct membuffer *b, struct dive *dive, const char *pre, const char *post); | ||||
| void put_HTML_notes(struct membuffer *b, struct dive *dive, const char *pre, const char *post); | ||||
| 
 | ||||
| char *replace_char(char *str, char replace, char *replace_by); | ||||
| char *quote(char *string); | ||||
| 
 | ||||
| void export_HTML(const char *file_name, const bool selected_only); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #endif | ||||
|  | @ -28,6 +28,7 @@ HEADERS = \ | |||
| 	helpers.h \ | ||||
| 	libdivecomputer.h \ | ||||
| 	planner.h \ | ||||
| 	save-html.h \ | ||||
| 	worldmap-save.h \ | ||||
| 	worldmap-options.h \ | ||||
| 	pref.h \ | ||||
|  | @ -104,6 +105,7 @@ SOURCES =  \ | |||
| 	profile.c \ | ||||
| 	divecomputer.cpp \ | ||||
| 	worldmap-save.c \ | ||||
| 	save-html.c \ | ||||
| 	qt-gui.cpp \ | ||||
| 	qthelper.cpp \ | ||||
| 	qt-ui/about.cpp \ | ||||
|  |  | |||
|  | @ -2,8 +2,10 @@ | |||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| #include "dive.h" | ||||
| #include "membuffer.h" | ||||
| #include "save-html.h" | ||||
| #include "worldmap-save.h" | ||||
| #include "worldmap-options.h" | ||||
| #include "gettext.h" | ||||
|  | @ -14,82 +16,6 @@ char *getGoogleApi() | |||
| 	return "https://maps.googleapis.com/maps/api/js?key=AIzaSyDzo9PWsqYDDSddVswg_13rpD9oH_dLuoQ"; | ||||
| } | ||||
| 
 | ||||
| void put_HTML_date(struct membuffer *b, struct dive *dive) | ||||
| { | ||||
| 	struct tm tm; | ||||
| 	utc_mkdate(dive->when, &tm); | ||||
| 	put_format(b, "<p>%s: %04u-%02u-%02u</p>", translate("gettextFromC", "Date"), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); | ||||
| 	put_format(b, "<p>%s: %02u:%02u:%02u</p>", translate("gettextFromC", "Time"), tm.tm_hour, tm.tm_min, tm.tm_sec); | ||||
| } | ||||
| 
 | ||||
| void put_HTML_temp(struct membuffer *b, struct dive *dive) | ||||
| { | ||||
| 	const char *unit; | ||||
| 	double value; | ||||
| 
 | ||||
| 	value = get_temp_units(dive->airtemp.mkelvin, &unit); | ||||
| 	put_format(b, "<p>%s: %.1f %s</p>", translate("gettextFromC", "Air Temp"), value, unit); | ||||
| 
 | ||||
| 	value = get_temp_units(dive->watertemp.mkelvin, &unit); | ||||
| 	put_format(b, "<p>%s: %.1f %s</p>", translate("gettextFromC", "Water Temp"), value, unit); | ||||
| } | ||||
| 
 | ||||
| char *replace_char(char *str, char replace, char *replace_by) | ||||
| { | ||||
| 	/*
 | ||||
| 		this fumction can't replace a character with a substring | ||||
| 		where the substring contains the character, infinte loop. | ||||
| 	*/ | ||||
| 
 | ||||
| 	if (!str) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	int i = 0, char_count = 0, new_size; | ||||
| 
 | ||||
| 	while (str[i] != '\0') { | ||||
| 		if (str[i] == replace) | ||||
| 			char_count++; | ||||
| 		i++; | ||||
| 	} | ||||
| 
 | ||||
| 	new_size = strlen(str) + char_count * strlen(replace_by) + 1; | ||||
| 	char *result = malloc(new_size); | ||||
| 	char *temp = strdup(str); | ||||
| 	char *p0, *p1; | ||||
| 	if (!result || !temp) | ||||
| 		return 0; | ||||
| 	result[0] = '\0'; | ||||
| 	p0 = temp; | ||||
| 	p1 = strchr(temp, replace); | ||||
| 	while (p1) { | ||||
| 		*p1 = '\0'; | ||||
| 		strcat(result, p0); | ||||
| 		strcat(result, replace_by); | ||||
| 		p0 = p1 + 1; | ||||
| 		p1 = strchr(p0, replace); | ||||
| 	} | ||||
| 	strcat(result, p0); /*concat the rest of the string*/ | ||||
| 	free(temp); | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| char *quote(char *string) | ||||
| { | ||||
| 	char *new_line_removed = replace_char(string, '\n', "<br>"); | ||||
| 	char *single_quotes_removed = replace_char(new_line_removed, '\'', "'"); | ||||
| 	free(new_line_removed); | ||||
| 	return single_quotes_removed; | ||||
| } | ||||
| 
 | ||||
| void put_HTML_notes(struct membuffer *b, struct dive *dive) | ||||
| { | ||||
| 	if (dive->notes) { | ||||
| 		char *notes = quote(dive->notes); | ||||
| 		put_format(b, "<p>%s: %s </p>", translate("gettextFromC", "Notes"), notes); | ||||
| 		free(notes); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void writeMarkers(struct membuffer *b, const bool selected_only) | ||||
| { | ||||
| 	int i, dive_no = 0; | ||||
|  | @ -106,12 +32,14 @@ void writeMarkers(struct membuffer *b, const bool selected_only) | |||
| 		put_degrees(b, dive->latitude, "temp = new google.maps.Marker({position: new google.maps.LatLng(", ""); | ||||
| 		put_degrees(b, dive->longitude, ",", ")});\n"); | ||||
| 		put_string(b, "markers.push(temp);\ntempinfowindow = new google.maps.InfoWindow({content: '<div id=\"content\">'+'<div id=\"siteNotice\">'+'</div>'+'<div id=\"bodyContent\">"); | ||||
| 		put_format(b, "<p><b>%s</b></p>", quote(dive->location)); | ||||
| 		put_HTML_date(b, dive); | ||||
| 		put_HTML_date(b, dive, translate("gettextFromC", "<p>Date:"), "</p>"); | ||||
| 		put_HTML_time(b, dive, translate("gettextFromC", "<p>Time:"), "</p>"); | ||||
| 		put_duration(b, dive->duration, translate("gettextFromC", "<p>Duration: "), translate("gettextFromC", " min</p>")); | ||||
| 		put_depth(b, dive->maxdepth, translate("gettextFromC", "<p>Max Depth: "), translate("gettextFromC", " m</p>")); | ||||
| 		put_HTML_temp(b, dive); | ||||
| 		put_HTML_notes(b, dive); | ||||
| 		put_HTML_airtemp(b, dive, translate("gettextFromC", "<p>Air Temp: "), "</p>"); | ||||
| 		put_HTML_watertemp(b, dive,translate("gettextFromC", "<p>Water Temp : ") , "</p>"); | ||||
| 		put_format(b, "<p>Location : <b>%s</b></p>", quote(dive->location)); | ||||
| 		put_HTML_notes(b, dive, translate("gettextFromC", "<p> Notes"), " </p>"); | ||||
| 		put_string(b, "</p>'+'</div>'+'</div>'});\ninfowindows.push(tempinfowindow);\n"); | ||||
| 		put_format(b, "google.maps.event.addListener(markers[%d], 'mouseover', function() {\ninfowindows[%d].open(map,markers[%d]);}", dive_no, dive_no, dive_no); | ||||
| 		put_format(b, ");google.maps.event.addListener(markers[%d], 'mouseout', function() {\ninfowindows[%d].close();});\n", dive_no, dive_no); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue