[libpeas] Show a tooltip for unavailable plugins
- From: Garrett Regier <gregier src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libpeas] Show a tooltip for unavailable plugins
- Date: Fri, 11 Feb 2011 10:38:24 +0000 (UTC)
commit a1bc5e801d539caf3c197cc68de934cd218f17ee
Author: Garrett Regier <alias301 gmail com>
Date: Wed Feb 9 22:33:56 2011 -0800
Show a tooltip for unavailable plugins
https://bugzilla.gnome.org/show_bug.cgi?id=511672
libpeas-gtk/peas-gtk-plugin-manager-store.c | 2 +-
libpeas-gtk/peas-gtk-plugin-manager-view.c | 50 +++++++++++++++++++++++++-
libpeas/peas-engine.c | 31 +++++++++++++---
libpeas/peas-plugin-info-priv.h | 2 +
libpeas/peas-plugin-info.c | 25 ++++++++++++-
libpeas/peas-plugin-info.h | 31 +++++++++++++++-
tests/libpeas/engine.c | 29 +++++++++++++--
tests/libpeas/plugin-info.c | 8 +++-
tests/libpeas/plugins/Makefile.am | 1 +
tests/libpeas/plugins/nonexistent-dep.plugin | 9 +++++
10 files changed, 174 insertions(+), 14 deletions(-)
---
diff --git a/libpeas-gtk/peas-gtk-plugin-manager-store.c b/libpeas-gtk/peas-gtk-plugin-manager-store.c
index 8109e43..6be2436 100644
--- a/libpeas-gtk/peas-gtk-plugin-manager-store.c
+++ b/libpeas-gtk/peas-gtk-plugin-manager-store.c
@@ -66,7 +66,7 @@ update_plugin (PeasGtkPluginManagerStore *store,
GdkPixbuf *icon_pixbuf = NULL;
loaded = peas_plugin_info_is_loaded (info);
- available = peas_plugin_info_is_available (info);
+ available = peas_plugin_info_is_available (info, NULL);
builtin = peas_plugin_info_is_builtin (info);
if (peas_plugin_info_get_description (info) == NULL)
diff --git a/libpeas-gtk/peas-gtk-plugin-manager-view.c b/libpeas-gtk/peas-gtk-plugin-manager-view.c
index 6aa5d04..a7afa90 100644
--- a/libpeas-gtk/peas-gtk-plugin-manager-view.c
+++ b/libpeas-gtk/peas-gtk-plugin-manager-view.c
@@ -278,7 +278,7 @@ create_popup_menu (PeasGtkPluginManagerView *view)
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
peas_plugin_info_is_loaded (info));
g_signal_connect (item, "toggled", G_CALLBACK (enabled_menu_cb), view);
- gtk_widget_set_sensitive (item, peas_plugin_info_is_available (info) &&
+ gtk_widget_set_sensitive (item, peas_plugin_info_is_available (info, NULL) &&
!peas_plugin_info_is_builtin (info));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
@@ -454,6 +454,8 @@ peas_gtk_plugin_manager_view_init (PeasGtkPluginManagerView *view)
G_CALLBACK (plugin_list_changed_cb),
view);
+ gtk_widget_set_has_tooltip (GTK_WIDGET (view), TRUE);
+
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
@@ -545,6 +547,51 @@ peas_gtk_plugin_manager_view_popup_menu (GtkWidget *widget)
return TRUE;
}
+static gboolean
+peas_gtk_plugin_manager_view_query_tooltip (GtkWidget *widget,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip)
+{
+ PeasGtkPluginManagerView *view = PEAS_GTK_PLUGIN_MANAGER_VIEW (widget);
+ gboolean is_row;
+ GtkTreeIter iter;
+ PeasPluginInfo *info;
+ GError *error = NULL;
+
+ is_row = gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (widget),
+ &x, &y, keyboard_mode,
+ NULL, NULL, &iter);
+
+ if (!is_row)
+ return FALSE;
+
+ convert_iter_to_child_iter (view, &iter);
+
+ info = peas_gtk_plugin_manager_store_get_plugin (view->priv->store, &iter);
+
+ if (!peas_plugin_info_is_available (info, &error))
+ {
+ gchar *message;
+
+ message = g_strdup_printf (_("<b>The plugin '%s' could not be loaded</b>\n"
+ "An error occurred: %s"),
+ peas_plugin_info_get_name (info),
+ error->message);
+
+ gtk_tooltip_set_markup (tooltip, message);
+
+ g_free (message);
+ g_error_free (error);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
static void
peas_gtk_plugin_manager_view_row_activated (GtkTreeView *tree_view,
GtkTreePath *path,
@@ -646,6 +693,7 @@ peas_gtk_plugin_manager_view_class_init (PeasGtkPluginManagerViewClass *klass)
widget_class->button_press_event = peas_gtk_plugin_manager_view_button_press_event;
widget_class->popup_menu = peas_gtk_plugin_manager_view_popup_menu;
+ widget_class->query_tooltip = peas_gtk_plugin_manager_view_query_tooltip;
tree_view_class->row_activated = peas_gtk_plugin_manager_view_row_activated;
diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c
index e59e8c8..af96bf8 100644
--- a/libpeas/peas-engine.c
+++ b/libpeas/peas-engine.c
@@ -768,7 +768,7 @@ load_plugin (PeasEngine *engine,
if (peas_plugin_info_is_loaded (info))
return TRUE;
- if (!peas_plugin_info_is_available (info))
+ if (!peas_plugin_info_is_available (info, NULL))
return FALSE;
/* We set the plugin info as loaded before trying to load the dependencies,
@@ -782,11 +782,23 @@ load_plugin (PeasEngine *engine,
if (!dep_info)
{
g_warning ("Plugin not found: %s", dependencies[i]);
+ g_set_error (&info->error,
+ PEAS_PLUGIN_INFO_ERROR,
+ PEAS_PLUGIN_INFO_ERROR_DEP_NOT_FOUND,
+ _("Dependency '%s' was not found"),
+ dependencies[i]);
goto error;
}
if (!peas_engine_load_plugin (engine, dep_info))
- goto error;
+ {
+ g_set_error (&info->error,
+ PEAS_PLUGIN_INFO_ERROR,
+ PEAS_PLUGIN_INFO_ERROR_LOADING_FAILED,
+ _("Dependency '%s' failed to load"),
+ dep_info->name);
+ goto error;
+ }
}
loader = get_plugin_loader (engine, info);
@@ -795,12 +807,21 @@ load_plugin (PeasEngine *engine,
{
g_warning ("Could not find loader '%s' for plugin '%s'",
info->loader, info->name);
+ g_set_error (&info->error,
+ PEAS_PLUGIN_INFO_ERROR,
+ PEAS_PLUGIN_INFO_ERROR_LOADER_NOT_FOUND,
+ _("Plugin loader '%s' was not found"),
+ info->loader);
goto error;
}
if (!peas_plugin_loader_load (loader, info))
{
g_warning ("Error loading plugin '%s'", info->name);
+ g_set_error (&info->error,
+ PEAS_PLUGIN_INFO_ERROR,
+ PEAS_PLUGIN_INFO_ERROR_LOADING_FAILED,
+ _("Failed to load"));
goto error;
}
@@ -839,7 +860,7 @@ peas_engine_load_plugin (PeasEngine *engine,
{
g_return_val_if_fail (info != NULL, FALSE);
- if (!peas_plugin_info_is_available (info))
+ if (!peas_plugin_info_is_available (info, NULL))
return FALSE;
if (peas_plugin_info_is_loaded (info))
@@ -859,7 +880,7 @@ peas_engine_unload_plugin_real (PeasEngine *engine,
PeasPluginLoader *loader;
if (!peas_plugin_info_is_loaded (info) ||
- !peas_plugin_info_is_available (info))
+ !peas_plugin_info_is_available (info, NULL))
return;
/* We set the plugin info as unloaded before trying to unload the
@@ -1133,7 +1154,7 @@ peas_engine_set_loaded_plugins (PeasEngine *engine,
gboolean is_loaded;
gboolean to_load;
- if (!peas_plugin_info_is_available (info))
+ if (!peas_plugin_info_is_available (info, NULL))
continue;
module_name = peas_plugin_info_get_module_name (info);
diff --git a/libpeas/peas-plugin-info-priv.h b/libpeas/peas-plugin-info-priv.h
index 6240e59..b617b84 100644
--- a/libpeas/peas-plugin-info-priv.h
+++ b/libpeas/peas-plugin-info-priv.h
@@ -48,6 +48,8 @@ struct _PeasPluginInfo {
guint iage;
GHashTable *keys;
+ GError *error;
+
gint loaded : 1;
/* A plugin is unavailable if it is not possible to load it
due to an error loading the plugin module (e.g. for Python plugins
diff --git a/libpeas/peas-plugin-info.c b/libpeas/peas-plugin-info.c
index 6dd94a7..478b60a 100644
--- a/libpeas/peas-plugin-info.c
+++ b/libpeas/peas-plugin-info.c
@@ -89,6 +89,8 @@ _peas_plugin_info_unref (PeasPluginInfo *info)
g_free (info->version);
g_free (info->help_uri);
g_strfreev (info->authors);
+ if (info->error != NULL)
+ g_error_free (info->error);
g_free (info);
}
@@ -106,6 +108,18 @@ peas_plugin_info_get_type (void)
return the_type;
}
+GQuark
+peas_plugin_info_error_quark (void)
+{
+ static volatile gsize quark = 0;
+
+ if (g_once_init_enter (&quark))
+ g_once_init_leave (&quark,
+ g_quark_from_static_string ("peas-plugin-info-error"));
+
+ return quark;
+}
+
static void
value_free (GValue *value)
{
@@ -361,19 +375,28 @@ peas_plugin_info_is_loaded (const PeasPluginInfo *info)
/**
* peas_plugin_info_is_available:
* @info: A #PeasPluginInfo.
+ * @error: A #GError.
*
* Check if the plugin is available.
*
* A plugin is marked as not available when there is no loader available to
* load it, or when there has been an error when trying to load it previously.
+ * If not available then @error will be set.
*
* Returns: %TRUE if the plugin is available.
*/
gboolean
-peas_plugin_info_is_available (const PeasPluginInfo *info)
+peas_plugin_info_is_available (const PeasPluginInfo *info,
+ GError **error)
{
g_return_val_if_fail (info != NULL, FALSE);
+ /* Uses g_propagate_error() so we get the right warning
+ * in the case that *error != NULL
+ */
+ if (error != NULL && info->error != NULL)
+ g_propagate_error (error, g_error_copy (info->error));
+
return info->available != FALSE;
}
diff --git a/libpeas/peas-plugin-info.h b/libpeas/peas-plugin-info.h
index 0dfe8ed..249d2d3 100644
--- a/libpeas/peas-plugin-info.h
+++ b/libpeas/peas-plugin-info.h
@@ -31,6 +31,33 @@ G_BEGIN_DECLS
#define PEAS_PLUGIN_INFO(obj) ((PeasPluginInfo *) (obj))
/**
+ * PEAS_PLUGIN_INFO_ERROR:
+ *
+ * Error domain for PeasPluginInfo. Errors in this domain will
+ * be from the PeasPluginInfoError enumeration. See GError for
+ * more information on error domains.
+ */
+#define PEAS_PLUGIN_INFO_ERROR peas_plugin_info_error_quark ()
+
+/**
+ * PeasPluginInfoError:
+ * @PEAS_PLUGIN_INFO_ERROR_LOADING_FAILED:
+ * The plugin failed to load.
+ * @PEAS_PLUGIN_INFO_ERROR_LOADER_NOT_FOUND:
+ * The plugin's loader was not found.
+ * @PEAS_PLUGIN_INFO_ERROR_DEP_NOT_FOUND:
+ * A dependancy of the plugin was not found.
+ * @PEAS_PLUGIN_INFO_ERROR_DEP_LOADING_FAILED:
+ * A dependancy of the plugin failed to load.
+ */
+typedef enum {
+ PEAS_PLUGIN_INFO_ERROR_LOADING_FAILED,
+ PEAS_PLUGIN_INFO_ERROR_LOADER_NOT_FOUND,
+ PEAS_PLUGIN_INFO_ERROR_DEP_NOT_FOUND,
+ PEAS_PLUGIN_INFO_ERROR_DEP_LOADING_FAILED
+} PeasPluginInfoError;
+
+/**
* PeasPluginInfo:
*
* The #PeasPluginInfo structure contains only private data and should only
@@ -39,9 +66,11 @@ G_BEGIN_DECLS
typedef struct _PeasPluginInfo PeasPluginInfo;
GType peas_plugin_info_get_type (void) G_GNUC_CONST;
+GQuark peas_plugin_info_error_quark (void);
gboolean peas_plugin_info_is_loaded (const PeasPluginInfo *info);
-gboolean peas_plugin_info_is_available (const PeasPluginInfo *info);
+gboolean peas_plugin_info_is_available (const PeasPluginInfo *info,
+ GError **error);
gboolean peas_plugin_info_is_builtin (const PeasPluginInfo *info);
const gchar *peas_plugin_info_get_module_name (const PeasPluginInfo *info);
diff --git a/tests/libpeas/engine.c b/tests/libpeas/engine.c
index f7054d0..9b8e97d 100644
--- a/tests/libpeas/engine.c
+++ b/tests/libpeas/engine.c
@@ -130,6 +130,23 @@ test_engine_load_plugin_with_self_dep (PeasEngine *engine)
}
static void
+test_engine_load_plugin_with_nonexistent_dep (PeasEngine *engine)
+{
+ GError *error = NULL;
+ PeasPluginInfo *info;
+
+ info = peas_engine_get_plugin_info (engine, "nonexistent-dep");
+
+ g_assert (!peas_engine_load_plugin (engine, info));
+ g_assert (!peas_plugin_info_is_loaded (info));
+ g_assert (!peas_plugin_info_is_available (info, &error));
+ g_assert_error (error, PEAS_PLUGIN_INFO_ERROR,
+ PEAS_PLUGIN_INFO_ERROR_DEP_NOT_FOUND);
+
+ g_error_free (error);
+}
+
+static void
test_engine_unload_plugin (PeasEngine *engine)
{
PeasPluginInfo *info;
@@ -181,7 +198,7 @@ test_engine_unavailable_plugin (PeasEngine *engine)
g_assert (!peas_engine_load_plugin (engine, info));
g_assert (!peas_plugin_info_is_loaded (info));
- g_assert (!peas_plugin_info_is_available (info));
+ g_assert (!peas_plugin_info_is_available (info, NULL));
}
static void
@@ -267,13 +284,18 @@ test_engine_loaded_plugins (PeasEngine *engine)
static void
test_engine_nonexistent_loader (PeasEngine *engine)
{
+ GError *error = NULL;
PeasPluginInfo *info;
info = peas_engine_get_plugin_info (engine, "nonexistent-loader");
g_assert (!peas_engine_load_plugin (engine, info));
g_assert (!peas_plugin_info_is_loaded (info));
- g_assert (!peas_plugin_info_is_available (info));
+ g_assert (!peas_plugin_info_is_available (info, &error));
+ g_assert_error (error, PEAS_PLUGIN_INFO_ERROR,
+ PEAS_PLUGIN_INFO_ERROR_LOADER_NOT_FOUND);
+
+ g_error_free (error);
}
static void
@@ -291,7 +313,7 @@ test_engine_disable_loader (PeasEngine *engine)
g_assert (!peas_engine_load_plugin (engine, info));
g_assert (!peas_plugin_info_is_loaded (info));
- g_assert (!peas_plugin_info_is_available (info));
+ g_assert (!peas_plugin_info_is_available (info, NULL));
info = peas_engine_get_plugin_info (engine, "loadable");
@@ -370,6 +392,7 @@ main (int argc,
TEST ("load-plugin", load_plugin);
TEST ("load-plugin-with-dep", load_plugin_with_dep);
TEST ("load-plugin-with-self-dep", load_plugin_with_self_dep);
+ TEST ("load-plugin-with-nonexistent-dep", load_plugin_with_nonexistent_dep);
TEST ("unload-plugin", unload_plugin);
TEST ("unload-plugin-with-dep", unload_plugin_with_dep);
diff --git a/tests/libpeas/plugin-info.c b/tests/libpeas/plugin-info.c
index 88d6a2d..6992386 100644
--- a/tests/libpeas/plugin-info.c
+++ b/tests/libpeas/plugin-info.c
@@ -61,12 +61,14 @@ static void
test_plugin_info_verify_full_info (PeasEngine *engine)
{
PeasPluginInfo *info;
+ GError *error = NULL;
const gchar **authors;
info = peas_engine_get_plugin_info (engine, "full-info");
g_assert (!peas_plugin_info_is_loaded (info));
- g_assert (peas_plugin_info_is_available (info));
+ g_assert (peas_plugin_info_is_available (info, &error));
+ g_assert_no_error (error);
g_assert (peas_plugin_info_is_builtin (info));
g_assert_cmpstr (peas_plugin_info_get_module_name (info), ==, "full-info");
@@ -95,11 +97,13 @@ static void
test_plugin_info_verify_min_info (PeasEngine *engine)
{
PeasPluginInfo *info;
+ GError *error = NULL;
info = peas_engine_get_plugin_info (engine, "min-info");
g_assert (!peas_plugin_info_is_loaded (info));
- g_assert (peas_plugin_info_is_available (info));
+ g_assert (peas_plugin_info_is_available (info, &error));
+ g_assert_no_error (error);
g_assert (!peas_plugin_info_is_builtin (info));
g_assert_cmpstr (peas_plugin_info_get_module_name (info), ==, "min-info");
diff --git a/tests/libpeas/plugins/Makefile.am b/tests/libpeas/plugins/Makefile.am
index 70f9066..8252c99 100644
--- a/tests/libpeas/plugins/Makefile.am
+++ b/tests/libpeas/plugins/Makefile.am
@@ -13,6 +13,7 @@ noinst_DATA = \
info-missing-module.plugin \
info-missing-name.plugin \
loader-disabled.plugin \
+ nonexistent-dep.plugin \
nonexistent-loader.plugin \
os-dependant-help.plugin
diff --git a/tests/libpeas/plugins/nonexistent-dep.plugin b/tests/libpeas/plugins/nonexistent-dep.plugin
new file mode 100644
index 0000000..1cfc76e
--- /dev/null
+++ b/tests/libpeas/plugins/nonexistent-dep.plugin
@@ -0,0 +1,9 @@
+[Plugin]
+Module=nonexistent-dep
+Depends=does-not-exist
+IAge=2
+Name=Nonexistent Dependency
+Description=This plugin has a nonexistent dependency.
+Authors=Garrett Regier
+Copyright=Copyright © 2011 Garrett Regier
+Website=http://live.gnome.org/Libpeas
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]