diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2012-09-09 09:06:44 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2012-09-09 17:38:01 -0700 |
commit | b73f29fea3ae88a06d8f773a6d48510520c127f0 (patch) | |
tree | d04166fd6e2fde7d716fe69cbfe35330e79cd1b9 | |
parent | b6812946319080699f6071656f09d402d23d3e46 (diff) | |
download | subsurface-b73f29fea3ae88a06d8f773a6d48510520c127f0.tar.gz |
First cut of adding a default file name
The default file name is OS specific and tries to follow the customs on
each of the OSs. It can be configured through the preferences dialog.
On MacOS we get a strange warning which appears to be a well documented
Gtk bug on MacOS.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | display-gtk.h | 2 | ||||
-rw-r--r-- | dive.h | 2 | ||||
-rw-r--r-- | gtk-gui.c | 95 | ||||
-rw-r--r-- | linux.c | 21 | ||||
-rw-r--r-- | macos.c | 19 | ||||
-rw-r--r-- | main.c | 11 | ||||
-rw-r--r-- | windows.c | 24 |
7 files changed, 168 insertions, 6 deletions
diff --git a/display-gtk.h b/display-gtk.h index dd7e2c4a0..e03861d39 100644 --- a/display-gtk.h +++ b/display-gtk.h @@ -50,8 +50,6 @@ extern const char *subsurface_icon_name(void); extern void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar, GtkWidget *vbox, GtkUIManager *ui_manager); -extern const char *divelist_font; - extern visible_cols_t visible_cols; extern const char *divelist_font; @@ -459,6 +459,8 @@ const char *monthname(int mon); #define FIVE_STARS UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR UTF8_BLACKSTAR extern const char *star_strings[]; +extern const char *default_filename; +extern const char *subsurface_default_filename(void); #define AIR_PERMILLE 209 #endif /* DIVE_H */ @@ -8,6 +8,7 @@ #include <stdlib.h> #include <time.h> #include <unistd.h> +#include <sys/stat.h> #include "dive.h" #include "divelist.h" @@ -26,6 +27,7 @@ GtkWidget *notebook; int error_count; const char *divelist_font; +const char *default_filename; struct units output_units; @@ -173,8 +175,8 @@ static void file_open(GtkWidget *w, gpointer data) } /* return the path and the file component contained in the full path */ -static char *path_and_file(char *pathin, char **fileout) { - char *slash = pathin, *next; +static char *path_and_file(const char *pathin, char **fileout) { + const char *slash = pathin, *next; char *result; size_t len, n; @@ -239,9 +241,24 @@ static void file_save_as(GtkWidget *w, gpointer data) static void file_save(GtkWidget *w, gpointer data) { + const char *current_default; + if (!existing_filename) return file_save_as(w, data); + current_default = subsurface_default_filename(); + if (strcmp(existing_filename, current_default) == 0) { + /* if we are using the default filename the directory + * that we are creating the file in may not exist */ + char *current_def_dir, *current_def_file; + struct stat sb; + + current_def_dir = path_and_file(existing_filename, ¤t_def_file); + if (stat(current_def_dir, &sb) != 0) { + mkdir(current_def_dir, S_IRUSR | S_IWUSR); + } + } + free((void *)current_default); save_dives(existing_filename); mark_divelist_changed(FALSE); } @@ -437,10 +454,66 @@ static void event_toggle(GtkWidget *w, gpointer _data) *plot_ev = GTK_TOGGLE_BUTTON(w)->active; } +static void pick_default_file(GtkWidget *w, GtkButton *button) +{ + GtkWidget *fs_dialog; + const char *current_default, *new_default = NULL; + char *current_def_file, *current_def_dir; + GtkFileFilter *filter; + struct stat sb; + gboolean need_rmdir = FALSE; + + fs_dialog = gtk_file_chooser_dialog_new("Choose Default XML File", + GTK_WINDOW(main_window), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + NULL); + current_default = subsurface_default_filename(); + current_def_dir = path_and_file(current_default, ¤t_def_file); + free((void *)current_default); + /* it's possible that the directory doesn't exist (especially for the default) + * For gtk's file select box to make sense we create it if needed and then remove + * it after the dialog has run */ + if (stat(current_def_dir, &sb) != 0) { + if (mkdir(current_def_dir, S_IRUSR | S_IWUSR) == 0) + need_rmdir = TRUE; + } + gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fs_dialog), current_def_dir); + gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fs_dialog), current_def_file); + gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(fs_dialog), FALSE); + filter = gtk_file_filter_new(); + gtk_file_filter_add_pattern(filter, "*.xml"); + gtk_file_filter_add_pattern(filter, "*.XML"); + gtk_file_filter_add_pattern(filter, "*.sda"); + gtk_file_filter_add_pattern(filter, "*.SDA"); + gtk_file_filter_add_mime_type(filter, "text/xml"); + gtk_file_filter_set_name(filter, "XML file"); + gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fs_dialog), filter); + gtk_widget_show_all(fs_dialog); + if (gtk_dialog_run(GTK_DIALOG(fs_dialog)) == GTK_RESPONSE_ACCEPT) { + GSList *list; + + list = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(fs_dialog)); + if (g_slist_length(list) == 1) { + new_default = strdup(list->data); + } + g_slist_free(list); + if (new_default) + gtk_button_set_label(button, new_default); + } + if (need_rmdir) + rmdir(current_def_dir); + free(current_def_dir); + free(current_def_file); + gtk_widget_destroy(fs_dialog); +} + static void preferences_dialog(GtkWidget *w, gpointer data) { int result; GtkWidget *dialog, *font, *frame, *box, *vbox, *button; + const char *current_default, *new_default; menu_units = output_units; @@ -541,6 +614,15 @@ static void preferences_dialog(GtkWidget *w, gpointer data) gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 6); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(autogroup_toggle), NULL); + frame = gtk_frame_new("Default XML Data File"); + gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 5); + box = gtk_hbox_new(FALSE, 6); + gtk_container_add(GTK_CONTAINER(frame), box); + current_default = subsurface_default_filename(); + button = gtk_button_new_with_label(current_default); + g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(pick_default_file), button); + gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 6); + gtk_widget_show_all(dialog); result = gtk_dialog_run(GTK_DIALOG(dialog)); if (result == GTK_RESPONSE_ACCEPT) { @@ -569,11 +651,18 @@ static void preferences_dialog(GtkWidget *w, gpointer data) subsurface_set_conf("OTU", PREF_BOOL, BOOL_TO_PTR(visible_cols.otu)); subsurface_set_conf("divelist_font", PREF_STRING, divelist_font); subsurface_set_conf("autogroup", PREF_BOOL, BOOL_TO_PTR(autogroup)); + new_default = strdup(gtk_button_get_label(GTK_BUTTON(button))); + if (strcmp(current_default, new_default)) { + subsurface_set_conf("default_filename", PREF_STRING, new_default); + free((void *)default_filename); + default_filename = new_default; + } /* Flush the changes out to the system */ subsurface_flush_conf(); } gtk_widget_destroy(dialog); + free((void *)current_default); } static void create_toggle(const char* label, int *on, void *_data) @@ -873,8 +962,8 @@ void init_ui(int *argcp, char ***argvp) visible_cols.sac = PTR_TO_BOOL(subsurface_get_conf("SAC", PREF_BOOL)); divelist_font = subsurface_get_conf("divelist_font", PREF_STRING); - autogroup = PTR_TO_BOOL(subsurface_get_conf("autogroup", PREF_BOOL)); + default_filename = subsurface_get_conf("default_filename", PREF_STRING); default_dive_computer_vendor = subsurface_get_conf("dive_computer_vendor", PREF_STRING); default_dive_computer_product = subsurface_get_conf("dive_computer_product", PREF_STRING); @@ -1,7 +1,10 @@ /* linux.c */ /* implements Linux specific functions */ +#include "dive.h" #include "display-gtk.h" #include <gconf/gconf-client.h> +#include <string.h> + #define DIVELIST_DEFAULT_FONT "Sans 8" GConfClient *gconf; @@ -63,6 +66,24 @@ const char *subsurface_icon_name() return "subsurface.svg"; } +const char *subsurface_default_filename() +{ + if (default_filename) { + return default_filename; + } else { + const char *home, *user; + char *buffer; + int len; + + home = g_get_home_dir(); + user = g_get_user_name(); + len = strlen(home) + strlen(user) + 17; + buffer = malloc(len); + snprintf(buffer, len, "%s/subsurface/%s.xml", home, user); + return buffer; + } +} + void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar, GtkWidget *vbox, GtkUIManager *ui_manager) { @@ -1,5 +1,6 @@ /* macos.c */ /* implements Mac OS X specific functions */ +#include "dive.h" #include "display-gtk.h" #include <CoreFoundation/CoreFoundation.h> #include <mach-o/dyld.h> @@ -85,6 +86,24 @@ const char *subsurface_icon_name() return path; } +const char *subsurface_default_filename() +{ + if (default_filename) { + return default_filename; + } else { + const char *home, *user; + char *buffer; + int len; + + home = g_get_home_dir(); + user = g_get_user_name(); + len = strlen(home) + strlen(user) + 45; + buffer = malloc(len); + snprintf(buffer, len, "%s/Library/Application Support/Subsurface/%s.xml", home, user); + return buffer; + } +} + void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar, GtkWidget *vbox, GtkUIManager *ui_manager) { @@ -211,6 +211,7 @@ void renumber_dives(int nr) int main(int argc, char **argv) { int i; + gboolean no_filenames = TRUE; output_units = SI_units; @@ -225,6 +226,7 @@ int main(int argc, char **argv) parse_argument(a); continue; } + no_filenames = FALSE; GError *error = NULL; parse_file(a, &error); @@ -235,7 +237,14 @@ int main(int argc, char **argv) error = NULL; } } - + if (no_filenames) { + GError *error = NULL; + const char *filename = subsurface_default_filename(); + parse_file(filename, &error); + /* don't report errors - this file may not exist, but make + sure we remember this as the filename in use */ + set_filename(filename); + } report_dives(imported); run_ui(); @@ -1,7 +1,9 @@ /* windows.c */ /* implements Windows specific functions */ +#include "dive.h" #include "display-gtk.h" #include <windows.h> +#include <shlobj.h> #define DIVELIST_DEFAULT_FONT "Sans 8" static HKEY hkey; @@ -93,6 +95,28 @@ const char *subsurface_icon_name() return "subsurface.ico"; } +const char *subsurface_default_filename() +{ + if (default_filename) { + return default_filename; + } else { + char datapath[MAX_PATH]; + const char *user; + char *buffer; + int len; + + user = g_get_user_name(); + if (! SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, datapath))) { + datapath[0] = '.'; + datapath[1] = '\0'; + } + len = strlen(datapath) + strlen(user) + 17; + buffer = malloc(len); + snprintf(buffer, len, "%s\\Subsurface\\%s.xml", datapath, user); + return buffer; + } +} + void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar, GtkWidget *vbox, GtkUIManager *ui_manager) { |