]> www.fi.muni.cz Git - evince.git/blob - shell/ev-message-area.c
4d3389871daf40d28c6d82a6c075e011e4ab0957
[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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  */
23
24 #include <config.h>
25
26 #include <gtk/gtk.h>
27
28 #include "ev-message-area.h"
29
30 #define EV_MESSAGE_AREA_GET_PRIVATE(obj) \
31         (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EV_TYPE_MESSAGE_AREA, EvMessageAreaPrivate))
32
33 struct _EvMessageAreaPrivate {
34         GtkWidget *main_box;
35         GtkWidget *image;
36         GtkWidget *label;
37         GtkWidget *secondary_label;
38         
39         guint      message_type : 3;
40 };
41
42 enum {
43         PROP_0,
44         PROP_TEXT,
45         PROP_SECONDARY_TEXT,
46         PROP_IMAGE
47 };
48
49 static void ev_message_area_set_property (GObject      *object,
50                                           guint         prop_id,
51                                           const GValue *value,
52                                           GParamSpec   *pspec);
53 static void ev_message_area_get_property (GObject      *object,
54                                           guint         prop_id,
55                                           GValue       *value,
56                                           GParamSpec   *pspec);
57
58 G_DEFINE_TYPE (EvMessageArea, ev_message_area, EV_TYPE_INFO_BAR)
59
60 static void
61 ev_message_area_class_init (EvMessageAreaClass *class)
62 {
63         GObjectClass *gobject_class = G_OBJECT_CLASS (class);
64
65         gobject_class->set_property = ev_message_area_set_property;
66         gobject_class->get_property = ev_message_area_get_property;
67
68         g_object_class_install_property (gobject_class,
69                                          PROP_TEXT,
70                                          g_param_spec_string ("text",
71                                                               "Text",
72                                                               "The primary text of the message dialog",
73                                                               NULL,
74                                                               G_PARAM_READWRITE));
75         g_object_class_install_property (gobject_class,
76                                          PROP_SECONDARY_TEXT,
77                                          g_param_spec_string ("secondary-text",
78                                                               "Secondary Text",
79                                                               "The secondary text of the message dialog",
80                                                               NULL,
81                                                               G_PARAM_READWRITE));
82         g_object_class_install_property (gobject_class,
83                                          PROP_IMAGE,
84                                          g_param_spec_object ("image",
85                                                               "Image",
86                                                               "The image",
87                                                               GTK_TYPE_WIDGET,
88                                                               G_PARAM_READWRITE));
89
90         g_type_class_add_private (gobject_class, sizeof (EvMessageAreaPrivate));
91 }
92
93 static void
94 ev_message_area_init (EvMessageArea *area)
95 {
96         GtkWidget *hbox, *vbox;
97         GtkWidget *content_area;
98
99         area->priv = EV_MESSAGE_AREA_GET_PRIVATE (area);
100
101         area->priv->main_box = gtk_vbox_new (FALSE, 12);
102
103         hbox = gtk_hbox_new (FALSE, 12);
104         vbox = gtk_vbox_new (FALSE, 12);
105
106         area->priv->label = gtk_label_new (NULL);
107         gtk_label_set_use_markup (GTK_LABEL (area->priv->label), TRUE);
108         gtk_label_set_line_wrap (GTK_LABEL (area->priv->label), TRUE);
109         gtk_label_set_selectable (GTK_LABEL (area->priv->label), TRUE);
110         gtk_misc_set_alignment (GTK_MISC (area->priv->label), 0.0, 0.5);
111         GTK_WIDGET_SET_FLAGS (area->priv->label, GTK_CAN_FOCUS);
112         gtk_box_pack_start (GTK_BOX (vbox), area->priv->label, TRUE, TRUE, 0);
113         gtk_widget_show (area->priv->label);
114
115         area->priv->secondary_label = gtk_label_new (NULL);
116         gtk_label_set_use_markup (GTK_LABEL (area->priv->secondary_label), TRUE);
117         gtk_label_set_line_wrap (GTK_LABEL (area->priv->secondary_label), TRUE);
118         gtk_label_set_selectable (GTK_LABEL (area->priv->secondary_label), TRUE);
119         gtk_misc_set_alignment (GTK_MISC (area->priv->secondary_label), 0.0, 0.5);
120         GTK_WIDGET_SET_FLAGS (area->priv->secondary_label, GTK_CAN_FOCUS);
121         gtk_box_pack_start (GTK_BOX (vbox), area->priv->secondary_label, TRUE, TRUE, 0);
122
123         area->priv->image = gtk_image_new_from_stock (NULL, GTK_ICON_SIZE_DIALOG);
124         gtk_misc_set_alignment (GTK_MISC (area->priv->image), 0.5, 0.0);
125         gtk_box_pack_start (GTK_BOX (hbox), area->priv->image, FALSE, FALSE, 0);
126         gtk_widget_show (area->priv->image);
127
128         gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
129         gtk_widget_show (vbox);
130
131         gtk_box_pack_start (GTK_BOX (area->priv->main_box), hbox, TRUE, TRUE, 0);
132         gtk_widget_show (hbox);
133
134         content_area = ev_info_bar_get_content_area (EV_INFO_BAR (area));
135         gtk_container_add (GTK_CONTAINER (content_area), area->priv->main_box);
136         gtk_widget_show (area->priv->main_box);
137 }
138
139 static void
140 ev_message_area_set_image_for_type (EvMessageArea *area,
141                                     GtkMessageType type)
142 {
143         const gchar *stock_id = NULL;
144         AtkObject   *atk_obj;
145
146         switch (type) {
147         case GTK_MESSAGE_INFO:
148                 stock_id = GTK_STOCK_DIALOG_INFO;
149                 break;
150         case GTK_MESSAGE_QUESTION:
151                 stock_id = GTK_STOCK_DIALOG_QUESTION;
152                 break;
153         case GTK_MESSAGE_WARNING:
154                 stock_id = GTK_STOCK_DIALOG_WARNING;
155                 break;
156         case GTK_MESSAGE_ERROR:
157                 stock_id = GTK_STOCK_DIALOG_ERROR;
158                 break;
159         case GTK_MESSAGE_OTHER:
160                 break;
161         default:
162                 g_warning ("Unknown GtkMessageType %u", type);
163                 break;
164         }
165
166         if (stock_id)
167                 gtk_image_set_from_stock (GTK_IMAGE (area->priv->image), stock_id,
168                                           GTK_ICON_SIZE_DIALOG);
169
170         atk_obj = gtk_widget_get_accessible (GTK_WIDGET (area));
171         if (GTK_IS_ACCESSIBLE (atk_obj)) {
172                 atk_object_set_role (atk_obj, ATK_ROLE_ALERT);
173                 if (stock_id) {
174                         GtkStockItem item;
175
176                         gtk_stock_lookup (stock_id, &item);
177                         atk_object_set_name (atk_obj, item.label);
178                 }
179         }
180 }
181
182 static void
183 ev_message_area_set_property (GObject      *object,
184                               guint         prop_id,
185                               const GValue *value,
186                               GParamSpec   *pspec)
187 {
188         EvMessageArea *area = EV_MESSAGE_AREA (object);
189
190         switch (prop_id) {
191         case PROP_TEXT:
192                 ev_message_area_set_text (area, g_value_get_string (value));
193                 break;
194         case PROP_SECONDARY_TEXT:
195                 ev_message_area_set_secondary_text (area, g_value_get_string (value));
196                 break;
197         case PROP_IMAGE:
198                 ev_message_area_set_image (area, (GtkWidget *)g_value_get_object (value));
199                 break;
200         default:
201                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
202                 break;
203         }
204 }
205
206 static void
207 ev_message_area_get_property (GObject     *object,
208                               guint        prop_id,
209                               GValue      *value,
210                               GParamSpec  *pspec)
211 {
212         EvMessageArea *area = EV_MESSAGE_AREA (object);
213
214         switch (prop_id) {
215         case PROP_TEXT:
216                 g_value_set_string (value, gtk_label_get_label (GTK_LABEL (area->priv->label)));
217                 break;
218         case PROP_SECONDARY_TEXT:
219                 g_value_set_string (value, gtk_label_get_label (GTK_LABEL (area->priv->secondary_label)));
220                 break;
221         case PROP_IMAGE:
222                 g_value_set_object (value, area->priv->image);
223                 break;
224         default:
225                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
226                 break;
227         }
228 }
229
230 void
231 _ev_message_area_add_buttons_valist (EvMessageArea *area,
232                                      const gchar   *first_button_text,
233                                      va_list        args)
234 {
235         const gchar* text;
236         gint response_id;
237
238         if (first_button_text == NULL)
239                 return;
240
241         text = first_button_text;
242         response_id = va_arg (args, gint);
243
244         while (text != NULL) {
245                 ev_info_bar_add_button (EV_INFO_BAR (area), text, response_id);
246
247                 text = va_arg (args, gchar*);
248                 if (text == NULL)
249                         break;
250
251                 response_id = va_arg (args, int);
252         }
253 }
254
255 GtkWidget *
256 _ev_message_area_get_main_box (EvMessageArea *area)
257 {
258         return area->priv->main_box;
259 }
260
261 GtkWidget *
262 ev_message_area_new (GtkMessageType type,
263                      const gchar   *text,
264                      const gchar   *first_button_text,
265                      ...)
266 {
267         GtkWidget *widget;
268
269         widget = g_object_new (EV_TYPE_MESSAGE_AREA,
270                                "message-type", type,
271                                "text", text,
272                                NULL);
273         ev_message_area_set_image_for_type (EV_MESSAGE_AREA (widget), type);
274         if (first_button_text) {
275                 va_list args;
276
277                 va_start (args, first_button_text);
278                 _ev_message_area_add_buttons_valist (EV_MESSAGE_AREA (widget),
279                                                      first_button_text, args);
280                 va_end (args);
281         }
282
283         return widget;
284 }
285
286 void
287 ev_message_area_set_image (EvMessageArea *area,
288                            GtkWidget     *image)
289 {
290         GtkWidget *parent;
291
292         g_return_if_fail (EV_IS_MESSAGE_AREA (area));
293
294         area->priv->message_type = GTK_MESSAGE_OTHER;
295
296         parent = area->priv->image->parent;
297         gtk_container_add (GTK_CONTAINER (parent), image);
298         gtk_container_remove (GTK_CONTAINER (parent), area->priv->image);
299         gtk_box_reorder_child (GTK_BOX (parent), image, 0);
300
301         area->priv->image = image;
302
303         g_object_notify (G_OBJECT (area), "image");
304 }
305
306 void
307 ev_message_area_set_image_from_stock (EvMessageArea *area,
308                                       const gchar   *stock_id)
309 {
310         g_return_if_fail (EV_IS_MESSAGE_AREA (area));
311         g_return_if_fail (stock_id != NULL);
312         
313         gtk_image_set_from_stock (GTK_IMAGE (area->priv->image),
314                                   stock_id,
315                                   GTK_ICON_SIZE_DIALOG);
316 }
317
318 void
319 ev_message_area_set_text (EvMessageArea *area,
320                           const gchar   *str)
321 {
322         g_return_if_fail (EV_IS_MESSAGE_AREA (area));
323
324         if (str) {
325                 gchar *msg;
326
327                 msg = g_strdup_printf ("<b>%s</b>", str);
328                 gtk_label_set_markup (GTK_LABEL (area->priv->label), msg);
329                 g_free (msg);
330         } else {
331                 gtk_label_set_markup (GTK_LABEL (area->priv->label), NULL);
332         }
333
334         g_object_notify (G_OBJECT (area), "text");
335 }
336
337 void
338 ev_message_area_set_secondary_text (EvMessageArea *area,
339                                     const gchar   *str)
340 {
341         g_return_if_fail (EV_IS_MESSAGE_AREA (area));
342
343         if (str) {
344                 gchar *msg;
345
346                 msg = g_strdup_printf ("<small>%s</small>", str);
347                 gtk_label_set_markup (GTK_LABEL (area->priv->secondary_label), msg);
348                 g_free (msg);
349                 gtk_widget_show (area->priv->secondary_label);
350         } else {
351                 gtk_label_set_markup (GTK_LABEL (area->priv->secondary_label), NULL);
352                 gtk_widget_hide (area->priv->secondary_label);
353         }
354
355         g_object_notify (G_OBJECT (area), "secondary-text");
356 }