git: Don't query non-existing style properties
[anjuta.git] / plugins / message-view / anjuta-msgman.c
blobc7ff67503f18b3bdc98596c854e4d65fdeb5b6c6
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /* anjuta-msgman.c (c) 2004 Johannes Schmid
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Library General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 #include <gtk/gtk.h>
19 #include <libanjuta/anjuta-utils.h>
20 #include <libanjuta/anjuta-debug.h>
21 #include <libanjuta/anjuta-shell.h>
22 #include <libanjuta/anjuta-tabber.h>
24 #include <libanjuta/resources.h>
25 #include "anjuta-msgman.h"
26 #include "message-view.h"
28 struct _AnjutaMsgmanPriv
30 AnjutaPreferences *preferences;
31 GtkWidget* popup_menu;
32 GtkWidget* tab_popup;
33 GList *views;
35 GtkWidget* tabber;
36 GSList* button_group;
39 struct _AnjutaMsgmanPage
41 GtkWidget *widget;
42 GtkWidget *pixmap;
43 GtkWidget *label;
44 GtkWidget *box;
45 GtkWidget *close_button;
46 GtkWidget *close_icon;
49 typedef struct _AnjutaMsgmanPage AnjutaMsgmanPage;
51 static void
52 on_msgman_close_page (GtkButton* button,
53 AnjutaMsgman *msgman)
55 MessageView *view = MESSAGE_VIEW (g_object_get_data (G_OBJECT (button),
56 "message_view"));
57 anjuta_msgman_remove_view (msgman, view);
60 static void
61 on_msgman_close_all(GtkMenuItem* item, AnjutaMsgman* msgman)
64 anjuta_msgman_remove_all_views(msgman);
67 static GtkWidget*
68 create_tab_popup_menu(AnjutaMsgman* msgman)
70 GtkWidget* menu;
71 GtkWidget* item_close_all;
73 menu = gtk_menu_new();
75 item_close_all = gtk_menu_item_new_with_label(_("Close all message tabs"));
76 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item_close_all);
77 g_signal_connect(G_OBJECT(item_close_all), "activate", G_CALLBACK(on_msgman_close_all),
78 msgman);
79 gtk_widget_show_all(menu);
81 gtk_menu_attach_to_widget(GTK_MENU(menu), GTK_WIDGET(msgman), NULL);
82 return menu;
85 static void
86 on_msgman_popup_menu(GtkWidget* widget, AnjutaMsgman* msgman)
88 gtk_menu_popup(GTK_MENU(msgman->priv->tab_popup),
89 NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
92 static gboolean
93 on_tab_button_press_event(GtkWidget* widget, GdkEventButton* event, AnjutaMsgman* msgman)
95 if (event->type == GDK_BUTTON_PRESS)
97 if (event->button == 3)
99 gtk_menu_popup(GTK_MENU(msgman->priv->tab_popup), NULL, NULL, NULL, NULL,
100 event->button, event->time);
101 return TRUE;
104 return FALSE;
107 static AnjutaMsgmanPage *
108 anjuta_msgman_page_new (GtkWidget * view, const gchar * name,
109 const gchar * pixmap, AnjutaMsgman * msgman)
111 AnjutaMsgmanPage *page;
112 int h, w;
113 GtkWidget* box;
115 g_return_val_if_fail (view != NULL, NULL);
117 page = g_new0 (AnjutaMsgmanPage, 1);
118 page->widget = GTK_WIDGET (view);
120 page->label = gtk_label_new (name);
121 gtk_misc_set_alignment (GTK_MISC(page->label), 0.0, 0.5);
122 gtk_label_set_ellipsize (GTK_LABEL(page->label), PANGO_ELLIPSIZE_END);
123 box = gtk_hbox_new (FALSE, 0);
124 gtk_box_set_spacing (GTK_BOX (box), 5);
125 if (pixmap && strlen(pixmap))
127 GtkStockItem unused;
128 if (gtk_stock_lookup(pixmap, &unused))
130 page->pixmap = gtk_image_new_from_stock(pixmap, GTK_ICON_SIZE_MENU);
132 else
134 page->pixmap = anjuta_res_get_image_sized (pixmap, 16, 16);
136 gtk_box_pack_start (GTK_BOX (box), page->pixmap, FALSE, FALSE, 0);
138 gtk_box_pack_start (GTK_BOX (box), page->label, TRUE, TRUE, 0);
139 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
140 page->close_icon = gtk_image_new_from_stock(GTK_STOCK_CLOSE,
141 GTK_ICON_SIZE_MENU);
142 gtk_widget_set_size_request(page->close_icon, w, h);
144 page->close_button = gtk_button_new();
145 gtk_container_add(GTK_CONTAINER(page->close_button), page->close_icon);
146 gtk_widget_set_size_request (page->close_button, w, h);
147 gtk_button_set_focus_on_click (GTK_BUTTON (page->close_button), FALSE);
148 gtk_button_set_relief(GTK_BUTTON(page->close_button), GTK_RELIEF_NONE);
149 /* This style is created int the document-manager which we simply
150 * assume is loaded before this plugin
152 gtk_widget_set_name (page->close_button, "anjuta-tab-close-button");
154 g_object_set_data (G_OBJECT (page->close_button), "message_view", page->widget);
155 g_signal_connect (page->close_button, "clicked",
156 G_CALLBACK(on_msgman_close_page),
157 msgman);
160 page->box = gtk_hbox_new (FALSE, 0);
161 gtk_box_pack_start (GTK_BOX(page->box), box, TRUE, TRUE, 0);
162 gtk_box_pack_start (GTK_BOX(page->box), page->close_button, FALSE, FALSE, 0);
164 gtk_widget_show_all (page->box);
166 return page;
169 static void
170 anjuta_msgman_page_destroy (AnjutaMsgmanPage * page)
172 g_free (page);
175 static AnjutaMsgmanPage *
176 anjuta_msgman_page_from_widget (AnjutaMsgman * msgman, MessageView * mv)
178 GList *node;
179 node = msgman->priv->views;
180 while (node)
182 AnjutaMsgmanPage *page;
183 page = node->data;
184 g_assert (page);
185 if (page->widget == GTK_WIDGET (mv))
186 return page;
187 node = g_list_next (node);
189 return NULL;
192 static gpointer parent_class;
194 static void
195 anjuta_msgman_dispose (GObject *obj)
197 G_OBJECT_CLASS (parent_class)->dispose (obj);
200 static void
201 anjuta_msgman_finalize (GObject *obj)
203 AnjutaMsgman *msgman = ANJUTA_MSGMAN (obj);
204 gtk_widget_destroy(msgman->priv->tab_popup);
205 if (msgman->priv)
207 g_free (msgman->priv);
208 msgman->priv = NULL;
210 G_OBJECT_CLASS (parent_class)->finalize (obj);
213 static void
214 anjuta_msgman_instance_init (AnjutaMsgman * msgman)
216 gtk_notebook_set_scrollable (GTK_NOTEBOOK (msgman), TRUE);
217 msgman->priv = g_new0(AnjutaMsgmanPriv, 1);
218 msgman->priv->views = NULL;
219 msgman->priv->tab_popup = create_tab_popup_menu(msgman);
220 msgman->priv->tabber = anjuta_tabber_new (GTK_NOTEBOOK (msgman));
221 msgman->priv->button_group = NULL;
223 g_signal_connect(msgman, "popup-menu",
224 G_CALLBACK(on_msgman_popup_menu), msgman);
225 g_signal_connect(msgman, "button-press-event",
226 G_CALLBACK(on_tab_button_press_event), msgman);
229 static void
230 anjuta_msgman_class_init (AnjutaMsgmanClass * klass)
232 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
234 parent_class = g_type_class_peek_parent (klass);
235 gobject_class->finalize = anjuta_msgman_finalize;
236 gobject_class->dispose = anjuta_msgman_dispose;
239 static void
240 set_message_tab(GSettings* settings, GtkNotebook *msgman)
242 gchar *tab_pos;
243 GtkPositionType pos;
245 tab_pos = g_settings_get_string (settings, MESSAGES_TABS_POS);
246 pos = GTK_POS_TOP;
247 if (tab_pos)
249 if (strcasecmp (tab_pos, "left") == 0)
250 pos = GTK_POS_LEFT;
251 else if (strcasecmp (tab_pos, "right") == 0)
252 pos = GTK_POS_RIGHT;
253 else if (strcasecmp (tab_pos, "bottom") == 0)
254 pos = GTK_POS_BOTTOM;
255 g_free (tab_pos);
257 gtk_notebook_set_tab_pos (msgman, pos);
260 void
261 on_notify_message_pref (GSettings *settings, const gchar* key,
262 gpointer user_data)
264 set_message_tab(settings, GTK_NOTEBOOK (user_data));
268 GtkWidget*
269 anjuta_msgman_new (GtkWidget *popup_menu)
271 GtkWidget *msgman = NULL;
272 msgman = gtk_widget_new (ANJUTA_TYPE_MSGMAN, "show-tabs", FALSE, NULL);
273 if (msgman)
275 ANJUTA_MSGMAN (msgman)->priv->popup_menu = popup_menu;
277 return msgman;
281 ANJUTA_TYPE_BEGIN (AnjutaMsgman, anjuta_msgman, GTK_TYPE_NOTEBOOK);
282 ANJUTA_TYPE_END;
284 static void
285 on_message_view_destroy (MessageView *view, AnjutaMsgman *msgman)
287 AnjutaMsgmanPage *page;
288 gint page_num;
290 page = anjuta_msgman_page_from_widget (msgman, view);
292 g_signal_handlers_disconnect_by_func (G_OBJECT (view),
293 G_CALLBACK (on_message_view_destroy), msgman);
295 page_num =
296 gtk_notebook_page_num (GTK_NOTEBOOK (msgman),
297 GTK_WIDGET (view));
298 msgman->priv->views = g_list_remove (msgman->priv->views, page);
299 anjuta_msgman_page_destroy (page);
303 static void
304 anjuta_msgman_append_view (AnjutaMsgman * msgman, GtkWidget *mv,
305 const gchar * name, const gchar * pixmap)
307 AnjutaMsgmanPage *page;
309 g_return_if_fail (msgman != NULL);
310 g_return_if_fail (mv != NULL);
311 g_return_if_fail (name != NULL);
313 gtk_widget_show_all (mv);
314 page = anjuta_msgman_page_new (mv, name, pixmap, msgman);
316 msgman->priv->views =
317 g_list_prepend (msgman->priv->views, (gpointer) page);
319 gtk_notebook_append_page (GTK_NOTEBOOK (msgman), mv, NULL);
321 anjuta_tabber_add_tab (ANJUTA_TABBER(msgman->priv->tabber), page->box);
323 g_signal_connect (G_OBJECT (mv), "destroy",
324 G_CALLBACK (on_message_view_destroy), msgman);
327 MessageView *
328 anjuta_msgman_add_view (AnjutaMsgman * msgman,
329 const gchar * name, const gchar * pixmap)
331 GtkWidget *mv;
333 g_return_val_if_fail (msgman != NULL, NULL);
334 g_return_val_if_fail (name != NULL, NULL);
336 mv = message_view_new (msgman->priv->popup_menu);
337 g_return_val_if_fail (mv != NULL, NULL);
338 g_object_set (G_OBJECT (mv), "highlite", TRUE, "label", name,
339 "pixmap", pixmap, NULL);
340 anjuta_msgman_append_view (msgman, mv, name, pixmap);
341 return MESSAGE_VIEW (mv);
344 void
345 anjuta_msgman_remove_view (AnjutaMsgman * msgman, MessageView *passed_view)
347 MessageView *view;
349 view = passed_view;
350 if (!view)
351 view = anjuta_msgman_get_current_view (msgman);
353 g_return_if_fail (view != NULL);
354 gtk_widget_destroy (GTK_WIDGET (view));
355 anjuta_msgman_set_current_view(msgman, NULL);
358 void
359 anjuta_msgman_remove_all_views (AnjutaMsgman * msgman)
361 GList *views, *node;
362 AnjutaMsgmanPage *page;
364 views = NULL;
365 node = msgman->priv->views;
366 while (node)
368 page = node->data;
369 views = g_list_prepend (views, page->widget);
370 node = g_list_next (node);
372 node = views;
373 while (node)
375 gtk_widget_destroy (GTK_WIDGET (node->data));
376 node = g_list_next (node);
379 g_list_free (msgman->priv->views);
380 g_list_free (views);
382 msgman->priv->views = NULL;
385 MessageView *
386 anjuta_msgman_get_current_view (AnjutaMsgman * msgman)
388 gint page = gtk_notebook_get_current_page (GTK_NOTEBOOK(msgman));
389 if (page != -1)
390 return MESSAGE_VIEW (gtk_notebook_get_nth_page (GTK_NOTEBOOK(msgman), page));
391 else
392 return NULL;
395 MessageView *
396 anjuta_msgman_get_view_by_name (AnjutaMsgman * msgman, const gchar * name)
398 GList *node;
400 g_return_val_if_fail (msgman != NULL, NULL);
401 g_return_val_if_fail (name != NULL, NULL);
403 node = msgman->priv->views;
404 while (node)
406 AnjutaMsgmanPage *page;
407 page = node->data;
408 g_assert (page);
409 if (strcmp (gtk_label_get_text (GTK_LABEL (page->label)),
410 name) == 0)
412 return MESSAGE_VIEW (page->widget);
414 node = g_list_next (node);
416 return NULL;
419 void
420 anjuta_msgman_set_current_view (AnjutaMsgman * msgman, MessageView * mv)
422 g_return_if_fail (msgman != NULL);
423 AnjutaMsgmanPage *page;
424 gint page_num;
426 if (mv)
428 page = anjuta_msgman_page_from_widget (msgman, mv);
429 page_num =
430 gtk_notebook_page_num (GTK_NOTEBOOK (msgman),
431 GTK_WIDGET (mv));
432 gtk_notebook_set_current_page (GTK_NOTEBOOK (msgman), page_num);
436 GList *
437 anjuta_msgman_get_all_views (AnjutaMsgman * msgman)
439 return msgman->priv->views;
442 void
443 anjuta_msgman_set_view_title (AnjutaMsgman *msgman, MessageView *view,
444 const gchar *title)
446 AnjutaMsgmanPage *page;
448 g_return_if_fail (title != NULL);
450 page = anjuta_msgman_page_from_widget (msgman, view);
451 g_return_if_fail (page != NULL);
453 gtk_label_set_text (GTK_LABEL (page->label), title);
456 void
457 anjuta_msgman_set_view_icon (AnjutaMsgman *msgman, MessageView *view,
458 GdkPixbufAnimation *icon)
460 AnjutaMsgmanPage *page;
462 g_return_if_fail (icon != NULL);
464 page = anjuta_msgman_page_from_widget (msgman, view);
465 g_return_if_fail (page != NULL);
467 gtk_image_set_from_animation (GTK_IMAGE (page->pixmap), icon);
470 void
471 anjuta_msgman_set_view_icon_from_stock (AnjutaMsgman *msgman, MessageView *view,
472 const gchar *icon)
474 AnjutaMsgmanPage *page;
476 g_return_if_fail (icon != NULL);
478 page = anjuta_msgman_page_from_widget (msgman, view);
479 g_return_if_fail (page != NULL);
481 gtk_image_set_from_stock (GTK_IMAGE (page->pixmap), icon,
482 GTK_ICON_SIZE_MENU);
485 gboolean
486 anjuta_msgman_serialize (AnjutaMsgman *msgman, AnjutaSerializer *serializer)
488 GList *node;
490 if (!anjuta_serializer_write_int (serializer, "views",
491 g_list_length (msgman->priv->views)))
492 return FALSE;
494 node = msgman->priv->views;
495 while (node)
497 AnjutaMsgmanPage *page = (AnjutaMsgmanPage*)node->data;
498 if (!message_view_serialize (MESSAGE_VIEW (page->widget), serializer))
499 return FALSE;
500 node = g_list_next (node);
502 return TRUE;
505 gboolean
506 anjuta_msgman_deserialize (AnjutaMsgman *msgman, AnjutaSerializer *serializer)
508 gint views, i;
510 if (!anjuta_serializer_read_int (serializer, "views", &views))
511 return FALSE;
513 for (i = 0; i < views; i++)
515 gchar *label, *pixmap;
516 GtkWidget *view;
517 view = message_view_new (msgman->priv->popup_menu);
518 g_return_val_if_fail (view != NULL, FALSE);
519 if (!message_view_deserialize (MESSAGE_VIEW (view), serializer))
521 gtk_widget_destroy (view);
522 return FALSE;
524 g_object_get (view, "label", &label, "pixmap", &pixmap, NULL);
525 anjuta_msgman_append_view (msgman, view, label, pixmap);
526 g_free (label);
527 g_free (pixmap);
529 return TRUE;
532 GtkWidget* anjuta_msgman_get_tabber (AnjutaMsgman* msgman)
534 return msgman->priv->tabber;