]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-base-password-dialog.c
688bbe8c4cb79e7d23fabf6720d3b1213ff79d0f
[empathy.git] / libempathy-gtk / empathy-base-password-dialog.c
1 /*
2  * empathy-base-password-dialog.c - Source for EmpathyBasePasswordDialog
3  * Copyright (C) 2010 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19
20 #include "config.h"
21
22 #include "empathy-base-password-dialog.h"
23
24 #include <glib/gi18n-lib.h>
25
26 #define DEBUG_FLAG EMPATHY_DEBUG_SASL
27 #include "libempathy/empathy-debug.h"
28 #include "libempathy/empathy-utils.h"
29
30 G_DEFINE_TYPE (EmpathyBasePasswordDialog, empathy_base_password_dialog,
31     GTK_TYPE_MESSAGE_DIALOG)
32
33 enum {
34   PROP_ACCOUNT = 1,
35
36   LAST_PROPERTY,
37 };
38
39 struct _EmpathyBasePasswordDialogPriv {
40   gboolean grabbing;
41 };
42
43 static void
44 empathy_base_password_dialog_get_property (GObject *object,
45     guint property_id,
46     GValue *value,
47     GParamSpec *pspec)
48 {
49   EmpathyBasePasswordDialog *self = (EmpathyBasePasswordDialog *) object;
50
51   switch (property_id)
52     {
53     case PROP_ACCOUNT:
54       g_value_set_object (value, self->account);
55       break;
56     default:
57       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
58       break;
59     }
60 }
61
62 static void
63 empathy_base_password_dialog_set_property (GObject *object,
64     guint property_id,
65     const GValue *value,
66     GParamSpec *pspec)
67 {
68   EmpathyBasePasswordDialog *self = (EmpathyBasePasswordDialog *) object;
69
70   switch (property_id)
71     {
72     case PROP_ACCOUNT:
73       g_assert (self->account == NULL); /* construct only */
74       self->account = g_value_dup_object (value);
75       break;
76     default:
77       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
78       break;
79     }
80 }
81
82 static void
83 empathy_base_password_dialog_dispose (GObject *object)
84 {
85   EmpathyBasePasswordDialog *self = (EmpathyBasePasswordDialog *) object;
86
87   tp_clear_object (&self->account);
88
89   G_OBJECT_CLASS (empathy_base_password_dialog_parent_class)->dispose (object);
90 }
91
92 static void
93 clear_icon_released_cb (GtkEntry *entry,
94     GtkEntryIconPosition icon_pos,
95     GdkEvent *event,
96     gpointer user_data)
97 {
98   gtk_entry_set_text (entry, "");
99 }
100
101 static void
102 password_entry_changed_cb (GtkEditable *entry,
103     gpointer user_data)
104 {
105   EmpathyBasePasswordDialog *self = user_data;
106   const gchar *str;
107
108   str = gtk_entry_get_text (GTK_ENTRY (entry));
109
110   gtk_entry_set_icon_sensitive (GTK_ENTRY (entry),
111       GTK_ENTRY_ICON_SECONDARY, !EMP_STR_EMPTY (str));
112
113   gtk_widget_set_sensitive (self->ok_button,
114       !EMP_STR_EMPTY (str));
115 }
116
117 static void
118 password_entry_activate_cb (GtkEntry *entry,
119     EmpathyBasePasswordDialog *self)
120 {
121   gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
122 }
123
124 static gboolean
125 base_password_dialog_grab_keyboard (GtkWidget *widget,
126     GdkEvent *event,
127     gpointer user_data)
128 {
129   EmpathyBasePasswordDialog *self = user_data;
130
131   if (!self->priv->grabbing)
132     {
133       GdkDevice *device = gdk_event_get_device (event);
134
135       if (device != NULL)
136         {
137           GdkGrabStatus status = gdk_device_grab (device,
138               gtk_widget_get_window (widget),
139               GDK_OWNERSHIP_WINDOW,
140               FALSE,
141               GDK_ALL_EVENTS_MASK,
142               NULL,
143               gdk_event_get_time (event));
144
145           if (status != GDK_GRAB_SUCCESS)
146             DEBUG ("Could not grab keyboard; grab status was %u", status);
147           else
148             self->priv->grabbing = TRUE;
149         }
150       else
151         DEBUG ("Could not get the event device!");
152     }
153
154   return FALSE;
155 }
156
157 static gboolean
158 base_password_dialog_ungrab_keyboard (GtkWidget *widget,
159     GdkEvent *event,
160     gpointer user_data)
161 {
162   EmpathyBasePasswordDialog *self = user_data;
163
164   if (self->priv->grabbing)
165     {
166       GdkDevice *device = gdk_event_get_device (event);
167
168       if (device != NULL)
169         {
170           gdk_device_ungrab (device, gdk_event_get_time (event));
171           self->priv->grabbing = FALSE;
172         }
173       else
174         DEBUG ("Could not get the event device!");
175     }
176
177   return FALSE;
178 }
179
180 static gboolean
181 base_password_dialog_window_state_changed (GtkWidget *widget,
182     GdkEventWindowState *event,
183     gpointer data)
184 {
185   GdkWindowState state = gdk_window_get_state (gtk_widget_get_window (widget));
186
187   if (state & GDK_WINDOW_STATE_WITHDRAWN
188       || state & GDK_WINDOW_STATE_ICONIFIED
189       || state & GDK_WINDOW_STATE_FULLSCREEN
190       || state & GDK_WINDOW_STATE_MAXIMIZED)
191     {
192       base_password_dialog_ungrab_keyboard (widget, (GdkEvent *) event, data);
193     }
194   else
195     {
196       base_password_dialog_grab_keyboard (widget, (GdkEvent *) event, data);
197     }
198
199   return FALSE;
200 }
201
202 static void
203 empathy_base_password_dialog_constructed (GObject *object)
204 {
205   EmpathyBasePasswordDialog *self;
206   GtkWidget *icon;
207   GtkBox *box;
208   gchar *text;
209
210   self = EMPATHY_BASE_PASSWORD_DIALOG (object);
211
212   g_assert (self->account != NULL);
213
214   self->priv->grabbing = FALSE;
215
216   /* dialog */
217   gtk_dialog_add_button (GTK_DIALOG (self),
218       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
219
220   self->ok_button = gtk_dialog_add_button (GTK_DIALOG (self),
221       GTK_STOCK_OK, GTK_RESPONSE_OK);
222   gtk_widget_set_sensitive (self->ok_button, FALSE);
223
224   text = g_strdup_printf (_("Enter your password for account\n<b>%s</b>"),
225       tp_account_get_display_name (self->account));
226   gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (self), text);
227   g_free (text);
228
229   gtk_window_set_icon_name (GTK_WINDOW (self),
230       GTK_STOCK_DIALOG_AUTHENTICATION);
231
232   box = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self)));
233
234   /* dialog icon */
235   icon = gtk_image_new_from_icon_name (
236       tp_account_get_icon_name (self->account), GTK_ICON_SIZE_DIALOG);
237   gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (self), icon);
238   gtk_widget_show (icon);
239
240   /* entry */
241   self->entry = gtk_entry_new ();
242   gtk_entry_set_visibility (GTK_ENTRY (self->entry), FALSE);
243
244   /* entry clear icon */
245   gtk_entry_set_icon_from_stock (GTK_ENTRY (self->entry),
246       GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_CLEAR);
247   gtk_entry_set_icon_sensitive (GTK_ENTRY (self->entry),
248       GTK_ENTRY_ICON_SECONDARY, FALSE);
249
250   g_signal_connect (self->entry, "icon-release",
251       G_CALLBACK (clear_icon_released_cb), NULL);
252   g_signal_connect (self->entry, "changed",
253       G_CALLBACK (password_entry_changed_cb), self);
254   g_signal_connect (self->entry, "activate",
255       G_CALLBACK (password_entry_activate_cb), self);
256
257   gtk_box_pack_start (box, self->entry, FALSE, FALSE, 0);
258   gtk_widget_show (self->entry);
259
260   /* remember password ticky box */
261   self->ticky = gtk_check_button_new_with_label (_("Remember password"));
262
263   gtk_box_pack_start (box, self->ticky, FALSE, FALSE, 0);
264
265   g_signal_connect (self, "window-state-event",
266       G_CALLBACK (base_password_dialog_window_state_changed), self);
267   g_signal_connect (self, "map-event",
268       G_CALLBACK (base_password_dialog_grab_keyboard), self);
269   g_signal_connect (self, "unmap-event",
270       G_CALLBACK (base_password_dialog_ungrab_keyboard), self);
271
272   gtk_widget_grab_focus (self->entry);
273
274   gtk_window_set_position (GTK_WINDOW (self), GTK_WIN_POS_CENTER_ALWAYS);
275
276   gtk_window_set_keep_above (GTK_WINDOW (self), TRUE);
277 }
278
279 static void
280 empathy_base_password_dialog_init (EmpathyBasePasswordDialog *self)
281 {
282   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
283       EMPATHY_TYPE_BASE_PASSWORD_DIALOG, EmpathyBasePasswordDialogPriv);
284 }
285
286 static void
287 empathy_base_password_dialog_class_init (EmpathyBasePasswordDialogClass *klass)
288 {
289   GParamSpec *pspec;
290   GObjectClass *oclass = G_OBJECT_CLASS (klass);
291
292   g_type_class_add_private (klass, sizeof (EmpathyBasePasswordDialogPriv));
293
294   oclass->set_property = empathy_base_password_dialog_set_property;
295   oclass->get_property = empathy_base_password_dialog_get_property;
296   oclass->dispose = empathy_base_password_dialog_dispose;
297   oclass->constructed = empathy_base_password_dialog_constructed;
298
299   pspec = g_param_spec_object ("account", "The TpAccount",
300       "The TpAccount to be used.",
301       TP_TYPE_ACCOUNT,
302       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
303   g_object_class_install_property (oclass, PROP_ACCOUNT, pspec);
304 }