summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Chimento <philip@endlessm.com>2015-03-24 21:24:38 -0700
committerPhilip Chimento <philip@endlessm.com>2015-03-25 17:46:11 -0700
commitab029d49fa0d40b027bc2a4e29defac176151eff (patch)
treeda55f67fe1651b36483a03771866f85411508cab
parent67c212e47a1db5f3e3dd1abaf552052e46512c93 (diff)
EosAttribution implements GInitable
Since the first thing we do is load the attribution information from the file and the object is useless if that fails, then we may as well make the file a construct property and implement GInitable. [endlessm/eos-sdk#2934]
-rw-r--r--endless/eosapplication.c8
-rw-r--r--endless/eosattribution-private.h10
-rw-r--r--endless/eosattribution.c133
3 files changed, 125 insertions, 26 deletions
diff --git a/endless/eosapplication.c b/endless/eosapplication.c
index 9ca109b..91dbd73 100644
--- a/endless/eosapplication.c
+++ b/endless/eosapplication.c
@@ -270,13 +270,11 @@ on_image_credits_activate (GSimpleAction *action,
GtkWidget *dialog, *attribution, *content;
GError *error = NULL;
- attribution = eos_attribution_new ();
- if (!eos_attribution_populate_from_json_file (EOS_ATTRIBUTION (attribution),
- priv->image_attribution_file,
- &error))
+ attribution = eos_attribution_new_sync (priv->image_attribution_file, NULL,
+ &error);
+ if (attribution == NULL)
{
g_warning ("Error loading image attribution file: %s", error->message);
- gtk_widget_destroy (attribution);
return;
}
gtk_widget_set_hexpand (attribution, TRUE);
diff --git a/endless/eosattribution-private.h b/endless/eosattribution-private.h
index b468a71..d23066f 100644
--- a/endless/eosattribution-private.h
+++ b/endless/eosattribution-private.h
@@ -44,13 +44,13 @@ struct _EosAttributionClass
GtkScrolledWindowClass parent_class;
};
-GType eos_attribution_get_type (void) G_GNUC_CONST;
+GType eos_attribution_get_type (void) G_GNUC_CONST;
-GtkWidget *eos_attribution_new (void);
+GtkWidget *eos_attribution_new_sync (GFile *file,
+ GCancellable *cancellable,
+ GError **error);
-gboolean eos_attribution_populate_from_json_file (EosAttribution *self,
- GFile *file,
- GError **error);
+GFile * eos_attribution_get_file (EosAttribution *self);
G_END_DECLS
diff --git a/endless/eosattribution.c b/endless/eosattribution.c
index ea22fe0..474f4e9 100644
--- a/endless/eosattribution.c
+++ b/endless/eosattribution.c
@@ -11,12 +11,19 @@
typedef struct
{
+ GFile *file;
GtkWidget *view;
GtkListStore *model;
} EosAttributionPrivate;
-G_DEFINE_TYPE_WITH_PRIVATE (EosAttribution, eos_attribution,
- GTK_TYPE_SCROLLED_WINDOW)
+/* Forward declarations */
+static void eos_attribution_init_initable (GInitableIface *, GInterfaceInfo *);
+
+G_DEFINE_TYPE_WITH_CODE (EosAttribution, eos_attribution,
+ GTK_TYPE_SCROLLED_WINDOW,
+ G_ADD_PRIVATE (EosAttribution)
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
+ eos_attribution_init_initable))
#define ROW_HEIGHT 50 /* Height of the pixbufs in each row */
@@ -27,6 +34,15 @@ enum {
static guint attribution_signals[LAST_SIGNAL] = { 0 };
+enum
+{
+ PROP_0,
+ PROP_FILE,
+ NPROPS
+};
+
+static GParamSpec *eos_attribution_props[NPROPS] = { NULL, };
+
/* These are the recognized string values for the "license" field. Any other
license must be clarified in the comments, or linked to with the "license_uri"
field. Make sure to add new values to the table "image-attribution-licenses" in
@@ -103,6 +119,45 @@ enum
};
static void
+eos_attribution_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EosAttribution *self = EOS_ATTRIBUTION (object);
+
+ switch (property_id)
+ {
+ case PROP_FILE:
+ g_value_set_object (value, eos_attribution_get_file (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+eos_attribution_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EosAttribution *self = EOS_ATTRIBUTION (object);
+ EosAttributionPrivate *priv = eos_attribution_get_instance_private (self);
+
+ switch (property_id)
+ {
+ case PROP_FILE:
+ priv->file = g_value_dup_object (value); /* construct only */
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
eos_attribution_finalize (GObject *object)
{
EosAttribution *self = EOS_ATTRIBUTION (object);
@@ -118,6 +173,8 @@ eos_attribution_class_init (EosAttributionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = eos_attribution_get_property;
+ object_class->set_property = eos_attribution_set_property;
object_class->finalize = eos_attribution_finalize;
attribution_signals[SHOW_URI] =
@@ -128,6 +185,15 @@ eos_attribution_class_init (EosAttributionClass *klass)
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE,
1, G_TYPE_STRING);
+
+ eos_attribution_props[PROP_FILE] =
+ g_param_spec_object ("file", "File",
+ "JSON file with attribution information for images",
+ G_TYPE_FILE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, NPROPS,
+ eos_attribution_props);
}
static void
@@ -398,12 +464,6 @@ eos_attribution_init (EosAttribution *self)
gtk_container_add (GTK_CONTAINER (self), priv->view);
}
-GtkWidget *
-eos_attribution_new (void)
-{
- return GTK_WIDGET (g_object_new (EOS_TYPE_ATTRIBUTION, NULL));
-}
-
/* Utility function, returns the index if an array of strings @strv terminated
by NULL contains the string @entry, -1 if it does not */
static gint strv_index (gchar * const *, const gchar *) G_GNUC_PURE;
@@ -423,23 +483,33 @@ strv_index (gchar * const *strv, const gchar *entry)
return -1;
}
-gboolean
-eos_attribution_populate_from_json_file (EosAttribution *self,
- GFile *file,
- GError **error)
+static gboolean
+eos_attribution_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
{
+ EosAttribution *self = EOS_ATTRIBUTION (initable);
EosAttributionPrivate *priv = eos_attribution_get_instance_private (self);
- GInputStream *stream = G_INPUT_STREAM (g_file_read (file, NULL, error));
+ GInputStream *stream = G_INPUT_STREAM (g_file_read (priv->file, cancellable,
+ error));
if (stream == NULL)
return FALSE;
JsonParser *parser = json_parser_new ();
- gboolean success = json_parser_load_from_stream (parser, stream, NULL, error);
- g_input_stream_close (stream, NULL, NULL); /* ignore errors */
- g_object_unref (stream);
+ gboolean success = json_parser_load_from_stream (parser, stream, cancellable,
+ error);
if (!success)
+ {
+ g_object_unref (stream);
+ goto fail;
+ }
+
+ success = g_input_stream_close (stream, cancellable, error);
+ g_object_unref (stream);
+ if (!success && g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
goto fail;
+ /* Ignore errors other than cancellation */
JsonReader *reader = json_reader_new (json_parser_get_root (parser));
gint num_images = json_reader_count_elements (reader);
@@ -580,3 +650,34 @@ fail:
g_object_unref (parser);
return FALSE;
}
+
+static void
+eos_attribution_init_initable (GInitableIface *iface,
+ GInterfaceInfo *info)
+{
+ iface->init = eos_attribution_initable_init;
+}
+
+GtkWidget *
+eos_attribution_new_sync (GFile *file,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable),
+ NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ return GTK_WIDGET (g_initable_new (EOS_TYPE_ATTRIBUTION, cancellable, error,
+ "file", file,
+ NULL));
+}
+
+GFile *
+eos_attribution_get_file (EosAttribution *self)
+{
+ g_return_val_if_fail (EOS_IS_ATTRIBUTION (self), NULL);
+
+ EosAttributionPrivate *priv = eos_attribution_get_instance_private (self);
+ return priv->file;
+}