]> www.fi.muni.cz Git - evince.git/blob - shell/ev-message-area.c
[dualscreen] fix crash on ctrl+w and fix control window closing
[evince.git] / shell / ev-message-area.c
1 /* ev-message-area.c
2  *  this file is part of evince, a gnome document viewer
3  *
4  * Copyright (C) 2007 Carlos Garcia Campos
5  *
6  * Author:
7  *   Carlos Garcia Campos <carlosgc@gnome.org>
8  *
9  * Evince is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Evince is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  */
23
24 #include <config.h>
25
26 #include "ev-message-area.h"
27
28 #define EV_MESSAGE_AREA_GET_PRIVATE(obj) \
29         (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EV_TYPE_MESSAGE_AREA, EvMessageAreaPrivate))
30
31 struct _EvMessageAreaPrivate {
32         GtkWidget *main_box;
33         GtkWidget *image;
34         GtkWidget *label;
35         GtkWidget *secondary_label;
36         
37         guint      message_type : 3;
38 };
39
40 enum {
41         PROP_0,
42         PROP_TEXT,
43         PROP_SECONDARY_TEXT,
44         PROP_IMAGE
45 };
46
47 static void ev_message_area_set_property (GObject      *object,
48                                           guint         prop_id,
49                                           const GValue *value,
50                                           GParamSpec   *pspec);
51 static void ev_message_area_get_property (GObject      *object,
52                                           guint         prop_id,
53                                           GValue       *value,
54                                           GParamSpec   *pspec);
55
56 G_DEFINE_TYPE (EvMessageArea, ev_message_area, GTK_TYPE_INFO_BAR)
57
58 static void
59 ev_message_area_class_init (EvMessageAreaClass *class)
60 {
61         GObjectClass *gobject_class = G_OBJECT_CLASS (class);
62
63         gobject_class->set_property = ev_message_area_set_property;
64         gobject_class->get_property = ev_message_area_get_property;
65
66         g_object_class_install_property (gobject_class,
67                                          PROP_TEXT,
68                                          g_param_spec_string ("text",
69                                                               "Text",
70                                                               "The primary text of the message dialog",
71                                                               NULL,
72                                                               G_PARAM_READWRITE));
73         g_object_class_install_property (gobject_class,
74                                          PROP_SECONDARY_TEXT,
75                                          g_param_spec_string ("secondary-text",
76                                                               "Secondary Text",
77                                                               "The secondary text of the message dialog",
78                                                               NULL,
79                                                               G_PARAM_READWRITE));
80         g_object_class_install_property (gobject_class,
81                                          PROP_IMAGE,
82                                          g_param_spec_object ("image",
83                                                               "Image",
84                                                               "The image",
85                                                               GTK_TYPE_WIDGET,
86                                                               G_PARAM_READWRITE));
87
88         g_type_class_add_private (gobject_class, sizeof (EvMessageAreaPrivate));
89 }
90
91 static void
92 ev_message_area_init (EvMessageArea *area)
93 {
94         GtkWidget *hbox, *vbox;
95         GtkWidget *content_area;
96
97         area->priv = EV_MESSAGE_AREA_GET_PRIVATE (area);
98
99         area->priv->main_box = gtk_vbox_new (FALSE, 12);
100
101         hbox = gtk_hbox_new (FALSE, 12);
102         vbox = gtk_vbox_new (FALSE, 12);
103
104         area->priv->label = gtk_label_new (NULL);
105         gtk_label_set_use_markup (GTK_LABEL (area->priv->label), TRUE);
106         gtk_label_set_line_wrap (GTK_LABEL (area->priv->label), TRUE);
107         gtk_label_set_selectable (GTK_LABEL (area->priv->label), TRUE);
108         gtk_misc_set_alignment (GTK_MISC (area->priv->label), 0.0, 0.5);
109         gtk_widget_set_can_focus (area->priv->label, TRUE);
110         gtk_box_pack_start (GTK_BOX (vbox), area->priv->label, TRUE, TRUE, 0);
111         gtk_widget_show (area->priv->label);
112
113         area->priv->secondary_label = gtk_label_new (NULL);
114         gtk_label_set_use_markup (GTK_LABEL (area->priv->secondary_label), TRUE);
115         gtk_label_set_line_wrap (GTK_LABEL (area->priv->secondary_label), TRUE);
116         gtk_label_set_selectable (GTK_LABEL (area->priv->secondary_label), TRUE);
117         gtk_misc_set_alignment (GTK_MISC (area->priv->secondary_label), 0.0, 0.5);
118         gtk_widget_set_can_focus (area->priv->secondary_label, TRUE);
119         gtk_box_pack_start (GTK_BOX (vbox), area->priv->secondary_label, TRUE, TRUE, 0);
120
121         area->priv->image = gtk_image_new_from_stock (NULL, GTK_ICON_SIZE_DIALOG);
122         gtk_misc_set_alignment (GTK_MISC (area->priv->image), 0.5, 0.0);
123         gtk_box_pack_start (GTK_BOX (hbox), area->priv->image, FALSE, FALSE, 0);
124         gtk_widget_show (area->priv->image);
125
126         gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
127         gtk_widget_show (vbox);
128
129         gtk_box_pack_start (GTK_BOX (area->priv->main_box), hbox, TRUE, TRUE, 0);
130         gtk_widget_show (hbox);
131
132         content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (area));
133         gtk_container_add (GTK_CONTAINER (content_area), area->priv->main_box);
134         gtk_widget_show (area->priv->main_box);
135 }
136
137 static void
138 ev_message_area_set_image_for_type (EvMessageArea *area,
139                                     GtkMessageType type)
140 {
141         const gchar *stock_id = NULL;
142         AtkObject   *atk_obj;
143
144         switch (type) {
145         case GTK_MESSAGE_INFO:
146                 stock_id = GTK_STOCK_DIALOG_INFO;
147                 break;
148         case GTK_MESSAGE_QUESTION:
149                 stock_id = GTK_STOCK_DIALOG_QUESTION;
150                 break;
151         case GTK_MESSAGE_WARNING:
152                 stock_id = GTK_STOCK_DIALOG_WARNING;
153                 break;
154         case GTK_MESSAGE_ERROR:
155                 stock_id = GTK_STOCK_DIALOG_ERROR;
156                 break;
157         case GTK_MESSAGE_OTHER:
158                 break;
159         default:
160                 g_warning ("Unknown GtkMessageType %u", type);
161                 break;
162         }
163
164         if (stock_id)
165                 gtk_image_set_from_stock (GTK_IMAGE (area->priv->image), stock_id,
166                                           GTK_ICON_SIZE_DIALOG);
167
168         atk_obj = gtk_widget_get_accessible (GTK_WIDGET (area));
169         if (GTK_IS_ACCESSIBLE (atk_obj)) {
170                 atk_object_set_role (atk_obj, ATK_ROLE_ALERT);
171                 if (stock_id) {
172                         GtkStockItem item;
173
174                         gtk_stock_lookup (stock_id, &item);
175                         atk_object_set_name (atk_obj, item.label);
176                 }
177         }
178 }
179
180 static void
181 ev_message_area_set_property (GObject      *object,
182                               guint         prop_id,
183                               const GValue *value,
184                               GParamSpec   *pspec)
185 {
186         EvMessageArea *area = EV_MESSAGE_AREA (object);
187
188         switch (prop_id) {
189         case PROP_TEXT:
190                 ev_message_area_set_text (area, g_value_get_string (value));
191                 break;
192         case PROP_SECONDARY_TEXT:
193                 ev_message_area_set_secondary_text (area, g_value_get_string (value));
194                 break;
195         case PROP_IMAGE:
196                 ev_message_area_set_image (area, (GtkWidget *)g_value_get_object (value));
197                 break;
198         default:
199                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
200                 break;
201         }
202 }
203
204 static void
205 ev_message_area_get_property (GObject     *object,
206                               guint        prop_id,
207                               GValue      *value,
208                               GParamSpec  *pspec)
209 {
210         EvMessageArea *area = EV_MESSAGE_AREA (object);
211
212         switch (prop_id) {
213         case PROP_TEXT:
214                 g_value_set_string (value, gtk_label_get_label (GTK_LABEL (area->priv->label)));
215                 break;
216         case PROP_SECONDARY_TEXT:
217                 g_value_set_string (value, gtk_label_get_label (GTK_LABEL (area->priv->secondary_label)));
218                 break;
219         case PROP_IMAGE:
220                 g_value_set_object (value, area->priv->image);
221                 break;
222         default:
223                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
224                 break;
225         }
226 }
227
228 void
229 _ev_message_area_add_buttons_valist (EvMessageArea *area,
230                                      const gchar   *first_button_text,
231                                      va_list        args)
232 {
233         const gchar* text;
234         gint response_id;
235
236         if (first_button_text == NULL)
237                 return;
238
239         text = first_button_text;
240         response_id = va_arg (args, gint);
241
242         while (text != NULL) {
243                 gtk_info_bar_add_button (GTK_INFO_BAR (area), text, response_id);
244
245                 text = va_arg (args, gchar*);
246                 if (text == NULL)
247                         break;
248
249                 response_id = va_arg (args, int);
250         }
251 }
252
253 GtkWidget *
254 _ev_message_area_get_main_box (EvMessageArea *area)
255 {
256         return area->priv->main_box;
257 }
258
259 GtkWidget *
260 ev_message_area_new (GtkMessageType type,
261                      const gchar   *text,
262                      const gchar   *first_button_text,
263                      ...)
264 {
265         GtkWidget *widget;
266
267         widget = g_object_new (EV_TYPE_MESSAGE_AREA,
268                                "message-type", type,
269                                "text", text,
270                                NULL);
271         ev_message_area_set_image_for_type (EV_MESSAGE_AREA (widget), type);
272         if (first_button_text) {
273                 va_list args;
274
275                 va_start (args, first_button_text);
276                 _ev_message_area_add_buttons_valist (EV_MESSAGE_AREA (widget),
277                                                      first_button_text, args);
278                 va_end (args);
279         }
280
281         return widget;
282 }
283
284 void
285 ev_message_area_set_image (EvMessageArea *area,
286                            GtkWidget     *image)
287 {
288         GtkWidget *parent;
289
290         g_return_if_fail (EV_IS_MESSAGE_AREA (area));
291
292         area->priv->message_type = GTK_MESSAGE_OTHER;
293
294         parent = gtk_widget_get_parent (area->priv->image);
295         gtk_container_add (GTK_CONTAINER (parent), image);
296         gtk_container_remove (GTK_CONTAINER (parent), area->priv->image);
297         gtk_box_reorder_child (GTK_BOX (parent), image, 0);
298
299         area->priv->image = image;
300
301         g_object_notify (G_OBJECT (area), "image");
302 }
303
304 void
305 ev_message_area_set_image_from_stock (EvMessageArea *area,
306                                       const gchar   *stock_id)
307 {
308         g_return_if_fail (EV_IS_MESSAGE_AREA (area));
309         g_return_if_fail (stock_id != NULL);
310         
311         gtk_image_set_from_stock (GTK_IMAGE (area->priv->image),
312                                   stock_id,
313                                   GTK_ICON_SIZE_DIALOG);
314 }
315
316 void
317 ev_message_area_set_text (EvMessageArea *area,
318                           const gchar   *str)
319 {
320         g_return_if_fail (EV_IS_MESSAGE_AREA (area));
321
322         if (str) {
323                 gchar *msg;
324
325                 msg = g_strdup_printf ("<b>%s</b>", str);
326                 gtk_label_set_markup (GTK_LABEL (area->priv->label), msg);
327                 g_free (msg);
328         } else {
329                 gtk_label_set_markup (GTK_LABEL (area->priv->label), NULL);
330         }
331
332         g_object_notify (G_OBJECT (area), "text");
333 }
334
335 void
336 ev_message_area_set_secondary_text (EvMessageArea *area,
337                                     const gchar   *str)
338 {
339         g_return_if_fail (EV_IS_MESSAGE_AREA (area));
340
341         if (str) {
342                 gchar *msg;
343
344                 msg = g_strdup_printf ("<small>%s</small>", str);
345                 gtk_label_set_markup (GTK_LABEL (area->priv->secondary_label), msg);
346                 g_free (msg);
347                 gtk_widget_show (area->priv->secondary_label);
348         } else {
349                 gtk_label_set_markup (GTK_LABEL (area->priv->secondary_label), NULL);
350                 gtk_widget_hide (area->priv->secondary_label);
351         }
352
353         g_object_notify (G_OBJECT (area), "secondary-text");
354 }