[gcr] gcr: Show import errors in an info bar under the viewer
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcr] gcr: Show import errors in an info bar under the viewer
- Date: Wed, 30 Nov 2011 11:09:26 +0000 (UTC)
commit 62fbbdb564bfb28addeebf060a58dd20f026b398
Author: Stef Walter <stefw collabora co uk>
Date: Wed Nov 30 11:20:07 2011 +0100
gcr: Show import errors in an info bar under the viewer
* Add importing signal to GcrImportButton
* Add a GtkInfoBar to GcrViewerWindow
docs/reference/gcr/gcr-sections.txt | 8 +---
docs/reference/gcr/gcr.interfaces | 7 +--
gcr/gcr-import-button.c | 16 +++++++
gcr/gcr-import-button.h | 6 +++
gcr/gcr-viewer-widget.c | 79 ++++++++++++++++++++++++++++++-----
gcr/gcr-viewer-widget.h | 11 +++--
gcr/gcr-viewer-window.c | 20 ++++++---
7 files changed, 115 insertions(+), 32 deletions(-)
---
diff --git a/docs/reference/gcr/gcr-sections.txt b/docs/reference/gcr/gcr-sections.txt
index 2c32313..29432bc 100644
--- a/docs/reference/gcr/gcr-sections.txt
+++ b/docs/reference/gcr/gcr-sections.txt
@@ -601,21 +601,17 @@ GcrUnlockOptionsWidgetPrivate
<SECTION>
<FILE>gcr-viewer-widget</FILE>
GcrViewerWidget
-GcrViewerWidgetClass
gcr_viewer_widget_new
gcr_viewer_widget_load_data
gcr_viewer_widget_load_file
gcr_viewer_widget_get_parser
+gcr_viewer_widget_show_error
+gcr_viewer_widget_clear_error
<SUBSECTION Standard>
gcr_viewer_widget_get_type
GCR_TYPE_VIEWER_WIDGET
GCR_IS_VIEWER_WIDGET
-GCR_IS_VIEWER_WIDGET_CLASS
GCR_VIEWER_WIDGET
-GCR_VIEWER_WIDGET_CLASS
-GCR_VIEWER_WIDGET_GET_CLASS
-<SUBSECTION Private>
-GcrViewerWidgetPrivate
</SECTION>
<SECTION>
diff --git a/docs/reference/gcr/gcr.interfaces b/docs/reference/gcr/gcr.interfaces
index 1ef3691..c65f21a 100644
--- a/docs/reference/gcr/gcr.interfaces
+++ b/docs/reference/gcr/gcr.interfaces
@@ -10,14 +10,13 @@ GtkComboBox AtkImplementorIface GtkBuildable GtkCellLayout GtkCellEditable
GcrComboSelector AtkImplementorIface GtkBuildable GtkCellLayout GtkCellEditable
GtkButton AtkImplementorIface GtkBuildable GtkActivatable
GcrImportButton AtkImplementorIface GtkBuildable GtkActivatable
-GtkScrolledWindow AtkImplementorIface GtkBuildable
-GcrDisplayScrolled AtkImplementorIface GtkBuildable GcrViewer
-GcrViewerWidget AtkImplementorIface GtkBuildable GcrViewer
GtkWindow AtkImplementorIface GtkBuildable
GcrViewerWindow AtkImplementorIface GtkBuildable
GtkTreeView AtkImplementorIface GtkBuildable GtkScrollable
GcrListSelector AtkImplementorIface GtkBuildable GtkScrollable
GcrTreeSelector AtkImplementorIface GtkBuildable GtkScrollable
+GtkBox AtkImplementorIface GtkBuildable GtkOrientable
+GcrViewerWidget AtkImplementorIface GtkBuildable GtkOrientable
GtkCellArea GtkCellLayout GtkBuildable
GtkTreeViewColumn GtkCellLayout GtkBuildable
GcrCollectionModel GtkTreeModel GtkTreeSortable
@@ -32,7 +31,7 @@ GtkContainerAccessible AtkComponent
GtkComboBoxAccessible AtkComponent AtkAction AtkSelection
GtkButtonAccessible AtkComponent AtkAction AtkImage
GtkTreeViewAccessible AtkComponent AtkTable AtkSelection GtkCellAccessibleParent
-GtkScrolledWindowAccessible AtkComponent
+GtkBoxAccessible AtkComponent
GtkWindowAccessible AtkComponent AtkWindow
GtkAction GtkBuildable
GckSession GInitable GAsyncInitable
diff --git a/gcr/gcr-import-button.c b/gcr/gcr-import-button.c
index 1e1c809..373eebb 100644
--- a/gcr/gcr-import-button.c
+++ b/gcr/gcr-import-button.c
@@ -56,6 +56,7 @@ enum {
/**
* GcrImportButtonClass:
* @parent_class: The parent class
+ * @importing: Emitted when the import begins.
* @imported: Emitted when the import completes, or fails.
*
* Class for #GcrImportButton.
@@ -76,6 +77,7 @@ struct _GcrImportButtonPrivate {
};
enum {
+ IMPORTING,
IMPORTED,
LAST_SIGNAL
};
@@ -313,6 +315,8 @@ begin_import (GcrImportButton *self,
g_return_if_fail (self->pv->importing == FALSE);
+ g_signal_emit (self, signals[IMPORTING], 0, importer);
+
self->pv->importing = TRUE;
g_free (self->pv->imported);
self->pv->imported = NULL;
@@ -489,6 +493,18 @@ gcr_import_button_class_init (GcrImportButtonClass *klass)
g_object_class_override_property (gobject_class, PROP_LABEL, "label");
/**
+ * GcrImportButton::importing:
+ * @self: the import button
+ * @importer: the importer that will be imported to
+ *
+ * Signal emitted when an import begins.
+ */
+ signals[IMPORTING] = g_signal_new ("importing", GCR_TYPE_IMPORT_BUTTON, G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GcrImportButtonClass, importing),
+ NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ /**
* GcrImportButton::imported:
* @self: the import button
* @importer: the importer that was imported to
diff --git a/gcr/gcr-import-button.h b/gcr/gcr-import-button.h
index 41ed222..b30f3f3 100644
--- a/gcr/gcr-import-button.h
+++ b/gcr/gcr-import-button.h
@@ -51,9 +51,15 @@ struct _GcrImportButton {
struct _GcrImportButtonClass {
GtkButtonClass parent_class;
+ void (*importing) (GcrImportButton *self,
+ GcrImporter *importer);
+
void (*imported) (GcrImportButton *self,
GcrImporter *importer,
GError *error);
+
+ /*< private >*/
+ gpointer padding[10];
};
GType gcr_import_button_get_type (void) G_GNUC_CONST;
diff --git a/gcr/gcr-viewer-widget.c b/gcr/gcr-viewer-widget.c
index 6e06599..df59a2c 100644
--- a/gcr/gcr-viewer-widget.c
+++ b/gcr/gcr-viewer-widget.c
@@ -70,14 +70,21 @@ enum {
* implementation, the parent class we derive from.
*/
+#define GCR_VIEWER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidgetClass))
+#define GCR_IS_VIEWER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_VIEWER_WIDGET))
+#define GCR_VIEWER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidgetClass))
+
+typedef struct _GcrViewerWidgetClass GcrViewerWidgetClass;
+typedef struct _GcrViewerWidgetPrivate GcrViewerWidgetPrivate;
+
struct _GcrViewerWidget {
/*< private >*/
- GcrDisplayScrolled parent;
+ GtkBox parent;
GcrViewerWidgetPrivate *pv;
};
struct _GcrViewerWidgetClass {
- GcrDisplayScrolledClass parent_class;
+ GtkBoxClass parent_class;
void (*added) (GcrViewerWidget *widget,
GcrRenderer *renderer,
@@ -85,6 +92,9 @@ struct _GcrViewerWidgetClass {
};
struct _GcrViewerWidgetPrivate {
+ GcrViewer *viewer;
+ GtkInfoBar *message_bar;
+ GtkLabel *message_label;
GQueue *files_to_load;
GcrParser *parser;
GCancellable *cancellable;
@@ -103,7 +113,7 @@ static guint signals[LAST_SIGNAL] = { 0, };
static void viewer_load_next_file (GcrViewerWidget *self);
static void viewer_stop_loading_files (GcrViewerWidget *self);
-G_DEFINE_TYPE (GcrViewerWidget, gcr_viewer_widget, GCR_TYPE_DISPLAY_SCROLLED);
+G_DEFINE_TYPE (GcrViewerWidget, gcr_viewer_widget, GTK_TYPE_BOX);
static const gchar *
get_parsed_label_or_display_name (GcrViewerWidget *self,
@@ -139,7 +149,7 @@ on_parser_parsed (GcrParser *parser,
}
/* And show the data */
- gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
+ gcr_viewer_add_renderer (self->pv->viewer, renderer);
/* Let callers know we're rendering data */
if (actual == TRUE)
@@ -183,7 +193,7 @@ on_unlock_renderer_clicked (GcrUnlockRenderer *unlock,
if (gcr_parser_parse_data (self->pv->parser, data, n_data, &error)) {
/* Done with this unlock renderer */
- gcr_viewer_remove_renderer (GCR_VIEWER (self), GCR_RENDERER (unlock));
+ gcr_viewer_remove_renderer (self->pv->viewer, GCR_RENDERER (unlock));
self->pv->unlocks = g_list_remove (self->pv->unlocks, unlock);
g_object_unref (unlock);
@@ -210,7 +220,7 @@ on_parser_authenticate_for_data (GcrParser *parser,
unlock = _gcr_unlock_renderer_new_for_parsed (parser);
if (unlock != NULL) {
g_object_set (unlock, "label", get_parsed_label_or_display_name (self, parser), NULL);
- gcr_viewer_add_renderer (GCR_VIEWER (self), GCR_RENDERER (unlock));
+ gcr_viewer_add_renderer (self->pv->viewer, GCR_RENDERER (unlock));
g_signal_connect (unlock, "unlock-clicked", G_CALLBACK (on_unlock_renderer_clicked), self);
self->pv->unlocks = g_list_prepend (self->pv->unlocks, unlock);
}
@@ -221,9 +231,28 @@ on_parser_authenticate_for_data (GcrParser *parser,
static void
gcr_viewer_widget_init (GcrViewerWidget *self)
{
+ GtkWidget *area;
+
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_VIEWER_WIDGET,
GcrViewerWidgetPrivate);
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (self),
+ GTK_ORIENTATION_VERTICAL);
+
+ self->pv->viewer = gcr_viewer_new_scrolled ();
+ gtk_box_pack_start (GTK_BOX (self), GTK_WIDGET (self->pv->viewer), TRUE, TRUE, 0);
+ gtk_widget_show (GTK_WIDGET (self->pv->viewer));
+
+ self->pv->message_label = GTK_LABEL (gtk_label_new (""));
+ gtk_label_set_use_markup (self->pv->message_label, TRUE);
+ gtk_label_set_ellipsize (self->pv->message_label, PANGO_ELLIPSIZE_END);
+ gtk_widget_show (GTK_WIDGET (self->pv->message_label));
+
+ self->pv->message_bar = GTK_INFO_BAR (gtk_info_bar_new ());
+ gtk_box_pack_start (GTK_BOX (self), GTK_WIDGET (self->pv->message_bar), FALSE, TRUE, 0);
+ area = gtk_info_bar_get_content_area (self->pv->message_bar);
+ gtk_container_add (GTK_CONTAINER (area), GTK_WIDGET (self->pv->message_label));
+
self->pv->files_to_load = g_queue_new ();
self->pv->parser = gcr_parser_new ();
self->pv->cancellable = g_cancellable_new ();
@@ -298,6 +327,8 @@ gcr_viewer_widget_class_init (GcrViewerWidgetClass *klass)
gobject_class->finalize = gcr_viewer_widget_finalize;
gobject_class->get_property = gcr_viewer_widget_get_property;
+ g_type_class_add_private (klass, sizeof (GcrViewerWidgetPrivate));
+
/**
* GcrViewerWidget:parser:
*
@@ -307,8 +338,6 @@ gcr_viewer_widget_class_init (GcrViewerWidgetClass *klass)
g_param_spec_object ("parser", "Parser", "Parser used to parse viewable items",
GCR_TYPE_PARSER, G_PARAM_READABLE));
- g_type_class_add_private (klass, sizeof (GcrViewerWidget));
-
/**
* GcrViewerWidget::added:
* @self: the viewer widget
@@ -343,7 +372,7 @@ on_parser_parse_stream_returned (GObject *source,
} else if (error) {
renderer = gcr_failure_renderer_new (self->pv->display_name, error);
- gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
+ gcr_viewer_add_renderer (self->pv->viewer, renderer);
g_object_unref (renderer);
g_error_free (error);
}
@@ -384,7 +413,7 @@ on_file_read_returned (GObject *source,
} else if (error) {
renderer = gcr_failure_renderer_new (self->pv->display_name, error);
- gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
+ gcr_viewer_add_renderer (self->pv->viewer, renderer);
g_object_unref (renderer);
g_error_free (error);
@@ -482,7 +511,7 @@ gcr_viewer_widget_load_data (GcrViewerWidget *self,
if (!gcr_parser_parse_data (self->pv->parser, data, n_data, &error)) {
renderer = gcr_failure_renderer_new (display_name, error);
- gcr_viewer_add_renderer (GCR_VIEWER (self), renderer);
+ gcr_viewer_add_renderer (self->pv->viewer, renderer);
g_object_unref (renderer);
g_error_free (error);
}
@@ -502,3 +531,31 @@ gcr_viewer_widget_get_parser (GcrViewerWidget *self)
g_return_val_if_fail (GCR_IS_VIEWER_WIDGET (self), NULL);
return self->pv->parser;
}
+
+void
+gcr_viewer_widget_show_error (GcrViewerWidget *self,
+ const gchar *message,
+ GError *error)
+{
+ gchar *markup;
+
+ g_return_if_fail (GCR_IS_VIEWER_WIDGET (self));
+ g_return_if_fail (message != NULL);
+
+ if (error)
+ markup = g_markup_printf_escaped ("<b>%s</b>: %s", message, error->message);
+ else
+ markup = g_markup_printf_escaped ("%s", message);
+
+ gtk_info_bar_set_message_type (self->pv->message_bar, GTK_MESSAGE_ERROR);
+ gtk_label_set_markup (self->pv->message_label, markup);
+ gtk_widget_show (GTK_WIDGET (self->pv->message_bar));
+ g_free (markup);
+}
+
+void
+gcr_viewer_widget_clear_error (GcrViewerWidget *self)
+{
+ g_return_if_fail (GCR_IS_VIEWER_WIDGET (self));
+ gtk_widget_hide (GTK_WIDGET (self->pv->message_bar));
+}
diff --git a/gcr/gcr-viewer-widget.h b/gcr/gcr-viewer-widget.h
index 3e1e17e..e52afec 100644
--- a/gcr/gcr-viewer-widget.h
+++ b/gcr/gcr-viewer-widget.h
@@ -28,14 +28,9 @@
#define GCR_TYPE_VIEWER_WIDGET (gcr_viewer_widget_get_type ())
#define GCR_VIEWER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidget))
-#define GCR_VIEWER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidgetClass))
#define GCR_IS_VIEWER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_VIEWER_WIDGET))
-#define GCR_IS_VIEWER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_VIEWER_WIDGET))
-#define GCR_VIEWER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_VIEWER_WIDGET, GcrViewerWidgetClass))
typedef struct _GcrViewerWidget GcrViewerWidget;
-typedef struct _GcrViewerWidgetClass GcrViewerWidgetClass;
-typedef struct _GcrViewerWidgetPrivate GcrViewerWidgetPrivate;
GType gcr_viewer_widget_get_type (void);
@@ -52,4 +47,10 @@ void gcr_viewer_widget_load_data (GcrViewerWidget *self,
GcrParser * gcr_viewer_widget_get_parser (GcrViewerWidget *self);
+void gcr_viewer_widget_show_error (GcrViewerWidget *self,
+ const gchar *message,
+ GError *error);
+
+void gcr_viewer_widget_clear_error (GcrViewerWidget *self);
+
#endif /* GCR_VIEWER_WIDGET_H */
diff --git a/gcr/gcr-viewer-window.c b/gcr/gcr-viewer-window.c
index c604d18..8bf816c 100644
--- a/gcr/gcr-viewer-window.c
+++ b/gcr/gcr-viewer-window.c
@@ -56,23 +56,28 @@ gcr_viewer_window_init (GcrViewerWindow *self)
}
static void
+on_import_button_importing (GcrImportButton *button,
+ GcrImporter *importer,
+ gpointer user_data)
+{
+ GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
+ gcr_viewer_widget_clear_error (self->pv->viewer);
+}
+
+static void
on_import_button_imported (GcrImportButton *button,
GcrImporter *importer,
GError *error,
gpointer user_data)
{
GcrViewerWindow *self = GCR_VIEWER_WINDOW (user_data);
- GcrRenderer *renderer;
if (error == NULL) {
g_object_set (button, "label", _("Imported"), NULL);
} else {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- renderer = gcr_failure_renderer_new (_("Import failed"), error);
- gcr_viewer_add_renderer (GCR_VIEWER (self->pv->viewer), renderer);
- g_object_unref (renderer);
- }
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ gcr_viewer_widget_show_error (self->pv->viewer, _("Import failed"), error);
}
}
@@ -101,6 +106,9 @@ gcr_viewer_window_constructed (GObject *obj)
gtk_widget_show (bbox);
self->pv->import = gcr_import_button_new (_("Import"));
+ g_signal_connect_object (self->pv->import, "importing",
+ G_CALLBACK (on_import_button_importing),
+ self, 0);
g_signal_connect_object (self->pv->import, "imported",
G_CALLBACK (on_import_button_imported),
self, 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]