From: P. F. Chimento Date: Tue, 21 Jun 2011 20:26:18 +0000 (+0200) Subject: Avoid duplicating code X-Git-Url: https://git.stderr.nl/gitweb?p=projects%2Fchimara%2Fchimara.git;a=commitdiff_plain;h=84814759ceb7dc7a97a3a73b6e365a5ca67d4ef8 Avoid duplicating code Move GtkBuilder and UI manager code into util.c; this now handles looking for the proper location of the files depending on whether DEBUG is defined or not. --- diff --git a/player/Makefile.am b/player/Makefile.am index a8343b6..3964d25 100644 --- a/player/Makefile.am +++ b/player/Makefile.am @@ -21,7 +21,8 @@ chimara_SOURCES = main.c \ error.c error.h \ player.c player.h \ app.c app.h \ - browser.c browser.h + browser.c browser.h \ + util.c util.h chimara_CPPFLAGS = $(AM_CPPFLAGS) \ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ diff --git a/player/app.c b/player/app.c index a9cf674..3d5ff08 100644 --- a/player/app.c +++ b/player/app.c @@ -15,6 +15,7 @@ #include "error.h" #include "preferences.h" #include "player.h" +#include "util.h" typedef struct _ChimaraAppPrivate { GtkActionGroup *action_group; @@ -52,17 +53,6 @@ chimara_app_class_init(ChimaraAppClass *klass) g_type_class_add_private(klass, sizeof(ChimaraAppPrivate)); } -static GObject * -load_object(GtkBuilder *builder, const gchar *name) -{ - GObject *retval; - if( (retval = gtk_builder_get_object(builder, name)) == NULL) { - error_dialog(NULL, NULL, "Error while getting object '%s'", name); - g_error("Error while getting object '%s'", name); - } - return retval; -} - static void chimara_app_init(ChimaraApp *self) { @@ -89,25 +79,12 @@ chimara_app_init(ChimaraApp *self) g_free(keyfile); /* Build user interface */ - GtkBuilder *builder = gtk_builder_new(); char *object_ids[] = { "app_group", "aboutwindow", NULL }; - - if( !gtk_builder_add_objects_from_file(builder, PACKAGE_DATA_DIR "/chimara.ui", object_ids, &error) ) { -#ifdef DEBUG - g_error_free(error); - error = NULL; - if( !gtk_builder_add_objects_from_file(builder, PACKAGE_SRC_DIR "/chimara.ui", object_ids, &error) ) { -#endif /* DEBUG */ - error_dialog(NULL, error, "Error while building interface: "); - return; -#ifdef DEBUG - } -#endif /* DEBUG */ - } + GtkBuilder *builder = new_builder_with_objects(object_ids); self->aboutwindow = GTK_WIDGET(load_object(builder, "aboutwindow")); priv->action_group = GTK_ACTION_GROUP(load_object(builder, "app_group")); diff --git a/player/browser.c b/player/browser.c index 4646eef..9be256a 100644 --- a/player/browser.c +++ b/player/browser.c @@ -3,7 +3,7 @@ #include #include "browser.h" #include "app.h" -#include "error.h" +#include "util.h" typedef struct _ChimaraBrowserPrivate { int dummy; @@ -49,19 +49,7 @@ chimara_browser_init(ChimaraBrowser *self) "title", _("Chimara"), NULL); - GtkUIManager *uimanager = gtk_ui_manager_new(); - if( !gtk_ui_manager_add_ui_from_file(uimanager, PACKAGE_DATA_DIR "/browser.menus", &error) ) { -#ifdef DEBUG - g_error_free(error); - error = NULL; - if( !gtk_ui_manager_add_ui_from_file(uimanager, PACKAGE_SRC_DIR "/browser.menus", &error) ) { -#endif /* DEBUG */ - error_dialog(NULL, error, "Error while building interface: "); - return; -#ifdef DEBUG - } -#endif /* DEBUG */ - } + GtkUIManager *uimanager = new_ui_manager("browser.menus"); gtk_ui_manager_insert_action_group(uimanager, chimara_app_get_action_group(theapp), 0); GtkWidget *menubar = gtk_ui_manager_get_widget(uimanager, "/browser_menu"); diff --git a/player/player.c b/player/player.c index d8b094f..19cbe45 100644 --- a/player/player.c +++ b/player/player.c @@ -5,6 +5,7 @@ #include "player.h" #include "error.h" #include "app.h" +#include "util.h" typedef struct _ChimaraPlayerPrivate { int dummy; @@ -15,17 +16,6 @@ typedef struct _ChimaraPlayerPrivate { G_DEFINE_TYPE(ChimaraPlayer, chimara_player, GTK_TYPE_WINDOW); -static GObject * -load_object(GtkBuilder *builder, const gchar *name) -{ - GObject *retval; - if( (retval = gtk_builder_get_object(builder, name)) == NULL) { - error_dialog(NULL, NULL, "Error while getting object '%s'", name); - g_error("Error while getting object '%s'", name); - } - return retval; -} - static void change_window_title(ChimaraGlk *glk, GParamSpec *pspec, GtkWindow *window) { @@ -93,6 +83,7 @@ static void chimara_player_init(ChimaraPlayer *self) { GError *error = NULL; + ChimaraApp *theapp = chimara_app_get(); /* Set parent properties */ g_object_set(self, @@ -102,76 +93,38 @@ chimara_player_init(ChimaraPlayer *self) NULL); /* Construct user interface */ - GtkBuilder *builder = gtk_builder_new(); char *object_ids[] = { "actiongroup", "player-vbox", NULL }; - - if( !gtk_builder_add_objects_from_file(builder, PACKAGE_DATA_DIR "/chimara.ui", object_ids, &error) ) { -#ifdef DEBUG - g_error_free(error); - error = NULL; - if( !gtk_builder_add_objects_from_file(builder, PACKAGE_SRC_DIR "/chimara.ui", object_ids, &error) ) { -#endif /* DEBUG */ - error_dialog(NULL, error, "Error while building interface: "); - return; -#ifdef DEBUG - } -#endif /* DEBUG */ - } - + GtkBuilder *builder = new_builder_with_objects(object_ids); + GtkActionGroup *actiongroup = GTK_ACTION_GROUP(load_object(builder, "actiongroup")); - + /* Set the default value of the "View/Toolbar" menu item upon creation of a new window to the "show-toolbar-default" setting, but bind the setting one-way only - we don't want toolbars to disappear suddenly */ GtkToggleAction *toolbar_action = GTK_TOGGLE_ACTION(load_object(builder, "toolbar")); //gtk_toggle_action_set_active(toolbar_action, g_settings_get_boolean(state_settings, "show-toolbar-default")); //g_settings_bind(state_settings, "show-toolbar-default", toolbar_action, "active", G_SETTINGS_BIND_SET); - - GtkUIManager *uimanager = gtk_ui_manager_new(); - if( !gtk_ui_manager_add_ui_from_file(uimanager, PACKAGE_DATA_DIR "/player.menus", &error) ) { -#ifdef DEBUG - g_error_free(error); - error = NULL; - if( !gtk_ui_manager_add_ui_from_file(uimanager, PACKAGE_SRC_DIR "/player.menus", &error) ) { -#endif /* DEBUG */ - error_dialog(NULL, error, "Error while building interface: "); - return; -#ifdef DEBUG - } -#endif /* DEBUG */ - } - + self->glk = chimara_if_new(); g_object_set(self->glk, "ignore-errors", TRUE, /*"interpreter-number", CHIMARA_IF_ZMACHINE_TANDY_COLOR,*/ NULL); - if( !chimara_glk_set_css_from_file(CHIMARA_GLK(self->glk), PACKAGE_DATA_DIR "/style.css", &error) ) { -#ifdef DEBUG - g_error_free(error); - error = NULL; - if( !chimara_glk_set_css_from_file(CHIMARA_GLK(self->glk), PACKAGE_SRC_DIR "/style.css", &error) ) { -#endif /* DEBUG */ - error_dialog(NULL, error, "Couldn't open CSS file: "); - return; -#ifdef DEBUG - } -#endif /* DEBUG */ + char *default_css = get_data_file_path("style.css"); + if( !chimara_glk_set_css_from_file(CHIMARA_GLK(self->glk), default_css, &error) ) { + error_dialog(self, error, "Couldn't open default CSS file: "); } /* DON'T UNCOMMENT THIS your eyes will burn but it is a good test of programmatically altering just one style chimara_glk_set_css_from_string(CHIMARA_GLK(glk), "buffer.normal { font-family: 'Comic Sans MS'; }");*/ - - GtkBox *vbox = GTK_BOX(load_object(builder, "player-vbox")); - - ChimaraApp *theapp = chimara_app_get(); + GtkUIManager *uimanager = new_ui_manager("player.menus"); gtk_ui_manager_insert_action_group(uimanager, actiongroup, 0); gtk_ui_manager_insert_action_group(uimanager, chimara_app_get_action_group(theapp), 1); GtkWidget *menubar = gtk_ui_manager_get_widget(uimanager, "/player_menu"); @@ -185,7 +138,8 @@ chimara_player_init(ChimaraPlayer *self) /* Connect the accelerators */ GtkAccelGroup *accels = gtk_ui_manager_get_accel_group(uimanager); gtk_window_add_accel_group(GTK_WINDOW(self), accels); - + + GtkBox *vbox = GTK_BOX(load_object(builder, "player-vbox")); gtk_box_pack_end(vbox, self->glk, TRUE, TRUE, 0); g_object_ref(self->glk); /* add an extra reference to keep it alive while the Glk program shuts down */ @@ -197,8 +151,8 @@ chimara_player_init(ChimaraPlayer *self) g_signal_connect(self->glk, "notify::program-name", G_CALLBACK(change_window_title), self); g_signal_connect(self->glk, "notify::story-name", G_CALLBACK(change_window_title), self); - g_object_unref( G_OBJECT(builder) ); - g_object_unref( G_OBJECT(uimanager) ); + g_object_unref(builder); + g_object_unref(uimanager); } /* PUBLIC FUNCTIONS */ diff --git a/player/preferences.c b/player/preferences.c index e03e81b..b5f2583 100644 --- a/player/preferences.c +++ b/player/preferences.c @@ -41,6 +41,7 @@ #include "error.h" #include "app.h" #include "preferences.h" +#include "util.h" typedef struct _ChimaraPrefsPrivate { int dummy; @@ -83,17 +84,6 @@ chimara_prefs_class_init(ChimaraPrefsClass *klass) g_type_class_add_private(klass, sizeof(ChimaraPrefsPrivate)); } -static GObject * -load_object(GtkBuilder *builder, const gchar *name) -{ - GObject *retval; - if( (retval = gtk_builder_get_object(builder, name)) == NULL) { - error_dialog(NULL, NULL, "Error while getting object '%s'", name); - g_error("Error while getting object '%s'", name); - } - return retval; -} - /* Internal functions to convert from human-readable names in the config file to enums and back. Later: replace with plugin functions. */ static ChimaraIFFormat @@ -202,7 +192,6 @@ chimara_prefs_init(ChimaraPrefs *self) NULL); /* Build user interface */ - GtkBuilder *builder = gtk_builder_new(); char *object_ids[] = { "prefs-notebook", "available_interpreters", @@ -210,19 +199,7 @@ chimara_prefs_init(ChimaraPrefs *self) "style-list", NULL }; - - if( !gtk_builder_add_objects_from_file(builder, PACKAGE_DATA_DIR "/chimara.ui", object_ids, &error) ) { -#ifdef DEBUG - g_error_free(error); - error = NULL; - if( !gtk_builder_add_objects_from_file(builder, PACKAGE_SRC_DIR "/chimara.ui", object_ids, &error) ) { -#endif /* DEBUG */ - error_dialog(NULL, error, "Error while building interface: "); - return; -#ifdef DEBUG - } -#endif /* DEBUG */ - } + GtkBuilder *builder = new_builder_with_objects(object_ids); GtkWidget *notebook = GTK_WIDGET( load_object(builder, "prefs-notebook") ); GtkWidget *content_area = gtk_dialog_get_content_area( GTK_DIALOG(self) ); diff --git a/player/util.c b/player/util.c new file mode 100644 index 0000000..5cd1598 --- /dev/null +++ b/player/util.c @@ -0,0 +1,76 @@ +#include +#include +#include "util.h" +#include "error.h" + +const char * +get_data_file_path(const char *filename) +{ + char *path = g_build_filename(PACKAGE_DATA_DIR, filename); + if(g_file_test(path, G_FILE_TEST_EXISTS)) + return path; +#ifdef DEBUG + g_free(path); + path = g_build_filename(PACKAGE_SRC_DIR, filename); + if(g_file_test(path, G_FILE_TEST_EXISTS)) + return path; +#endif /* DEBUG */ + g_error("Could not find data file: %s", filename); +} + +GtkBuilder * +new_builder_with_objects(char **object_ids) +{ + GError *error = NULL; + GtkBuilder *builder = gtk_builder_new(); + + if( !gtk_builder_add_objects_from_file(builder, PACKAGE_DATA_DIR "/chimara.ui", object_ids, &error) ) { +#ifdef DEBUG + g_error_free(error); + error = NULL; + if( !gtk_builder_add_objects_from_file(builder, PACKAGE_SRC_DIR "/chimara.ui", object_ids, &error) ) +#endif /* DEBUG */ + goto fail; + } + return builder; + +fail: + error_dialog(NULL, error, _("Error while building interface: ")); + return NULL; +} + +GObject * +load_object(GtkBuilder *builder, const char *name) +{ + GObject *retval; + if( (retval = gtk_builder_get_object(builder, name)) == NULL) { + error_dialog(NULL, NULL, "Error while getting object '%s'", name); + g_error("Error while getting object '%s'", name); + } + return retval; +} + +GtkUIManager * +new_ui_manager(const char *filename) +{ + GError *error = NULL; + GtkUIManager *uimanager = gtk_ui_manager_new(); + char *path = g_build_filename(PACKAGE_DATA_DIR, filename, NULL); + + if( !gtk_ui_manager_add_ui_from_file(uimanager, path, &error) ) { +#ifdef DEBUG + g_free(path); + path = g_build_filename(PACKAGE_SRC_DIR, filename, NULL); + g_error_free(error); + error = NULL; + if( !gtk_ui_manager_add_ui_from_file(uimanager, path, &error) ) +#endif /* DEBUG */ + goto fail; + } + return uimanager; + +fail: + error_dialog(NULL, error, _("Error while building interface: ")); + return NULL; +} + diff --git a/player/util.h b/player/util.h new file mode 100644 index 0000000..1ce0d7b --- /dev/null +++ b/player/util.h @@ -0,0 +1,15 @@ +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include + +G_BEGIN_DECLS + +const char *get_data_file_path(const char *filename); +GtkBuilder *new_builder_with_objects(char **object_ids); +GObject *load_object(GtkBuilder *builder, const char *name); +GtkUIManager *new_ui_manager(const char *filename); + +G_END_DECLS + +#endif /* __UTIL_H__ */