summaryrefslogtreecommitdiffstats
path: root/panels/user-accounts/cc-login-history-dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'panels/user-accounts/cc-login-history-dialog.c')
-rw-r--r--panels/user-accounts/cc-login-history-dialog.c346
1 files changed, 346 insertions, 0 deletions
diff --git a/panels/user-accounts/cc-login-history-dialog.c b/panels/user-accounts/cc-login-history-dialog.c
new file mode 100644
index 0000000..fcb7457
--- /dev/null
+++ b/panels/user-accounts/cc-login-history-dialog.c
@@ -0,0 +1,346 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright 2012 Red Hat, Inc,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Written by: Ondrej Holy <oholy@redhat.com>
+ */
+
+#include "config.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <adwaita.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <act/act.h>
+
+#include "cc-login-history-dialog.h"
+#include "cc-user-accounts-resources.h"
+#include "cc-util.h"
+#include "user-utils.h"
+
+struct _CcLoginHistoryDialog
+{
+ GtkDialog parent_instance;
+
+ GtkHeaderBar *header_bar;
+ GtkLabel *title_label;
+ GtkListBox *history_box;
+ GtkButton *next_button;
+ GtkButton *previous_button;
+
+ GDateTime *week;
+ GDateTime *current_week;
+
+ ActUser *user;
+};
+
+G_DEFINE_TYPE (CcLoginHistoryDialog, cc_login_history_dialog, GTK_TYPE_DIALOG)
+
+typedef struct {
+ gint64 login_time;
+ gint64 logout_time;
+ const gchar *type;
+} CcLoginHistory;
+
+static void
+show_week_label (CcLoginHistoryDialog *self)
+{
+ g_autofree gchar *label = NULL;
+ GTimeSpan span;
+
+ span = g_date_time_difference (self->current_week, self->week);
+ if (span == 0) {
+ label = g_strdup (_("This Week"));
+ }
+ else if (span == G_TIME_SPAN_DAY * 7) {
+ label = g_strdup (_("Last Week"));
+ }
+ else {
+ g_autofree gchar *from = NULL;
+ g_autofree gchar *to = NULL;
+ g_autoptr(GDateTime) date = NULL;
+
+ date = g_date_time_add_days (self->week, 6);
+ /* Translators: This is a date format string in the style of "Feb 18",
+ shown as the first day of a week on login history dialog. */
+ from = g_date_time_format (self->week, C_("login history week label","%b %e"));
+ if (g_date_time_get_year (self->week) == g_date_time_get_year (self->current_week)) {
+ /* Translators: This is a date format string in the style of "Feb 24",
+ shown as the last day of a week on login history dialog. */
+ to = g_date_time_format (date, C_("login history week label","%b %e"));
+ }
+ else {
+ /* Translators: This is a date format string in the style of "Feb 24, 2013",
+ shown as the last day of a week on login history dialog. */
+ to = g_date_time_format (date, C_("login history week label","%b %e, %Y"));
+ }
+
+ /* Translators: This indicates a week label on a login history.
+ The first %s is the first day of a week, and the second %s the last day. */
+ label = g_strdup_printf(C_("login history week label", "%s — %s"), from, to);
+ }
+
+ gtk_label_set_label (self->title_label, label);
+}
+
+static void
+clear_history (CcLoginHistoryDialog *self)
+{
+ GtkWidget *child;
+
+ child = gtk_widget_get_first_child (GTK_WIDGET (self->history_box));
+ while (child) {
+ GtkWidget *next = gtk_widget_get_next_sibling (child);
+
+ if (ADW_ACTION_ROW (child))
+ gtk_list_box_remove (self->history_box, GTK_WIDGET (child));
+
+ child = next;
+ }
+}
+
+static GArray *
+get_login_history (ActUser *user)
+{
+ GArray *login_history;
+ GVariantIter *iter, *iter2;
+ GVariant *variant;
+ const GVariant *value;
+ const gchar *key;
+ CcLoginHistory history;
+
+ login_history = NULL;
+ value = act_user_get_login_history (user);
+ g_variant_get ((GVariant *) value, "a(xxa{sv})", &iter);
+ while (g_variant_iter_loop (iter, "(xxa{sv})", &history.login_time, &history.logout_time, &iter2)) {
+ while (g_variant_iter_loop (iter2, "{&sv}", &key, &variant)) {
+ if (g_strcmp0 (key, "type") == 0) {
+ history.type = g_variant_get_string (variant, NULL);
+ }
+ }
+
+ if (login_history == NULL) {
+ login_history = g_array_new (FALSE, TRUE, sizeof (CcLoginHistory));
+ }
+
+ g_array_append_val (login_history, history);
+ }
+
+ return login_history;
+}
+
+static void
+set_sensitivity (CcLoginHistoryDialog *self)
+{
+ g_autoptr(GArray) login_history = NULL;
+ CcLoginHistory history;
+ gboolean sensitive = FALSE;
+
+ login_history = get_login_history (self->user);
+ if (login_history != NULL) {
+ history = g_array_index (login_history, CcLoginHistory, 0);
+ sensitive = g_date_time_to_unix (self->week) > history.login_time;
+ }
+ gtk_widget_set_sensitive (GTK_WIDGET (self->previous_button), sensitive);
+
+ sensitive = (g_date_time_compare (self->current_week, self->week) == 1);
+ gtk_widget_set_sensitive (GTK_WIDGET (self->next_button), sensitive);
+}
+
+static void
+add_record (CcLoginHistoryDialog *self, GDateTime *datetime, gchar *record_string, gint line)
+{
+ g_autofree gchar *date = NULL;
+ g_autofree gchar *time = NULL;
+ g_autofree gchar *str = NULL;
+ GtkWidget *row;
+
+ date = cc_util_get_smart_date (datetime);
+ /* Translators: This is a time format string in the style of "22:58".
+ It indicates a login time which follows a date. */
+ time = g_date_time_format (datetime, C_("login date-time", "%k:%M"));
+ /* Translators: This indicates a login date-time.
+ The first %s is a date, and the second %s a time. */
+ str = g_strdup_printf(C_("login date-time", "%s, %s"), date, time);
+
+ row = adw_action_row_new ();
+ adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), record_string);
+ adw_action_row_set_subtitle (ADW_ACTION_ROW (row), str);
+
+ gtk_list_box_insert (self->history_box, row, line);
+}
+
+static void
+show_week (CcLoginHistoryDialog *self)
+{
+ g_autoptr(GArray) login_history = NULL;
+ g_autoptr(GDateTime) datetime = NULL;
+ g_autoptr(GDateTime) temp = NULL;
+ gint64 from, to;
+ gint i, line;
+ CcLoginHistory history;
+
+ show_week_label (self);
+ clear_history (self);
+ set_sensitivity (self);
+
+ login_history = get_login_history (self->user);
+ if (login_history == NULL) {
+ return;
+ }
+
+ /* Find first record for week */
+ from = g_date_time_to_unix (self->week);
+ temp = g_date_time_add_weeks (self->week, 1);
+ to = g_date_time_to_unix (temp);
+ for (i = login_history->len - 1; i >= 0; i--) {
+ history = g_array_index (login_history, CcLoginHistory, i);
+ if (history.login_time < to) {
+ break;
+ }
+ }
+
+ /* Add new session records */
+ line = 0;
+ for (;i >= 0; i--) {
+ history = g_array_index (login_history, CcLoginHistory, i);
+
+ /* Display only x-session and tty records */
+ if (!g_str_has_prefix (history.type, ":") &&
+ !g_str_has_prefix (history.type, "tty")) {
+ continue;
+ }
+
+ if (history.logout_time > 0 && history.logout_time < from) {
+ break;
+ }
+
+ if (history.logout_time > 0 && history.logout_time < to) {
+ datetime = g_date_time_new_from_unix_local (history.logout_time);
+ add_record (self, datetime, _("Session Ended"), line);
+ line++;
+ }
+
+ if (history.login_time >= from) {
+ datetime = g_date_time_new_from_unix_local (history.login_time);
+ add_record (self, datetime, _("Session Started"), line);
+ line++;
+ }
+ }
+}
+
+static void
+previous_button_clicked_cb (CcLoginHistoryDialog *self)
+{
+ g_autoptr(GDateTime) temp = NULL;
+
+ temp = self->week;
+ self->week = g_date_time_add_weeks (self->week, -1);
+
+ show_week (self);
+}
+
+static void
+next_button_clicked_cb (CcLoginHistoryDialog *self)
+{
+ g_autoptr(GDateTime) temp = NULL;
+
+ temp = self->week;
+ self->week = g_date_time_add_weeks (self->week, 1);
+
+ show_week (self);
+}
+
+static void
+cc_login_history_dialog_dispose (GObject *object)
+{
+ CcLoginHistoryDialog *self = CC_LOGIN_HISTORY_DIALOG (object);
+
+ g_clear_object (&self->user);
+ g_clear_pointer (&self->week, g_date_time_unref);
+ g_clear_pointer (&self->current_week, g_date_time_unref);
+
+ G_OBJECT_CLASS (cc_login_history_dialog_parent_class)->dispose (object);
+}
+
+void
+cc_login_history_dialog_class_init (CcLoginHistoryDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->dispose = cc_login_history_dialog_dispose;
+
+ gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/user-accounts/cc-login-history-dialog.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, header_bar);
+ gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, title_label);
+ gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, history_box);
+ gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, next_button);
+ gtk_widget_class_bind_template_child (widget_class, CcLoginHistoryDialog, previous_button);
+
+ gtk_widget_class_bind_template_callback (widget_class, next_button_clicked_cb);
+ gtk_widget_class_bind_template_callback (widget_class, previous_button_clicked_cb);
+}
+
+void
+cc_login_history_dialog_init (CcLoginHistoryDialog *self)
+{
+ g_resources_register (cc_user_accounts_get_resource ());
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+}
+
+CcLoginHistoryDialog *
+cc_login_history_dialog_new (ActUser *user)
+{
+ CcLoginHistoryDialog *self;
+ g_autoptr(GDateTime) temp = NULL;
+ g_autoptr(GDateTime) local = NULL;
+ g_autofree gchar *title = NULL;
+
+ g_return_val_if_fail (ACT_IS_USER (user), NULL);
+
+ self = g_object_new (CC_TYPE_LOGIN_HISTORY_DIALOG,
+ "use-header-bar", 1,
+ NULL);
+
+ self->user = g_object_ref (user);
+
+ /* Set the first day of this week */
+ local = g_date_time_new_now_local ();
+ temp = g_date_time_new_local (g_date_time_get_year (local),
+ g_date_time_get_month (local),
+ g_date_time_get_day_of_month (local),
+ 0, 0, 0);
+ self->week = g_date_time_add_days (temp, 1 - g_date_time_get_day_of_week (temp));
+ self->current_week = g_date_time_ref (self->week);
+
+ /* Translators: This is the title of the "Account Activity" dialog.
+ The %s is the user real name. */
+ title = g_strdup_printf (_("%s — Account Activity"),
+ act_user_get_real_name (self->user));
+ gtk_label_set_label (self->title_label, title);
+
+ show_week (self);
+
+ return self;
+}