[gnome-software] Add UI to support unavailable packages
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Add UI to support unavailable packages
- Date: Thu, 11 Dec 2014 16:54:35 +0000 (UTC)
commit 2a6d6ac3f8c020f3add926c04b73e9f843a9ab63
Author: Richard Hughes <richard hughsie com>
Date: Thu Dec 11 16:49:53 2014 +0000
Add UI to support unavailable packages
data/org.gnome.software.gschema.xml | 5 ++
src/gs-app-row.c | 13 +++-
src/gs-shell-details.c | 21 ++++++-
src/gs-shell-search.c | 33 +++++++++-
src/gs-utils.c | 120 +++++++++++++++++++++++++++++++++++
src/gs-utils.h | 3 +
6 files changed, 190 insertions(+), 5 deletions(-)
---
diff --git a/data/org.gnome.software.gschema.xml b/data/org.gnome.software.gschema.xml
index bfd9fb4..559ab8e 100644
--- a/data/org.gnome.software.gschema.xml
+++ b/data/org.gnome.software.gschema.xml
@@ -19,6 +19,11 @@
<summary>Applications require AppData to be shown in the search results</summary>
<description>If enabled applications require a long description before they are shown to the user in
the search results.</description>
</key>
+ <key name="prompt-for-nonfree" type="b">
+ <default>true</default>
+ <summary>Non-free applications show a warning dialog before install</summary>
+ <description>When non-free applications are installed a warning dialog can be shown. This controls if
that dialog is supressed.</description>
+ </key>
<key name="check-timestamp" type="x">
<default>0</default>
<summary>The last update check timestamp</summary>
diff --git a/src/gs-app-row.c b/src/gs-app-row.c
index e306731..4d607a4 100644
--- a/src/gs-app-row.c
+++ b/src/gs-app-row.c
@@ -186,9 +186,16 @@ gs_app_row_refresh (GsAppRow *app_row)
switch (gs_app_get_state (app_row->priv->app)) {
case AS_APP_STATE_UNAVAILABLE:
gtk_widget_set_visible (priv->button, TRUE);
- /* TRANSLATORS: this is a button next to the search results that
- * allows the application to be easily installed */
- gtk_button_set_label (GTK_BUTTON (priv->button), _("Visit website"));
+ if (gs_app_get_url (app_row->priv->app, AS_URL_KIND_MISSING) != NULL) {
+ /* TRANSLATORS: this is a button next to the search results that
+ * allows the application to be easily installed */
+ gtk_button_set_label (GTK_BUTTON (priv->button), _("Visit website"));
+ } else {
+ /* TRANSLATORS: this is a button next to the search results that
+ * allows the application to be easily installed.
+ * The ellipsis indicates that further steps are required */
+ gtk_button_set_label (GTK_BUTTON (priv->button), _("Install…"));
+ }
break;
case AS_APP_STATE_QUEUED_FOR_INSTALL:
gtk_widget_set_visible (priv->label, TRUE);
diff --git a/src/gs-shell-details.c b/src/gs-shell-details.c
index d95dd35..9657e11 100644
--- a/src/gs-shell-details.c
+++ b/src/gs-shell-details.c
@@ -189,9 +189,20 @@ gs_shell_details_switch_to (GsShellDetails *shell_details)
case AS_APP_STATE_INSTALLED:
case AS_APP_STATE_REMOVING:
case AS_APP_STATE_UPDATABLE:
- case AS_APP_STATE_UNAVAILABLE:
gtk_widget_set_visible (priv->button_install, FALSE);
break;
+ case AS_APP_STATE_UNAVAILABLE:
+ if (gs_app_get_url (priv->app, AS_URL_KIND_MISSING) != NULL) {
+ gtk_widget_set_visible (priv->button_install, FALSE);
+ } else {
+ gtk_widget_set_visible (priv->button_install, TRUE);
+ /* TRANSLATORS: this is a button that allows the apps to
+ * be installed.
+ * The ellipsis indicates that further steps are required,
+ * e.g. enabling software sources or the like */
+ gtk_button_set_label (GTK_BUTTON (priv->button_install), _("_Install…"));
+ }
+ break;
default:
g_warning ("App unexpectedly in state %s",
as_app_state_to_string (state));
@@ -1182,6 +1193,14 @@ gs_shell_details_app_install (GsShellDetails *shell_details, GsApp *app)
{
GsShellDetailsPrivate *priv = shell_details->priv;
GsShellDetailsHelper *helper;
+ GtkResponseType response;
+
+ /* probably non-free */
+ if (gs_app_get_state (app) == AS_APP_STATE_UNAVAILABLE) {
+ response = gs_app_notify_unavailable (app, gs_shell_get_window (priv->shell));
+ if (response != GTK_RESPONSE_OK)
+ return;
+ }
helper = g_new0 (GsShellDetailsHelper, 1);
helper->shell_details = g_object_ref (shell_details);
diff --git a/src/gs-shell-search.c b/src/gs-shell-search.c
index 81a2f42..f9ffb41 100644
--- a/src/gs-shell-search.c
+++ b/src/gs-shell-search.c
@@ -219,6 +219,32 @@ gs_shell_search_show_missing_url (GsApp *app)
}
/**
+ * gs_shell_search_install_unavailable_app:
+ **/
+static void
+gs_shell_search_install_unavailable_app (GsShellSearch *shell_search, GsApp *app)
+{
+ GsShellSearchPrivate *priv = shell_search->priv;
+ GtkResponseType response;
+ GsShellSearchHelper *helper;
+
+ /* get confirmation */
+ response = gs_app_notify_unavailable (app, gs_shell_get_window (priv->shell));
+ if (response == GTK_RESPONSE_OK) {
+ g_debug ("installing %s", gs_app_get_id (app));
+ helper = g_new0 (GsShellSearchHelper, 1);
+ helper->shell_search = g_object_ref (shell_search);
+ helper->app = g_object_ref (app);
+ gs_plugin_loader_app_action_async (priv->plugin_loader,
+ app,
+ GS_PLUGIN_LOADER_ACTION_INSTALL,
+ priv->cancellable,
+ gs_shell_search_app_installed_cb,
+ helper);
+ }
+}
+
+/**
* gs_shell_search_app_row_clicked_cb:
**/
static void
@@ -231,8 +257,13 @@ gs_shell_search_app_row_clicked_cb (GsAppRow *app_row,
gs_shell_search_app_install (shell_search, app);
else if (gs_app_get_state (app) == AS_APP_STATE_INSTALLED)
gs_shell_search_app_remove (shell_search, app);
- else if (gs_app_get_state (app) == AS_APP_STATE_UNAVAILABLE)
+ else if (gs_app_get_state (app) == AS_APP_STATE_UNAVAILABLE) {
+ if (gs_app_get_url (app, AS_URL_KIND_MISSING) == NULL) {
+ gs_shell_search_install_unavailable_app (shell_search, app);
+ return;
+ }
gs_shell_search_show_missing_url (app);
+ }
}
/**
diff --git a/src/gs-utils.c b/src/gs-utils.c
index 01fa2d7..f12bb3f 100644
--- a/src/gs-utils.c
+++ b/src/gs-utils.c
@@ -189,6 +189,126 @@ gs_app_notify_failed_modal (GsApp *app,
gtk_window_present (GTK_WINDOW (dialog));
}
+/**
+ * gs_app_notify_unavailable_nonfree:
+ **/
+static GtkResponseType
+gs_app_notify_unavailable_nonfree (GsApp *app, GtkWindow *parent)
+{
+ GtkResponseType response;
+ GtkWidget *dialog;
+ _cleanup_object_unref_ GSettings *settings = NULL;
+ _cleanup_string_free_ GString *body = NULL;
+ _cleanup_string_free_ GString *title = NULL;
+
+ /* check if the user has already dismissed */
+ settings = g_settings_new ("org.gnome.software");
+ if (!g_settings_get_boolean (settings, "prompt-for-nonfree"))
+ return GTK_RESPONSE_OK;
+
+ title = g_string_new ("");
+ g_string_append_printf (title, "<b>%s</b>",
+ /* TRANSLATORS: window title, nonfree in this
+ * case refers to Free and Open Source */
+ _("You're About to Install Non-Free Software"));
+ dialog = gtk_message_dialog_new (parent,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_CANCEL,
+ NULL);
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), title->str);
+
+ body = g_string_new ("");
+ g_string_append_printf (body,
+ /* TRANSLATORS: the replacements are as follows:
+ * 1. Application name, e.g. "Firefox"
+ * 2. Start of hypertext e.g. <a>
+ * 3. End of hypertext e.g. </a> */
+ _("%s is not %sfree and open source software%s."),
+ gs_app_get_name (app),
+ "<a href=\"http://en.wikipedia.org/wiki/Free_and_open-source_software\">",
+ "</a>");
+ g_string_append (body, " ");
+ g_string_append (body,
+ /* TRANSLATORS: Laws are geographical, urgh... */
+ _("Depending on your country of residence, "
+ "installing it could make you liable to prosecution."));
+ g_string_append (body, "\n");
+ g_string_append (body,
+ /* TRANSLATORS: ...and you need to ask for advice */
+ _("If you are uncertain about this, "
+ "you should obtain legal advice."));
+
+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", body->str);
+ /* TRANSLATORS: this is button text to not ask about non-free content again */
+ gtk_dialog_add_button (GTK_DIALOG (dialog), _("Don't Warn Again"), GTK_RESPONSE_YES);
+ /* TRANSLATORS: this is button text to enable the repo and install the app */
+ gtk_dialog_add_button (GTK_DIALOG (dialog), _("Install"), GTK_RESPONSE_OK);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ if (response == GTK_RESPONSE_YES) {
+ response = GTK_RESPONSE_OK;
+ g_settings_set_boolean (settings, "prompt-for-nonfree", FALSE);
+ }
+ gtk_widget_destroy (dialog);
+ return response;
+}
+
+/**
+ * gs_app_notify_unavailable_other:
+ **/
+static GtkResponseType
+gs_app_notify_unavailable_other (GsApp *app, GtkWindow *parent)
+{
+ GtkResponseType response;
+ GtkWidget *dialog;
+ _cleanup_string_free_ GString *body = NULL;
+ _cleanup_string_free_ GString *title = NULL;
+
+ title = g_string_new ("");
+ g_string_append_printf (title, "<b>%s</b>",
+ /* TRANSLATORS: window title, additional in this
+ * case means not-currently-enabled */
+ _("Enable Additional Software Source?"));
+ dialog = gtk_message_dialog_new (parent,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_CANCEL,
+ NULL);
+ gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), title->str);
+
+ body = g_string_new ("");
+ g_string_append_printf (body,
+ /* TRANSLATORS: the replacements are as follows:
+ * 1. Application name, e.g. "Firefox"
+ * 2. Software source name, e.g. fedora-optional */
+ _("%s is provided by %s."),
+ gs_app_get_name (app),
+ gs_app_get_origin (app));
+ g_string_append (body, "\n");
+ g_string_append (body,
+ /* TRANSLATORS: once the source is enabled it stays enabled */
+ _("Do you want to enable it?"));
+
+ gtk_message_dialog_format_secondary_markup (GTK_MESSAGE_DIALOG (dialog), "%s", body->str);
+ /* TRANSLATORS: this is button text to enable the repo and install the app */
+ gtk_dialog_add_button (GTK_DIALOG (dialog), _("Enable"), GTK_RESPONSE_OK);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ return response;
+}
+
+/**
+ * gs_app_notify_unavailable:
+ **/
+GtkResponseType
+gs_app_notify_unavailable (GsApp *app, GtkWindow *parent)
+{
+ /* this is very crude */
+ if (g_strstr_len (gs_app_get_licence (app), -1, "Proprietary") != NULL)
+ return gs_app_notify_unavailable_nonfree (app, parent);
+ return gs_app_notify_unavailable_other (app, parent);
+}
+
guint
gs_string_replace (GString *string, const gchar *search, const gchar *replace)
{
diff --git a/src/gs-utils.h b/src/gs-utils.h
index aeac877..a92f670 100644
--- a/src/gs-utils.h
+++ b/src/gs-utils.h
@@ -39,6 +39,9 @@ void gs_app_notify_failed_modal (GsApp *app,
GtkWindow *parent_window,
GsPluginLoaderAction action,
const GError *error);
+GtkResponseType
+ gs_app_notify_unavailable (GsApp *app,
+ GtkWindow *parent);
guint gs_string_replace (GString *string,
const gchar *search,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]