Revision: 1857 http://geany-plugins.svn.sourceforge.net/geany-plugins/?rev=1857&view=re... Author: colombanw Date: 2011-01-19 18:38:07 +0000 (Wed, 19 Jan 2011)
Log Message: ----------- WebHelper: Make GwhSettings object a lot more dynamic
Now settings are installed dynamically by the caller rather than built-in. This makes adding a new setting ways easier and cleaner: the caller only needs to register a new item using gwh_settings_install_property().
Modified Paths: -------------- trunk/geany-plugins/webhelper/src/gwh-plugin.c trunk/geany-plugins/webhelper/src/gwh-settings.c trunk/geany-plugins/webhelper/src/gwh-settings.h
Modified: trunk/geany-plugins/webhelper/src/gwh-plugin.c =================================================================== --- trunk/geany-plugins/webhelper/src/gwh-plugin.c 2011-01-18 23:32:03 UTC (rev 1856) +++ trunk/geany-plugins/webhelper/src/gwh-plugin.c 2011-01-19 18:38:07 UTC (rev 1857) @@ -35,6 +35,7 @@ #include "gwh-settings.h" #include "gwh-plugin.h" #include "gwh-keybindings.h" +#include "gwh-enum-types.h"
GeanyPlugin *geany_plugin; @@ -289,6 +290,46 @@ GError *err = NULL;
G_settings = gwh_settings_get_default (); + + gwh_settings_install_property (G_settings, g_param_spec_boolean ( + "browser-auto-reload", + "Browser auto reload", + "Whether the browser reloads itself upon document saving", + TRUE, + G_PARAM_READWRITE)); + gwh_settings_install_property (G_settings, g_param_spec_string ( + "browser-last-uri", + "Browser last URI", + "Last URI visited by the browser", + "about:blank", + G_PARAM_READWRITE)); + gwh_settings_install_property (G_settings, g_param_spec_enum ( + "browser-orientation", + "Browser orientation", + "Orientation of the browser widget", + GTK_TYPE_ORIENTATION, + GTK_ORIENTATION_VERTICAL, + G_PARAM_READWRITE)); + gwh_settings_install_property (G_settings, g_param_spec_enum ( + "browser-position", + "Browser position", + "Position of the browser widget in Geany's UI", + GWH_TYPE_BROWSER_POSITION, + GWH_BROWSER_POSITION_MESSAGE_WINDOW, + G_PARAM_READWRITE)); + gwh_settings_install_property (G_settings, g_param_spec_string ( + "browser-separate-window-geometry", + "Browser separate window geometry", + "Last geometry of the separated browser's window", + "400x300", + G_PARAM_READWRITE)); + gwh_settings_install_property (G_settings, g_param_spec_string ( + "inspector-window-geometry", + "Inspector window geometry", + "Last geometry of the inspector window", + "400x300", + G_PARAM_READWRITE)); + path = get_config_filename (); if (! gwh_settings_load_from_file (G_settings, path, &err)) { g_warning ("Failed to load configuration: %s", err->message);
Modified: trunk/geany-plugins/webhelper/src/gwh-settings.c =================================================================== --- trunk/geany-plugins/webhelper/src/gwh-settings.c 2011-01-18 23:32:03 UTC (rev 1856) +++ trunk/geany-plugins/webhelper/src/gwh-settings.c 2011-01-19 18:38:07 UTC (rev 1857) @@ -22,45 +22,15 @@ #include <string.h> #include <glib.h> #include <glib-object.h> -#include <gtk/gtk.h> /* for GtkOrientation */ +#include <gtk/gtk.h>
-#include "gwh-enum-types.h" /* for GwhUiBrowserPosition */
- -/* sets @ptr to @value, freeing @ptr before. - * note that: - * * ptr can be used to compute @value, assignation is done after comuptation - * * ptr is used twice, so it must be side-effects-free */ -#define setptr(ptr, value) \ - G_STMT_START { \ - gpointer new_ptr = (value); \ - g_free (ptr); \ - ptr = new_ptr; \ - } G_STMT_END - - struct _GwhSettingsPrivate { - gboolean browser_auto_reload; - gchar *browser_last_uri; - GtkOrientation browser_orientation; - GwhBrowserPosition browser_position; - gchar *browser_separate_window_geometry; - gchar *inspector_window_geometry; + GPtrArray *prop_array; };
-enum -{ - PROP_0, - PROP_BROWSER_AUTO_RELOAD, - PROP_BROWSER_LAST_URI, - PROP_BROWSER_ORIENTATION, - PROP_BROWSER_POSITION, - PROP_BROWSER_SEPARATE_WINDOW_GEOMETRY, - PROP_INSPECTOR_WINDOW_GEOMETRY -};
- G_DEFINE_TYPE (GwhSettings, gwh_settings, G_TYPE_OBJECT)
@@ -72,28 +42,13 @@ { GwhSettings *self = GWH_SETTINGS (object);
- switch (prop_id) { - case PROP_BROWSER_AUTO_RELOAD: - g_value_set_boolean (value, self->priv->browser_auto_reload); - break; - case PROP_BROWSER_LAST_URI: - g_value_set_string (value, self->priv->browser_last_uri); - break; - case PROP_BROWSER_ORIENTATION: - g_value_set_enum (value, self->priv->browser_orientation); - break; - case PROP_BROWSER_POSITION: - g_value_set_enum (value, self->priv->browser_position); - break; - case PROP_BROWSER_SEPARATE_WINDOW_GEOMETRY: - g_value_set_string (value, self->priv->browser_separate_window_geometry); - break; - case PROP_INSPECTOR_WINDOW_GEOMETRY: - g_value_set_string (value, self->priv->inspector_window_geometry); - break; + if (G_LIKELY (prop_id > 0 && prop_id <= self->priv->prop_array->len)) { + GValue *prop_value;
- default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + prop_value = g_ptr_array_index (self->priv->prop_array, prop_id - 1); + g_value_copy (prop_value, value); + } else { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
@@ -105,29 +60,13 @@ { GwhSettings *self = GWH_SETTINGS (object);
- switch (prop_id) { - case PROP_BROWSER_AUTO_RELOAD: - self->priv->browser_auto_reload = g_value_get_boolean (value); - break; - case PROP_BROWSER_LAST_URI: - setptr (self->priv->browser_last_uri, g_value_dup_string (value)); - break; - case PROP_BROWSER_ORIENTATION: - self->priv->browser_orientation = g_value_get_enum (value); - break; - case PROP_BROWSER_POSITION: - self->priv->browser_position = g_value_get_enum (value); - break; - case PROP_BROWSER_SEPARATE_WINDOW_GEOMETRY: - setptr (self->priv->browser_separate_window_geometry, - g_value_dup_string (value)); - break; - case PROP_INSPECTOR_WINDOW_GEOMETRY: - setptr (self->priv->inspector_window_geometry, g_value_dup_string (value)); - break; + if (G_LIKELY (prop_id > 0 && prop_id <= self->priv->prop_array->len)) { + GValue *prop_value;
- default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + prop_value = g_ptr_array_index (self->priv->prop_array, prop_id - 1); + g_value_copy (value, prop_value); + } else { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } }
@@ -137,7 +76,7 @@ GObjectConstructParam *properties) { static GObject *obj = NULL; - + if (G_UNLIKELY (! obj)) { obj = G_OBJECT_CLASS (gwh_settings_parent_class)->constructor (gtype, n_properties, @@ -153,15 +92,21 @@ }
static void +free_prop_item (gpointer data, + gpointer user_data) +{ + g_value_unset (data); + g_free (data); +} + +static void gwh_settings_finalize (GObject *object) { GwhSettings *self = GWH_SETTINGS (object);
- self->priv->browser_auto_reload = FALSE; - setptr (self->priv->browser_last_uri, NULL); - self->priv->browser_orientation = 0; - self->priv->browser_position = 0; - setptr (self->priv->inspector_window_geometry, NULL); + g_ptr_array_foreach (self->priv->prop_array, free_prop_item, NULL); + g_ptr_array_free (self->priv->prop_array, TRUE); + self->priv->prop_array = NULL;
G_OBJECT_CLASS (gwh_settings_parent_class)->finalize (object); } @@ -176,45 +121,6 @@ object_class->get_property = gwh_settings_get_property; object_class->set_property = gwh_settings_set_property;
- g_object_class_install_property (object_class, PROP_BROWSER_AUTO_RELOAD, - g_param_spec_boolean ("browser-auto-reload", - "Browser auto reload", - "Whether the browser reloads itself upon document saving", - TRUE, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_BROWSER_LAST_URI, - g_param_spec_string ("browser-last-uri", - "Browser last URI", - "Last URI visited by the browser", - "about:blank", - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_BROWSER_ORIENTATION, - g_param_spec_enum ("browser-orientation", - "Browser orientation", - "Orientation of the browser widget", - GTK_TYPE_ORIENTATION, - GTK_ORIENTATION_VERTICAL, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_BROWSER_POSITION, - g_param_spec_enum ("browser-position", - "Browser position", - "Position of the browser widget in Geany's UI", - GWH_TYPE_BROWSER_POSITION, - GWH_BROWSER_POSITION_MESSAGE_WINDOW, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_BROWSER_SEPARATE_WINDOW_GEOMETRY, - g_param_spec_string ("browser-separate-window-geometry", - "Browser separate window geometry", - "Last geometry of the separated browser's window", - "400x300", - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_INSPECTOR_WINDOW_GEOMETRY, - g_param_spec_string ("inspector-window-geometry", - "Inspector window geometry", - "Last geometry of the inspector window", - "400x300", - G_PARAM_READWRITE)); - g_type_class_add_private (klass, sizeof (GwhSettingsPrivate)); }
@@ -223,12 +129,7 @@ { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GWH_TYPE_SETTINGS, GwhSettingsPrivate); - self->priv->browser_auto_reload = TRUE; - self->priv->browser_last_uri = g_strdup ("about:blank"); - self->priv->browser_orientation = GTK_ORIENTATION_VERTICAL; - self->priv->browser_position = GWH_BROWSER_POSITION_MESSAGE_WINDOW; - self->priv->browser_separate_window_geometry = g_strdup ("400x300"); - self->priv->inspector_window_geometry = g_strdup ("400x300"); + self->priv->prop_array = g_ptr_array_new (); }
@@ -240,6 +141,86 @@ return g_object_new (GWH_TYPE_SETTINGS, NULL); }
+static gboolean +is_pspec_installed (GObject *obj, + const GParamSpec *pspec) +{ + GParamSpec **pspecs; + guint n_props; + guint i; + gboolean installed = FALSE; + + pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (obj), &n_props); + for (i = 0; ! installed && i < n_props; i++) { + installed = (pspec->value_type == pspecs[i]->value_type && + strcmp (pspec->name, pspecs[i]->name) == 0); + } + g_free (pspecs); + + return installed; +} + +void +gwh_settings_install_property (GwhSettings *self, + GParamSpec *pspec) +{ + GValue *value; + + g_return_if_fail (GWH_IS_SETTINGS (self)); + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + + /* a bit hackish, but allows to install the same property twice because the + * class will not be destroyed if the plugin gets reloaded. safe since the + * object is a singleton that will never de destroyed, and the plugin is + * resident, so the object is still valid after a reload. */ + if (is_pspec_installed (G_OBJECT (self), pspec)) { + return; + } + + value = g_value_init (g_malloc0 (sizeof *value), pspec->value_type); + switch (G_TYPE_FUNDAMENTAL (pspec->value_type)) { + #define HANDLE_BASIC_TYPE(NAME, Name, name) \ + case G_TYPE_##NAME: \ + g_value_set_##name (value, ((GParamSpec##Name*)pspec)->default_value); \ + break; + + HANDLE_BASIC_TYPE (BOOLEAN, Boolean, boolean) + HANDLE_BASIC_TYPE (CHAR, Char, char) + HANDLE_BASIC_TYPE (UCHAR, UChar, uchar) + HANDLE_BASIC_TYPE (INT, Int, int) + HANDLE_BASIC_TYPE (UINT, UInt, uint) + HANDLE_BASIC_TYPE (LONG, Long, long) + HANDLE_BASIC_TYPE (ULONG, ULong, ulong) + HANDLE_BASIC_TYPE (INT64, Int64, int64) + HANDLE_BASIC_TYPE (UINT64, UInt64, uint64) + HANDLE_BASIC_TYPE (FLOAT, Float, float) + HANDLE_BASIC_TYPE (DOUBLE, Double, double) + HANDLE_BASIC_TYPE (ENUM, Enum, enum) + HANDLE_BASIC_TYPE (FLAGS, Flags, flags) + HANDLE_BASIC_TYPE (STRING, String, string) + + #undef HANDLE_BASIC_TYPE + + case G_TYPE_PARAM: + case G_TYPE_BOXED: + case G_TYPE_POINTER: + case G_TYPE_OBJECT: + /* nothing to do with these types, default GValue is fine since they have + * no default value */ + break; + + default: + g_critical ("Unsupported property type "%s" for property "%s"", + G_VALUE_TYPE_NAME (value), pspec->name); + g_value_unset (value); + g_free (value); + return; + } + g_ptr_array_add (self->priv->prop_array, value); + g_object_class_install_property (G_OBJECT_GET_CLASS (self), + self->priv->prop_array->len, pspec); +} + static void get_key_and_group_from_property_name (const gchar *name, gchar **group, @@ -473,9 +454,9 @@
+/* display/edit widgets stuff */
- static GtkWidget * gwh_settings_widget_new_boolean (GwhSettings *self, const GValue *value,
Modified: trunk/geany-plugins/webhelper/src/gwh-settings.h =================================================================== --- trunk/geany-plugins/webhelper/src/gwh-settings.h 2011-01-18 23:32:03 UTC (rev 1856) +++ trunk/geany-plugins/webhelper/src/gwh-settings.h 2011-01-19 18:38:07 UTC (rev 1857) @@ -56,6 +56,9 @@ G_GNUC_INTERNAL GwhSettings *gwh_settings_get_default (void); G_GNUC_INTERNAL +void gwh_settings_install_property (GwhSettings *self, + GParamSpec *pspec); +G_GNUC_INTERNAL gboolean gwh_settings_save_to_file (GwhSettings *self, const gchar *filename, GError **error);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.