[yelp] Automatically install packages for missing documents
- From: Shaun McCance <shaunm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [yelp] Automatically install packages for missing documents
- Date: Wed, 5 Jan 2011 15:16:30 +0000 (UTC)
commit 231a2bf510a30b19419ef29f577eb952a7498bcc
Author: Shaun McCance <shaunm gnome org>
Date: Wed Jan 5 10:14:04 2011 -0500
Automatically install packages for missing documents
libyelp/yelp-view.c | 1 +
src/yelp-application.c | 168 +++++++++++++++++++++++++++++++++++++++---------
src/yelp-application.h | 6 ++-
src/yelp-window.c | 100 ++++++++++++++++++++++++----
4 files changed, 229 insertions(+), 46 deletions(-)
---
diff --git a/libyelp/yelp-view.c b/libyelp/yelp-view.c
index e30d263..292d963 100644
--- a/libyelp/yelp-view.c
+++ b/libyelp/yelp-view.c
@@ -1464,6 +1464,7 @@ view_show_error_page (YelpView *view,
left, iconsize, left, iconsize, left, iconsize,
titlecolor, title, error->message);
g_object_set (view, "state", YELP_VIEW_STATE_ERROR, NULL);
+ g_signal_emit (view, signals[LOADED], 0);
g_signal_handler_block (view, priv->navigation_requested);
webkit_web_view_load_string (WEBKIT_WEB_VIEW (view),
page,
diff --git a/src/yelp-application.c b/src/yelp-application.c
index cae00dd..713ef6a 100644
--- a/src/yelp-application.c
+++ b/src/yelp-application.c
@@ -45,6 +45,7 @@ static gboolean editor_mode = FALSE;
enum {
READ_LATER_CHANGED,
+ HELP_INSTALLED,
LAST_SIGNAL
};
static gint signals[LAST_SIGNAL] = { 0 };
@@ -171,6 +172,14 @@ yelp_application_class_init (YelpApplicationClass *klass)
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
+ signals[HELP_INSTALLED] =
+ g_signal_new ("help-installed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
g_type_class_add_private (klass, sizeof (YelpApplicationPrivate));
}
@@ -707,8 +716,8 @@ yelp_application_is_bookmarked (YelpBookmarks *bookmarks,
GSettings *settings;
YelpApplication *app = YELP_APPLICATION (bookmarks);
- g_return_if_fail (page_id);
- g_return_if_fail (doc_uri);
+ g_return_val_if_fail (page_id, FALSE);
+ g_return_val_if_fail (doc_uri, FALSE);
settings = application_get_doc_settings (app, doc_uri);
if (settings == NULL)
@@ -783,33 +792,6 @@ yelp_application_get_bookmarks (YelpApplication *app,
return g_settings_get_value (settings, "bookmarks");
}
-static void
-packages_installed (GDBusConnection *connection,
- GAsyncResult *res,
- YelpApplication *app)
-{
- GError *error = NULL;
- g_dbus_connection_call_finish (connection, res, &error);
- if (error) {
- const gchar *err = NULL;
- if (error->domain == G_DBUS_ERROR) {
- if (error->code == G_DBUS_ERROR_SERVICE_UNKNOWN)
- err = _("You do not have PackageKit installed. Package installation links require PackageKit.");
- else
- err = error->message;
- }
- if (err != NULL) {
- GtkWidget *dialog = gtk_message_dialog_new (NULL, 0,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_CLOSE,
- "%s", err);
- gtk_dialog_run ((GtkDialog *) dialog);
- gtk_widget_destroy (dialog);
- }
- g_error_free (error);
- }
-}
-
void
yelp_application_add_read_later (YelpApplication *app,
const gchar *doc_uri,
@@ -880,14 +862,140 @@ yelp_application_get_read_later (YelpApplication *app,
return g_settings_get_value (settings, "readlater");
}
+typedef struct _YelpHelpInstallInfo YelpHelpInstallInfo;
+struct _YelpHelpInstallInfo {
+ YelpApplication *app;
+ gchar *uri;
+};
+
+static void
+help_installed (GDBusConnection *connection,
+ GAsyncResult *res,
+ YelpHelpInstallInfo *info)
+{
+ GError *error = NULL;
+ g_dbus_connection_call_finish (connection, res, &error);
+
+ if (error != NULL)
+ g_error_free (error);
+ else
+ g_signal_emit (info->app, signals[HELP_INSTALLED], 0, info->uri);
+
+ g_free (info->uri);
+ g_object_unref (info->app);
+ g_free (info);
+}
+
+void
+yelp_application_install_help (YelpApplication *app,
+ const gchar *uri,
+ GtkWindow *window)
+{
+ const gchar * const *datadirs = g_get_system_data_dirs ();
+ YelpApplicationPrivate *priv = GET_PRIV (app);
+ gint datadirs_i;
+ GVariantBuilder *strv;
+ guint32 xid = 0;
+ gboolean ghelp;
+ const gchar *docname;
+ gchar *docbook, *fname;
+ YelpHelpInstallInfo *info;
+
+ if (g_str_has_prefix (uri, "help:")) {
+ ghelp = FALSE;
+ docname = (const gchar *) uri + 5;
+ }
+ else if (g_str_has_prefix (uri, "ghelp:")) {
+ ghelp = TRUE;
+ docname = (const gchar *) uri + 6;
+ }
+ else
+ return;
+ docbook = g_strconcat (docname, ".xml", NULL);
+
+ info = g_new0 (YelpHelpInstallInfo, 1);
+ info->app = g_object_ref (app);
+ info->uri = g_strdup (uri);
+
+ if (window != NULL)
+ xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (window)));
+
+ strv = g_variant_builder_new (G_VARIANT_TYPE ("as"));
+ for (datadirs_i = 0; datadirs[datadirs_i] != NULL; datadirs_i++) {
+ if (ghelp) {
+ fname = g_build_filename (datadirs[datadirs_i], "gnome", "help",
+ docname, "C", "index.page", NULL);
+ g_variant_builder_add (strv, "s", fname);
+ g_free (fname);
+ fname = g_build_filename (datadirs[datadirs_i], "gnome", "help",
+ docname, "C", docbook, NULL);
+ g_variant_builder_add (strv, "s", fname);
+ g_free (fname);
+ }
+ else {
+ fname = g_build_filename (datadirs[datadirs_i], "help", "C",
+ docname, "index.page", NULL);
+ g_variant_builder_add (strv, "s", fname);
+ g_free (fname);
+ fname = g_build_filename (datadirs[datadirs_i], "help", "C",
+ docname, "index.docbook", NULL);
+ g_variant_builder_add (strv, "s", fname);
+ g_free (fname);
+ }
+ }
+ g_free (docbook);
+ g_dbus_connection_call (priv->connection,
+ "org.freedesktop.PackageKit",
+ "/org/freedesktop/PackageKit",
+ "org.freedesktop.PackageKit.Modify",
+ "InstallProvideFiles",
+ g_variant_new ("(uass)", xid, strv, "hide-warning"),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ G_MAXINT, NULL,
+ (GAsyncReadyCallback) help_installed,
+ info);
+ g_variant_builder_unref (strv);
+}
+
+static void
+packages_installed (GDBusConnection *connection,
+ GAsyncResult *res,
+ YelpApplication *app)
+{
+ GError *error = NULL;
+ g_dbus_connection_call_finish (connection, res, &error);
+ if (error) {
+ const gchar *err = NULL;
+ if (error->domain == G_DBUS_ERROR) {
+ if (error->code == G_DBUS_ERROR_SERVICE_UNKNOWN)
+ err = _("You do not have PackageKit. Package install links require PackageKit.");
+ else
+ err = error->message;
+ }
+ if (err != NULL) {
+ GtkWidget *dialog = gtk_message_dialog_new (NULL, 0,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ "%s", err);
+ gtk_dialog_run ((GtkDialog *) dialog);
+ gtk_widget_destroy (dialog);
+ }
+ g_error_free (error);
+ }
+}
+
void
yelp_application_install_package (YelpApplication *app,
const gchar *pkg,
- const gchar *alt)
+ const gchar *alt,
+ GtkWindow *window)
{
GVariantBuilder *strv;
YelpApplicationPrivate *priv = GET_PRIV (app);
guint32 xid = 0;
+ if (window != NULL)
+ xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (window)));
strv = g_variant_builder_new (G_VARIANT_TYPE ("as"));
g_variant_builder_add (strv, "s", pkg);
g_dbus_connection_call (priv->connection,
diff --git a/src/yelp-application.h b/src/yelp-application.h
index 35ccbde..fa95294 100644
--- a/src/yelp-application.h
+++ b/src/yelp-application.h
@@ -88,8 +88,12 @@ void yelp_application_remove_read_later (YelpApplication *app,
const gchar *full_uri);
GVariant * yelp_application_get_read_later (YelpApplication *app,
const gchar *doc_uri);
+void yelp_application_install_help (YelpApplication *app,
+ const gchar *uri,
+ GtkWindow *window);
void yelp_application_install_package (YelpApplication *app,
const gchar *pkg,
- const gchar *alt);
+ const gchar *alt,
+ GtkWindow *window);
#endif /* __YELP_APPLICATION_H__ */
diff --git a/src/yelp-window.c b/src/yelp-window.c
index 7605d11..a0febbf 100644
--- a/src/yelp-window.c
+++ b/src/yelp-window.c
@@ -95,6 +95,9 @@ static void app_read_later_changed (YelpApplication *app,
static void app_bookmarks_changed (YelpApplication *app,
const gchar *doc_uri,
YelpWindow *window);
+static void app_help_installed (YelpApplication *app,
+ const gchar *doc_uri,
+ YelpWindow *window);
static void window_set_bookmarks (YelpWindow *window,
const gchar *doc_uri);
static void window_set_bookmark_action (YelpWindow *window);
@@ -226,6 +229,9 @@ struct _YelpWindowPrivate {
GtkListStore *bookmarks_store;
gulong bookmarks_changed;
+ gulong read_later_changed;
+ gulong help_installed;
+
/* no refs on these, owned by containers */
YelpView *view;
GtkWidget *vbox_view;
@@ -368,11 +374,21 @@ yelp_window_dispose (GObject *object)
priv->bookmark_actions = NULL;
}
+ if (priv->read_later_changed) {
+ g_source_remove (priv->read_later_changed);
+ priv->read_later_changed = 0;
+ }
+
if (priv->bookmarks_changed) {
g_source_remove (priv->bookmarks_changed);
priv->bookmarks_changed = 0;
}
+ if (priv->help_installed) {
+ g_source_remove (priv->help_installed);
+ priv->help_installed = 0;
+ }
+
if (priv->align_location) {
g_object_unref (priv->align_location);
priv->align_location = NULL;
@@ -468,7 +484,9 @@ window_construct (YelpWindow *window)
yelp_view_add_link_action (priv->view, action,
(YelpViewActionValidFunc) view_is_xref_uri,
window);
- g_signal_connect (priv->application, "read-later-changed", G_CALLBACK (app_read_later_changed), window);
+ priv->read_later_changed =
+ g_signal_connect (priv->application, "read-later-changed",
+ G_CALLBACK (app_read_later_changed), window);
priv->vbox_full = gtk_vbox_new (FALSE, 3);
gtk_container_add (GTK_CONTAINER (window), priv->vbox_full);
@@ -606,6 +624,10 @@ window_construct (YelpWindow *window)
gtk_drag_dest_add_uri_targets (GTK_WIDGET (window));
g_signal_connect (window, "drag-data-received",
G_CALLBACK (window_drag_received), NULL);
+
+ priv->help_installed =
+ g_signal_connect (priv->application, "help-installed",
+ G_CALLBACK (app_help_installed), window);
}
/******************************************************************************/
@@ -883,6 +905,36 @@ app_bookmarks_changed (YelpApplication *app,
g_object_unref (uri);
}
+static void
+app_help_installed (YelpApplication *app,
+ const gchar *doc_uri,
+ YelpWindow *window)
+{
+ YelpViewState state;
+ YelpWindowPrivate *priv = GET_PRIV (window);
+
+ g_object_get (priv->view, "state", &state, NULL);
+
+ if (state == YELP_VIEW_STATE_ERROR) {
+ YelpUri *uri;
+ gchar *view_doc_uri;
+
+ g_object_get (priv->view, "yelp-uri", &uri, NULL);
+ if (uri == NULL)
+ return;
+ view_doc_uri = yelp_uri_get_document_uri (uri);
+
+ if (g_str_equal (view_doc_uri, doc_uri)) {
+ gchar *fulluri = yelp_uri_get_canonical_uri (uri);
+ yelp_view_load (priv->view, fulluri);
+ g_free (fulluri);
+ }
+
+ g_free (view_doc_uri);
+ g_object_unref (uri);
+ }
+}
+
typedef struct _YelpMenuEntry YelpMenuEntry;
struct _YelpMenuEntry {
gchar *page_id;
@@ -1429,7 +1481,8 @@ view_external_uri (YelpView *view,
if (g_str_has_prefix (struri, "install:")) {
YelpWindowPrivate *priv = GET_PRIV (window);
gchar *pkg = struri + 8;
- yelp_application_install_package (priv->application, pkg, "");
+ yelp_application_install_package (priv->application, pkg, "",
+ (GtkWindow *) window);
}
else
g_app_info_launch_default_for_uri (struri, NULL, NULL);
@@ -1452,28 +1505,45 @@ view_loaded (YelpView *view,
{
YelpUri *uri;
- gchar *doc_uri, *page_id, *icon, *title;
+ gchar *doc_uri;
+ YelpViewState state;
YelpWindowPrivate *priv = GET_PRIV (window);
g_object_get (view,
"yelp-uri", &uri,
- "page-id", &page_id,
- "page-icon", &icon,
- "page-title", &title,
+ "state", &state,
NULL);
doc_uri = yelp_uri_get_document_uri (uri);
- yelp_application_update_bookmarks (priv->application,
- doc_uri,
- page_id,
- icon,
- title);
gdk_window_set_cursor (gtk_widget_get_window (GTK_WIDGET (window)), NULL);
- g_free (page_id);
- g_free (icon);
- g_free (title);
- app_read_later_changed (priv->application, doc_uri, window);
+ if (state == YELP_VIEW_STATE_ERROR) {
+ if (yelp_uri_get_document_type (uri) == YELP_URI_DOCUMENT_TYPE_NOT_FOUND) {
+ if (g_str_has_prefix (doc_uri, "ghelp:") ||
+ g_str_has_prefix (doc_uri, "help:")) {
+ yelp_application_install_help (priv->application, doc_uri,
+ (GtkWindow *) window);
+ }
+ }
+ }
+ else {
+ gchar *page_id, *icon, *title;
+ g_object_get (view,
+ "page-id", &page_id,
+ "page-icon", &icon,
+ "page-title", &title,
+ NULL);
+ yelp_application_update_bookmarks (priv->application,
+ doc_uri,
+ page_id,
+ icon,
+ title);
+ app_read_later_changed (priv->application, doc_uri, window);
+ g_free (page_id);
+ g_free (icon);
+ g_free (title);
+ }
+ g_free (doc_uri);
g_object_unref (uri);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]