]> git.street.me.uk Git - andy/viking.git/commitdiff
Extract a UI module for babel
authorGuilhem Bonnefille <guilhem.bonnefille@gmail.com>
Mon, 4 Nov 2013 22:31:23 +0000 (23:31 +0100)
committerGuilhem Bonnefille <guilhem.bonnefille@gmail.com>
Mon, 4 Nov 2013 22:31:23 +0000 (23:31 +0100)
Create a module to factorize some UI related code.

Signed-off-by: Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
po/POTFILES.in
src/Makefile.am
src/babel.c
src/babel.h
src/babel_ui.c [new file with mode: 0644]
src/babel_ui.h [new file with mode: 0644]
src/datasource_file.c
test/Makefile.am
test/test_babel.c [new file with mode: 0644]

index 6c9b17783b2d11492d258e87068812a783d842dc..6e273ee57872dc6885be70dfef0f05451ecb01f3 100644 (file)
@@ -1,4 +1,5 @@
 src/acquire.c
+src/babel_ui.c
 src/background.c
 src/bing.c
 src/bingmapsource.c
index 48d88406c68ae260bbdda51c89e7d905c5822ca2..20d4d0bd7406bddbe4c7970c3136821327948076 100644 (file)
@@ -112,6 +112,7 @@ libviking_a_SOURCES = \
        garminsymbols.c garminsymbols.h \
        acquire.c acquire.h \
        babel.c babel.h \
+       babel_ui.c babel_ui.h \
        datasource_file.c \
        datasource_gps.c datasource_gps.h \
        datasource_routing.c \
index a1b39007bd8d01e94089453e53cbf7aa2ee4046d..c9622926bc7323736f1179ca0dbf0d6da361378d 100644 (file)
@@ -73,6 +73,31 @@ GList *a_babel_file_list;
  */
 GList *a_babel_device_list;
 
+/**
+ * Run a function on all file formats supporting a given mode.
+ */
+void a_babel_foreach_file_with_mode (BabelMode mode, GFunc func, gpointer user_data)
+{
+  GList *current;
+  for ( current = g_list_first (a_babel_file_list) ;
+        current != NULL ;
+        current = g_list_next (current) )
+  {
+    BabelFile *currentFile = current->data;
+    /* Check compatibility of modes */
+    gboolean compat = TRUE;
+    if (mode.waypointsRead  && ! currentFile->mode.waypointsRead)  compat = FALSE;
+    if (mode.waypointsWrite && ! currentFile->mode.waypointsWrite) compat = FALSE;
+    if (mode.tracksRead     && ! currentFile->mode.tracksRead)     compat = FALSE;
+    if (mode.tracksWrite    && ! currentFile->mode.tracksWrite)    compat = FALSE;
+    if (mode.routesRead     && ! currentFile->mode.routesRead)     compat = FALSE;
+    if (mode.routesWrite    && ! currentFile->mode.routesWrite)    compat = FALSE;
+    /* Do call */
+    if (compat)
+      func (currentFile, user_data);
+  }
+}
+
 /**
  * a_babel_convert:
  * @vt:        The TRW layer to modify. All data will be deleted, and replaced by what gpsbabel outputs.
index 77d630b2351e2130bd6ef87d766961b135c33f0a..47652d01d01879cd18b2c6d19637666eb7965986 100644 (file)
@@ -95,6 +95,8 @@ typedef struct {
 GList *a_babel_file_list;
 GList *a_babel_device_list;
 
+void a_babel_foreach_file_with_mode (BabelMode mode, GFunc func, gpointer user_data);
+
 gboolean a_babel_convert( VikTrwLayer *vt, const char *babelargs, BabelStatusFunc cb, gpointer user_data, gpointer options );
 gboolean a_babel_convert_from( VikTrwLayer *vt, const char *babelargs, const char *file, BabelStatusFunc cb, gpointer user_data, gpointer options );
 gboolean a_babel_convert_from_shellcommand ( VikTrwLayer *vt, const char *input_cmd, const char *input_file_type, BabelStatusFunc cb, gpointer user_data, gpointer options );
diff --git a/src/babel_ui.c b/src/babel_ui.c
new file mode 100644 (file)
index 0000000..1448219
--- /dev/null
@@ -0,0 +1,181 @@
+
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
+ *
+ * Copyright (C) 2013, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+#include <glib/gi18n.h>
+
+#include "babel.h"
+#include "babel_ui.h"
+
+
+static void babel_ui_selector_add_entry_cb ( gpointer data, gpointer user_data )
+{
+  BabelFile *file = (BabelFile*)data;
+  GtkWidget *combo = GTK_WIDGET(user_data);
+
+  GList *formats = g_object_get_data ( G_OBJECT(combo), "formats" );
+  formats = g_list_append ( formats, file );
+  g_object_set_data ( G_OBJECT(combo), "formats", formats );
+
+  const gchar *label = file->label;
+  vik_combo_box_text_append ( combo, label );
+}
+
+void a_babel_ui_type_selector_dialog_sensitivity_cb ( GtkComboBox *widget, gpointer user_data )
+{
+  /* user_data is the GtkDialog */
+  GtkDialog *dialog = GTK_DIALOG(user_data);
+
+  /* Retrieve the associated file format descriptor */
+  BabelFile *file = a_babel_ui_file_type_selector_get ( GTK_WIDGET(widget) );
+
+  if ( file )
+    /* Not NULL => valid selection */
+    gtk_dialog_set_response_sensitive ( dialog, GTK_RESPONSE_ACCEPT, TRUE );
+  else
+    /* NULL => invalid selection */
+    gtk_dialog_set_response_sensitive ( dialog, GTK_RESPONSE_ACCEPT, FALSE );
+}
+
+/**
+ * a_babel_ui_file_type_selector_new:
+ * @mode: the mode to filter the file types
+ *
+ * Create a file type selector.
+ *
+ * This widget relies on a combo box listing labels of file formats.
+ * We store in the "data" of the GtkWidget a list with the BabelFile
+ * entries, in order to retrieve the selected file format.
+ *
+ * Returns: a GtkWidget
+ */
+GtkWidget *a_babel_ui_file_type_selector_new ( BabelMode mode )
+{
+  GList *formats = NULL;
+  /* Create the combo */
+  GtkWidget * combo = vik_combo_box_text_new ();
+
+  /* Add a first label to invite user to select a file format */
+  /* We store a NULL pointer to distinguish this entry */
+  formats = g_list_append ( formats, NULL );
+  vik_combo_box_text_append ( combo, _("Select a file format") );
+
+  /* Prepare space for file format list */
+  g_object_set_data ( G_OBJECT(combo), "formats", formats );
+
+  /* Add all known and compatible file formats */
+  a_babel_foreach_file_with_mode ( mode, babel_ui_selector_add_entry_cb, combo );
+
+  /* Initialize the selection with the really first entry */
+  gtk_combo_box_set_active ( GTK_COMBO_BOX(combo), 0 );
+
+  return combo;
+}
+
+/**
+ * a_babel_ui_file_type_selector_destroy:
+ * @selector: the selector to destroy
+ *
+ * Destroy the selector and any related data.
+ */
+void a_babel_ui_file_type_selector_destroy ( GtkWidget *selector )
+{
+  GList *formats = g_object_get_data ( G_OBJECT(selector), "formats" );
+  g_free ( formats );
+}
+
+/**
+ * a_babel_ui_file_type_selector_get:
+ * @selector: the selector
+ *
+ * Retrieve the selected file type.
+ *
+ * Returns: the selected BabelFile or NULL
+ */
+BabelFile *a_babel_ui_file_type_selector_get ( GtkWidget *selector )
+{
+  gint active = gtk_combo_box_get_active ( GTK_COMBO_BOX(selector) );
+  if (active >= 0) {
+    GList *formats = g_object_get_data ( G_OBJECT(selector), "formats" );
+    return (BabelFile*)g_list_nth_data ( formats, active );
+  } else {
+    return NULL;
+  }
+}
+
+/**
+ * a_babel_ui_modes_new:
+ * @tracks:
+ * @routes:
+ * @waypoints:
+ *
+ * Creates a selector for babel modes.
+ * This selector is based on 3 checkboxes.
+ *
+ * Returns: a GtkWidget packing all checkboxes.
+ */
+GtkWidget *a_babel_ui_modes_new ( gboolean tracks, gboolean routes, gboolean waypoints )
+{
+  GtkWidget *hbox = gtk_hbox_new( FALSE, 0 );
+  GtkWidget *button = NULL;
+
+  button = gtk_check_button_new_with_label ( _("Tracks") );
+  gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(button), tracks );
+  gtk_box_pack_start ( GTK_BOX(hbox), button, TRUE, TRUE, 0 );
+  gtk_widget_show ( button );
+
+  button = gtk_check_button_new_with_label ( _("Routes") );
+  gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(button), routes );
+  gtk_box_pack_start ( GTK_BOX(hbox), button, TRUE, TRUE, 0 );
+  gtk_widget_show ( button );
+
+  button = gtk_check_button_new_with_label ( _("Waypoints") );
+  gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON(button), waypoints );
+  gtk_box_pack_start ( GTK_BOX(hbox), button, TRUE, TRUE, 0 );
+  gtk_widget_show ( button );
+
+  return hbox;
+}
+
+/**
+ * a_babel_ui_modes_get:
+ * @container:
+ * @tracks: return value
+ * @routes: return value
+ * @waypoints: return value
+ *
+ * Retrieve state of checkboxes.
+ */
+void a_babel_ui_modes_get ( GtkWidget *container, gboolean *tracks, gboolean *routes, gboolean *waypoints )
+{
+  GList* children = gtk_container_get_children ( GTK_CONTAINER(container) );
+  GtkWidget *child = NULL;
+
+  child = g_list_nth_data ( children, 0 );
+  *tracks = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON(child) );
+
+  child = g_list_nth_data ( children, 1 );
+  *routes = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON(child) );
+
+  child = g_list_nth_data ( children, 2 );
+  *waypoints = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON(child) );
+}
+
diff --git a/src/babel_ui.h b/src/babel_ui.h
new file mode 100644 (file)
index 0000000..8af9a22
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
+ *
+ * Copyright (C) 2013 Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef _VIKING_BABEL_UI_H
+#define _VIKING_BABEL_UI_H
+
+#include <gtk/gtk.h>
+
+#include "babel.h"
+
+G_BEGIN_DECLS
+
+GtkWidget *a_babel_ui_file_type_selector_new ( BabelMode mode );
+void a_babel_ui_file_type_selector_destroy ( GtkWidget *selector );
+BabelFile *a_babel_ui_file_type_selector_get ( GtkWidget *selector );
+void a_babel_ui_type_selector_dialog_sensitivity_cb ( GtkComboBox *widget, gpointer user_data );
+
+GtkWidget *a_babel_ui_modes_new ( gboolean tracks, gboolean routes, gboolean waypoints );
+void a_babel_ui_modes_get ( GtkWidget *container, gboolean *tracks, gboolean *routes, gboolean *waypoints );
+
+G_END_DECLS
+
+#endif
index 0a749e5d089db6756157b7862884a767e48c56d4..929bf0cafb60818fb83c691dcf17289ee4603e80 100644 (file)
@@ -31,6 +31,7 @@
 #include "viking.h"
 #include "babel.h"
 #include "gpx.h"
+#include "babel_ui.h"
 #include "acquire.h"
 
 typedef struct {
@@ -81,12 +82,6 @@ static gpointer datasource_file_init ( acq_vik_t *avt )
   return widgets;
 }
 
-static void fill_combo_box (gpointer data, gpointer user_data)
-{
-  const gchar *label = ((BabelFile*) data)->label;
-  vik_combo_box_text_append (GTK_WIDGET(user_data), label);
-}
-
 static void add_file_filter (gpointer data, gpointer user_data)
 {
   GtkFileChooser *chooser = GTK_FILE_CHOOSER ( user_data );
@@ -140,9 +135,14 @@ static void datasource_file_add_setup_widgets ( GtkWidget *dialog, VikViewport *
 
   /* The file format selector */
   type_label = gtk_label_new (_("File type:"));
-  widgets->type = vik_combo_box_text_new ();
-  g_list_foreach (a_babel_file_list, fill_combo_box, widgets->type);
-  gtk_combo_box_set_active (GTK_COMBO_BOX (widgets->type), last_type);
+  /* Propose all readable file */
+  BabelMode mode = { 1, 0, 1, 0, 1, 0 };
+  widgets->type = a_babel_ui_file_type_selector_new ( mode );
+  g_signal_connect ( G_OBJECT(widgets->type), "changed",
+      G_CALLBACK(a_babel_ui_type_selector_dialog_sensitivity_cb), dialog );
+  gtk_combo_box_set_active ( GTK_COMBO_BOX(widgets->type), last_type );
+  /* Manually call the callback to fix the state */
+  a_babel_ui_type_selector_dialog_sensitivity_cb ( widgets->type, dialog );
 
   /* Packing all these widgets */
   GtkBox *box = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
@@ -171,8 +171,7 @@ static void datasource_file_get_cmd_string ( datasource_file_widgets_t *widgets,
   /* Retrieve and memorize file format selected */
   gchar *type = NULL;
   last_type = gtk_combo_box_get_active ( GTK_COMBO_BOX (widgets->type) );
-  if ( a_babel_file_list )
-    type = ((BabelFile*)g_list_nth_data (a_babel_file_list, last_type))->name;
+  type = (a_babel_ui_file_type_selector_get ( widgets->type ))->name;
 
   /* Build the string */
   *cmd = g_strdup_printf( "-i %s", type);
index f8334e297b39e803f757c2a9920b27bd358f0220..6007277d9a2aa4eb17db35ec34b2533f9cbcbb29 100644 (file)
@@ -7,7 +7,7 @@ endif
 
 TESTS = check_degrees_conversions.sh
 
-check_PROGRAMS = degrees_converter gpx2gpx test_vikgotoxmltool test_coord_conversion
+check_PROGRAMS = degrees_converter gpx2gpx test_vikgotoxmltool test_coord_conversion test_babel
 
 check_SCRIPTS = check_degrees_conversions.sh
 
@@ -32,3 +32,9 @@ test_coord_conversion_SOURCES = test_coord_conversion.c
 test_coord_conversion_LDADD = \
   $(top_builddir)/src/libviking.a \
   $(LDADD)
+
+test_babel_SOURCES = test_babel.c
+test_babel_LDADD = \
+  $(top_builddir)/src/libviking.a \
+  $(LDADD)
+
diff --git a/test/test_babel.c b/test/test_babel.c
new file mode 100644 (file)
index 0000000..49a8311
--- /dev/null
@@ -0,0 +1,24 @@
+#include <babel.h>
+
+void print_file_format (BabelFile *file, gconstpointer user_data)
+{
+       printf("%s : %d%d%d%d%d%d\n",
+               file->label,
+               file->mode.waypointsRead, file->mode.waypointsWrite,
+               file->mode.tracksRead, file->mode.tracksWrite,
+               file->mode.routesRead, file->mode.routesWrite);
+}
+
+int main(int argc, char*argv[])
+{
+       a_babel_init();
+
+       if (argc != 7) return 1;
+       BabelMode mode = { atoi(argv[1]),atoi(argv[2]),atoi(argv[3]),atoi(argv[4]),atoi(argv[5]),atoi(argv[6]) };
+       a_babel_foreach_file_with_mode(mode, print_file_format, NULL);
+
+       a_babel_uninit();
+
+       return 0;
+}
+