[gnome-software] repos dialog: Rewrite according to latest mockups
- From: Kalev Lember <klember src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] repos dialog: Rewrite according to latest mockups
- Date: Wed, 14 Feb 2018 23:53:43 +0000 (UTC)
commit 93847b414b8cc776d3f5f52af1cba36b6cc614fe
Author: Kalev Lember <klember redhat com>
Date: Wed Feb 14 22:18:22 2018 +0100
repos dialog: Rewrite according to latest mockups
https://raw.githubusercontent.com/gnome-design-team/gnome-mockups-software/master/wireframes/software-sources.png
po/POTFILES.in | 2 +
src/gs-repos-dialog-row.c | 274 ++++++++++++++++++++++++---
src/gs-repos-dialog-row.h | 19 +-
src/gs-repos-dialog-row.ui | 119 ++++++++++--
src/gs-repos-dialog.c | 448 ++++++++++++++++++++++++---------------------
src/gs-repos-dialog.ui | 369 ++++---------------------------------
6 files changed, 646 insertions(+), 585 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 5e439a0a..d9baa51c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -49,6 +49,8 @@ src/gs-removal-dialog.c
src/gs-removal-dialog.ui
src/gs-repos-dialog.c
src/gs-repos-dialog.ui
+src/gs-repos-dialog-row.c
+src/gs-repos-dialog-row.ui
src/gs-review-dialog.c
src/gs-review-dialog.ui
src/gs-review-histogram.ui
diff --git a/src/gs-repos-dialog-row.c b/src/gs-repos-dialog-row.c
index d48b5522..70b8fe92 100644
--- a/src/gs-repos-dialog-row.c
+++ b/src/gs-repos-dialog-row.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
- * Copyright (C) 2015 Kalev Lember <klember redhat com>
+ * Copyright (C) 2015-2018 Kalev Lember <klember redhat com>
*
* Licensed under the GNU General Public License Version 2
*
@@ -23,15 +23,23 @@
#include "gs-repos-dialog-row.h"
-struct _GsReposDialogRow
-{
- GtkListBoxRow parent_instance;
+#include <glib/gi18n.h>
+typedef struct
+{
+ GsApp *repo;
GtkWidget *active_switch;
+ GtkWidget *button;
GtkWidget *name_label;
GtkWidget *comment_label;
- GtkWidget *description_label;
-};
+ GtkWidget *details_revealer;
+ GtkWidget *status_label;
+ GtkWidget *url_title_label;
+ GtkWidget *url_value_label;
+ guint refresh_idle_id;
+} GsReposDialogRowPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GsReposDialogRow, gs_repos_dialog_row, GTK_TYPE_LIST_BOX_ROW)
enum {
PROP_0,
@@ -39,50 +47,221 @@ enum {
PROP_LAST
};
-G_DEFINE_TYPE (GsReposDialogRow, gs_repos_dialog_row, GTK_TYPE_LIST_BOX_ROW)
+enum {
+ SIGNAL_BUTTON_CLICKED,
+ SIGNAL_LAST
+};
+
+static guint signals [SIGNAL_LAST] = { 0 };
void
gs_repos_dialog_row_set_switch_enabled (GsReposDialogRow *row,
gboolean switch_enabled)
{
- gtk_widget_set_visible (row->active_switch, switch_enabled);
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+ gtk_widget_set_visible (priv->active_switch, switch_enabled);
}
void
gs_repos_dialog_row_set_switch_active (GsReposDialogRow *row,
gboolean switch_active)
{
- gtk_switch_set_active (GTK_SWITCH (row->active_switch), switch_active);
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+ gtk_switch_set_active (GTK_SWITCH (priv->active_switch), switch_active);
}
void
gs_repos_dialog_row_set_name (GsReposDialogRow *row, const gchar *name)
{
- gtk_label_set_text (GTK_LABEL (row->name_label), name);
- gtk_widget_set_visible (row->name_label, name != NULL);
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ gtk_label_set_text (GTK_LABEL (priv->name_label), name);
+ gtk_widget_set_visible (priv->name_label, name != NULL);
}
void
gs_repos_dialog_row_set_comment (GsReposDialogRow *row, const gchar *comment)
{
- gtk_label_set_markup (GTK_LABEL (row->comment_label), comment);
- gtk_widget_set_visible (row->comment_label, comment != NULL);
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ gtk_label_set_markup (GTK_LABEL (priv->comment_label), comment);
+ gtk_widget_set_visible (priv->comment_label, comment != NULL);
+}
+
+void
+gs_repos_dialog_row_set_url (GsReposDialogRow *row, const gchar *url)
+{
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ gtk_label_set_text (GTK_LABEL (priv->url_value_label), url);
+ gtk_widget_set_visible (priv->url_value_label, url != NULL);
+ gtk_widget_set_visible (priv->url_title_label, url != NULL);
+}
+
+static gboolean
+repo_supports_removal (GsApp *repo)
+{
+ const gchar *management_plugin = gs_app_get_management_plugin (repo);
+
+ /* can't remove a repo, only enable/disable existing ones */
+ if (g_strcmp0 (management_plugin, "fwupd") == 0 ||
+ g_strcmp0 (management_plugin, "packagekit") == 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+refresh_ui (GsReposDialogRow *row)
+{
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ if (priv->repo == NULL) {
+ gtk_widget_set_visible (priv->button, FALSE);
+ return;
+ }
+
+ gtk_widget_set_visible (priv->button, TRUE);
- /* make the name bold */
- if (comment != NULL) {
- PangoAttrList *attr_list = pango_attr_list_new ();
- pango_attr_list_insert (attr_list,
- pango_attr_weight_new (PANGO_WEIGHT_BOLD));
- gtk_label_set_attributes (GTK_LABEL (row->name_label), attr_list);
- pango_attr_list_unref (attr_list);
+ /* set button text */
+ switch (gs_app_get_state (priv->repo)) {
+ case AS_APP_STATE_AVAILABLE:
+ case AS_APP_STATE_AVAILABLE_LOCAL:
+ /* TRANSLATORS: this is a button in the software repositories
+ dialog for enabling a repo */
+ gtk_button_set_label (GTK_BUTTON (priv->button), _("_Enable"));
+ /* enable button */
+ gtk_widget_set_sensitive (priv->button, TRUE);
+ break;
+ case AS_APP_STATE_INSTALLED:
+ if (repo_supports_removal (priv->repo)) {
+ /* TRANSLATORS: this is a button in the software repositories dialog
+ for removing a repo. The ellipsis indicates that further
+ steps are required */
+ gtk_button_set_label (GTK_BUTTON (priv->button), _("_Remove…"));
+ } else {
+ /* TRANSLATORS: this is a button in the software repositories dialog
+ for disabling a repo. The ellipsis indicates that further
+ steps are required */
+ gtk_button_set_label (GTK_BUTTON (priv->button), _("_Disable…"));
+ }
+ /* enable button */
+ gtk_widget_set_sensitive (priv->button, TRUE);
+ break;
+ case AS_APP_STATE_INSTALLING:
+ /* TRANSLATORS: this is a button in the software repositories dialog
+ that shows the status of a repo being enabled */
+ gtk_button_set_label (GTK_BUTTON (priv->button), _("Enabling"));
+ /* disable button */
+ gtk_widget_set_sensitive (priv->button, FALSE);
+ break;
+ case AS_APP_STATE_REMOVING:
+ if (repo_supports_removal (priv->repo)) {
+ /* TRANSLATORS: this is a button in the software repositories dialog
+ that shows the status of a repo being removed */
+ gtk_button_set_label (GTK_BUTTON (priv->button), _("Removing"));
+ } else {
+ /* TRANSLATORS: this is a button in the software repositories dialog
+ that shows the status of a repo being disabled */
+ gtk_button_set_label (GTK_BUTTON (priv->button), _("Disabling"));
+ }
+ /* disable button */
+ gtk_widget_set_sensitive (priv->button, FALSE);
+ break;
+ default:
+ break;
}
+
+ /* set enabled/disabled label */
+ switch (gs_app_get_state (priv->repo)) {
+ case AS_APP_STATE_INSTALLED:
+ /* TRANSLATORS: this is a label in the software repositories
+ dialog that indicates that a repo is enabled. */
+ gtk_label_set_text (GTK_LABEL (priv->status_label), _("Enabled"));
+ break;
+ case AS_APP_STATE_AVAILABLE:
+ case AS_APP_STATE_AVAILABLE_LOCAL:
+ /* TRANSLATORS: this is a label in the software repositories
+ dialog that indicates that a repo is disabled. */
+ gtk_label_set_text (GTK_LABEL (priv->status_label), _("Disabled"));
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean
+refresh_idle (gpointer user_data)
+{
+ g_autoptr(GsReposDialogRow) row = (GsReposDialogRow *) user_data;
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ refresh_ui (row);
+
+ priv->refresh_idle_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static void
+repo_state_changed_cb (GsApp *repo, GParamSpec *pspec, GsReposDialogRow *row)
+{
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ if (priv->refresh_idle_id > 0)
+ return;
+ priv->refresh_idle_id = g_idle_add (refresh_idle, g_object_ref (row));
+}
+
+void
+gs_repos_dialog_row_set_repo (GsReposDialogRow *row, GsApp *repo)
+{
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ g_assert (priv->repo == NULL);
+
+ priv->repo = g_object_ref (repo);
+ g_signal_connect_object (priv->repo, "notify::state",
+ G_CALLBACK (repo_state_changed_cb),
+ row, 0);
+ refresh_ui (row);
+}
+
+GsApp *
+gs_repos_dialog_row_get_repo (GsReposDialogRow *row)
+{
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+ return priv->repo;
+}
+
+void
+gs_repos_dialog_row_show_details (GsReposDialogRow *row)
+{
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
+ gtk_revealer_set_reveal_child (GTK_REVEALER (priv->details_revealer), TRUE);
+}
+
+void
+gs_repos_dialog_row_hide_details (GsReposDialogRow *row)
+{
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), TRUE);
+ gtk_revealer_set_reveal_child (GTK_REVEALER (priv->details_revealer), FALSE);
}
void
-gs_repos_dialog_row_set_description (GsReposDialogRow *row, const gchar *description)
+gs_repos_dialog_row_show_status (GsReposDialogRow *row)
{
- gtk_label_set_markup (GTK_LABEL (row->description_label), description);
- gtk_widget_set_visible (row->description_label, description != NULL);
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+ gtk_widget_set_visible (priv->status_label, TRUE);
+}
+
+static void
+button_clicked_cb (GtkWidget *widget, GsReposDialogRow *row)
+{
+ g_signal_emit (row, signals[SIGNAL_BUTTON_CLICKED], 0);
}
static void
@@ -96,7 +275,9 @@ gs_repos_dialog_switch_active_cb (GtkSwitch *active_switch,
gboolean
gs_repos_dialog_row_get_switch_active (GsReposDialogRow *row)
{
- return gtk_switch_get_active (GTK_SWITCH (row->active_switch));
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ return gtk_switch_get_active (GTK_SWITCH (priv->active_switch));
}
static void
@@ -117,12 +298,35 @@ gs_repos_dialog_row_get_property (GObject *object,
}
}
+static void
+gs_repos_dialog_row_destroy (GtkWidget *object)
+{
+ GsReposDialogRow *row = GS_REPOS_DIALOG_ROW (object);
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
+ if (priv->repo != NULL) {
+ g_signal_handlers_disconnect_by_func (priv->repo, repo_state_changed_cb, row);
+ g_clear_object (&priv->repo);
+ }
+
+ if (priv->refresh_idle_id != 0) {
+ g_source_remove (priv->refresh_idle_id);
+ priv->refresh_idle_id = 0;
+ }
+
+ GTK_WIDGET_CLASS (gs_repos_dialog_row_parent_class)->destroy (object);
+}
+
static void
gs_repos_dialog_row_init (GsReposDialogRow *row)
{
+ GsReposDialogRowPrivate *priv = gs_repos_dialog_row_get_instance_private (row);
+
gtk_widget_init_template (GTK_WIDGET (row));
- g_signal_connect (row->active_switch, "notify::active",
+ g_signal_connect (priv->active_switch, "notify::active",
G_CALLBACK (gs_repos_dialog_switch_active_cb), row);
+ g_signal_connect (priv->button, "clicked",
+ G_CALLBACK (button_clicked_cb), row);
}
static void
@@ -133,17 +337,29 @@ gs_repos_dialog_row_class_init (GsReposDialogRowClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->get_property = gs_repos_dialog_row_get_property;
+ widget_class->destroy = gs_repos_dialog_row_destroy;
pspec = g_param_spec_string ("switch-active", NULL, NULL, FALSE,
G_PARAM_READABLE);
g_object_class_install_property (object_class, PROP_SWITCH_ACTIVE, pspec);
+ signals [SIGNAL_BUTTON_CLICKED] =
+ g_signal_new ("button-clicked",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GsReposDialogRowClass, button_clicked),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/Software/gs-repos-dialog-row.ui");
- gtk_widget_class_bind_template_child (widget_class, GsReposDialogRow, active_switch);
- gtk_widget_class_bind_template_child (widget_class, GsReposDialogRow, name_label);
- gtk_widget_class_bind_template_child (widget_class, GsReposDialogRow, comment_label);
- gtk_widget_class_bind_template_child (widget_class, GsReposDialogRow, description_label);
+ gtk_widget_class_bind_template_child_private (widget_class, GsReposDialogRow, active_switch);
+ gtk_widget_class_bind_template_child_private (widget_class, GsReposDialogRow, button);
+ gtk_widget_class_bind_template_child_private (widget_class, GsReposDialogRow, name_label);
+ gtk_widget_class_bind_template_child_private (widget_class, GsReposDialogRow, comment_label);
+ gtk_widget_class_bind_template_child_private (widget_class, GsReposDialogRow, details_revealer);
+ gtk_widget_class_bind_template_child_private (widget_class, GsReposDialogRow, status_label);
+ gtk_widget_class_bind_template_child_private (widget_class, GsReposDialogRow, url_title_label);
+ gtk_widget_class_bind_template_child_private (widget_class, GsReposDialogRow, url_value_label);
}
GtkWidget *
diff --git a/src/gs-repos-dialog-row.h b/src/gs-repos-dialog-row.h
index 88a7cf2f..8f49dd28 100644
--- a/src/gs-repos-dialog-row.h
+++ b/src/gs-repos-dialog-row.h
@@ -22,13 +22,20 @@
#ifndef GS_REPOS_DIALOG_ROW_H
#define GS_REPOS_DIALOG_ROW_H
+#include "gnome-software-private.h"
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GS_TYPE_REPOS_DIALOG_ROW (gs_repos_dialog_row_get_type ())
-G_DECLARE_FINAL_TYPE (GsReposDialogRow, gs_repos_dialog_row, GS, REPOS_DIALOG_ROW, GtkListBoxRow)
+G_DECLARE_DERIVABLE_TYPE (GsReposDialogRow, gs_repos_dialog_row, GS, REPOS_DIALOG_ROW, GtkListBoxRow)
+
+struct _GsReposDialogRowClass
+{
+ GtkListBoxRowClass parent_class;
+ void (*button_clicked) (GsReposDialogRow *row);
+};
GtkWidget *gs_repos_dialog_row_new (void);
void gs_repos_dialog_row_set_switch_enabled (GsReposDialogRow *row,
@@ -40,8 +47,14 @@ void gs_repos_dialog_row_set_name (GsReposDialogRow *row,
const gchar *name);
void gs_repos_dialog_row_set_comment (GsReposDialogRow *row,
const gchar *comment);
-void gs_repos_dialog_row_set_description (GsReposDialogRow *row,
- const gchar *description);
+void gs_repos_dialog_row_set_url (GsReposDialogRow *row,
+ const gchar *url);
+void gs_repos_dialog_row_set_repo (GsReposDialogRow *row,
+ GsApp *repo);
+GsApp *gs_repos_dialog_row_get_repo (GsReposDialogRow *row);
+void gs_repos_dialog_row_show_details (GsReposDialogRow *row);
+void gs_repos_dialog_row_hide_details (GsReposDialogRow *row);
+void gs_repos_dialog_row_show_status (GsReposDialogRow *row);
G_END_DECLS
diff --git a/src/gs-repos-dialog-row.ui b/src/gs-repos-dialog-row.ui
index 318db606..9b6c4226 100644
--- a/src/gs-repos-dialog-row.ui
+++ b/src/gs-repos-dialog-row.ui
@@ -18,10 +18,31 @@
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
- <object class="GtkLabel" id="name_label">
+ <object class="GtkBox" id="hbox">
<property name="visible">True</property>
- <property name="halign">start</property>
- <property name="ellipsize">end</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="ellipsize">end</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="status_label">
+ <property name="visible">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
@@ -34,6 +55,9 @@
<property name="halign">start</property>
<property name="xalign">0</property>
<property name="wrap">True</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
</object>
<packing>
<property name="expand">False</property>
@@ -41,19 +65,84 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="description_label">
+ <object class="GtkRevealer" id="details_revealer">
<property name="visible">True</property>
- <property name="halign">start</property>
- <property name="xalign">0</property>
- <property name="wrap">True</property>
- <style>
- <class name="dim-label"/>
- </style>
+ <property name="transition-type">slide-down</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkBox" id="url_box">
+ <property name="visible">True</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkLabel" id="url_title_label">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="label" translatable="yes">URL</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="url_value_label">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="ellipsize">end</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">8</property>
+ <child>
+ <object class="GtkButton" id="button">
+ <property name="visible">True</property>
+ <property name="use_underline">True</property>
+ <property name="width_request">105</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
</child>
</object>
<packing>
@@ -66,7 +155,7 @@
<property name="visible">False</property>
<property name="can_focus">True</property>
<property name="halign">end</property>
- <property name="valign">start</property>
+ <property name="valign">center</property>
</object>
<packing>
<property name="expand">False</property>
diff --git a/src/gs-repos-dialog.c b/src/gs-repos-dialog.c
index 28c88af2..733d2673 100644
--- a/src/gs-repos-dialog.c
+++ b/src/gs-repos-dialog.c
@@ -2,6 +2,7 @@
*
* Copyright (C) 2013-2017 Richard Hughes <richard hughsie com>
* Copyright (C) 2013 Matthias Clasen <mclasen redhat com>
+ * Copyright (C) 2014-2018 Kalev Lember <klember redhat com>
*
* Licensed under the GNU General Public License Version 2
*
@@ -22,13 +23,13 @@
#include "config.h"
-#include <glib/gi18n.h>
+#include "gs-repos-dialog.h"
#include "gnome-software-private.h"
-#include "gs-repos-dialog.h"
+#include "gs-common.h"
#include "gs-os-release.h"
#include "gs-repos-dialog-row.h"
-#include "gs-common.h"
+#include <glib/gi18n.h>
struct _GsReposDialog
{
@@ -38,16 +39,12 @@ struct _GsReposDialog
GCancellable *cancellable;
GsPluginLoader *plugin_loader;
- GtkWidget *button_back;
GtkWidget *frame_third_party;
- GtkWidget *grid_noresults;
- GtkWidget *label2;
+ GtkWidget *label_description;
GtkWidget *label_empty;
GtkWidget *label_header;
GtkWidget *listbox;
- GtkWidget *listbox_apps;
GtkWidget *row_third_party;
- GtkWidget *scrolledwindow_apps;
GtkWidget *spinner;
GtkWidget *stack;
};
@@ -56,119 +53,281 @@ G_DEFINE_TYPE (GsReposDialog, gs_repos_dialog, GTK_TYPE_DIALOG)
typedef struct {
GsReposDialog *dialog;
+ GsApp *repo;
GsPluginAction action;
-} InstallData;
+} InstallRemoveData;
static void
-install_data_free (InstallData *install_data)
+install_remove_data_free (InstallRemoveData *data)
{
- g_clear_object (&install_data->dialog);
- g_slice_free (InstallData, install_data);
+ g_clear_object (&data->dialog);
+ g_clear_object (&data->repo);
+ g_slice_free (InstallRemoveData, data);
}
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstallRemoveData, install_remove_data_free);
+
static void reload_sources (GsReposDialog *dialog);
static void reload_third_party_repo (GsReposDialog *dialog);
static void refresh_third_party_repo (GsReposDialog *dialog);
static gchar *
-get_source_installed_text (GPtrArray *sources)
+get_repo_installed_text (GsApp *repo)
{
+ GPtrArray *related;
guint cnt_addon = 0;
guint cnt_apps = 0;
g_autofree gchar *addons_text = NULL;
g_autofree gchar *apps_text = NULL;
- /* split up the types */
- for (guint j = 0; j < sources->len; j++) {
- GsApp *app = g_ptr_array_index (sources, j);
- GPtrArray *related = gs_app_get_related (app);
- for (guint i = 0; i < related->len; i++) {
- GsApp *app_tmp = g_ptr_array_index (related, i);
- switch (gs_app_get_kind (app_tmp)) {
- case AS_APP_KIND_WEB_APP:
- case AS_APP_KIND_DESKTOP:
- cnt_apps++;
- break;
- case AS_APP_KIND_FONT:
- case AS_APP_KIND_CODEC:
- case AS_APP_KIND_INPUT_METHOD:
- case AS_APP_KIND_ADDON:
- cnt_addon++;
- break;
- default:
- break;
- }
+ related = gs_app_get_related (repo);
+ for (guint i = 0; i < related->len; i++) {
+ GsApp *app_tmp = g_ptr_array_index (related, i);
+ switch (gs_app_get_kind (app_tmp)) {
+ case AS_APP_KIND_WEB_APP:
+ case AS_APP_KIND_DESKTOP:
+ cnt_apps++;
+ break;
+ case AS_APP_KIND_FONT:
+ case AS_APP_KIND_CODEC:
+ case AS_APP_KIND_INPUT_METHOD:
+ case AS_APP_KIND_ADDON:
+ cnt_addon++;
+ break;
+ default:
+ break;
}
}
- /* nothing! */
if (cnt_apps == 0 && cnt_addon == 0) {
- /* TRANSLATORS: This string describes a software repository that
- has no software installed from it. */
- return g_strdup (_("No applications or addons installed; other software might still be"));
+ /* nothing! */
+ return NULL;
}
if (cnt_addon == 0) {
/* TRANSLATORS: This string is used to construct the 'X applications
installed' sentence, describing a software repository. */
return g_strdup_printf (ngettext ("%u application installed",
- "%u applications installed",
- cnt_apps), cnt_apps);
+ "%u applications installed",
+ cnt_apps), cnt_apps);
}
if (cnt_apps == 0) {
/* TRANSLATORS: This string is used to construct the 'X add-ons
installed' sentence, describing a software repository. */
return g_strdup_printf (ngettext ("%u add-on installed",
- "%u add-ons installed",
- cnt_addon), cnt_addon);
+ "%u add-ons installed",
+ cnt_addon), cnt_addon);
}
/* TRANSLATORS: This string is used to construct the 'X applications
and y add-ons installed' sentence, describing a software repository.
The correct form here depends on the number of applications. */
apps_text = g_strdup_printf (ngettext ("%u application",
- "%u applications",
- cnt_apps), cnt_apps);
+ "%u applications",
+ cnt_apps), cnt_apps);
/* TRANSLATORS: This string is used to construct the 'X applications
and y add-ons installed' sentence, describing a software repository.
The correct form here depends on the number of add-ons. */
addons_text = g_strdup_printf (ngettext ("%u add-on",
- "%u add-ons",
- cnt_addon), cnt_addon);
+ "%u add-ons",
+ cnt_addon), cnt_addon);
/* TRANSLATORS: This string is used to construct the 'X applications
and y add-ons installed' sentence, describing a software repository.
The correct form here depends on the total number of
applications and add-ons. */
return g_strdup_printf (ngettext ("%s and %s installed",
- "%s and %s installed",
- cnt_apps + cnt_addon),
- apps_text, addons_text);
+ "%s and %s installed",
+ cnt_apps + cnt_addon),
+ apps_text, addons_text);
+}
+
+static gboolean
+repo_supports_removal (GsApp *repo)
+{
+ const gchar *management_plugin = gs_app_get_management_plugin (repo);
+
+ /* can't remove a repo, only enable/disable existing ones */
+ if (g_strcmp0 (management_plugin, "fwupd") == 0 ||
+ g_strcmp0 (management_plugin, "packagekit") == 0)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+repo_enabled_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
+ g_autoptr(InstallRemoveData) install_remove_data = (InstallRemoveData *) user_data;
+ g_autoptr(GError) error = NULL;
+ const gchar *action_str;
+
+ action_str = gs_plugin_action_to_string (install_remove_data->action);
+
+ if (!gs_plugin_loader_job_action_finish (plugin_loader, res, &error)) {
+ if (g_error_matches (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_CANCELLED)) {
+ g_debug ("repo %s cancelled", action_str);
+ return;
+ }
+
+ g_warning ("failed to %s repo: %s", action_str, error->message);
+ return;
+ }
+
+ g_debug ("finished %s repo %s", action_str, gs_app_get_id (install_remove_data->repo));
+}
+
+static void
+enable_repo (GsReposDialog *dialog, GsApp *repo)
+{
+ InstallRemoveData *install_data;
+ g_autoptr(GsPluginJob) plugin_job = NULL;
+
+ install_data = g_slice_new0 (InstallRemoveData);
+ install_data->action = GS_PLUGIN_ACTION_INSTALL;
+ install_data->repo = g_object_ref (repo);
+ install_data->dialog = g_object_ref (dialog);
+
+ g_debug ("enabling repo %s", gs_app_get_id (install_data->repo));
+ plugin_job = gs_plugin_job_newv (install_data->action,
+ "app", repo,
+ NULL);
+ gs_plugin_loader_job_process_async (dialog->plugin_loader, plugin_job,
+ dialog->cancellable,
+ repo_enabled_cb,
+ install_data);
+}
+
+static void
+remove_repo_response_cb (GtkDialog *confirm_dialog,
+ gint response,
+ gpointer user_data)
+{
+ g_autoptr(InstallRemoveData) remove_data = (InstallRemoveData *) user_data;
+ GsReposDialog *dialog = remove_data->dialog;
+ g_autoptr(GsPluginJob) plugin_job = NULL;
+
+ /* unmap the dialog */
+ gtk_widget_destroy (GTK_WIDGET (confirm_dialog));
+
+ /* not agreed */
+ if (response != GTK_RESPONSE_OK)
+ return;
+
+ g_debug ("removing repo %s", gs_app_get_id (remove_data->repo));
+ plugin_job = gs_plugin_job_newv (remove_data->action,
+ "app", remove_data->repo,
+ NULL);
+ gs_plugin_loader_job_process_async (dialog->plugin_loader, plugin_job,
+ dialog->cancellable,
+ repo_enabled_cb,
+ g_steal_pointer (&remove_data));
+}
+
+static void
+remove_confirm_repo (GsReposDialog *dialog, GsApp *repo)
+{
+ InstallRemoveData *remove_data;
+ GtkWidget *confirm_dialog;
+ g_autofree gchar *message = NULL;
+ g_autofree gchar *title = NULL;
+
+ remove_data = g_slice_new0 (InstallRemoveData);
+ remove_data->action = GS_PLUGIN_ACTION_REMOVE;
+ remove_data->repo = g_object_ref (repo);
+ remove_data->dialog = g_object_ref (dialog);
+
+ if (repo_supports_removal (repo)) {
+ /* TRANSLATORS: this is a prompt message, and '%s' is a
+ * repository name, e.g. 'GNOME Nightly' */
+ title = g_strdup_printf (_("Remove “%s”?"),
+ gs_app_get_name (repo));
+ } else {
+ /* TRANSLATORS: this is a prompt message, and '%s' is a
+ * repository name, e.g. 'GNOME Nightly' */
+ title = g_strdup_printf (_("Disable “%s”?"),
+ gs_app_get_name (repo));
+ }
+ /* TRANSLATORS: longer dialog text */
+ message = g_strdup (_("Software that has been installed from this "
+ "repository will no longer receive updates, "
+ "including security fixes."));
+
+ /* ask for confirmation */
+ confirm_dialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_CANCEL,
+ "%s", title);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (confirm_dialog),
+ "%s", message);
+
+ if (repo_supports_removal (repo)) {
+ /* TRANSLATORS: this is button text to remove the repo */
+ gtk_dialog_add_button (GTK_DIALOG (confirm_dialog), _("Remove"), GTK_RESPONSE_OK);
+ } else {
+ /* TRANSLATORS: this is button text to remove the repo */
+ gtk_dialog_add_button (GTK_DIALOG (confirm_dialog), _("Disable"), GTK_RESPONSE_OK);
+ }
+
+ /* handle this async */
+ g_signal_connect (confirm_dialog, "response",
+ G_CALLBACK (remove_repo_response_cb), remove_data);
+
+ gtk_window_set_modal (GTK_WINDOW (confirm_dialog), TRUE);
+ gtk_window_present (GTK_WINDOW (confirm_dialog));
}
static void
-add_source (GtkListBox *listbox, GsApp *app)
+repo_button_clicked_cb (GsReposDialogRow *row,
+ GsReposDialog *dialog)
+{
+ GsApp *repo;
+
+ repo = gs_repos_dialog_row_get_repo (row);
+
+ switch (gs_app_get_state (repo)) {
+ case AS_APP_STATE_AVAILABLE:
+ case AS_APP_STATE_AVAILABLE_LOCAL:
+ enable_repo (dialog, repo);
+ break;
+ case AS_APP_STATE_INSTALLED:
+ remove_confirm_repo (dialog, repo);
+ break;
+ default:
+ g_warning ("repo %s button clicked in unexpected state %s",
+ gs_app_get_id (repo),
+ as_app_state_to_string (gs_app_get_state (repo)));
+ break;
+ }
+}
+
+static void
+add_repo (GsReposDialog *dialog, GsApp *app)
{
GtkWidget *row;
g_autofree gchar *text = NULL;
- g_autoptr(GPtrArray) sources = g_ptr_array_new ();
row = gs_repos_dialog_row_new ();
gs_repos_dialog_row_set_name (GS_REPOS_DIALOG_ROW (row),
gs_app_get_name (app));
- g_ptr_array_add (sources, app);
- text = get_source_installed_text (sources);
- gs_repos_dialog_row_set_description (GS_REPOS_DIALOG_ROW (row),
- text);
-
- g_object_set_data_full (G_OBJECT (row), "GsShell::app",
- g_object_ref (app),
- (GDestroyNotify) g_object_unref);
+ text = get_repo_installed_text (app);
+ gs_repos_dialog_row_set_comment (GS_REPOS_DIALOG_ROW (row), text);
+ gs_repos_dialog_row_set_url (GS_REPOS_DIALOG_ROW (row),
+ gs_app_get_url (app, AS_URL_KIND_HOMEPAGE));
+ gs_repos_dialog_row_show_status (GS_REPOS_DIALOG_ROW (row));
+ gs_repos_dialog_row_set_repo (GS_REPOS_DIALOG_ROW (row), app);
g_object_set_data_full (G_OBJECT (row),
"sort",
g_utf8_casefold (gs_app_get_name (app), -1),
g_free);
- gtk_list_box_prepend (listbox, row);
+ g_signal_connect (row, "button-clicked",
+ G_CALLBACK (repo_button_clicked_cb), dialog);
+
+ gtk_list_box_prepend (GTK_LIST_BOX (dialog->listbox), row);
gtk_widget_show (row);
}
@@ -178,7 +337,7 @@ third_party_repo_installed_cb (GObject *source,
gpointer user_data)
{
GsPluginLoader *plugin_loader = GS_PLUGIN_LOADER (source);
- InstallData *install_data = (InstallData *) user_data;
+ InstallRemoveData *install_data = (InstallRemoveData *) user_data;
g_autoptr(GError) error = NULL;
if (!gs_plugin_loader_job_action_finish (plugin_loader, res, &error)) {
@@ -197,14 +356,14 @@ third_party_repo_installed_cb (GObject *source,
}
out:
- install_data_free (install_data);
+ install_remove_data_free (install_data);
}
static void
install_third_party_repo (GsReposDialog *dialog, gboolean install)
{
GsPluginAction action;
- InstallData *install_data;
+ InstallRemoveData *install_data;
g_autoptr(GsPluginJob) plugin_job = NULL;
if (install && gs_app_get_state (dialog->third_party_repo) == AS_APP_STATE_AVAILABLE) {
@@ -218,7 +377,7 @@ install_third_party_repo (GsReposDialog *dialog, gboolean install)
return;
}
- install_data = g_slice_new0 (InstallData);
+ install_data = g_slice_new0 (InstallRemoveData);
install_data->dialog = g_object_ref (dialog);
install_data->action = action;
@@ -306,9 +465,7 @@ get_sources_cb (GsPluginLoader *plugin_loader,
gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "sources");
for (guint i = 0; i < gs_app_list_length (list); i++) {
app = gs_app_list_index (list, i);
- if (gs_app_get_state (app) != AS_APP_STATE_INSTALLED)
- continue;
- add_source (GTK_LIST_BOX (dialog->listbox), app);
+ add_repo (dialog, app);
}
}
@@ -350,13 +507,13 @@ reload_sources (GsReposDialog *dialog)
gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "waiting");
gs_start_spinner (GTK_SPINNER (dialog->spinner));
- gtk_widget_hide (dialog->button_back);
gs_container_remove_all (GTK_CONTAINER (dialog->listbox));
/* get the list of non-core software repositories */
plugin_job = gs_plugin_job_newv (GS_PLUGIN_ACTION_GET_SOURCES,
"failure-flags", GS_PLUGIN_FAILURE_FLAGS_NONE,
- "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED,
+ "refine-flags", GS_PLUGIN_REFINE_FLAGS_REQUIRE_RELATED |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN_HOSTNAME,
NULL);
gs_plugin_loader_job_process_async (dialog->plugin_loader, plugin_job,
dialog->cancellable,
@@ -424,122 +581,21 @@ list_sort_func (GtkListBoxRow *a,
return g_strcmp0 (key1, key2);
}
-static void
-add_app (GtkListBox *listbox, GsApp *app)
-{
- GtkWidget *box;
- GtkWidget *widget;
- GtkWidget *row;
-
- box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
- gtk_widget_set_margin_top (box, 12);
- gtk_widget_set_margin_start (box, 12);
- gtk_widget_set_margin_bottom (box, 12);
- gtk_widget_set_margin_end (box, 12);
-
- widget = gtk_label_new (gs_app_get_name (app));
- gtk_widget_set_halign (widget, GTK_ALIGN_START);
- gtk_label_set_ellipsize (GTK_LABEL (widget), PANGO_ELLIPSIZE_END);
- gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
-
- g_object_set_data_full (G_OBJECT (box),
- "sort",
- g_utf8_casefold (gs_app_get_name (app), -1),
- g_free);
-
- gtk_list_box_prepend (listbox, box);
- gtk_widget_show (widget);
- gtk_widget_show (box);
-
- row = gtk_widget_get_parent (box);
- gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE);
-}
-
static void
list_row_activated_cb (GtkListBox *list_box,
GtkListBoxRow *row,
GsReposDialog *dialog)
{
- GPtrArray *related;
- GsApp *app;
- guint cnt_apps = 0;
-
- gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "details");
+ GtkListBoxRow *other_row;
- gtk_widget_show (dialog->button_back);
+ gs_repos_dialog_row_show_details (GS_REPOS_DIALOG_ROW (row));
- gs_container_remove_all (GTK_CONTAINER (dialog->listbox_apps));
- app = GS_APP (g_object_get_data (G_OBJECT (row),
- "GsShell::app"));
- related = gs_app_get_related (app);
- for (guint i = 0; i < related->len; i++) {
- GsApp *app_tmp = g_ptr_array_index (related, i);
- switch (gs_app_get_kind (app_tmp)) {
- case AS_APP_KIND_DESKTOP:
- add_app (GTK_LIST_BOX (dialog->listbox_apps), app_tmp);
- cnt_apps++;
- break;
- default:
- break;
- }
- }
-
- /* save this */
- g_object_set_data_full (G_OBJECT (dialog->stack), "GsShell::app",
- g_object_ref (app),
- (GDestroyNotify) g_object_unref);
-
- gtk_widget_set_visible (dialog->scrolledwindow_apps, cnt_apps != 0);
- gtk_widget_set_visible (dialog->label2, cnt_apps != 0);
- gtk_widget_set_visible (dialog->grid_noresults, cnt_apps == 0);
-}
-
-static void
-back_button_cb (GtkWidget *widget, GsReposDialog *dialog)
-{
- gtk_widget_hide (dialog->button_back);
- gtk_stack_set_visible_child_name (GTK_STACK (dialog->stack), "sources");
-}
+ for (guint i = 0; (other_row = gtk_list_box_get_row_at_index (list_box, i)) != NULL; i++) {
+ if (other_row == row)
+ continue;
-static gboolean
-key_press_event (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
-{
- GsReposDialog *dialog = (GsReposDialog *) widget;
- GdkKeymap *keymap;
- GdkModifierType state;
- gboolean is_rtl;
-
- if (!gtk_widget_is_visible (dialog->button_back) || !gtk_widget_is_sensitive (dialog->button_back))
- return GDK_EVENT_PROPAGATE;
-
- state = event->state;
- keymap = gdk_keymap_get_for_display (gtk_widget_get_display (widget));
- gdk_keymap_add_virtual_modifiers (keymap, &state);
- state = state & gtk_accelerator_get_default_mod_mask ();
- is_rtl = gtk_widget_get_direction (dialog->button_back) == GTK_TEXT_DIR_RTL;
-
- if ((!is_rtl && state == GDK_MOD1_MASK && event->keyval == GDK_KEY_Left) ||
- (is_rtl && state == GDK_MOD1_MASK && event->keyval == GDK_KEY_Right) ||
- event->keyval == GDK_KEY_Back) {
- gtk_widget_activate (dialog->button_back);
- return GDK_EVENT_STOP;
+ gs_repos_dialog_row_hide_details (GS_REPOS_DIALOG_ROW (other_row));
}
-
- return GDK_EVENT_PROPAGATE;
-}
-
-static gboolean
-button_press_event (GsReposDialog *dialog, GdkEventButton *event)
-{
- /* Mouse hardware back button is 8 */
- if (event->button != 8)
- return GDK_EVENT_PROPAGATE;
-
- if (!gtk_widget_is_visible (dialog->button_back) || !gtk_widget_is_sensitive (dialog->button_back))
- return GDK_EVENT_PROPAGATE;
-
- gtk_widget_activate (dialog->button_back);
- return GDK_EVENT_STOP;
}
static gchar *
@@ -599,7 +655,8 @@ gs_repos_dialog_dispose (GObject *object)
static void
gs_repos_dialog_init (GsReposDialog *dialog)
{
- g_autofree gchar *label_text = NULL;
+ g_autofree gchar *label_description_text = NULL;
+ g_autofree gchar *label_empty_text = NULL;
g_autofree gchar *os_name = NULL;
g_autofree gchar *uri = NULL;
g_autoptr(GString) str = g_string_new (NULL);
@@ -621,13 +678,11 @@ gs_repos_dialog_init (GsReposDialog *dialog)
g_signal_connect (dialog->listbox, "row-activated",
G_CALLBACK (list_row_activated_cb), dialog);
- gtk_list_box_set_header_func (GTK_LIST_BOX (dialog->listbox_apps),
- list_header_func,
- dialog,
- NULL);
- gtk_list_box_set_sort_func (GTK_LIST_BOX (dialog->listbox_apps),
- list_sort_func,
- dialog, NULL);
+ /* TRANSLATORS: This is the description text displayed in the Software Repositories dialog.
+ %s gets replaced by the name of the actual distro, e.g. Fedora. */
+ label_description_text = g_strdup_printf (_("These repositories supplement the default software
provided by %s."),
+ os_name);
+ gtk_label_set_text (GTK_LABEL (dialog->label_description), label_description_text);
/* set up third party repository row */
g_signal_connect (dialog->row_third_party, "notify::switch-active",
@@ -655,24 +710,13 @@ gs_repos_dialog_init (GsReposDialog *dialog)
_("Find out more…"));
}
gs_repos_dialog_row_set_comment (GS_REPOS_DIALOG_ROW (dialog->row_third_party), str->str);
- gs_repos_dialog_row_set_description (GS_REPOS_DIALOG_ROW (dialog->row_third_party), NULL);
refresh_third_party_repo (dialog);
- /* TRANSLATORS: This is the text displayed in the Software Repositories
- dialog when no OS-provided software repositories are enabled. %s gets
- replaced by the name of the actual distro, e.g. Fedora. */
- label_text = g_strdup_printf (_("Software repositories can be downloaded from the internet. They give
you access to additional software that is not provided by %s."),
- os_name);
- gtk_label_set_text (GTK_LABEL (dialog->label_empty), label_text);
-
- g_signal_connect (dialog->button_back, "clicked",
- G_CALLBACK (back_button_cb), dialog);
-
- /* global keynav and mouse back button */
- g_signal_connect (dialog, "key-press-event",
- G_CALLBACK (key_press_event), NULL);
- g_signal_connect (dialog, "button-press-event",
- G_CALLBACK (button_press_event), NULL);
+ /* TRANSLATORS: This is the description text displayed in the Software Repositories dialog.
+ %s gets replaced by the name of the actual distro, e.g. Fedora. */
+ label_empty_text = g_strdup_printf (_("These repositories supplement the default software provided by
%s."),
+ os_name);
+ gtk_label_set_text (GTK_LABEL (dialog->label_empty), label_empty_text);
}
static void
@@ -685,16 +729,12 @@ gs_repos_dialog_class_init (GsReposDialogClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-repos-dialog.ui");
- gtk_widget_class_bind_template_child (widget_class, GsReposDialog, button_back);
gtk_widget_class_bind_template_child (widget_class, GsReposDialog, frame_third_party);
- gtk_widget_class_bind_template_child (widget_class, GsReposDialog, grid_noresults);
- gtk_widget_class_bind_template_child (widget_class, GsReposDialog, label2);
+ gtk_widget_class_bind_template_child (widget_class, GsReposDialog, label_description);
gtk_widget_class_bind_template_child (widget_class, GsReposDialog, label_empty);
gtk_widget_class_bind_template_child (widget_class, GsReposDialog, label_header);
gtk_widget_class_bind_template_child (widget_class, GsReposDialog, listbox);
- gtk_widget_class_bind_template_child (widget_class, GsReposDialog, listbox_apps);
gtk_widget_class_bind_template_child (widget_class, GsReposDialog, row_third_party);
- gtk_widget_class_bind_template_child (widget_class, GsReposDialog, scrolledwindow_apps);
gtk_widget_class_bind_template_child (widget_class, GsReposDialog, spinner);
gtk_widget_class_bind_template_child (widget_class, GsReposDialog, stack);
}
diff --git a/src/gs-repos-dialog.ui b/src/gs-repos-dialog.ui
index dd6d3e1c..6a877086 100644
--- a/src/gs-repos-dialog.ui
+++ b/src/gs-repos-dialog.ui
@@ -13,32 +13,6 @@
<property name="use_header_bar">1</property>
<child internal-child="headerbar">
<object class="GtkHeaderBar">
- <child>
- <object class="GtkButton" id="button_back">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <child internal-child="accessible">
- <object class="AtkObject" id="button_back_accessible">
- <property name="accessible-name" translatable="yes">Go back</property>
- </object>
- </child>
- <style>
- <class name="image-button"/>
- </style>
- <child>
- <object class="GtkImage" id="image_back">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="icon_name">go-previous-symbolic</property>
- <property name="icon_size">1</property>
- </object>
- </child>
- </object>
- <packing>
- <property name="pack-type">start</property>
- </packing>
- </child>
<child type="title">
<object class="GtkLabel" id="label_header">
<property name="can_focus">False</property>
@@ -100,11 +74,12 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="label_empty">
+ <object class="GtkLabel" id="label_empty_title">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="justify">center</property>
<property name="wrap">True</property>
+ <property name="label" translatable="yes">No Additional Repositories</property>
<property name="max_width_chars">40</property>
<property name="halign">center</property>
<property name="valign">center</property>
@@ -115,6 +90,22 @@
<property name="position">1</property>
</packing>
</child>
+ <child>
+ <object class="GtkLabel" id="label_empty">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="justify">center</property>
+ <property name="wrap">True</property>
+ <property name="max_width_chars">40</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="name">empty</property>
@@ -130,57 +121,14 @@
<property name="margin_bottom">32</property>
<property name="orientation">vertical</property>
<property name="spacing">4</property>
-
- <child>
- <object class="GtkFrame" id="frame_third_party">
- <property name="visible">True</property>
- <property name="shadow_type">in</property>
- <property name="halign">fill</property>
- <property name="valign">start</property>
- <property name="margin_bottom">16</property>
- <child>
- <object class="GtkListBox" id="listbox_third_party">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="selection_mode">none</property>
- <child>
- <object class="GsReposDialogRow" id="row_third_party">
- <property name="visible">True</property>
- <property name="activatable">False</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
<child>
- <object class="GtkLabel" id="label1">
+ <object class="GtkLabel" id="label_description">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
- <property name="label" translatable="yes">Additional Repositories</property>
- <property name="wrap">True</property>
- <property name="max_width_chars">30</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label3">
- <property name="visible">False</property> <!-- Bug #754315 -->
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Removing a source will also remove any
software you have installed from it.</property>
<property name="wrap">True</property>
<property name="max_width_chars">30</property>
+ <property name="margin_bottom">16</property>
<style>
<class name="dim-label"/>
</style>
@@ -191,133 +139,43 @@
</packing>
</child>
<child>
- <object class="GtkScrolledWindow" id="scrolledwindow">
+ <object class="GtkFrame" id="frame_third_party">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="vscrollbar_policy">automatic</property>
- <property name="shadow_type">none</property>
- <property name="margin_top">9</property>
+ <property name="shadow_type">in</property>
+ <property name="halign">fill</property>
+ <property name="valign">start</property>
+ <property name="margin_bottom">16</property>
<child>
- <object class="GtkFrame" id="frame">
+ <object class="GtkListBox" id="listbox_third_party">
<property name="visible">True</property>
- <property name="shadow_type">in</property>
- <property name="halign">fill</property>
- <property name="valign">start</property>
+ <property name="can_focus">False</property>
+ <property name="selection_mode">none</property>
<child>
- <object class="GtkListBox" id="listbox">
+ <object class="GsReposDialogRow" id="row_third_party">
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="selection_mode">none</property>
+ <property name="activatable">False</property>
</object>
</child>
</object>
</child>
</object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
</child>
- </object>
- <packing>
- <property name="name">sources</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="box2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="margin_start">16</property>
- <property name="margin_end">16</property>
- <property name="margin_top">16</property>
- <property name="margin_bottom">16</property>
- <property name="orientation">vertical</property>
- <property name="spacing">4</property>
<child>
- <object class="GtkGrid" id="grid_noresults">
- <property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="vexpand">True</property>
- <property name="halign">center</property>
- <property name="valign">center</property>
- <property name="row-spacing">12</property>
- <property name="column-spacing">12</property>
- <style>
- <class name="dim-label"/>
- </style>
- <child>
- <object class="GtkImage" id="image_noresults">
- <property name="visible">True</property>
- <property name="icon_name">org.gnome.Software-symbolic</property>
- <property name="pixel-size">64</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left-attach">0</property>
- <property name="top-attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_noresults">
- <property name="visible">True</property>
- <property name="label" translatable="yes">No software installed from this
source</property>
- <property name="halign">center</property>
- <property name="valign">center</property>
- <property name="justify">center</property>
- <property name="wrap">True</property>
- <property name="max_width_chars">25</property>
- <attributes>
- <attribute name="scale" value="1.2"/>
- </attributes>
- </object>
- <packing>
- <property name="left-attach">0</property>
- <property name="top-attach">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0.5</property>
- <property name="label" translatable="yes">Installed from this Source</property>
- <property name="wrap">True</property>
- <property name="max_width_chars">30</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow_apps">
+ <object class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">none</property>
+ <property name="margin_top">9</property>
<child>
- <object class="GtkFrame" id="frame_apps">
+ <object class="GtkFrame" id="frame">
<property name="visible">True</property>
<property name="shadow_type">in</property>
<property name="halign">fill</property>
<property name="valign">start</property>
<child>
- <object class="GtkListBox" id="listbox_apps">
+ <object class="GtkListBox" id="listbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="selection_mode">none</property>
@@ -329,168 +187,11 @@
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_details">
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Source Details</property>
- <property name="wrap">True</property>
- <property name="max_width_chars">30</property>
- <attributes>
- <attribute name="weight" value="bold"/>
- </attributes>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkGrid" id="grid_details">
- <property name="can_focus">False</property>
- <property name="halign">center</property>
- <property name="valign">start</property>
- <property name="row_spacing">3</property>
- <property name="column_spacing">24</property>
- <property name="row_homogeneous">True</property>
- <child>
- <object class="GtkLabel" id="label_header_version">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Version</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_version">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label">0.12.3</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_header_lastchecked">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Last Checked</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_header_added">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Added</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_header_website">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label" translatable="yes">Website</property>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_added">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label">May 12, 2012</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">1</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_website">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label">superrepo.com</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_lastchecked">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="xalign">0</property>
- <property name="label">January 30, 2014</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">2</property>
- <property name="width">1</property>
- <property name="height">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">3</property>
</packing>
</child>
</object>
<packing>
- <property name="name">details</property>
+ <property name="name">sources</property>
</packing>
</child>
</object>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]