mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Merge branch 'quit-handling' of git://github.com/dirkhh/subsurface
* 'quit-handling' of git://github.com/dirkhh/subsurface: Use the last (or only) filename on command line as default for saving Show the "save changes" dialog before the main window is destroyed Check for changes at regular 'quit' events as well Catch changes to the info of the current dive when quitting Tracking changes to tanks is trivial Simplistic first attempt to get changes saved when quitting subsurface
This commit is contained in:
commit
d94fb7ca6b
7 changed files with 105 additions and 13 deletions
1
dive.h
1
dive.h
|
@ -197,6 +197,7 @@ static inline struct dive *get_dive(unsigned int nr)
|
|||
|
||||
extern void parse_xml_init(void);
|
||||
extern void parse_xml_file(const char *filename, GError **error);
|
||||
extern void set_filename(const char *filename);
|
||||
|
||||
extern void show_dive_info(struct dive *);
|
||||
extern void flush_dive_info_changes(struct dive *);
|
||||
|
|
18
divelist.c
18
divelist.c
|
@ -7,6 +7,8 @@
|
|||
* void dive_list_update_dives(void)
|
||||
* void update_dive_list_units(void)
|
||||
* void set_divelist_font(const char *font)
|
||||
* void mark_divelist_changed(int changed)
|
||||
* int unsaved_changes()
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -24,6 +26,7 @@ struct DiveList {
|
|||
GtkListStore *model;
|
||||
GtkTreeViewColumn *date, *depth, *duration, *location;
|
||||
GtkTreeViewColumn *temperature, *cylinder, *nitrox, *sac;
|
||||
int changed;
|
||||
};
|
||||
|
||||
static struct DiveList dive_list;
|
||||
|
@ -45,9 +48,6 @@ enum {
|
|||
DIVELIST_COLUMNS
|
||||
};
|
||||
|
||||
/* the global dive list that we maintain */
|
||||
static struct DiveList dive_list;
|
||||
|
||||
static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model)
|
||||
{
|
||||
GtkTreeIter iter;
|
||||
|
@ -492,5 +492,17 @@ GtkWidget *dive_list_create(void)
|
|||
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||
gtk_container_add(GTK_CONTAINER(dive_list.container_widget), dive_list.tree_view);
|
||||
|
||||
dive_list.changed = 0;
|
||||
|
||||
return dive_list.container_widget;
|
||||
}
|
||||
|
||||
void mark_divelist_changed(int changed)
|
||||
{
|
||||
dive_list.changed = changed;
|
||||
}
|
||||
|
||||
int unsaved_changes()
|
||||
{
|
||||
return dive_list.changed;
|
||||
}
|
||||
|
|
|
@ -7,4 +7,6 @@ extern void dive_list_update_dives(void);
|
|||
extern void update_dive_list_units(void);
|
||||
extern void flush_divelist(struct dive *);
|
||||
|
||||
extern void mark_divelist_changed(int);
|
||||
extern int unsaved_changes(void);
|
||||
#endif
|
||||
|
|
|
@ -249,6 +249,7 @@ static void apply_cb(GtkButton *button, gpointer data)
|
|||
|
||||
for (i = 0; i < MAX_CYLINDERS; i++)
|
||||
record_cylinder_changes(dive->cylinder+i, gtk_cylinder+i);
|
||||
mark_divelist_changed(TRUE);
|
||||
flush_divelist(dive);
|
||||
}
|
||||
|
||||
|
|
55
gtk-gui.c
55
gtk-gui.c
|
@ -31,11 +31,6 @@ struct units output_units;
|
|||
|
||||
#define GCONF_NAME(x) "/apps/subsurface/" #x
|
||||
|
||||
void on_destroy(GtkWidget* w, gpointer data)
|
||||
{
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
static GtkWidget *dive_profile;
|
||||
|
||||
void repaint_dive(void)
|
||||
|
@ -146,12 +141,53 @@ static void file_save(GtkWidget *w, gpointer data)
|
|||
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
save_dives(filename);
|
||||
g_free(filename);
|
||||
mark_divelist_changed(FALSE);
|
||||
}
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
static void ask_save_changes()
|
||||
{
|
||||
GtkWidget *dialog, *label, *content;
|
||||
dialog = gtk_dialog_new_with_buttons("Save Changes?",
|
||||
GTK_WINDOW(main_window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
NULL);
|
||||
content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
|
||||
label = gtk_label_new ("You have unsaved changes\nWould you like to save those before exiting the program?");
|
||||
gtk_container_add (GTK_CONTAINER (content), label);
|
||||
gtk_widget_show_all (dialog);
|
||||
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
|
||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
file_save(NULL,NULL);
|
||||
}
|
||||
gtk_widget_destroy(dialog);
|
||||
}
|
||||
|
||||
static gboolean on_delete(GtkWidget* w, gpointer data)
|
||||
{
|
||||
/* Make sure to flush any modified dive data */
|
||||
update_dive(NULL);
|
||||
|
||||
if (unsaved_changes())
|
||||
ask_save_changes();
|
||||
|
||||
return FALSE; /* go ahead, kill the program, we're good now */
|
||||
}
|
||||
|
||||
static void on_destroy(GtkWidget* w, gpointer data)
|
||||
{
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
static void quit(GtkWidget *w, gpointer data)
|
||||
{
|
||||
/* Make sure to flush any modified dive data */
|
||||
update_dive(NULL);
|
||||
|
||||
if (unsaved_changes())
|
||||
ask_save_changes();
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
|
@ -387,6 +423,7 @@ void init_ui(int argc, char **argv)
|
|||
error_info_bar = NULL;
|
||||
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_icon_from_file(GTK_WINDOW(win), "icon.svg", NULL);
|
||||
g_signal_connect(G_OBJECT(win), "delete-event", G_CALLBACK (on_delete), NULL);
|
||||
g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(on_destroy), NULL);
|
||||
main_window = win;
|
||||
|
||||
|
@ -614,3 +651,11 @@ void update_progressbar(progressbar_t *progress, double value)
|
|||
{
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress->bar), value);
|
||||
}
|
||||
|
||||
|
||||
void set_filename(const char *filename)
|
||||
{
|
||||
if (filename)
|
||||
existing_filename = strdup(filename);
|
||||
return;
|
||||
}
|
||||
|
|
37
info.c
37
info.c
|
@ -33,30 +33,59 @@ static char *get_text(GtkTextBuffer *buffer)
|
|||
return gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
|
||||
}
|
||||
|
||||
/* old is NULL or a valid string, new is a valid string
|
||||
* NOTW: NULL and "" need to be treated as "unchanged" */
|
||||
static int text_changed(char *old, char *new)
|
||||
{
|
||||
return ((old && strcmp(old,new)) ||
|
||||
(!old && strcmp("",new)));
|
||||
}
|
||||
|
||||
void flush_dive_info_changes(struct dive *dive)
|
||||
{
|
||||
char *old_text;
|
||||
int changed = 0;
|
||||
|
||||
if (!dive)
|
||||
return;
|
||||
|
||||
if (location_changed) {
|
||||
g_free(dive->location);
|
||||
old_text = dive->location;
|
||||
dive->location = gtk_editable_get_chars(GTK_EDITABLE(location), 0, -1);
|
||||
if (text_changed(old_text,dive->location))
|
||||
changed = 1;
|
||||
if (old_text)
|
||||
g_free(old_text);
|
||||
}
|
||||
|
||||
if (divemaster_changed) {
|
||||
g_free(dive->divemaster);
|
||||
old_text = dive->divemaster;
|
||||
dive->divemaster = gtk_editable_get_chars(GTK_EDITABLE(divemaster), 0, -1);
|
||||
if (text_changed(old_text,dive->divemaster))
|
||||
changed = 1;
|
||||
if (old_text)
|
||||
g_free(old_text);
|
||||
}
|
||||
|
||||
if (buddy_changed) {
|
||||
g_free(dive->buddy);
|
||||
old_text = dive->buddy;
|
||||
dive->buddy = gtk_editable_get_chars(GTK_EDITABLE(buddy), 0, -1);
|
||||
if (text_changed(old_text,dive->buddy))
|
||||
changed = 1;
|
||||
if (old_text)
|
||||
g_free(old_text);
|
||||
}
|
||||
|
||||
if (notes_changed) {
|
||||
g_free(dive->notes);
|
||||
old_text = dive->notes;
|
||||
dive->notes = get_text(notes);
|
||||
if (text_changed(old_text,dive->notes))
|
||||
changed = 1;
|
||||
if (old_text)
|
||||
g_free(old_text);
|
||||
}
|
||||
if (changed)
|
||||
mark_divelist_changed(TRUE);
|
||||
}
|
||||
|
||||
#define SET_TEXT_ENTRY(x) \
|
||||
|
|
|
@ -1380,7 +1380,9 @@ void parse_xml_file(const char *filename, GError **error)
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* we assume that the last (or only) filename passed as argument is a
|
||||
* great filename to use as default when saving the dives */
|
||||
set_filename(filename);
|
||||
reset_all();
|
||||
dive_start();
|
||||
traverse(xmlDocGetRootElement(doc));
|
||||
|
|
Loading…
Add table
Reference in a new issue