~larsu/indicator-session/glib-deadlock-workaround

« back to all changes in this revision

Viewing changes to src/dialog.c

  • Committer: Charles Kerr
  • Date: 2013-03-22 21:34:34 UTC
  • mto: (384.2.29 ng)
  • mto: This revision was merged to the branch mainline in revision 399.
  • Revision ID: charles.kerr@canonical.com-20130322213434-a85qbob8bi4fvfx2
port indicator-session to GMenu/cmake. Code coverage increased from 0% to 95.4%.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
A dialog to ask the user about the various logout options that
3
 
are available.
4
 
 
5
 
Copyright 2010 Canonical Ltd.
6
 
 
7
 
Authors:
8
 
    Ted Gould <ted@canonical.com>
9
 
 
10
 
This program is free software: you can redistribute it and/or modify it
11
 
under the terms of the GNU General Public License version 3, as published
12
 
by the Free Software Foundation.
13
 
 
14
 
This program is distributed in the hope that it will be useful, but
15
 
WITHOUT ANY WARRANTY; without even the implied warranties of
16
 
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
17
 
PURPOSE.  See the GNU General Public License for more details.
18
 
 
19
 
You should have received a copy of the GNU General Public License along
20
 
with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 
*/
22
 
 
23
 
#ifdef HAVE_CONFIG_H
24
 
#include "config.h"
25
 
#endif
26
 
 
27
 
#include <glib/gi18n.h>
28
 
 
29
 
#include "dbus-consolekit-manager.h"
30
 
#include "dialog.h"
31
 
 
32
 
/* Strings */
33
 
 
34
 
static const gchar * title_strings[LOGOUT_DIALOG_TYPE_CNT] = {
35
 
        /* LOGOUT_DIALOG_LOGOUT, */     NC_("title", "Log Out"),
36
 
        /* LOGOUT_DIALOG_RESTART, */    NC_("title", "Restart"),
37
 
        /* LOGOUT_DIALOG_SHUTDOWN, */   NC_("title", "Shut Down")
38
 
};
39
 
 
40
 
static const gchar * body_strings[LOGOUT_DIALOG_TYPE_CNT] = {
41
 
        /* LOGOUT_DIALOG_LOGOUT, */     N_("Are you sure you want to close all programs and log out of the computer?"),
42
 
        /* LOGOUT_DIALOG_RESTART, */    N_("Are you sure you want to close all programs and restart the computer?"),
43
 
        /* LOGOUT_DIALOG_SHUTDOWN, */   N_("Are you sure you want to close all programs and shut down the computer?")
44
 
};
45
 
 
46
 
static const gchar * button_strings[LOGOUT_DIALOG_TYPE_CNT] = {
47
 
        /* LOGOUT_DIALOG_LOGOUT, */     NC_("button", "Log Out"),
48
 
        /* LOGOUT_DIALOG_RESTART, */    NC_("button", "Restart"),
49
 
        /* LOGOUT_DIALOG_SHUTDOWN, */   NC_("button", "Shut Down")
50
 
};
51
 
 
52
 
/* TRANSLATORS: These strings have an ellipsis so that the user knows
53
 
   they are also going to get a password dialog to do the action. */
54
 
static const gchar * button_auth_strings[LOGOUT_DIALOG_TYPE_CNT] = {
55
 
        /* LOGOUT_DIALOG_LOGOUT, */     NC_("button auth", "Log Out"),
56
 
        /* LOGOUT_DIALOG_RESTART, */    NC_("button auth", "Restart…"),
57
 
        /* LOGOUT_DIALOG_SHUTDOWN, */   NC_("button auth", "Shut Down…")
58
 
};
59
 
 
60
 
/* TRANSLATORS: This button appears on the logout dialog when
61
 
   there are updates that require restart.  It will do a restart
62
 
   in place of a log out. */
63
 
static const gchar * restart_updates = N_("Restart Instead");
64
 
static const gchar * restart_auth = N_("Restart Instead…");
65
 
static const gchar * body_logout_update = N_("Some software updates won’t apply until the computer next restarts.");
66
 
 
67
 
static const gchar * icon_strings[LOGOUT_DIALOG_TYPE_CNT] = {
68
 
        /* LOGOUT_DIALOG_LOGOUT, */     "system-log-out",
69
 
        /* LOGOUT_DIALOG_RESTART, */    "system-restart",
70
 
        /* LOGOUT_DIALOG_SHUTDOWN, */   "system-shutdown"
71
 
};
72
 
 
73
 
 
74
 
 
75
 
typedef struct _LogoutDialogPrivate LogoutDialogPrivate;
76
 
struct _LogoutDialogPrivate {
77
 
        guint type;
78
 
};
79
 
 
80
 
#define LOGOUT_DIALOG_GET_PRIVATE(o) \
81
 
(G_TYPE_INSTANCE_GET_PRIVATE ((o), LOGOUT_DIALOG_TYPE, LogoutDialogPrivate))
82
 
 
83
 
static void logout_dialog_class_init (LogoutDialogClass *klass);
84
 
static void logout_dialog_init       (LogoutDialog *self);
85
 
static void logout_dialog_dispose    (GObject *object);
86
 
static void logout_dialog_finalize   (GObject *object);
87
 
 
88
 
G_DEFINE_TYPE (LogoutDialog, logout_dialog, GTK_TYPE_MESSAGE_DIALOG);
89
 
 
90
 
static void
91
 
logout_dialog_class_init (LogoutDialogClass *klass)
92
 
{
93
 
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
94
 
 
95
 
        g_type_class_add_private (klass, sizeof (LogoutDialogPrivate));
96
 
 
97
 
        object_class->dispose = logout_dialog_dispose;
98
 
        object_class->finalize = logout_dialog_finalize;
99
 
 
100
 
        return;
101
 
}
102
 
 
103
 
static void
104
 
logout_dialog_init (LogoutDialog *self)
105
 
{
106
 
 
107
 
        return;
108
 
}
109
 
 
110
 
static void
111
 
logout_dialog_dispose (GObject *object)
112
 
{
113
 
 
114
 
 
115
 
        G_OBJECT_CLASS (logout_dialog_parent_class)->dispose (object);
116
 
        return;
117
 
}
118
 
 
119
 
static void
120
 
logout_dialog_finalize (GObject *object)
121
 
{
122
 
 
123
 
 
124
 
        G_OBJECT_CLASS (logout_dialog_parent_class)->finalize (object);
125
 
        return;
126
 
}
127
 
 
128
 
/* Checks for updates that would signal that a restart is
129
 
   required for them to apply */
130
 
static gboolean
131
 
check_restart_required (void)
132
 
{
133
 
        return g_file_test("/var/run/reboot-required", G_FILE_TEST_EXISTS);
134
 
}
135
 
 
136
 
/* Checks with console kit to see if we can do what we want */
137
 
static gboolean
138
 
ck_check_allowed (LogoutDialogType type)
139
 
{
140
 
        gboolean allowed = TRUE;
141
 
 
142
 
        ConsoleKitManager * ck_proxy = console_kit_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
143
 
                                                                                   G_DBUS_PROXY_FLAGS_NONE,
144
 
                                                                                   "org.freedesktop.ConsoleKit",
145
 
                                                                                   "/org/freedesktop/ConsoleKit/Manager",
146
 
                                                                                   NULL,
147
 
                                                                                   NULL);
148
 
        if (ck_proxy != NULL)
149
 
        {
150
 
                switch (type) {
151
 
                case LOGOUT_DIALOG_TYPE_RESTART:
152
 
                        console_kit_manager_call_can_restart_sync (ck_proxy, &allowed, NULL, NULL);
153
 
                        break;
154
 
                case LOGOUT_DIALOG_TYPE_SHUTDOWN:
155
 
                        console_kit_manager_call_can_stop_sync (ck_proxy, &allowed, NULL, NULL);
156
 
                        break;
157
 
                default:
158
 
                        break;
159
 
                }
160
 
 
161
 
                g_object_unref(ck_proxy);
162
 
        }
163
 
 
164
 
        return allowed;
165
 
}
166
 
 
167
 
LogoutDialog *
168
 
logout_dialog_new (LogoutDialogType type)
169
 
{
170
 
        GtkWidget * image = gtk_image_new_from_icon_name(icon_strings[type], GTK_ICON_SIZE_DIALOG);
171
 
        gtk_widget_show(image);
172
 
 
173
 
        LogoutDialog * dialog = LOGOUT_DIALOG(g_object_new(LOGOUT_DIALOG_TYPE,
174
 
                                              /* Window */
175
 
                                              "icon-name", icon_strings[type],
176
 
                                              "modal", TRUE,
177
 
                                              "resizable", FALSE,
178
 
                                              "title", g_dpgettext2 (NULL, "title", title_strings[type]),
179
 
                                              "window-position", GTK_WIN_POS_CENTER_ALWAYS,
180
 
                                              /* Message Dialog */
181
 
                                              "buttons", GTK_BUTTONS_NONE,
182
 
                                              "image", image,
183
 
                                              "message-type", GTK_MESSAGE_OTHER,
184
 
                                              "text", _(body_strings[type]),
185
 
                                              NULL));
186
 
 
187
 
        gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE);
188
 
 
189
 
        gboolean allowed = FALSE;
190
 
        if (type == LOGOUT_DIALOG_TYPE_LOG_OUT) {
191
 
                allowed = ck_check_allowed(LOGOUT_DIALOG_TYPE_RESTART);
192
 
        } else {
193
 
                allowed = ck_check_allowed(type);
194
 
        }
195
 
 
196
 
        gboolean restart_required = FALSE;
197
 
        if (type == LOGOUT_DIALOG_TYPE_LOG_OUT) {
198
 
                restart_required = check_restart_required();
199
 
        }
200
 
 
201
 
        const gchar * button_text;
202
 
        if (allowed) {
203
 
                button_text = g_dpgettext2 (NULL, "button", button_strings[type]);
204
 
        } else {
205
 
                button_text = g_dpgettext2 (NULL, "button auth", button_auth_strings[type]);
206
 
        }
207
 
 
208
 
        if (restart_required) {
209
 
                const gchar * restart_req;
210
 
                if (allowed) {
211
 
                        restart_req = restart_updates;
212
 
                } else {
213
 
                        restart_req = restart_auth;
214
 
                }
215
 
 
216
 
                g_object_set(dialog, "secondary-text", _(body_logout_update), NULL);
217
 
 
218
 
                gtk_dialog_add_buttons(GTK_DIALOG(dialog),
219
 
                                       _(restart_req), GTK_RESPONSE_HELP,
220
 
                                       _("Cancel"), GTK_RESPONSE_CANCEL,
221
 
                                       button_text, GTK_RESPONSE_OK,
222
 
                                       NULL);
223
 
        } else {
224
 
                gtk_dialog_add_buttons(GTK_DIALOG(dialog),
225
 
                                       _("Cancel"), GTK_RESPONSE_CANCEL,
226
 
                                       button_text, GTK_RESPONSE_OK,
227
 
                                       NULL);
228
 
        }
229
 
 
230
 
        gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
231
 
 
232
 
        /* The following  is a workaround to fix an issue in GtkMessageDialog
233
 
           in which the user can tab through the text in addition to
234
 
           the buttons. */
235
 
        GtkWidget *message_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog));
236
 
        GList *children = gtk_container_get_children(GTK_CONTAINER(message_area));
237
 
        GList *l;
238
 
 
239
 
        for (l = children; l != NULL; l = g_list_next (l))
240
 
        {
241
 
                GtkWidget *child = l->data;
242
 
                gtk_widget_set_can_focus(child, FALSE);
243
 
        }
244
 
 
245
 
        g_list_free (children);
246
 
 
247
 
        return dialog;
248
 
}