]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Separate out the UI from the program logic
authorDirk Hohndel <dirk@hohndel.org>
Tue, 20 Sep 2011 19:40:34 +0000 (12:40 -0700)
committerDirk Hohndel <dirk@hohndel.org>
Tue, 20 Sep 2011 19:48:56 +0000 (12:48 -0700)
The following are UI toolkit specific:
gtk-gui.c   - overall layout, main window of the UI
divelist.c  - list of dives subsurface maintains
equipment.c - equipment / tank information for each dive
info.c      - detailed dive info
print.c     - printing

The rest is independent of the UI:
main.c i    - program frame
dive.c i    - creates and maintaines the internal dive list structure
libdivecomputer.c
uemis.c
parse-xml.c
save-xml.c  - interface with dive computers and the XML files
profile.c   - creates the data for the profile and draws it using cairo

This commit should contain NO functional changes, just moving code around
and a couple of minor abstractions.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
18 files changed:
Makefile
README
display-gtk.h [new file with mode: 0644]
display.h
dive.c
dive.h
divelist.c
divelist.h
equipment.c
gtk-gui.c [new file with mode: 0644]
info.c
libdivecomputer.c
libdivecomputer.h [new file with mode: 0644]
main.c
print.c
profile.c
uemis.c
uemis.h

index 8f12d0a0af4dfae20757ddebdd76032699c0099f..59363e2a166b155a5433c6a1b3c655205022c2d3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,8 @@ LIBDIVECOMPUTERARCHIVE = $(LIBDIVECOMPUTERDIR)/lib/libdivecomputer.a
 LIBS = `pkg-config --libs gtk+-2.0 glib-2.0 gconf-2.0`
 
 OBJS = main.o dive.o profile.o info.o equipment.o divelist.o \
 LIBS = `pkg-config --libs gtk+-2.0 glib-2.0 gconf-2.0`
 
 OBJS = main.o dive.o profile.o info.o equipment.o divelist.o \
-       parse-xml.o save-xml.o libdivecomputer.o print.o uemis.o
+       parse-xml.o save-xml.o libdivecomputer.o print.o uemis.o \
+       gtk-gui.o
 
 subsurface: $(OBJS)
        $(CC) $(LDFLAGS) -o subsurface $(OBJS) \
 
 subsurface: $(OBJS)
        $(CC) $(LDFLAGS) -o subsurface $(OBJS) \
@@ -26,13 +27,13 @@ dive.o: dive.c dive.h
        $(CC) $(CFLAGS) `pkg-config --cflags glib-2.0` -c dive.c
 
 main.o: main.c dive.h display.h divelist.h
        $(CC) $(CFLAGS) `pkg-config --cflags glib-2.0` -c dive.c
 
 main.o: main.c dive.h display.h divelist.h
-       $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0 gconf-2.0` \
+       $(CC) $(CFLAGS) `pkg-config --cflags glib-2.0 gconf-2.0` \
                -c main.c
 
 profile.o: profile.c dive.h display.h divelist.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c profile.c
 
                -c main.c
 
 profile.o: profile.c dive.h display.h divelist.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c profile.c
 
-info.o: info.c dive.h display.h divelist.h
+info.o: info.c dive.h display.h display-gtk.h divelist.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c info.c
 
 equipment.o: equipment.c dive.h display.h divelist.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c info.c
 
 equipment.o: equipment.c dive.h display.h divelist.h
@@ -41,13 +42,18 @@ equipment.o: equipment.c dive.h display.h divelist.h
 divelist.o: divelist.c dive.h display.h divelist.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c divelist.c
 
 divelist.o: divelist.c dive.h display.h divelist.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c divelist.c
 
-print.o: print.c dive.h display.h
+print.o: print.c dive.h display.h display-gtk.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c print.c
 
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c print.c
 
-libdivecomputer.o: libdivecomputer.c dive.h display.h
+libdivecomputer.o: libdivecomputer.c dive.h display.h display-gtk.h libdivecomputer.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` \
                        -I$(LIBDIVECOMPUTERINCLUDES) \
                        -c libdivecomputer.c
 
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` \
                        -I$(LIBDIVECOMPUTERINCLUDES) \
                        -c libdivecomputer.c
 
+gtk-gui.o: gtk-gui.c dive.h display.h divelist.h display-gtk.h libdivecomputer.h
+       $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0 gconf-2.0` \
+                       -I$(LIBDIVECOMPUTERINCLUDES) \
+                       -c gtk-gui.c
+
 uemis.o: uemis.c uemis.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c uemis.c
 uemis.o: uemis.c uemis.h
        $(CC) $(CFLAGS) `pkg-config --cflags gtk+-2.0 glib-2.0` -c uemis.c
diff --git a/README b/README
index 35c9c6913b5eda0422f0407f94f83b26ba3ecbaf..204b9a3bf8290a8e454f65a464e4e5df1d02fa60 100644 (file)
--- a/README
+++ b/README
@@ -37,6 +37,25 @@ and subsurface will de-duplicate the ones that are exactly the same
 the dives have duplicates that were edited by Dirk in the Suunto Dive
 Manager, so they don't trigger the "exact duplicates" match.
 
 the dives have duplicates that were edited by Dirk in the Suunto Dive
 Manager, so they don't trigger the "exact duplicates" match.
 
+Implementation details:
+
+main.c - program frame
+dive.c - creates and maintaines the internal dive list structure
+libdivecomputer.c 
+uemis.c 
+parse-xml.c 
+save-xml.c - interface with dive computers and the XML files 
+profile.c - creates the data for the profile and draws it using cairo
+
+A first UI has been implemented in gtk and an attempt has been made to
+separate program logic from UI implementation. 
+
+gtk-gui.c - overall layout, main window of the UI
+divelist.c  - list of dives subsurface maintains
+equipment.c - equipment / tank information for each dive
+info.c      - detailed dive info 
+print.c     - printing 
+
 WARNING! I wasn't kidding when I said that I've done this by reading
 gtk2 tutorials as I've gone along.  If somebody is more comfortable with
 gtk, feel free to send me (signed-off) patches.
 WARNING! I wasn't kidding when I said that I've done this by reading
 gtk2 tutorials as I've gone along.  If somebody is more comfortable with
 gtk, feel free to send me (signed-off) patches.
diff --git a/display-gtk.h b/display-gtk.h
new file mode 100644 (file)
index 0000000..dee6636
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef DISPLAY_GTK_H
+#define DISPLAY_GTK_H
+
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+
+extern GtkWidget *main_window;
+
+/* we want a progress bar as part of the device_data_t - let's abstract this out */
+typedef struct {
+       GtkWidget *bar;
+} progressbar_t;
+
+extern const char *divelist_font;
+extern void set_divelist_font(const char *);
+
+extern void import_dialog(GtkWidget *, gpointer);
+extern void report_error(GError* error);
+extern int process_ui_events(void);
+extern void update_progressbar(progressbar_t *progress, double value);
+
+extern GtkWidget *dive_profile_widget(void);
+extern GtkWidget *dive_info_frame(void);
+extern GtkWidget *extended_dive_info_widget(void);
+extern GtkWidget *equipment_widget(void);
+
+extern GtkWidget *dive_list_create(void);
+
+#endif
index b5b0f919bd5e112ce09218f472efa43684638740..9cd401a893da34928212b797110a146fe46107a5 100644 (file)
--- a/display.h
+++ b/display.h
@@ -1,23 +1,8 @@
 #ifndef DISPLAY_H
 #define DISPLAY_H
 
 #ifndef DISPLAY_H
 #define DISPLAY_H
 
-#include <gtk/gtk.h>
-#include <gdk/gdk.h>
 #include <cairo.h>
 
 #include <cairo.h>
 
-extern GtkWidget *main_window;
-
-extern const char *divelist_font;
-extern void set_divelist_font(const char *);
-
-extern void import_dialog(GtkWidget *, gpointer);
-extern void report_error(GError* error);
-
-extern GtkWidget *dive_profile_widget(void);
-extern GtkWidget *dive_info_frame(void);
-extern GtkWidget *extended_dive_info_widget(void);
-extern GtkWidget *equipment_widget(void);
-
 extern void repaint_dive(void);
 extern void do_print(void);
 
 extern void repaint_dive(void);
 extern void do_print(void);
 
@@ -38,5 +23,6 @@ struct graphics_context {
 };
 
 extern void plot(struct graphics_context *gc, int w, int h, struct dive *dive);
 };
 
 extern void plot(struct graphics_context *gc, int w, int h, struct dive *dive);
+extern void set_source_rgb(struct graphics_context *gc, double r, double g, double b);
 
 #endif
 
 #endif
diff --git a/dive.c b/dive.c
index b7f61293636bba44b0d0c49cf344615ba22ef03f..1b906ee43bd9a7e86db41d08cc5d3f288732a012 100644 (file)
--- a/dive.c
+++ b/dive.c
@@ -1,3 +1,5 @@
+/* dive.c */
+/* maintains the internal dive list structure */
 #include <string.h>
 #include <stdio.h>
 
 #include <string.h>
 #include <stdio.h>
 
diff --git a/dive.h b/dive.h
index 109d0c57da1a984e59aa03dd0792c3f6ac258276..1927da7215a68e69ece2ce062cb58e61b6914bd9 100644 (file)
--- a/dive.h
+++ b/dive.h
@@ -222,8 +222,21 @@ extern void report_dives(void);
 extern struct dive *fixup_dive(struct dive *dive);
 extern struct dive *try_to_merge(struct dive *a, struct dive *b);
 
 extern struct dive *fixup_dive(struct dive *dive);
 extern struct dive *try_to_merge(struct dive *a, struct dive *b);
 
-extern void update_air_info(char *buffer);
+extern void renumber_dives(int nr);
 
 
+/* UI related protopypes */
+
+extern void init_ui(int argc, char **argv);
+
+extern void run_ui(void);
+
+extern void report_error(GError* error);
+
+extern void dive_list_update_dives(void);
+extern void flush_divelist(struct dive *dive);
+
+extern int open_import_file_dialog(char *filterpattern, char *filtertext, 
+                               void(* parse_function)(char *));
 #define DIVE_ERROR_PARSE 1
 
 const char *weekday(int wday);
 #define DIVE_ERROR_PARSE 1
 
 const char *weekday(int wday);
index 01ab1b11ad2c6b126b0e49a74c025b4b3c9b96e6..e000924368de40763520d22e1ab371957e287ce4 100644 (file)
@@ -1,3 +1,13 @@
+/* divelist.c */
+/* this creates the UI for the dive list - 
+ * controlled through the following interfaces:
+ * 
+ * void flush_divelist(struct dive *dive)
+ * GtkWidget dive_list_create(void)
+ * void dive_list_update_dives(void)
+ * void update_dive_list_units(void)
+ * void set_divelist_font(const char *font)
+ */
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -6,6 +16,7 @@
 #include "divelist.h"
 #include "dive.h"
 #include "display.h"
 #include "divelist.h"
 #include "dive.h"
 #include "display.h"
+#include "display-gtk.h"
 
 struct DiveList {
        GtkWidget    *tree_view;
 
 struct DiveList {
        GtkWidget    *tree_view;
@@ -34,6 +45,8 @@ enum {
        DIVELIST_COLUMNS
 };
 
        DIVELIST_COLUMNS
 };
 
+/* the global dive list that we maintain */
+static struct DiveList dive_list;
 
 static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model)
 {
 
 static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model)
 {
@@ -48,23 +61,6 @@ static void selection_cb(GtkTreeSelection *selection, GtkTreeModel *model)
        repaint_dive();
 }
 
        repaint_dive();
 }
 
-const char *weekday(int wday)
-{
-       static const char wday_array[7][4] = {
-               "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
-       };
-       return wday_array[wday];
-}
-
-const char *monthname(int mon)
-{
-       static const char month_array[12][4] = {
-               "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-               "Jul", "Aug", "Oct", "Sep", "Nov", "Dec",
-       };
-       return month_array[mon];
-}
-
 static void date_data_func(GtkTreeViewColumn *col,
                           GtkCellRenderer *renderer,
                           GtkTreeModel *model,
 static void date_data_func(GtkTreeViewColumn *col,
                           GtkCellRenderer *renderer,
                           GtkTreeModel *model,
index 25de6837a6f9c38332d3a3659fffa0a9ee613a27..7684a72d3e8e8d337666971b4cbe676c3f74f62f 100644 (file)
@@ -1,11 +1,8 @@
 #ifndef DIVELIST_H
 #define DIVELIST_H
 
 #ifndef DIVELIST_H
 #define DIVELIST_H
 
-#include <gtk/gtk.h>
-
 struct dive;
 
 struct dive;
 
-extern GtkWidget *dive_list_create(void);
 extern void dive_list_update_dives(void);
 extern void update_dive_list_units(void);
 extern void flush_divelist(struct dive *);
 extern void dive_list_update_dives(void);
 extern void update_dive_list_units(void);
 extern void flush_divelist(struct dive *);
index b9b9259b5a8cd0631816842e95d513e14d1066e3..1e0721b9abd195370b6daa8ecdb81f2938cf70d4 100644 (file)
@@ -1,3 +1,13 @@
+/* equipment.c */
+/* creates the UI for the equipment page -
+ * controlled through the following interfaces:
+ * 
+ * void show_dive_equipment(struct dive *dive)
+ * void flush_dive_equipment_changes(struct dive *dive)
+ *
+ * called from gtk-ui:
+ * GtkWidget *equipment_widget(void)
+ */
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -6,6 +16,7 @@
 
 #include "dive.h"
 #include "display.h"
 
 #include "dive.h"
 #include "display.h"
+#include "display-gtk.h"
 #include "divelist.h"
 
 struct cylinder_widget {
 #include "divelist.h"
 
 struct cylinder_widget {
diff --git a/gtk-gui.c b/gtk-gui.c
new file mode 100644 (file)
index 0000000..77cf4a9
--- /dev/null
+++ b/gtk-gui.c
@@ -0,0 +1,616 @@
+/* gtk-gui.c */
+/* gtk UI implementation */
+/* creates the window and overall layout
+ * divelist, dive info, equipment and printing are handled in their own source files
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <gconf/gconf-client.h>
+
+#include "dive.h"
+#include "divelist.h"
+#include "display.h"
+#include "display-gtk.h"
+
+#include "libdivecomputer.h"
+
+GtkWidget *main_window;
+GtkWidget *main_vbox;
+GtkWidget *error_info_bar;
+GtkWidget *error_label;
+int        error_count;
+
+#define DIVELIST_DEFAULT_FONT "Sans 8"
+const char *divelist_font;
+
+GConfClient *gconf;
+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)
+{
+       update_dive(current_dive);
+       gtk_widget_queue_draw(dive_profile);
+}
+
+static char *existing_filename;
+
+static void on_info_bar_response(GtkWidget *widget, gint response,
+                                 gpointer data)
+{
+       if (response == GTK_RESPONSE_OK)
+       {
+               gtk_widget_destroy(widget);
+               error_info_bar = NULL;
+       }
+}
+
+void report_error(GError* error)
+{
+       if (error == NULL)
+       {
+               return;
+       }
+       
+       if (error_info_bar == NULL)
+       {
+               error_count = 1;
+               error_info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_OK,
+                                                              GTK_RESPONSE_OK,
+                                                              NULL);
+               g_signal_connect(error_info_bar, "response", G_CALLBACK(on_info_bar_response), NULL);
+               gtk_info_bar_set_message_type(GTK_INFO_BAR(error_info_bar),
+                                             GTK_MESSAGE_ERROR);
+               
+               error_label = gtk_label_new(error->message);
+               GtkWidget *container = gtk_info_bar_get_content_area(GTK_INFO_BAR(error_info_bar));
+               gtk_container_add(GTK_CONTAINER(container), error_label);
+               
+               gtk_box_pack_start(GTK_BOX(main_vbox), error_info_bar, FALSE, FALSE, 0);
+               gtk_widget_show_all(main_vbox);
+       }
+       else
+       {
+               error_count++;
+               char buffer[256];
+               snprintf(buffer, sizeof(buffer), "Failed to open %i files.", error_count);
+               gtk_label_set(GTK_LABEL(error_label), buffer);
+       }
+}
+
+static void file_open(GtkWidget *w, gpointer data)
+{
+       GtkWidget *dialog;
+       dialog = gtk_file_chooser_dialog_new("Open File",
+               GTK_WINDOW(main_window),
+               GTK_FILE_CHOOSER_ACTION_OPEN,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+               NULL);
+       gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
+
+       if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+               GSList *filenames;
+               char *filename;
+               filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
+               
+               GError *error = NULL;
+               while(filenames != NULL) {
+                       filename = (char *)filenames->data;
+                       parse_xml_file(filename, &error);
+                       if (error != NULL)
+                       {
+                               report_error(error);
+                               g_error_free(error);
+                               error = NULL;
+                       }
+                       
+                       g_free(filename);
+                       filenames = g_slist_next(filenames);
+               }
+               g_slist_free(filenames);
+               report_dives();
+               dive_list_update_dives();
+       }
+       gtk_widget_destroy(dialog);
+}
+
+static void file_save(GtkWidget *w, gpointer data)
+{
+       GtkWidget *dialog;
+       dialog = gtk_file_chooser_dialog_new("Save File",
+               GTK_WINDOW(main_window),
+               GTK_FILE_CHOOSER_ACTION_SAVE,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+               GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+               NULL);
+       gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
+       if (!existing_filename) {
+               gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "Untitled document");
+       } else
+               gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), existing_filename);
+
+       if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+               char *filename;
+               filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+               save_dives(filename);
+               g_free(filename);
+       }
+       gtk_widget_destroy(dialog);
+}
+
+static void quit(GtkWidget *w, gpointer data)
+{
+       gtk_main_quit();
+}
+
+static void create_radio(GtkWidget *dialog, const char *name, ...)
+{
+       va_list args;
+       GtkRadioButton *group = NULL;
+       GtkWidget *box, *label;
+
+       box = gtk_hbox_new(TRUE, 10);
+       gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), box);
+
+       label = gtk_label_new(name);
+       gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0);
+
+       va_start(args, name);
+       for (;;) {
+               int enabled;
+               const char *name;
+               GtkWidget *button;
+               void *callback_fn;
+
+               name = va_arg(args, char *);
+               if (!name)
+                       break;
+               callback_fn = va_arg(args, void *);
+               enabled = va_arg(args, int);
+
+               button = gtk_radio_button_new_with_label_from_widget(group, name);
+               group = GTK_RADIO_BUTTON(button);
+               gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
+               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), enabled);
+               g_signal_connect(button, "toggled", G_CALLBACK(callback_fn), NULL);
+       }
+       va_end(args);
+}
+
+#define UNITCALLBACK(name, type, value)                                \
+static void name(GtkWidget *w, gpointer data)                  \
+{                                                              \
+       if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) \
+               menu_units.type = value;                        \
+}
+
+static struct units menu_units;
+
+UNITCALLBACK(set_meter, length, METERS)
+UNITCALLBACK(set_feet, length, FEET)
+UNITCALLBACK(set_bar, pressure, BAR)
+UNITCALLBACK(set_psi, pressure, PSI)
+UNITCALLBACK(set_liter, volume, LITER)
+UNITCALLBACK(set_cuft, volume, CUFT)
+UNITCALLBACK(set_celsius, temperature, CELSIUS)
+UNITCALLBACK(set_fahrenheit, temperature, FAHRENHEIT)
+
+static void preferences_dialog(GtkWidget *w, gpointer data)
+{
+       int result;
+       GtkWidget *dialog, *font, *frame, *box;
+
+       menu_units = output_units;
+
+       dialog = gtk_dialog_new_with_buttons("Preferences",
+               GTK_WINDOW(main_window),
+               GTK_DIALOG_DESTROY_WITH_PARENT,
+               GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+               NULL);
+
+       frame = gtk_frame_new("Units");
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+
+       box = gtk_vbox_new(FALSE, 6);
+       gtk_container_add(GTK_CONTAINER(frame), box);
+
+       create_radio(box, "Depth:",
+               "Meter", set_meter, (output_units.length == METERS),
+               "Feet",  set_feet, (output_units.length == FEET),
+               NULL);
+
+       create_radio(box, "Pressure:",
+               "Bar", set_bar, (output_units.pressure == BAR),
+               "PSI",  set_psi, (output_units.pressure == PSI),
+               NULL);
+
+       create_radio(box, "Volume:",
+               "Liter",  set_liter, (output_units.volume == LITER),
+               "CuFt", set_cuft, (output_units.volume == CUFT),
+               NULL);
+
+       create_radio(box, "Temperature:",
+               "Celsius", set_celsius, (output_units.temperature == CELSIUS),
+               "Fahrenheit",  set_fahrenheit, (output_units.temperature == FAHRENHEIT),
+               NULL);
+
+       font = gtk_font_button_new_with_font(divelist_font);
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), font, FALSE, FALSE, 5);
+
+       gtk_widget_show_all(dialog);
+       result = gtk_dialog_run(GTK_DIALOG(dialog));
+       if (result == GTK_RESPONSE_ACCEPT) {
+               /* Make sure to flush any modified old dive data with old units */
+               update_dive(NULL);
+
+               divelist_font = strdup(gtk_font_button_get_font_name(GTK_FONT_BUTTON(font)));
+               set_divelist_font(divelist_font);
+
+               output_units = menu_units;
+               update_dive_list_units();
+               repaint_dive();
+               gconf_client_set_bool(gconf, GCONF_NAME(feet), output_units.length == FEET, NULL);
+               gconf_client_set_bool(gconf, GCONF_NAME(psi), output_units.pressure == PSI, NULL);
+               gconf_client_set_bool(gconf, GCONF_NAME(cuft), output_units.volume == CUFT, NULL);
+               gconf_client_set_bool(gconf, GCONF_NAME(fahrenheit), output_units.temperature == FAHRENHEIT, NULL);
+               gconf_client_set_string(gconf, GCONF_NAME(divelist_font), divelist_font, NULL);
+       }
+       gtk_widget_destroy(dialog);
+}
+
+static void renumber_dialog(GtkWidget *w, gpointer data)
+{
+       int result;
+       GtkWidget *dialog, *frame, *button;
+
+       dialog = gtk_dialog_new_with_buttons("Renumber",
+               GTK_WINDOW(main_window),
+               GTK_DIALOG_DESTROY_WITH_PARENT,
+               GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+               NULL);
+
+       frame = gtk_frame_new("New starting number");
+       gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), frame);
+
+       button = gtk_spin_button_new_with_range(1, 50000, 1);
+       gtk_container_add(GTK_CONTAINER(frame), button);
+
+       gtk_widget_show_all(dialog);
+       result = gtk_dialog_run(GTK_DIALOG(dialog));
+       if (result == GTK_RESPONSE_ACCEPT) {
+               int nr = gtk_spin_button_get_value(GTK_SPIN_BUTTON(button));
+               renumber_dives(nr);
+               repaint_dive();
+       }
+       gtk_widget_destroy(dialog);
+}
+
+static GtkActionEntry menu_items[] = {
+       { "FileMenuAction", GTK_STOCK_FILE, "File", NULL, NULL, NULL},
+       { "LogMenuAction",  GTK_STOCK_FILE, "Log", NULL, NULL, NULL},
+       { "OpenFile",       GTK_STOCK_OPEN, NULL,   "<control>O", NULL, G_CALLBACK(file_open) },
+       { "SaveFile",       GTK_STOCK_SAVE, NULL,   "<control>S", NULL, G_CALLBACK(file_save) },
+       { "Print",          GTK_STOCK_PRINT, NULL,  "<control>P", NULL, G_CALLBACK(do_print) },
+       { "Import",         NULL, "Import", NULL, NULL, G_CALLBACK(import_dialog) },
+       { "Preferences",    NULL, "Preferences", NULL, NULL, G_CALLBACK(preferences_dialog) },
+       { "Renumber",       NULL, "Renumber", NULL, NULL, G_CALLBACK(renumber_dialog) },
+       { "Quit",           GTK_STOCK_QUIT, NULL,   "<control>Q", NULL, G_CALLBACK(quit) },
+};
+static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
+
+static const gchar* ui_string = " \
+       <ui> \
+               <menubar name=\"MainMenu\"> \
+                       <menu name=\"FileMenu\" action=\"FileMenuAction\"> \
+                               <menuitem name=\"Open\" action=\"OpenFile\" /> \
+                               <menuitem name=\"Save\" action=\"SaveFile\" /> \
+                               <menuitem name=\"Print\" action=\"Print\" /> \
+                               <separator name=\"Separator1\"/> \
+                               <menuitem name=\"Import\" action=\"Import\" /> \
+                               <separator name=\"Separator2\"/> \
+                               <menuitem name=\"Preferences\" action=\"Preferences\" /> \
+                               <separator name=\"Separator3\"/> \
+                               <menuitem name=\"Quit\" action=\"Quit\" /> \
+                       </menu> \
+                       <menu name=\"LogMenu\" action=\"LogMenuAction\"> \
+                               <menuitem name=\"Renumber\" action=\"Renumber\" /> \
+                       </menu> \
+               </menubar> \
+       </ui> \
+";
+
+static GtkWidget *get_menubar_menu(GtkWidget *window)
+{
+       GtkActionGroup *action_group = gtk_action_group_new("Menu");
+       gtk_action_group_add_actions(action_group, menu_items, nmenu_items, 0);
+
+       GtkUIManager *ui_manager = gtk_ui_manager_new();
+       gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);
+       GError* error = 0;
+       gtk_ui_manager_add_ui_from_string(GTK_UI_MANAGER(ui_manager), ui_string, -1, &error);
+
+       gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(ui_manager));
+       GtkWidget* menu = gtk_ui_manager_get_widget(ui_manager, "/MainMenu");
+
+       return menu;
+}
+
+static void switch_page(GtkNotebook *notebook, gint arg1, gpointer user_data)
+{
+       repaint_dive();
+}
+
+void init_ui(int argc, char **argv)
+{
+       GtkWidget *win;
+       GtkWidget *paned;
+       GtkWidget *info_box;
+       GtkWidget *notebook;
+       GtkWidget *dive_info;
+       GtkWidget *dive_list;
+       GtkWidget *equipment;
+       GtkWidget *menubar;
+       GtkWidget *vbox;
+
+       gtk_init(&argc, &argv);
+
+       g_type_init();
+       gconf = gconf_client_get_default();
+
+       if (gconf_client_get_bool(gconf, GCONF_NAME(feet), NULL))
+               output_units.length = FEET;
+       if (gconf_client_get_bool(gconf, GCONF_NAME(psi), NULL))
+               output_units.pressure = PSI;
+       if (gconf_client_get_bool(gconf, GCONF_NAME(cuft), NULL))
+               output_units.volume = CUFT;
+       if (gconf_client_get_bool(gconf, GCONF_NAME(fahrenheit), NULL))
+               output_units.temperature = FAHRENHEIT;
+
+       divelist_font = gconf_client_get_string(gconf, GCONF_NAME(divelist_font), NULL);
+       if (!divelist_font)
+               divelist_font = DIVELIST_DEFAULT_FONT;
+
+       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), "destroy", G_CALLBACK(on_destroy), NULL);
+       main_window = win;
+
+       vbox = gtk_vbox_new(FALSE, 0);
+       gtk_container_add(GTK_CONTAINER(win), vbox);
+       main_vbox = vbox;
+
+       menubar = get_menubar_menu(win);
+       gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
+
+       /* HPane for left the dive list, and right the dive info */
+       paned = gtk_vpaned_new();
+       gtk_box_pack_end(GTK_BOX(vbox), paned, TRUE, TRUE, 0);
+
+       /* Create the actual divelist */
+       dive_list = dive_list_create();
+       gtk_paned_add2(GTK_PANED(paned), dive_list);
+
+       /* VBox for dive info, and tabs */
+       info_box = gtk_vbox_new(FALSE, 6);
+       gtk_paned_add1(GTK_PANED(paned), info_box);
+
+       /* Notebook for dive info vs profile vs .. */
+       notebook = gtk_notebook_new();
+       g_signal_connect(notebook, "switch-page", G_CALLBACK(switch_page), NULL);
+       gtk_box_pack_start(GTK_BOX(info_box), notebook, TRUE, TRUE, 6);
+
+       /* Frame for dive profile */
+       dive_profile = dive_profile_widget();
+       gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_profile, gtk_label_new("Dive Profile"));
+
+       /* Frame for extended dive info */
+       dive_info = extended_dive_info_widget();
+       gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_info, gtk_label_new("Dive Notes"));
+
+       /* Frame for dive equipment */
+       equipment = equipment_widget();
+       gtk_notebook_append_page(GTK_NOTEBOOK(notebook), equipment, gtk_label_new("Equipment"));
+
+       gtk_widget_set_app_paintable(win, TRUE);
+       gtk_widget_show_all(win);
+
+       return;
+}
+
+void run_ui(void)
+{
+       gtk_main();
+}
+
+/* get the filenames the user selects and call the parsing function
+ * on them
+ * return 0 if the user cancelled the dialog
+ */
+int open_import_file_dialog(char *filterpattern, char *filtertext, 
+                       void(* parse_function)(char *))
+{
+       int ret=0;
+
+       GtkWidget *dialog;
+       GtkFileFilter *filter = gtk_file_filter_new ();
+       gtk_file_filter_add_pattern (filter, filterpattern);
+       gtk_file_filter_set_name(filter, filtertext);
+       dialog = gtk_file_chooser_dialog_new("Open File",
+                                       GTK_WINDOW(main_window),
+                                       GTK_FILE_CHOOSER_ACTION_OPEN,
+                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                       GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                       NULL);
+       gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
+       gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter);
+
+       if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+               GSList *filenames;
+               char *filename;
+               filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
+               while(filenames != NULL) {
+                       filename = (char *)filenames->data;
+                       parse_function(filename);
+                       g_free(filename);
+                       filenames = g_slist_next(filenames);
+               }
+               g_slist_free(filenames);
+               ret = 1;
+       }
+       gtk_widget_destroy(dialog);
+
+       return ret;
+}
+
+static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
+{
+       struct dive *dive = current_dive;
+       struct graphics_context gc = { .printer = 0 };
+       int w,h;
+
+       w = widget->allocation.width;
+       h = widget->allocation.height;
+
+       gc.cr = gdk_cairo_create(widget->window);
+       set_source_rgb(&gc, 0, 0, 0);
+       cairo_paint(gc.cr);
+
+       if (dive)
+               plot(&gc, w, h, dive);
+
+       cairo_destroy(gc.cr);
+
+       return FALSE;
+}
+
+GtkWidget *dive_profile_widget(void)
+{
+       GtkWidget *da;
+
+       da = gtk_drawing_area_new();
+       gtk_widget_set_size_request(da, 350, 250);
+       g_signal_connect(da, "expose_event", G_CALLBACK(expose_event), NULL);
+
+       return da;
+}
+
+int process_ui_events(void)
+{
+       int ret=0;
+
+       while (gtk_events_pending()) {
+               if (gtk_main_iteration_do(0)) {
+                       ret = 1;
+                       break;
+               }
+       }
+       return(ret);
+}
+
+
+static void fill_computer_list(GtkListStore *store)
+{
+       GtkTreeIter iter;
+       struct device_list *list = device_list;
+
+       for (list = device_list ; list->name ; list++) {
+               gtk_list_store_append(store, &iter);
+               gtk_list_store_set(store, &iter,
+                       0, list->name,
+                       1, list->type,
+                       -1);
+       }
+}
+
+static GtkComboBox *dive_computer_selector(GtkWidget *dialog)
+{
+       GtkWidget *hbox, *combo_box;
+       GtkListStore *model;
+       GtkCellRenderer *renderer;
+
+       hbox = gtk_hbox_new(FALSE, 6);
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 3);
+
+       model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
+       fill_computer_list(model);
+
+       combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
+       gtk_box_pack_start(GTK_BOX(hbox), combo_box, FALSE, TRUE, 3);
+
+       renderer = gtk_cell_renderer_text_new();
+       gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), renderer, TRUE);
+       gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), renderer, "text", 0, NULL);
+
+       return GTK_COMBO_BOX(combo_box);
+}
+
+void import_dialog(GtkWidget *w, gpointer data)
+{
+       int result;
+       GtkWidget *dialog, *hbox;
+       GtkComboBox *computer;
+       device_data_t devicedata = {
+               .devname = "/dev/ttyUSB0",
+       };
+
+       dialog = gtk_dialog_new_with_buttons("Import from dive computer",
+               GTK_WINDOW(main_window),
+               GTK_DIALOG_DESTROY_WITH_PARENT,
+               GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+               GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+               NULL);
+
+       computer = dive_computer_selector(dialog);
+
+       hbox = gtk_hbox_new(FALSE, 6);
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, TRUE, 3);
+       devicedata.progress->bar = gtk_progress_bar_new();
+       gtk_container_add(GTK_CONTAINER(hbox), devicedata.progress->bar);
+
+       gtk_widget_show_all(dialog);
+       result = gtk_dialog_run(GTK_DIALOG(dialog));
+       switch (result) {
+               int type;
+               GtkTreeIter iter;
+               GtkTreeModel *model;
+               const char *comp;
+       case GTK_RESPONSE_ACCEPT:
+               if (!gtk_combo_box_get_active_iter(computer, &iter))
+                       break;
+               model = gtk_combo_box_get_model(computer);
+               gtk_tree_model_get(model, &iter,
+                       0, &comp,
+                       1, &type,
+                       -1);
+               devicedata.type = type;
+               devicedata.name = comp;
+               do_import(&devicedata);
+               break;
+       default:
+               break;
+       }
+       gtk_widget_destroy(dialog);
+
+       report_dives();
+       dive_list_update_dives();
+}
+
+void update_progressbar(progressbar_t *progress, double value)
+{
+       gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress->bar), value);
+}
diff --git a/info.c b/info.c
index c1779cc452ac6a96fab304eb7adfbf5aeb5846ab..9e061970d808ba14bb18d9c259de638781b0c0af 100644 (file)
--- a/info.c
+++ b/info.c
@@ -1,3 +1,13 @@
+/* info.c */
+/* creates the UI for the info frame - 
+ * controlled through the following interfaces:
+ * 
+ * void flush_dive_info_changes(struct dive *dive)
+ * void show_dive_info(struct dive *dive)
+ *
+ * called from gtk-ui:
+ * GtkWidget *extended_dive_info_widget(void)
+ */
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -5,6 +15,7 @@
 
 #include "dive.h"
 #include "display.h"
 
 #include "dive.h"
 #include "display.h"
+#include "display-gtk.h"
 #include "divelist.h"
 
 static GtkEntry *location, *buddy, *divemaster;
 #include "divelist.h"
 
 static GtkEntry *location, *buddy, *divemaster;
index 9e5bd907ec18eb9e98281296f3644603f7ca50a4..cf8b048c9e79e62ea63f30bc04a364ce3ce59855 100644 (file)
@@ -1,26 +1,12 @@
 #include <stdio.h>
 #include <stdio.h>
-#include <gtk/gtk.h>
 #include <pthread.h>
 
 #include "dive.h"
 #include "divelist.h"
 #include "display.h"
 #include <pthread.h>
 
 #include "dive.h"
 #include "divelist.h"
 #include "display.h"
+#include "display-gtk.h"
 
 
-/* libdivecomputer */
-#include <device.h>
-#include <suunto.h>
-#include <reefnet.h>
-#include <uwatec.h>
-#include <oceanic.h>
-#include <mares.h>
-#include <hw.h>
-#include <cressi.h>
-#include <zeagle.h>
-#include <atomics.h>
-#include <utils.h>
-
-/* handling uemis Zurich SDA files */
-#include "uemis.h"
+#include "libdivecomputer.h"
 
 static void error(const char *fmt, ...)
 {
 
 static void error(const char *fmt, ...)
 {
@@ -36,14 +22,6 @@ static void error(const char *fmt, ...)
        g_error_free(error);
 }
 
        g_error_free(error);
 }
 
-typedef struct device_data_t {
-       device_type_t type;
-       const char *name, *devname;
-       GtkWidget *progressbar;
-       device_devinfo_t devinfo;
-       device_clock_t clock;
-} device_data_t;
-
 static parser_status_t create_parser(device_data_t *devdata, parser_t **parser)
 {
        switch (devdata->type) {
 static parser_status_t create_parser(device_data_t *devdata, parser_t **parser)
 {
        switch (devdata->type) {
@@ -379,8 +357,7 @@ static device_status_t device_open(const char *devname,
        }
 }
 
        }
 }
 
-static void
-event_cb(device_t *device, device_event_t event, const void *data, void *userdata)
+static void event_cb(device_t *device, device_event_t event, const void *data, void *userdata)
 {
        const device_progress_t *progress = (device_progress_t *) data;
        const device_devinfo_t *devinfo = (device_devinfo_t *) data;
 {
        const device_progress_t *progress = (device_progress_t *) data;
        const device_devinfo_t *devinfo = (device_devinfo_t *) data;
@@ -392,7 +369,7 @@ event_cb(device_t *device, device_event_t event, const void *data, void *userdat
                printf("Event: waiting for user action\n");
                break;
        case DEVICE_EVENT_PROGRESS:
                printf("Event: waiting for user action\n");
                break;
        case DEVICE_EVENT_PROGRESS:
-               gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(devdata->progressbar),
+               update_progressbar(devdata->progress,
                        (double) progress->current / (double) progress->maximum);
                break;
        case DEVICE_EVENT_DEVINFO:
                        (double) progress->current / (double) progress->maximum);
                break;
        case DEVICE_EVENT_DEVINFO:
@@ -462,7 +439,7 @@ static void *pthread_wrapper(void *_data)
        return (void *)err_string;
 }
 
        return (void *)err_string;
 }
 
-static void do_import(device_data_t *data)
+void do_import(device_data_t *data)
 {
        pthread_t pthread;
        void *retval;
 {
        pthread_t pthread;
        void *retval;
@@ -470,16 +447,11 @@ static void do_import(device_data_t *data)
        if (data->type == DEVICE_TYPE_UEMIS)
                return uemis_import();
 
        if (data->type == DEVICE_TYPE_UEMIS)
                return uemis_import();
 
-       /* I'm sure there is some better interface for waiting on a thread in a gtk main loop */
+       /* I'm sure there is some better interface for waiting on a thread in a UI main loop */
        import_thread_done = 0;
        pthread_create(&pthread, NULL, pthread_wrapper, data);
        while (!import_thread_done) {
        import_thread_done = 0;
        pthread_create(&pthread, NULL, pthread_wrapper, data);
        while (!import_thread_done) {
-               while (gtk_events_pending()) {
-                       if (gtk_main_iteration_do(0)) {
-                               import_thread_cancelled = 1;
-                               break;
-                       }
-               }
+               import_thread_cancelled = process_ui_events();
                usleep(100000);
        }
        if (pthread_join(pthread, &retval) < 0)
                usleep(100000);
        }
        if (pthread_join(pthread, &retval) < 0)
@@ -495,10 +467,7 @@ static void do_import(device_data_t *data)
  * libdivecomputer tell us what devices it supports,
  * rather than have the application have to know..
  */
  * libdivecomputer tell us what devices it supports,
  * rather than have the application have to know..
  */
-struct device_list {
-       const char *name;
-       device_type_t type;
-} device_list[] = {
+struct device_list device_list[] = {
        { "Suunto Solution",    DEVICE_TYPE_SUUNTO_SOLUTION },
        { "Suunto Eon",         DEVICE_TYPE_SUUNTO_EON },
        { "Suunto Vyper",       DEVICE_TYPE_SUUNTO_VYPER },
        { "Suunto Solution",    DEVICE_TYPE_SUUNTO_SOLUTION },
        { "Suunto Eon",         DEVICE_TYPE_SUUNTO_EON },
        { "Suunto Vyper",       DEVICE_TYPE_SUUNTO_VYPER },
@@ -523,90 +492,3 @@ struct device_list {
        { "Uemis Zurich SDA",   DEVICE_TYPE_UEMIS },
        { NULL }
 };
        { "Uemis Zurich SDA",   DEVICE_TYPE_UEMIS },
        { NULL }
 };
-
-static void fill_computer_list(GtkListStore *store)
-{
-       GtkTreeIter iter;
-       struct device_list *list = device_list;
-
-       for (list = device_list ; list->name ; list++) {
-               gtk_list_store_append(store, &iter);
-               gtk_list_store_set(store, &iter,
-                       0, list->name,
-                       1, list->type,
-                       -1);
-       }
-}
-
-static GtkComboBox *dive_computer_selector(GtkWidget *dialog)
-{
-       GtkWidget *hbox, *combo_box;
-       GtkListStore *model;
-       GtkCellRenderer *renderer;
-
-       hbox = gtk_hbox_new(FALSE, 6);
-       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 3);
-
-       model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
-       fill_computer_list(model);
-
-       combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model));
-       gtk_box_pack_start(GTK_BOX(hbox), combo_box, FALSE, TRUE, 3);
-
-       renderer = gtk_cell_renderer_text_new();
-       gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo_box), renderer, TRUE);
-       gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo_box), renderer, "text", 0, NULL);
-
-       return GTK_COMBO_BOX(combo_box);
-}
-
-void import_dialog(GtkWidget *w, gpointer data)
-{
-       int result;
-       GtkWidget *dialog, *hbox;
-       GtkComboBox *computer;
-       device_data_t devicedata = {
-               .devname = "/dev/ttyUSB0",
-       };
-
-       dialog = gtk_dialog_new_with_buttons("Import from dive computer",
-               GTK_WINDOW(main_window),
-               GTK_DIALOG_DESTROY_WITH_PARENT,
-               GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-               GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-               NULL);
-
-       computer = dive_computer_selector(dialog);
-
-       hbox = gtk_hbox_new(FALSE, 6);
-       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, TRUE, 3);
-       devicedata.progressbar = gtk_progress_bar_new();
-       gtk_container_add(GTK_CONTAINER(hbox), devicedata.progressbar);
-
-       gtk_widget_show_all(dialog);
-       result = gtk_dialog_run(GTK_DIALOG(dialog));
-       switch (result) {
-               int type;
-               GtkTreeIter iter;
-               GtkTreeModel *model;
-               const char *comp;
-       case GTK_RESPONSE_ACCEPT:
-               if (!gtk_combo_box_get_active_iter(computer, &iter))
-                       break;
-               model = gtk_combo_box_get_model(computer);
-               gtk_tree_model_get(model, &iter,
-                       0, &comp,
-                       1, &type,
-                       -1);
-               devicedata.type = type;
-               devicedata.name = comp;
-               do_import(&devicedata);
-               break;
-       default:
-               break;
-       }
-       gtk_widget_destroy(dialog);
-
-       report_dives();
-       dive_list_update_dives();
-}
diff --git a/libdivecomputer.h b/libdivecomputer.h
new file mode 100644 (file)
index 0000000..205f28e
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef LIBDIVECOMPUTER_H
+#define LIBDIVECOMPUTER_H
+
+/* libdivecomputer */
+#include <device.h>
+#include <suunto.h>
+#include <reefnet.h>
+#include <uwatec.h>
+#include <oceanic.h>
+#include <mares.h>
+#include <hw.h>
+#include <cressi.h>
+#include <zeagle.h>
+#include <atomics.h>
+#include <utils.h>
+
+/* handling uemis Zurich SDA files */
+#include "uemis.h"
+
+/* don't forget to include the UI toolkit specific display-XXX.h first
+   to get the definition of progressbar_t */
+typedef struct device_data_t {
+       device_type_t type;
+       const char *name, *devname;
+       progressbar_t *progress;
+       device_devinfo_t devinfo;
+       device_clock_t clock;
+} device_data_t;
+
+struct device_list {
+       const char *name;
+       device_type_t type;
+};
+
+extern struct device_list device_list[];
+extern void do_import(device_data_t *data);
+
+#endif
diff --git a/main.c b/main.c
index 7d65c87e10669066bf53cd7b6793aff87d59e2bb..3e4145645ba9ed48ecdf647e865d414b291e224c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,3 +1,4 @@
+/* main.c */
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -7,22 +8,13 @@
 
 #include "dive.h"
 #include "divelist.h"
 
 #include "dive.h"
 #include "divelist.h"
-#include "display.h"
-
-GtkWidget *main_window;
-GtkWidget *main_vbox;
-GtkWidget *error_info_bar;
-GtkWidget *error_label;
-int        error_count;
-
-#define DIVELIST_DEFAULT_FONT "Sans 8"
-const char *divelist_font;
 
 GConfClient *gconf;
 struct units output_units;
 
 #define GCONF_NAME(x) "/apps/subsurface/" #x
 
 
 GConfClient *gconf;
 struct units output_units;
 
 #define GCONF_NAME(x) "/apps/subsurface/" #x
 
+/* random helper functions, used here or elsewhere */
 static int sortfn(const void *_a, const void *_b)
 {
        const struct dive *a = *(void **)_a;
 static int sortfn(const void *_a, const void *_b)
 {
        const struct dive *a = *(void **)_a;
@@ -35,6 +27,23 @@ static int sortfn(const void *_a, const void *_b)
        return 0;
 }
 
        return 0;
 }
 
+const char *weekday(int wday)
+{
+       static const char wday_array[7][4] = {
+               "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+       };
+       return wday_array[wday];
+}
+
+const char *monthname(int mon)
+{
+       static const char month_array[12][4] = {
+               "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+               "Jul", "Aug", "Oct", "Sep", "Nov", "Dec",
+       };
+       return month_array[mon];
+}
+
 /*
  * This doesn't really report anything at all. We just sort the
  * dives, the GUI does the reporting
 /*
  * This doesn't really report anything at all. We just sort the
  * dives, the GUI does the reporting
@@ -85,13 +94,6 @@ static void parse_argument(const char *arg)
        } while (*++p);
 }
 
        } while (*++p);
 }
 
-static void on_destroy(GtkWidget* w, gpointer data)
-{
-       gtk_main_quit();
-}
-
-static GtkWidget *dive_profile;
-
 void update_dive(struct dive *new_dive)
 {
        static struct dive *buffered_dive;
 void update_dive(struct dive *new_dive)
 {
        static struct dive *buffered_dive;
@@ -109,240 +111,7 @@ void update_dive(struct dive *new_dive)
        buffered_dive = new_dive;
 }
 
        buffered_dive = new_dive;
 }
 
-void repaint_dive(void)
-{
-       update_dive(current_dive);
-       gtk_widget_queue_draw(dive_profile);
-}
-
-static char *existing_filename;
-
-static void on_info_bar_response(GtkWidget *widget, gint response,
-                                 gpointer data)
-{
-       if (response == GTK_RESPONSE_OK)
-       {
-               gtk_widget_destroy(widget);
-               error_info_bar = NULL;
-       }
-}
-
-void report_error(GError* error)
-{
-       if (error == NULL)
-       {
-               return;
-       }
-       
-       if (error_info_bar == NULL)
-       {
-               error_count = 1;
-               error_info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_OK,
-                                                              GTK_RESPONSE_OK,
-                                                              NULL);
-               g_signal_connect(error_info_bar, "response", G_CALLBACK(on_info_bar_response), NULL);
-               gtk_info_bar_set_message_type(GTK_INFO_BAR(error_info_bar),
-                                             GTK_MESSAGE_ERROR);
-               
-               error_label = gtk_label_new(error->message);
-               GtkWidget *container = gtk_info_bar_get_content_area(GTK_INFO_BAR(error_info_bar));
-               gtk_container_add(GTK_CONTAINER(container), error_label);
-               
-               gtk_box_pack_start(GTK_BOX(main_vbox), error_info_bar, FALSE, FALSE, 0);
-               gtk_widget_show_all(main_vbox);
-       }
-       else
-       {
-               error_count++;
-               char buffer[256];
-               snprintf(buffer, sizeof(buffer), "Failed to open %i files.", error_count);
-               gtk_label_set(GTK_LABEL(error_label), buffer);
-       }
-}
-
-static void file_open(GtkWidget *w, gpointer data)
-{
-       GtkWidget *dialog;
-       dialog = gtk_file_chooser_dialog_new("Open File",
-               GTK_WINDOW(main_window),
-               GTK_FILE_CHOOSER_ACTION_OPEN,
-               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-               NULL);
-       gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
-
-       if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
-               GSList *filenames;
-               char *filename;
-               filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
-               
-               GError *error = NULL;
-               while(filenames != NULL) {
-                       filename = (char *)filenames->data;
-                       parse_xml_file(filename, &error);
-                       if (error != NULL)
-                       {
-                               report_error(error);
-                               g_error_free(error);
-                               error = NULL;
-                       }
-                       
-                       g_free(filename);
-                       filenames = g_slist_next(filenames);
-               }
-               g_slist_free(filenames);
-               report_dives();
-               dive_list_update_dives();
-       }
-       gtk_widget_destroy(dialog);
-}
-
-static void file_save(GtkWidget *w, gpointer data)
-{
-       GtkWidget *dialog;
-       dialog = gtk_file_chooser_dialog_new("Save File",
-               GTK_WINDOW(main_window),
-               GTK_FILE_CHOOSER_ACTION_SAVE,
-               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-               GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
-               NULL);
-       gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
-       if (!existing_filename) {
-               gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "Untitled document");
-       } else
-               gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), existing_filename);
-
-       if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
-               char *filename;
-               filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
-               save_dives(filename);
-               g_free(filename);
-       }
-       gtk_widget_destroy(dialog);
-}
-
-static void quit(GtkWidget *w, gpointer data)
-{
-       gtk_main_quit();
-}
-
-static void create_radio(GtkWidget *vbox, const char *name, ...)
-{
-       va_list args;
-       GtkRadioButton *group = NULL;
-       GtkWidget *box, *label;
-
-       box = gtk_hbox_new(TRUE, 10);
-       gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
-
-       label = gtk_label_new(name);
-       gtk_box_pack_start(GTK_BOX(box), label, TRUE, TRUE, 0);
-
-       va_start(args, name);
-       for (;;) {
-               int enabled;
-               const char *name;
-               GtkWidget *button;
-               void *callback_fn;
-
-               name = va_arg(args, char *);
-               if (!name)
-                       break;
-               callback_fn = va_arg(args, void *);
-               enabled = va_arg(args, int);
-
-               button = gtk_radio_button_new_with_label_from_widget(group, name);
-               group = GTK_RADIO_BUTTON(button);
-               gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
-               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), enabled);
-               g_signal_connect(button, "toggled", G_CALLBACK(callback_fn), NULL);
-       }
-       va_end(args);
-}
-
-#define UNITCALLBACK(name, type, value)                                \
-static void name(GtkWidget *w, gpointer data)                  \
-{                                                              \
-       if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) \
-               menu_units.type = value;                        \
-}
-
-static struct units menu_units;
-
-UNITCALLBACK(set_meter, length, METERS)
-UNITCALLBACK(set_feet, length, FEET)
-UNITCALLBACK(set_bar, pressure, BAR)
-UNITCALLBACK(set_psi, pressure, PSI)
-UNITCALLBACK(set_liter, volume, LITER)
-UNITCALLBACK(set_cuft, volume, CUFT)
-UNITCALLBACK(set_celsius, temperature, CELSIUS)
-UNITCALLBACK(set_fahrenheit, temperature, FAHRENHEIT)
-
-static void preferences_dialog(GtkWidget *w, gpointer data)
-{
-       int result;
-       GtkWidget *dialog, *font, *frame, *box;
-
-       menu_units = output_units;
-
-       dialog = gtk_dialog_new_with_buttons("Preferences",
-               GTK_WINDOW(main_window),
-               GTK_DIALOG_DESTROY_WITH_PARENT,
-               GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-               GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-               NULL);
-
-       frame = gtk_frame_new("Units");
-       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
-
-       box = gtk_vbox_new(FALSE, 6);
-       gtk_container_add(GTK_CONTAINER(frame), box);
-
-       create_radio(box, "Depth:",
-               "Meter", set_meter, (output_units.length == METERS),
-               "Feet",  set_feet, (output_units.length == FEET),
-               NULL);
-
-       create_radio(box, "Pressure:",
-               "Bar", set_bar, (output_units.pressure == BAR),
-               "PSI",  set_psi, (output_units.pressure == PSI),
-               NULL);
-
-       create_radio(box, "Volume:",
-               "Liter",  set_liter, (output_units.volume == LITER),
-               "CuFt", set_cuft, (output_units.volume == CUFT),
-               NULL);
-
-       create_radio(box, "Temperature:",
-               "Celsius", set_celsius, (output_units.temperature == CELSIUS),
-               "Fahrenheit",  set_fahrenheit, (output_units.temperature == FAHRENHEIT),
-               NULL);
-
-       font = gtk_font_button_new_with_font(divelist_font);
-       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), font, FALSE, FALSE, 5);
-
-       gtk_widget_show_all(dialog);
-       result = gtk_dialog_run(GTK_DIALOG(dialog));
-       if (result == GTK_RESPONSE_ACCEPT) {
-               /* Make sure to flush any modified old dive data with old units */
-               update_dive(NULL);
-
-               divelist_font = strdup(gtk_font_button_get_font_name(GTK_FONT_BUTTON(font)));
-               set_divelist_font(divelist_font);
-
-               output_units = menu_units;
-               update_dive_list_units();
-               repaint_dive();
-               gconf_client_set_bool(gconf, GCONF_NAME(feet), output_units.length == FEET, NULL);
-               gconf_client_set_bool(gconf, GCONF_NAME(psi), output_units.pressure == PSI, NULL);
-               gconf_client_set_bool(gconf, GCONF_NAME(cuft), output_units.volume == CUFT, NULL);
-               gconf_client_set_bool(gconf, GCONF_NAME(fahrenheit), output_units.temperature == FAHRENHEIT, NULL);
-               gconf_client_set_string(gconf, GCONF_NAME(divelist_font), divelist_font, NULL);
-       }
-       gtk_widget_destroy(dialog);
-}
-
-static void renumber_dives(int nr)
+void renumber_dives(int nr)
 {
        int i;
 
 {
        int i;
 
@@ -352,167 +121,14 @@ static void renumber_dives(int nr)
        }
 }
 
        }
 }
 
-static void renumber_dialog(GtkWidget *w, gpointer data)
-{
-       int result;
-       GtkWidget *dialog, *frame, *button;
-
-       dialog = gtk_dialog_new_with_buttons("Renumber",
-               GTK_WINDOW(main_window),
-               GTK_DIALOG_DESTROY_WITH_PARENT,
-               GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
-               GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
-               NULL);
-
-       frame = gtk_frame_new("New starting number");
-       gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), frame);
-
-       button = gtk_spin_button_new_with_range(1, 50000, 1);
-       gtk_container_add(GTK_CONTAINER(frame), button);
-
-       gtk_widget_show_all(dialog);
-       result = gtk_dialog_run(GTK_DIALOG(dialog));
-       if (result == GTK_RESPONSE_ACCEPT) {
-               int nr = gtk_spin_button_get_value(GTK_SPIN_BUTTON(button));
-               renumber_dives(nr);
-               repaint_dive();
-       }
-       gtk_widget_destroy(dialog);
-}
-
-static GtkActionEntry menu_items[] = {
-       { "FileMenuAction", GTK_STOCK_FILE, "File", NULL, NULL, NULL},
-       { "LogMenuAction",  GTK_STOCK_FILE, "Log", NULL, NULL, NULL},
-       { "OpenFile",       GTK_STOCK_OPEN, NULL,   "<control>O", NULL, G_CALLBACK(file_open) },
-       { "SaveFile",       GTK_STOCK_SAVE, NULL,   "<control>S", NULL, G_CALLBACK(file_save) },
-       { "Print",          GTK_STOCK_PRINT, NULL,  "<control>P", NULL, G_CALLBACK(do_print) },
-       { "Import",         NULL, "Import", NULL, NULL, G_CALLBACK(import_dialog) },
-       { "Preferences",    NULL, "Preferences", NULL, NULL, G_CALLBACK(preferences_dialog) },
-       { "Renumber",       NULL, "Renumber", NULL, NULL, G_CALLBACK(renumber_dialog) },
-       { "Quit",           GTK_STOCK_QUIT, NULL,   "<control>Q", NULL, G_CALLBACK(quit) },
-};
-static gint nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
-
-static const gchar* ui_string = " \
-       <ui> \
-               <menubar name=\"MainMenu\"> \
-                       <menu name=\"FileMenu\" action=\"FileMenuAction\"> \
-                               <menuitem name=\"Open\" action=\"OpenFile\" /> \
-                               <menuitem name=\"Save\" action=\"SaveFile\" /> \
-                               <menuitem name=\"Print\" action=\"Print\" /> \
-                               <separator name=\"Separator1\"/> \
-                               <menuitem name=\"Import\" action=\"Import\" /> \
-                               <separator name=\"Separator2\"/> \
-                               <menuitem name=\"Preferences\" action=\"Preferences\" /> \
-                               <separator name=\"Separator3\"/> \
-                               <menuitem name=\"Quit\" action=\"Quit\" /> \
-                       </menu> \
-                       <menu name=\"LogMenu\" action=\"LogMenuAction\"> \
-                               <menuitem name=\"Renumber\" action=\"Renumber\" /> \
-                       </menu> \
-               </menubar> \
-       </ui> \
-";
-
-static GtkWidget *get_menubar_menu(GtkWidget *window)
-{
-       GtkActionGroup *action_group = gtk_action_group_new("Menu");
-       gtk_action_group_add_actions(action_group, menu_items, nmenu_items, 0);
-
-       GtkUIManager *ui_manager = gtk_ui_manager_new();
-       gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);
-       GError* error = 0;
-       gtk_ui_manager_add_ui_from_string(GTK_UI_MANAGER(ui_manager), ui_string, -1, &error);
-
-       gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(ui_manager));
-       GtkWidget* menu = gtk_ui_manager_get_widget(ui_manager, "/MainMenu");
-
-       return menu;
-}
-
-static void switch_page(GtkNotebook *notebook, gint arg1, gpointer user_data)
-{
-       repaint_dive();
-}
-
 int main(int argc, char **argv)
 {
        int i;
 int main(int argc, char **argv)
 {
        int i;
-       GtkWidget *win;
-       GtkWidget *paned;
-       GtkWidget *info_box;
-       GtkWidget *notebook;
-       GtkWidget *dive_info;
-       GtkWidget *dive_list;
-       GtkWidget *equipment;
-       GtkWidget *menubar;
-       GtkWidget *vbox;
 
        output_units = SI_units;
        parse_xml_init();
 
 
        output_units = SI_units;
        parse_xml_init();
 
-       gtk_init(&argc, &argv);
-
-       g_type_init();
-       gconf = gconf_client_get_default();
-
-       if (gconf_client_get_bool(gconf, GCONF_NAME(feet), NULL))
-               output_units.length = FEET;
-       if (gconf_client_get_bool(gconf, GCONF_NAME(psi), NULL))
-               output_units.pressure = PSI;
-       if (gconf_client_get_bool(gconf, GCONF_NAME(cuft), NULL))
-               output_units.volume = CUFT;
-       if (gconf_client_get_bool(gconf, GCONF_NAME(fahrenheit), NULL))
-               output_units.temperature = FAHRENHEIT;
-
-       divelist_font = gconf_client_get_string(gconf, GCONF_NAME(divelist_font), NULL);
-       if (!divelist_font)
-               divelist_font = DIVELIST_DEFAULT_FONT;
-
-       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), "destroy", G_CALLBACK(on_destroy), NULL);
-       main_window = win;
-
-       vbox = gtk_vbox_new(FALSE, 0);
-       gtk_container_add(GTK_CONTAINER(win), vbox);
-       main_vbox = vbox;
-
-       menubar = get_menubar_menu(win);
-       gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
-
-       /* HPane for left the dive list, and right the dive info */
-       paned = gtk_vpaned_new();
-       gtk_box_pack_end(GTK_BOX(vbox), paned, TRUE, TRUE, 0);
-
-       /* Create the actual divelist */
-       dive_list = dive_list_create();
-       gtk_paned_add2(GTK_PANED(paned), dive_list);
-
-       /* VBox for dive info, and tabs */
-       info_box = gtk_vbox_new(FALSE, 6);
-       gtk_paned_add1(GTK_PANED(paned), info_box);
-
-       /* Notebook for dive info vs profile vs .. */
-       notebook = gtk_notebook_new();
-       g_signal_connect(notebook, "switch-page", G_CALLBACK(switch_page), NULL);
-       gtk_box_pack_start(GTK_BOX(info_box), notebook, TRUE, TRUE, 6);
-
-       /* Frame for dive profile */
-       dive_profile = dive_profile_widget();
-       gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_profile, gtk_label_new("Dive Profile"));
-
-       /* Frame for extended dive info */
-       dive_info = extended_dive_info_widget();
-       gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_info, gtk_label_new("Dive Notes"));
-
-       /* Frame for dive equipment */
-       equipment = equipment_widget();
-       gtk_notebook_append_page(GTK_NOTEBOOK(notebook), equipment, gtk_label_new("Equipment"));
-
-       gtk_widget_set_app_paintable(win, TRUE);
-       gtk_widget_show_all(win);
+       init_ui(argc, argv);
        
        for (i = 1; i < argc; i++) {
                const char *a = argv[i];
        
        for (i = 1; i < argc; i++) {
                const char *a = argv[i];
@@ -535,6 +151,6 @@ int main(int argc, char **argv)
        report_dives();
        dive_list_update_dives();
 
        report_dives();
        dive_list_update_dives();
 
-       gtk_main();
+       run_ui();
        return 0;
 }
        return 0;
 }
diff --git a/print.c b/print.c
index 57cac80757f3533c2ce458c9249cd5196d54365f..af7fc4cd6c232368ebe6adcaa111a626b17f88cd 100644 (file)
--- a/print.c
+++ b/print.c
@@ -2,6 +2,7 @@
 
 #include "dive.h"
 #include "display.h"
 
 #include "dive.h"
 #include "display.h"
+#include "display-gtk.h"
 
 static void draw_page(GtkPrintOperation *operation,
                        GtkPrintContext *context,
 
 static void draw_page(GtkPrintOperation *operation,
                        GtkPrintContext *context,
index 9a9d98642934bc308e12b0f0a9be7b5cb6497d0e..20317b93717704e922000528cf1b5060df1d7bd1 100644 (file)
--- a/profile.c
+++ b/profile.c
@@ -1,3 +1,7 @@
+/* profile.c */
+/* creates all the necessary data for drawing the dive profile 
+ * uses cairo to draw it
+ */
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -72,7 +76,7 @@ static void set_source_rgba(struct graphics_context *gc, double r, double g, dou
        cairo_set_source_rgba(gc->cr, r, g, b, a);
 }
 
        cairo_set_source_rgba(gc->cr, r, g, b, a);
 }
 
-static void set_source_rgb(struct graphics_context *gc, double r, double g, double b)
+void set_source_rgb(struct graphics_context *gc, double r, double g, double b)
 {
        set_source_rgba(gc, r, g, b, 1);
 }
 {
        set_source_rgba(gc, r, g, b, 1);
 }
@@ -741,35 +745,3 @@ void plot(struct graphics_context *gc, int w, int h, struct dive *dive)
        cairo_stroke(gc->cr);
 
 }
        cairo_stroke(gc->cr);
 
 }
-
-static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
-{
-       struct dive *dive = current_dive;
-       struct graphics_context gc = { .printer = 0 };
-       int w,h;
-
-       w = widget->allocation.width;
-       h = widget->allocation.height;
-
-       gc.cr = gdk_cairo_create(widget->window);
-       set_source_rgb(&gc, 0, 0, 0);
-       cairo_paint(gc.cr);
-
-       if (dive)
-               plot(&gc, w, h, dive);
-
-       cairo_destroy(gc.cr);
-
-       return FALSE;
-}
-
-GtkWidget *dive_profile_widget(void)
-{
-       GtkWidget *da;
-
-       da = gtk_drawing_area_new();
-       gtk_widget_set_size_request(da, 350, 250);
-       g_signal_connect(da, "expose_event", G_CALLBACK(expose_event), NULL);
-
-       return da;
-}
diff --git a/uemis.c b/uemis.c
index 5cede0facce9b161bde15db1e1ab2b8903cff38e..c390aae3b74635fa67466db2094030d4a99ce8bd 100644 (file)
--- a/uemis.c
+++ b/uemis.c
 #include <time.h>
 #include <regex.h>
 
 #include <time.h>
 #include <regex.h>
 
-#include <gtk/gtk.h>
-
 #include "dive.h"
 #include "dive.h"
-#include "display.h"
 #include "uemis.h"
 
 /*
 #include "uemis.h"
 
 /*
@@ -214,8 +211,11 @@ static void parse_divelog_binary(char *base64, struct dive **divep) {
        return;
 }
 
        return;
 }
 
+/* parse a single file
+ * TODO: we don't report any errors when the parse fails - we simply don't add them to the list
+ */
 void
 void
-parse_uemis_file(char *divelogfilename,GError **error) {
+parse_uemis_file(char *divelogfilename) {
        char *found=NULL;
        struct tm tm;
        struct dive *dive;
        char *found=NULL;
        struct tm tm;
        struct dive *dive;
@@ -261,40 +261,7 @@ bail:
  */
 void
 uemis_import() {
  */
 void
 uemis_import() {
-       GtkWidget *dialog;
-       GtkFileFilter *filter = gtk_file_filter_new ();
-       gtk_file_filter_add_pattern (filter, "*.SDA");
-       gtk_file_filter_set_name(filter, "uemis Zurich SDA files");
-       dialog = gtk_file_chooser_dialog_new("Open File",
-                                       GTK_WINDOW(main_window),
-                                       GTK_FILE_CHOOSER_ACTION_OPEN,
-                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                       GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-                                       NULL);
-       gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
-       gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog),filter);
-
-       if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
-               GSList *filenames;
-               char *filename;
-               filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
-
-               GError *error = NULL;
-               while(filenames != NULL) {
-                       filename = (char *)filenames->data;
-                       parse_uemis_file(filename, &error);
-                       if (error != NULL)
-                       {
-                               report_error(error);
-                               g_error_free(error);
-                               error = NULL;
-                       }
-
-                       g_free(filename);
-                       filenames = g_slist_next(filenames);
-               }
-               g_slist_free(filenames);
+       if (open_import_file_dialog("*.SDA","uemis Zurich SDA files",
+                                       &parse_uemis_file))
                report_dives();
                report_dives();
-       }
-       gtk_widget_destroy(dialog);
-}
+}      
diff --git a/uemis.h b/uemis.h
index 1b6c026d1ca1d23fb02f14cbb783d8501f32c6fe..d694007d031e2eb919136c2ce46d8dc9e9165be1 100644 (file)
--- a/uemis.h
+++ b/uemis.h
@@ -10,6 +10,4 @@
 
 void uemis_import();
 
 
 void uemis_import();
 
-extern GtkWidget *main_window;
-
 #endif /* DIVE_H */
 #endif /* DIVE_H */