diff options
Diffstat (limited to 'src/gs-history-dialog.c')
-rw-r--r-- | src/gs-history-dialog.c | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/src/gs-history-dialog.c b/src/gs-history-dialog.c new file mode 100644 index 0000000..7863e61 --- /dev/null +++ b/src/gs-history-dialog.c @@ -0,0 +1,239 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2013-2014 Richard Hughes <richard@hughsie.com> + * Copyright (C) 2013 Matthias Clasen <mclasen@redhat.com> + * Copyright (C) 2014-2015 Kalev Lember <klember@redhat.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "config.h" + +#include <glib/gi18n.h> + +#include "gs-history-dialog.h" +#include "gs-common.h" + +struct _GsHistoryDialog +{ + GtkDialog parent_instance; + + GtkSizeGroup *sizegroup_state; + GtkSizeGroup *sizegroup_timestamp; + GtkSizeGroup *sizegroup_version; + GtkWidget *list_box; + GtkWidget *scrolledwindow; +}; + +G_DEFINE_TYPE (GsHistoryDialog, gs_history_dialog, GTK_TYPE_DIALOG) + +static gint +history_sort_cb (GsApp *app1, GsApp *app2, gpointer user_data) +{ + guint64 timestamp_a = gs_app_get_install_date (app1); + guint64 timestamp_b = gs_app_get_install_date (app2); + if (timestamp_a < timestamp_b) + return 1; + if (timestamp_a > timestamp_b) + return -1; + return 0; +} + +void +gs_history_dialog_set_app (GsHistoryDialog *dialog, GsApp *app) +{ + const gchar *tmp; + GsAppList *history; + GtkBox *box; + GtkWidget *row; + GtkWidget *widget; + guint64 timestamp; + guint i; + + /* add each history package to the dialog */ + gs_container_remove_all (GTK_CONTAINER (dialog->list_box)); + history = gs_app_get_history (app); + gs_app_list_sort (history, history_sort_cb, NULL); + for (i = 0; i < gs_app_list_length (history); i++) { + g_autoptr(GDateTime) datetime = NULL; + g_autofree gchar *date_str = NULL; + app = gs_app_list_index (history, i); + box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0)); + + /* add the action */ + switch (gs_app_get_state (app)) { + case AS_APP_STATE_AVAILABLE: + case AS_APP_STATE_REMOVING: + /* TRANSLATORS: this is the status in the history UI, + * where we are showing the application was removed */ + tmp = C_("app status", "Removed"); + break; + case AS_APP_STATE_INSTALLED: + case AS_APP_STATE_INSTALLING: + /* TRANSLATORS: this is the status in the history UI, + * where we are showing the application was installed */ + tmp = C_("app status", "Installed"); + break; + case AS_APP_STATE_UPDATABLE: + case AS_APP_STATE_UPDATABLE_LIVE: + /* TRANSLATORS: this is the status in the history UI, + * where we are showing the application was updated */ + tmp = C_("app status", "Updated"); + break; + default: + /* TRANSLATORS: this is the status in the history UI, + * where we are showing that something happened to the + * application but we don't know what */ + tmp = C_("app status", "Unknown"); + break; + } + widget = gtk_label_new (tmp); + g_object_set (widget, + "margin-start", 20, + "margin-end", 20, + "margin-top", 6, + "margin-bottom", 6, + "xalign", 0.0, + "hexpand", TRUE, + NULL); + gtk_size_group_add_widget (dialog->sizegroup_state, widget); + gtk_container_add (GTK_CONTAINER (box), widget); + + /* add the timestamp */ + timestamp = gs_app_get_install_date (app); + datetime = g_date_time_new_from_unix_utc ((gint) timestamp); + if (timestamp == GS_APP_INSTALL_DATE_UNKNOWN) { + date_str = g_strdup (""); + } else { + /* TRANSLATORS: This is the date string with: day number, month name, year. + i.e. "25 May 2012" */ + date_str = g_date_time_format (datetime, _("%e %B %Y")); + } + widget = gtk_label_new (date_str); + g_object_set (widget, + "margin-start", 20, + "margin-end", 20, + "margin-top", 6, + "margin-bottom", 6, + "xalign", 0.0, + "hexpand", TRUE, + NULL); + gtk_size_group_add_widget (dialog->sizegroup_timestamp, widget); + gtk_container_add (GTK_CONTAINER (box), widget); + + /* add the version */ + widget = gtk_label_new (gs_app_get_version (app)); + g_object_set (widget, + "margin-start", 20, + "margin-end", 20, + "margin-top", 6, + "margin-bottom", 6, + "xalign", 1.0, + "ellipsize", PANGO_ELLIPSIZE_END, + "width-chars", 10, + "hexpand", TRUE, + NULL); + gtk_size_group_add_widget (dialog->sizegroup_version, widget); + gtk_container_add (GTK_CONTAINER (box), widget); + + gtk_widget_show_all (GTK_WIDGET (box)); + gtk_list_box_insert (GTK_LIST_BOX (dialog->list_box), GTK_WIDGET (box), -1); + + row = gtk_widget_get_parent (GTK_WIDGET (box)); + gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), FALSE); + } +} + +static void +update_header_func (GtkListBoxRow *row, + GtkListBoxRow *before, + gpointer user_data) +{ + GtkWidget *header; + + /* first entry */ + header = gtk_list_box_row_get_header (row); + if (before == NULL) { + gtk_list_box_row_set_header (row, NULL); + return; + } + + /* already set */ + if (header != NULL) + return; + + /* set new */ + header = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); + gtk_list_box_row_set_header (row, header); +} + +static void +scrollbar_mapped_cb (GtkWidget *sb, GtkScrolledWindow *swin) +{ + GtkWidget *frame; + + frame = gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN (swin)))); + if (gtk_widget_get_mapped (GTK_WIDGET (sb))) { + gtk_scrolled_window_set_shadow_type (swin, GTK_SHADOW_IN); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE); + } else { + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); + gtk_scrolled_window_set_shadow_type (swin, GTK_SHADOW_NONE); + } +} + +static void +gs_history_dialog_dispose (GObject *object) +{ + GsHistoryDialog *dialog = GS_HISTORY_DIALOG (object); + + g_clear_object (&dialog->sizegroup_state); + g_clear_object (&dialog->sizegroup_timestamp); + g_clear_object (&dialog->sizegroup_version); + + G_OBJECT_CLASS (gs_history_dialog_parent_class)->dispose (object); +} + +static void +gs_history_dialog_init (GsHistoryDialog *dialog) +{ + GtkWidget *scrollbar; + + gtk_widget_init_template (GTK_WIDGET (dialog)); + + dialog->sizegroup_state = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + dialog->sizegroup_timestamp = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + dialog->sizegroup_version = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + gtk_list_box_set_header_func (GTK_LIST_BOX (dialog->list_box), + update_header_func, + dialog, + NULL); + + scrollbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (dialog->scrolledwindow)); + g_signal_connect (scrollbar, "map", G_CALLBACK (scrollbar_mapped_cb), dialog->scrolledwindow); + g_signal_connect (scrollbar, "unmap", G_CALLBACK (scrollbar_mapped_cb), dialog->scrolledwindow); +} + +static void +gs_history_dialog_class_init (GsHistoryDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->dispose = gs_history_dialog_dispose; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-history-dialog.ui"); + + gtk_widget_class_bind_template_child (widget_class, GsHistoryDialog, list_box); + gtk_widget_class_bind_template_child (widget_class, GsHistoryDialog, scrolledwindow); +} + +GtkWidget * +gs_history_dialog_new (void) +{ + return GTK_WIDGET (g_object_new (GS_TYPE_HISTORY_DIALOG, + "use-header-bar", TRUE, + NULL)); +} |