Fix a Gtk warning when checking path input in the log viewer.
[anjuta-git-plugin.git] / libanjuta / anjuta-message-area.c
blob47659ab0273d61fbf3928c5121cfe694e92dfd55
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta-message-area.c
4 * This file is part of anjuta
6 * Copyright (C) 2005 - Paolo Maggi
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330,
21 * Boston, MA 02111-1307, USA.
25 * Modified by the anjuta Team, 2005. See the AUTHORS file for a
26 * list of people on the anjuta Team.
27 * See the ChangeLog files for a list of changes.
29 * $Id$
32 /* TODO: Style properties */
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
38 #include <glib/gi18n.h>
39 #include <gtk/gtk.h>
40 #include <gdk/gdk.h>
41 #include <gdk/gdkkeysyms.h>
43 #include "anjuta-message-area.h"
44 #include "anjuta-utils.h"
46 #define ANJUTA_MESSAGE_AREA_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
47 ANJUTA_TYPE_MESSAGE_AREA, \
48 AnjutaMessageAreaPrivate))
50 struct _AnjutaMessageAreaPrivate
52 GtkWidget *label;
53 GtkWidget *image;
54 GtkWidget *action_area;
56 gboolean changing_style;
59 typedef struct _ResponseData ResponseData;
61 struct _ResponseData
63 gint response_id;
66 enum {
67 RESPONSE,
68 CLOSE,
69 LAST_SIGNAL
72 static guint signals[LAST_SIGNAL];
74 G_DEFINE_TYPE(AnjutaMessageArea, anjuta_message_area, GTK_TYPE_HBOX)
76 static void
77 anjuta_message_area_finalize (GObject *object)
79 G_OBJECT_CLASS (anjuta_message_area_parent_class)->finalize (object);
82 static ResponseData *
83 get_response_data (GtkWidget *widget, gboolean create)
85 ResponseData *ad = g_object_get_data (G_OBJECT (widget),
86 "anjuta-message-area-response-data");
88 if (ad == NULL && create)
90 ad = g_new (ResponseData, 1);
92 g_object_set_data_full (G_OBJECT (widget),
93 "anjuta-message-area-response-data",
94 ad,
95 g_free);
98 return ad;
101 static gboolean
102 paint_message_area (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
104 gtk_paint_flat_box (widget->style,
105 widget->window,
106 GTK_STATE_NORMAL,
107 GTK_SHADOW_OUT,
108 NULL,
109 widget,
110 "tooltip",
111 widget->allocation.x + 1,
112 widget->allocation.y + 1,
113 widget->allocation.width - 2,
114 widget->allocation.height - 2);
116 return FALSE;
119 static void
120 anjuta_message_area_class_init (AnjutaMessageAreaClass *klass)
122 GObjectClass *object_class;
123 GtkBindingSet *binding_set;
125 object_class = G_OBJECT_CLASS (klass);
126 object_class->finalize = anjuta_message_area_finalize;
128 //klass->close = anjuta_message_area_close;
130 g_type_class_add_private (object_class, sizeof(AnjutaMessageAreaPrivate));
132 signals[RESPONSE] = g_signal_new ("response",
133 G_OBJECT_CLASS_TYPE (klass),
134 G_SIGNAL_RUN_LAST,
135 G_STRUCT_OFFSET (AnjutaMessageAreaClass, response),
136 NULL, NULL,
137 g_cclosure_marshal_VOID__INT,
138 G_TYPE_NONE, 1,
139 G_TYPE_INT);
141 signals[CLOSE] = g_signal_new ("close",
142 G_OBJECT_CLASS_TYPE (klass),
143 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
144 G_STRUCT_OFFSET (AnjutaMessageAreaClass, close),
145 NULL, NULL,
146 g_cclosure_marshal_VOID__VOID,
147 G_TYPE_NONE, 0);
149 binding_set = gtk_binding_set_by_class (klass);
151 gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "close", 0);
154 static void
155 style_set (GtkWidget *widget, GtkStyle *prev_style, AnjutaMessageArea *message_area)
157 GtkWidget *window;
158 GtkStyle *style;
160 if (message_area->priv->changing_style)
161 return;
163 /* This is a hack needed to use the tooltip background color */
164 window = gtk_window_new (GTK_WINDOW_POPUP);
165 gtk_widget_set_name (window, "gtk-tooltip");
166 gtk_widget_ensure_style (window);
167 style = gtk_widget_get_style (window);
169 message_area->priv->changing_style = TRUE;
170 gtk_widget_set_style (GTK_WIDGET (message_area), style);
171 message_area->priv->changing_style = FALSE;
173 gtk_widget_destroy (window);
175 gtk_widget_queue_draw (GTK_WIDGET (message_area));
178 static void
179 anjuta_message_area_init (AnjutaMessageArea *message_area)
181 GtkWidget *main_hbox;
182 GtkWidget *image;
183 GtkWidget *label;
185 message_area->priv = ANJUTA_MESSAGE_AREA_GET_PRIVATE (message_area);
187 main_hbox = gtk_hbox_new (FALSE, 16);
188 gtk_widget_show (main_hbox);
190 image = gtk_image_new ();
191 gtk_widget_show (image);
192 gtk_box_pack_start (GTK_BOX (main_hbox), image, FALSE, FALSE, 0);
193 gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0);
194 message_area->priv->image = image;
196 label = gtk_label_new (NULL);
197 gtk_widget_show (label);
198 gtk_box_pack_start (GTK_BOX (main_hbox), label, TRUE, TRUE, 0);
199 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
200 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
201 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
202 GTK_WIDGET_SET_FLAGS (label, GTK_CAN_FOCUS);
203 gtk_label_set_selectable (GTK_LABEL (label), TRUE);
204 message_area->priv->label = label;
206 gtk_widget_show (main_hbox);
207 gtk_container_set_border_width (GTK_CONTAINER (main_hbox), 8);
209 message_area->priv->action_area = gtk_vbox_new (TRUE, 8);
210 gtk_widget_show (message_area->priv->action_area);
211 gtk_box_pack_end (GTK_BOX (main_hbox),
212 message_area->priv->action_area,
213 FALSE,
214 FALSE,
217 gtk_box_pack_start (GTK_BOX (message_area),
218 main_hbox,
219 TRUE,
220 TRUE,
223 gtk_widget_set_app_paintable (GTK_WIDGET (message_area), TRUE);
225 g_signal_connect (message_area,
226 "expose-event",
227 G_CALLBACK (paint_message_area),
228 NULL);
230 /* Note that we connect to style-set on one of the internal
231 * widgets, not on the message area itself, since gtk does
232 * not deliver any further style-set signals for a widget on
233 * which the style has been forced with gtk_widget_set_style() */
234 g_signal_connect (main_hbox,
235 "style-set",
236 G_CALLBACK (style_set),
237 message_area);
240 static gint
241 get_response_for_widget (AnjutaMessageArea *message_area, GtkWidget *widget)
243 ResponseData *rd;
245 rd = get_response_data (widget, FALSE);
246 if (!rd)
247 return GTK_RESPONSE_NONE;
248 else
249 return rd->response_id;
252 static void
253 action_widget_activated (GtkWidget *widget, AnjutaMessageArea *message_area)
255 gint response_id;
257 response_id = get_response_for_widget (message_area, widget);
258 anjuta_message_area_response (message_area, response_id);
261 void
262 anjuta_message_area_set_text (AnjutaMessageArea *message_area,
263 const gchar *text)
265 gchar *markup;
267 if (text != NULL)
269 markup = g_strdup_printf ("<b>%s</b>", text);
270 gtk_label_set_markup (GTK_LABEL (message_area->priv->label), markup);
271 g_free (markup);
275 void
276 anjuta_message_area_set_image (AnjutaMessageArea *message_area,
277 const gchar *icon_stock_id)
279 if (icon_stock_id != NULL)
281 gtk_image_set_from_stock (GTK_IMAGE (message_area->priv->image),
282 icon_stock_id, GTK_ICON_SIZE_DIALOG);
286 static void
287 anjuta_message_area_add_action_widget (AnjutaMessageArea *message_area,
288 GtkWidget *child, gint response_id)
290 ResponseData *ad;
291 guint signal_id;
292 GClosure *closure;
294 g_return_if_fail (ANJUTA_IS_MESSAGE_AREA (message_area));
295 g_return_if_fail (GTK_IS_BUTTON (child));
297 ad = get_response_data (child, TRUE);
299 ad->response_id = response_id;
301 signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
302 closure = g_cclosure_new_object (G_CALLBACK (action_widget_activated),
303 G_OBJECT (message_area));
305 g_signal_connect_closure_by_id (child,
306 signal_id,
308 closure,
309 FALSE);
311 gtk_box_pack_start (GTK_BOX (message_area->priv->action_area),
312 child,
313 FALSE,
314 FALSE,
318 GtkWidget *
319 anjuta_message_area_new (const gchar *text,
320 const gchar *icon_stock_id)
322 AnjutaMessageArea *message_area;
324 message_area = g_object_new (ANJUTA_TYPE_MESSAGE_AREA, NULL);
325 anjuta_message_area_set_text (message_area, text);
326 anjuta_message_area_set_image (message_area, icon_stock_id);
328 return GTK_WIDGET (message_area);
330 void
331 anjuta_message_area_response (AnjutaMessageArea *message_area,
332 gint response_id)
334 g_return_if_fail (ANJUTA_IS_MESSAGE_AREA (message_area));
336 g_signal_emit (message_area,
337 signals[RESPONSE],
339 response_id);
342 GtkWidget*
343 anjuta_message_area_add_button (AnjutaMessageArea *message_area,
344 const gchar *button_text,
345 gint response_id)
347 GtkWidget *button;
349 g_return_val_if_fail (ANJUTA_IS_MESSAGE_AREA (message_area), NULL);
350 g_return_val_if_fail (button_text != NULL, NULL);
352 button = gtk_button_new_from_stock (button_text);
354 GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
356 gtk_widget_show (button);
358 anjuta_message_area_add_action_widget (message_area,
359 button,
360 response_id);
362 return button;
365 GtkWidget *
366 anjuta_message_area_add_button_with_stock_image (AnjutaMessageArea *message_area,
367 const gchar *text,
368 const gchar *stock_id,
369 gint response_id)
371 GtkWidget *button;
373 g_return_val_if_fail (ANJUTA_IS_MESSAGE_AREA (message_area), NULL);
374 g_return_val_if_fail (text != NULL, NULL);
375 g_return_val_if_fail (stock_id != NULL, NULL);
377 button = anjuta_util_button_new_with_stock_image (text, stock_id);
378 gtk_widget_show (button);
380 anjuta_message_area_add_action_widget (message_area,
381 button,
382 response_id);
384 return button;