summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
+}