3 * This file is part of gedit
5 * Copyright (C) 2005 - Paolo Maggi
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * Modified by the gedit Team, 2005. See the AUTHORS file for a
25 * list of people on the gedit Team.
26 * See the ChangeLog files for a list of changes.
28 * $Id: gedit-message-area.c 5887 2007-09-07 07:20:19Z pborelli $
31 /* TODO: Style properties */
37 #include <glib/gi18n.h>
40 #include <gdk/gdkkeysyms.h>
42 #include "gedit-message-area.h"
44 #define GEDIT_MESSAGE_AREA_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
45 GEDIT_TYPE_MESSAGE_AREA, \
46 GeditMessageAreaPrivate))
48 struct _GeditMessageAreaPrivate
53 GtkWidget *action_area;
55 gboolean changing_style;
58 typedef struct _ResponseData ResponseData;
71 static guint signals[LAST_SIGNAL];
73 G_DEFINE_TYPE(GeditMessageArea, gedit_message_area, GTK_TYPE_HBOX)
77 gedit_message_area_finalize (GObject *object)
80 GeditMessageArea *message_area = GEDIT_MESSAGE_AREA (object);
83 G_OBJECT_CLASS (gedit_message_area_parent_class)->finalize (object);
87 get_response_data (GtkWidget *widget,
90 ResponseData *ad = g_object_get_data (G_OBJECT (widget),
91 "gedit-message-area-response-data");
93 if (ad == NULL && create)
95 ad = g_new (ResponseData, 1);
97 g_object_set_data_full (G_OBJECT (widget),
98 "gedit-message-area-response-data",
107 find_button (GeditMessageArea *message_area,
110 GList *children, *tmp_list;
111 GtkWidget *child = NULL;
113 children = gtk_container_get_children (
114 GTK_CONTAINER (message_area->priv->action_area));
116 for (tmp_list = children; tmp_list; tmp_list = tmp_list->next)
118 ResponseData *rd = get_response_data (tmp_list->data, FALSE);
120 if (rd && rd->response_id == response_id)
122 child = tmp_list->data;
127 g_list_free (children);
133 gedit_message_area_close (GeditMessageArea *message_area)
135 if (!find_button (message_area, GTK_RESPONSE_CLOSE))
138 /* emit response signal */
139 gedit_message_area_response (GEDIT_MESSAGE_AREA (message_area),
144 paint_message_area (GtkWidget *widget,
145 GdkEventExpose *event,
148 gtk_paint_flat_box (widget->style,
155 widget->allocation.x + 1,
156 widget->allocation.y + 1,
157 widget->allocation.width - 2,
158 widget->allocation.height - 2);
164 gedit_message_area_class_init (GeditMessageAreaClass *klass)
166 GObjectClass *object_class;
167 GtkBindingSet *binding_set;
169 object_class = G_OBJECT_CLASS (klass);
170 object_class->finalize = gedit_message_area_finalize;
172 klass->close = gedit_message_area_close;
174 g_type_class_add_private (object_class, sizeof(GeditMessageAreaPrivate));
176 signals[RESPONSE] = g_signal_new ("response",
177 G_OBJECT_CLASS_TYPE (klass),
179 G_STRUCT_OFFSET (GeditMessageAreaClass, response),
181 g_cclosure_marshal_VOID__INT,
185 signals[CLOSE] = g_signal_new ("close",
186 G_OBJECT_CLASS_TYPE (klass),
187 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
188 G_STRUCT_OFFSET (GeditMessageAreaClass, close),
190 g_cclosure_marshal_VOID__VOID,
193 binding_set = gtk_binding_set_by_class (klass);
195 gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "close", 0);
199 style_set (GtkWidget *widget,
200 GtkStyle *prev_style,
201 GeditMessageArea *message_area)
206 if (message_area->priv->changing_style)
209 /* This is a hack needed to use the tooltip background color */
210 window = gtk_window_new (GTK_WINDOW_POPUP);
211 gtk_widget_set_name (window, "gtk-tooltip");
212 gtk_widget_ensure_style (window);
213 style = gtk_widget_get_style (window);
215 message_area->priv->changing_style = TRUE;
216 gtk_widget_set_style (GTK_WIDGET (message_area), style);
217 message_area->priv->changing_style = FALSE;
219 gtk_widget_destroy (window);
221 gtk_widget_queue_draw (GTK_WIDGET (message_area));
225 gedit_message_area_init (GeditMessageArea *message_area)
227 message_area->priv = GEDIT_MESSAGE_AREA_GET_PRIVATE (message_area);
229 message_area->priv->main_hbox = gtk_hbox_new (FALSE, 16); /* FIXME: use style properties */
230 gtk_widget_show (message_area->priv->main_hbox);
231 gtk_container_set_border_width (GTK_CONTAINER (message_area->priv->main_hbox),
232 8); /* FIXME: use style properties */
234 message_area->priv->action_area = gtk_vbox_new (TRUE, 10); /* FIXME: use style properties */
235 gtk_widget_show (message_area->priv->action_area);
236 gtk_box_pack_end (GTK_BOX (message_area->priv->main_hbox),
237 message_area->priv->action_area,
242 gtk_box_pack_start (GTK_BOX (message_area),
243 message_area->priv->main_hbox,
248 gtk_widget_set_app_paintable (GTK_WIDGET (message_area), TRUE);
250 g_signal_connect (message_area,
252 G_CALLBACK (paint_message_area),
255 /* Note that we connect to style-set on one of the internal
256 * widgets, not on the message area itself, since gtk does
257 * not deliver any further style-set signals for a widget on
258 * which the style has been forced with gtk_widget_set_style() */
259 g_signal_connect (message_area->priv->main_hbox,
261 G_CALLBACK (style_set),
266 get_response_for_widget (GeditMessageArea *message_area,
271 rd = get_response_data (widget, FALSE);
273 return GTK_RESPONSE_NONE;
275 return rd->response_id;
279 action_widget_activated (GtkWidget *widget, GeditMessageArea *message_area)
283 response_id = get_response_for_widget (message_area, widget);
285 gedit_message_area_response (message_area, response_id);
289 gedit_message_area_add_action_widget (GeditMessageArea *message_area,
296 g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
297 g_return_if_fail (GTK_IS_WIDGET (child));
299 ad = get_response_data (child, TRUE);
301 ad->response_id = response_id;
303 if (GTK_IS_BUTTON (child))
304 signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
306 signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal;
312 closure = g_cclosure_new_object (G_CALLBACK (action_widget_activated),
313 G_OBJECT (message_area));
315 g_signal_connect_closure_by_id (child,
322 g_warning ("Only 'activatable' widgets can be packed into the action area of a GeditMessageArea");
324 if (response_id != GTK_RESPONSE_HELP)
325 gtk_box_pack_start (GTK_BOX (message_area->priv->action_area),
331 gtk_box_pack_end (GTK_BOX (message_area->priv->action_area),
339 gedit_message_area_set_contents (GeditMessageArea *message_area,
342 g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
343 g_return_if_fail (GTK_IS_WIDGET (contents));
345 message_area->priv->contents = contents;
346 gtk_box_pack_start (GTK_BOX (message_area->priv->main_hbox),
347 message_area->priv->contents,
354 gedit_message_area_get_contents (GeditMessageArea *message_area)
356 return message_area->priv->contents;
360 gedit_message_area_add_button (GeditMessageArea *message_area,
361 const gchar *button_text,
366 g_return_val_if_fail (GEDIT_IS_MESSAGE_AREA (message_area), NULL);
367 g_return_val_if_fail (button_text != NULL, NULL);
369 button = gtk_button_new_from_stock (button_text);
371 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
373 gtk_widget_show (button);
375 gedit_message_area_add_action_widget (message_area,
383 gedit_message_area_add_buttons_valist (GeditMessageArea *message_area,
384 const gchar *first_button_text,
390 g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
392 if (first_button_text == NULL)
395 text = first_button_text;
396 response_id = va_arg (args, gint);
400 gedit_message_area_add_button (message_area,
404 text = va_arg (args, gchar*);
408 response_id = va_arg (args, int);
413 gedit_message_area_add_buttons (GeditMessageArea *message_area,
414 const gchar *first_button_text,
419 va_start (args, first_button_text);
421 gedit_message_area_add_buttons_valist (message_area,
429 gedit_message_area_new (void)
431 return g_object_new (GEDIT_TYPE_MESSAGE_AREA, NULL);
435 gedit_message_area_new_with_buttons (const gchar *first_button_text,
438 GeditMessageArea *message_area;
441 message_area = GEDIT_MESSAGE_AREA (gedit_message_area_new ());
443 va_start (args, first_button_text);
445 gedit_message_area_add_buttons_valist (message_area,
451 return GTK_WIDGET (message_area);
455 gedit_message_area_set_response_sensitive (GeditMessageArea *message_area,
462 g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
464 children = gtk_container_get_children (GTK_CONTAINER (message_area->priv->action_area));
467 while (tmp_list != NULL)
469 GtkWidget *widget = tmp_list->data;
470 ResponseData *rd = get_response_data (widget, FALSE);
472 if (rd && rd->response_id == response_id)
473 gtk_widget_set_sensitive (widget, setting);
475 tmp_list = g_list_next (tmp_list);
478 g_list_free (children);
482 gedit_message_area_set_default_response (GeditMessageArea *message_area,
488 g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
490 children = gtk_container_get_children (GTK_CONTAINER (message_area->priv->action_area));
493 while (tmp_list != NULL)
495 GtkWidget *widget = tmp_list->data;
496 ResponseData *rd = get_response_data (widget, FALSE);
498 if (rd && rd->response_id == response_id)
499 gtk_widget_grab_default (widget);
501 tmp_list = g_list_next (tmp_list);
504 g_list_free (children);
508 gedit_message_area_response (GeditMessageArea *message_area,
511 g_return_if_fail (GEDIT_IS_MESSAGE_AREA (message_area));
513 g_signal_emit (message_area,
520 gedit_message_area_add_stock_button_with_text (GeditMessageArea *message_area,
522 const gchar *stock_id,
527 g_return_val_if_fail (GEDIT_IS_MESSAGE_AREA (message_area), NULL);
528 g_return_val_if_fail (text != NULL, NULL);
529 g_return_val_if_fail (stock_id != NULL, NULL);
531 button = gtk_button_new_with_mnemonic (text);
532 gtk_button_set_image (GTK_BUTTON (button),
533 gtk_image_new_from_stock (stock_id,
534 GTK_ICON_SIZE_BUTTON));
536 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
538 gtk_widget_show (button);
540 gedit_message_area_add_action_widget (message_area,