Back to index

indicator-session  12.10.0
dialog.c
Go to the documentation of this file.
00001 /*
00002 A dialog to ask the user about the various logout options that
00003 are available.
00004 
00005 Copyright 2010 Canonical Ltd.
00006 
00007 Authors:
00008     Ted Gould <ted@canonical.com>
00009 
00010 This program is free software: you can redistribute it and/or modify it
00011 under the terms of the GNU General Public License version 3, as published
00012 by the Free Software Foundation.
00013 
00014 This program is distributed in the hope that it will be useful, but
00015 WITHOUT ANY WARRANTY; without even the implied warranties of
00016 MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
00017 PURPOSE.  See the GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License along
00020 with this program.  If not, see <http://www.gnu.org/licenses/>.
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 #include <glib/gi18n.h>
00028 
00029 #include "dbus-consolekit-manager.h"
00030 #include "dialog.h"
00031 
00032 /* Strings */
00033 
00034 static const gchar * title_strings[LOGOUT_DIALOG_TYPE_CNT] = {
00035        /* LOGOUT_DIALOG_LOGOUT, */        NC_("title", "Log Out"),
00036        /* LOGOUT_DIALOG_RESTART, */       NC_("title", "Restart"),
00037        /* LOGOUT_DIALOG_SHUTDOWN, */      NC_("title", "Switch Off")
00038 };
00039 
00040 static const gchar * body_strings[LOGOUT_DIALOG_TYPE_CNT] = {
00041        /* LOGOUT_DIALOG_LOGOUT, */        N_("Are you sure you want to close all programs and log out of the computer?"),
00042        /* LOGOUT_DIALOG_RESTART, */       N_("Are you sure you want to close all programs and restart the computer?"),
00043        /* LOGOUT_DIALOG_SHUTDOWN, */      N_("Are you sure you want to close all programs and shut down the computer?")
00044 };
00045 
00046 static const gchar * button_strings[LOGOUT_DIALOG_TYPE_CNT] = {
00047        /* LOGOUT_DIALOG_LOGOUT, */        NC_("button", "Log Out"),
00048        /* LOGOUT_DIALOG_RESTART, */       NC_("button", "Restart"),
00049        /* LOGOUT_DIALOG_SHUTDOWN, */      NC_("button", "Switch Off")
00050 };
00051 
00052 /* TRANSLATORS: These strings have an ellipsis so that the user knows
00053    they are also going to get a password dialog to do the action. */
00054 static const gchar * button_auth_strings[LOGOUT_DIALOG_TYPE_CNT] = {
00055        /* LOGOUT_DIALOG_LOGOUT, */        NC_("button auth", "Log Out"),
00056        /* LOGOUT_DIALOG_RESTART, */       NC_("button auth", "Restart…"),
00057        /* LOGOUT_DIALOG_SHUTDOWN, */      NC_("button auth", "Switch Off…")
00058 };
00059 
00060 /* TRANSLATORS: This button appears on the logout dialog when
00061    there are updates that require restart.  It will do a restart
00062    in place of a log out. */
00063 static const gchar * restart_updates = N_("Restart Instead");
00064 static const gchar * restart_auth = N_("Restart Instead…");
00065 static const gchar * body_logout_update = N_("Some software updates won’t apply until the computer next restarts.");
00066 
00067 static const gchar * icon_strings[LOGOUT_DIALOG_TYPE_CNT] = {
00068        /* LOGOUT_DIALOG_LOGOUT, */        "system-log-out",
00069        /* LOGOUT_DIALOG_RESTART, */       "system-restart",
00070        /* LOGOUT_DIALOG_SHUTDOWN, */      "system-shutdown"
00071 };
00072 
00073 
00074 
00075 typedef struct _LogoutDialogPrivate LogoutDialogPrivate;
00076 struct _LogoutDialogPrivate {
00077        guint type;
00078 };
00079 
00080 #define LOGOUT_DIALOG_GET_PRIVATE(o) \
00081 (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOGOUT_DIALOG_TYPE, LogoutDialogPrivate))
00082 
00083 static void logout_dialog_class_init (LogoutDialogClass *klass);
00084 static void logout_dialog_init       (LogoutDialog *self);
00085 static void logout_dialog_dispose    (GObject *object);
00086 static void logout_dialog_finalize   (GObject *object);
00087 
00088 G_DEFINE_TYPE (LogoutDialog, logout_dialog, GTK_TYPE_MESSAGE_DIALOG);
00089 
00090 static void
00091 logout_dialog_class_init (LogoutDialogClass *klass)
00092 {
00093        GObjectClass *object_class = G_OBJECT_CLASS (klass);
00094 
00095        g_type_class_add_private (klass, sizeof (LogoutDialogPrivate));
00096 
00097        object_class->dispose = logout_dialog_dispose;
00098        object_class->finalize = logout_dialog_finalize;
00099 
00100        return;
00101 }
00102 
00103 static void
00104 logout_dialog_init (LogoutDialog *self)
00105 {
00106 
00107        return;
00108 }
00109 
00110 static void
00111 logout_dialog_dispose (GObject *object)
00112 {
00113 
00114 
00115        G_OBJECT_CLASS (logout_dialog_parent_class)->dispose (object);
00116        return;
00117 }
00118 
00119 static void
00120 logout_dialog_finalize (GObject *object)
00121 {
00122 
00123 
00124        G_OBJECT_CLASS (logout_dialog_parent_class)->finalize (object);
00125        return;
00126 }
00127 
00128 /* Checks for updates that would signal that a restart is
00129    required for them to apply */
00130 static gboolean
00131 check_restart_required (void)
00132 {
00133        return g_file_test("/var/run/reboot-required", G_FILE_TEST_EXISTS);
00134 }
00135 
00136 /* Checks with console kit to see if we can do what we want */
00137 static gboolean
00138 ck_check_allowed (LogoutDialogType type)
00139 {
00140        gboolean allowed = TRUE;
00141 
00142        ConsoleKitManager * ck_proxy = console_kit_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
00143                                                                                   G_DBUS_PROXY_FLAGS_NONE,
00144                                                                                   "org.freedesktop.ConsoleKit",
00145                                                                                   "/org/freedesktop/ConsoleKit/Manager",
00146                                                                                   NULL,
00147                                                                                   NULL);
00148        if (ck_proxy != NULL)
00149        {
00150               switch (type) {
00151               case LOGOUT_DIALOG_TYPE_RESTART:
00152                      console_kit_manager_call_can_restart_sync (ck_proxy, &allowed, NULL, NULL);
00153                      break;
00154               case LOGOUT_DIALOG_TYPE_SHUTDOWN:
00155                      console_kit_manager_call_can_stop_sync (ck_proxy, &allowed, NULL, NULL);
00156                      break;
00157               default:
00158                      break;
00159               }
00160 
00161               g_object_unref(ck_proxy);
00162        }
00163 
00164        return allowed;
00165 }
00166 
00167 LogoutDialog *
00168 logout_dialog_new (LogoutDialogType type)
00169 {
00170        GtkWidget * image = gtk_image_new_from_icon_name(icon_strings[type], GTK_ICON_SIZE_DIALOG);
00171        gtk_widget_show(image);
00172 
00173        LogoutDialog * dialog = LOGOUT_DIALOG(g_object_new(LOGOUT_DIALOG_TYPE,
00174                                              /* Window */
00175                                              "icon-name", icon_strings[type],
00176                                              "modal", TRUE,
00177                                              "resizable", FALSE,
00178                                              "title", g_dpgettext2 (NULL, "title", title_strings[type]),
00179                                              "window-position", GTK_WIN_POS_CENTER_ALWAYS,
00180                                              /* Message Dialog */
00181                                              "buttons", GTK_BUTTONS_NONE,
00182                                              "image", image,
00183                                              "message-type", GTK_MESSAGE_OTHER,
00184                                              "text", _(body_strings[type]),
00185                                              NULL));
00186 
00187        gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
00188 
00189        gboolean allowed = FALSE;
00190        if (type == LOGOUT_DIALOG_TYPE_LOG_OUT) {
00191               allowed = ck_check_allowed(LOGOUT_DIALOG_TYPE_RESTART);
00192        } else {
00193               allowed = ck_check_allowed(type);
00194        }
00195 
00196        gboolean restart_required = FALSE;
00197        if (type == LOGOUT_DIALOG_TYPE_LOG_OUT) {
00198               restart_required = check_restart_required();
00199        }
00200 
00201        const gchar * button_text;
00202        if (allowed) {
00203               button_text = g_dpgettext2 (NULL, "button", button_strings[type]);
00204        } else {
00205               button_text = g_dpgettext2 (NULL, "button auth", button_auth_strings[type]);
00206        }
00207 
00208        if (restart_required) {
00209               const gchar * restart_req;
00210               if (allowed) {
00211                      restart_req = restart_updates;
00212               } else {
00213                      restart_req = restart_auth;
00214               }
00215 
00216               g_object_set(dialog, "secondary-text", _(body_logout_update), NULL);
00217 
00218               gtk_dialog_add_buttons(GTK_DIALOG(dialog),
00219                                      _(restart_req), GTK_RESPONSE_HELP,
00220                                      _("Cancel"), GTK_RESPONSE_CANCEL,
00221                                      button_text, GTK_RESPONSE_OK,
00222                                      NULL);
00223        } else {
00224               gtk_dialog_add_buttons(GTK_DIALOG(dialog),
00225                                      _("Cancel"), GTK_RESPONSE_CANCEL,
00226                                      button_text, GTK_RESPONSE_OK,
00227                                      NULL);
00228        }
00229 
00230        if (type == LOGOUT_DIALOG_TYPE_SHUTDOWN) {
00231               const gchar * restart_text;
00232               restart_text = g_dpgettext2 (NULL, "button", button_strings[LOGOUT_DIALOG_TYPE_RESTART]);
00233               gtk_dialog_add_button (GTK_DIALOG(dialog), restart_text, GTK_RESPONSE_HELP);
00234        }
00235 
00236        gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
00237 
00238         /* The following  is a workaround to fix an issue in GtkMessageDialog
00239            in which the user can tab through the text in addition to
00240            the buttons. */
00241         GtkWidget *message_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog));
00242         GList *children = gtk_container_get_children(GTK_CONTAINER(message_area));
00243         GList *l;
00244 
00245         for (l = children; l != NULL; l = g_list_next (l))
00246         {
00247                 GtkWidget *child = l->data;
00248                 gtk_widget_set_can_focus(child, FALSE);
00249         }
00250 
00251         g_list_free (children);
00252 
00253        return dialog;
00254 }