* manuals/reference/libanjuta/libanjuta-docs.sgml:
[anjuta-git-plugin.git] / plugins / message-view / anjuta-msgman.c
blob1a98c1aad4d1c6d08ff8aef00b95d66a5b5fb02d
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/gtknotebook.h>
19 #include <libanjuta/anjuta-utils.h>
20 #include <libanjuta/anjuta-debug.h>
21 #include <libanjuta/anjuta-shell.h>
23 #include <libanjuta/resources.h>
24 #include "anjuta-msgman.h"
25 #include "message-view.h"
27 struct _AnjutaMsgmanPriv
29 AnjutaPreferences *preferences;
30 GtkWidget* popup_menu;
31 GtkWidget* tab_popup;
32 GList *views;
35 struct _AnjutaMsgmanPage
37 GtkWidget *widget;
38 GtkWidget *pixmap;
39 GtkWidget *label;
40 GtkWidget *box;
41 GtkWidget *button;
42 GtkWidget *close_icon;
45 typedef struct _AnjutaMsgmanPage AnjutaMsgmanPage;
47 static void
48 on_msgman_close_page (GtkButton* button,
49 AnjutaMsgman *msgman)
51 MessageView *view = MESSAGE_VIEW (g_object_get_data (G_OBJECT (button),
52 "message_view"));
53 anjuta_msgman_remove_view (msgman, view);
56 static void
57 on_msgman_close_all(GtkMenuItem* item, AnjutaMsgman* msgman)
60 anjuta_msgman_remove_all_views(msgman);
63 static GtkWidget*
64 create_tab_popup_menu(AnjutaMsgman* msgman)
66 GtkWidget* menu;
67 GtkWidget* item_close_all;
69 menu = gtk_menu_new();
71 item_close_all = gtk_menu_item_new_with_label(_("Close all message tabs"));
72 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item_close_all);
73 g_signal_connect(G_OBJECT(item_close_all), "activate", G_CALLBACK(on_msgman_close_all),
74 msgman);
75 gtk_widget_show_all(menu);
77 gtk_menu_attach_to_widget(GTK_MENU(menu), GTK_WIDGET(msgman), NULL);
78 return menu;
81 static void
82 on_msgman_popup_menu(GtkWidget* widget, AnjutaMsgman* msgman)
84 gtk_menu_popup(GTK_MENU(msgman->priv->tab_popup),
85 NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
88 static gboolean
89 on_tab_button_press_event(GtkWidget* widget, GdkEventButton* event, AnjutaMsgman* msgman)
91 if (event->type == GDK_BUTTON_PRESS)
93 if (event->button == 3)
95 gtk_menu_popup(GTK_MENU(msgman->priv->tab_popup), NULL, NULL, NULL, NULL,
96 event->button, event->time);
97 return TRUE;
100 return FALSE;
103 static AnjutaMsgmanPage *
104 anjuta_msgman_page_new (GtkWidget * view, const gchar * name,
105 const gchar * pixmap, AnjutaMsgman * msgman)
107 AnjutaMsgmanPage *page;
108 int h, w;
110 g_return_val_if_fail (view != NULL, NULL);
112 page = g_new0 (AnjutaMsgmanPage, 1);
113 page->widget = GTK_WIDGET (view);
115 page->label = gtk_label_new (name);
116 gtk_misc_set_alignment (GTK_MISC(page->label), 0.0, 0.5);
117 page->box = gtk_hbox_new (FALSE, 0);
118 gtk_box_set_spacing (GTK_BOX (page->box), 5);
119 if (pixmap && strlen(pixmap))
121 GtkStockItem unused;
122 if (gtk_stock_lookup(pixmap, &unused))
124 page->pixmap = gtk_image_new_from_stock(pixmap, GTK_ICON_SIZE_MENU);
126 else
128 page->pixmap = anjuta_res_get_image_sized (pixmap, 16, 16);
130 gtk_box_pack_start (GTK_BOX (page->box), page->pixmap, FALSE, FALSE, 0);
132 gtk_box_pack_start (GTK_BOX (page->box), page->label, TRUE, TRUE, 0);
133 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
134 page->close_icon = gtk_image_new_from_stock(GTK_STOCK_CLOSE,
135 GTK_ICON_SIZE_MENU);
136 gtk_widget_set_size_request(page->close_icon, w, h);
138 page->button = gtk_button_new();
139 gtk_container_add(GTK_CONTAINER(page->button), page->close_icon);
140 gtk_widget_set_size_request (page->button, w, h);
141 gtk_button_set_focus_on_click (GTK_BUTTON (page->button), FALSE);
142 gtk_button_set_relief(GTK_BUTTON(page->button), GTK_RELIEF_NONE);
143 /* This style is created int the document-manager which we simply
144 * assume is loaded before this plugin
146 gtk_widget_set_name (page->button, "anjuta-tab-close-button");
148 gtk_box_pack_start (GTK_BOX (page->box), page->button, FALSE, FALSE, 0);
150 g_object_set_data (G_OBJECT (page->button), "message_view", page->widget);
151 g_signal_connect (GTK_OBJECT (page->button), "clicked",
152 G_CALLBACK(on_msgman_close_page),
153 msgman);
154 return page;
157 static void
158 anjuta_msgman_page_destroy (AnjutaMsgmanPage * page)
160 g_free (page);
163 static void
164 on_notebook_switch_page (GtkNotebook * notebook,
165 GtkNotebookPage * page,
166 gint page_num, AnjutaMsgman * msgman)
168 g_return_if_fail (notebook != NULL);
169 g_return_if_fail (page != NULL);
170 g_return_if_fail (msgman != NULL);
172 anjuta_msgman_set_current_view(msgman, NULL);
175 static gpointer parent_class;
177 static void
178 anjuta_msgman_dispose (GObject *obj)
180 AnjutaMsgman *msgman = ANJUTA_MSGMAN (obj);
181 if (msgman->priv->views)
183 anjuta_msgman_remove_all_views (msgman);
185 G_OBJECT_CLASS (parent_class)->dispose (obj);
188 static void
189 anjuta_msgman_finalize (GObject *obj)
191 AnjutaMsgman *msgman = ANJUTA_MSGMAN (obj);
192 gtk_widget_destroy(msgman->priv->tab_popup);
193 if (msgman->priv)
195 g_free (msgman->priv);
196 msgman->priv = NULL;
198 G_OBJECT_CLASS (parent_class)->finalize (obj);
201 static void
202 anjuta_msgman_instance_init (AnjutaMsgman * msgman)
204 g_signal_connect (GTK_NOTEBOOK (msgman), "switch-page",
205 G_CALLBACK (on_notebook_switch_page), msgman);
206 gtk_notebook_set_scrollable (GTK_NOTEBOOK (msgman), TRUE);
207 msgman->priv = g_new0(AnjutaMsgmanPriv, 1);
208 msgman->priv->views = NULL;
209 msgman->priv->tab_popup = create_tab_popup_menu(msgman);
210 g_signal_connect(GTK_OBJECT(msgman), "popup-menu",
211 G_CALLBACK(on_msgman_popup_menu), msgman);
212 g_signal_connect(GTK_OBJECT(msgman), "button-press-event",
213 G_CALLBACK(on_tab_button_press_event), msgman);
216 static void
217 anjuta_msgman_class_init (AnjutaMsgmanClass * klass)
219 static gboolean initialized = FALSE;
220 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
222 if (!initialized) {
223 /* Signal */
224 g_signal_new ("view-changed",
225 ANJUTA_TYPE_MSGMAN,
226 G_SIGNAL_RUN_LAST,
227 G_STRUCT_OFFSET (AnjutaMsgman, view_changed),
228 NULL, NULL,
229 g_cclosure_marshal_VOID__VOID,
230 G_TYPE_NONE,
232 NULL);
235 initialized = TRUE;
238 parent_class = g_type_class_peek_parent (klass);
239 gobject_class->finalize = anjuta_msgman_finalize;
240 gobject_class->dispose = anjuta_msgman_dispose;
243 static void
244 set_message_tab(AnjutaPreferences *pref, GtkNotebook *msgman)
246 gchar *tab_pos;
247 GtkPositionType pos;
249 tab_pos = anjuta_preferences_get (pref, MESSAGES_TABS_POS);
250 pos = GTK_POS_TOP;
251 if (tab_pos)
253 if (strcasecmp (tab_pos, "left") == 0)
254 pos = GTK_POS_LEFT;
255 else if (strcasecmp (tab_pos, "right") == 0)
256 pos = GTK_POS_RIGHT;
257 else if (strcasecmp (tab_pos, "bottom") == 0)
258 pos = GTK_POS_BOTTOM;
259 g_free (tab_pos);
261 gtk_notebook_set_tab_pos (msgman, pos);
264 void
265 on_gconf_notify_message_pref (GConfClient *gclient, guint cnxn_id,
266 GConfEntry *entry, gpointer user_data)
268 AnjutaPreferences *pref;
270 pref = ANJUTA_MSGMAN (user_data)->priv->preferences;
271 set_message_tab(pref, GTK_NOTEBOOK (user_data));
275 GtkWidget*
276 anjuta_msgman_new (AnjutaPreferences *pref, GtkWidget *popup_menu)
278 GtkWidget *msgman = NULL;
279 msgman = gtk_widget_new (ANJUTA_TYPE_MSGMAN, NULL);
280 if (msgman)
282 ANJUTA_MSGMAN (msgman)->priv->preferences = pref;
283 ANJUTA_MSGMAN (msgman)->priv->popup_menu = popup_menu;
285 return msgman;
289 ANJUTA_TYPE_BEGIN (AnjutaMsgman, anjuta_msgman, GTK_TYPE_NOTEBOOK);
290 ANJUTA_TYPE_END;
292 static AnjutaMsgmanPage *
293 anjuta_msgman_page_from_widget (AnjutaMsgman * msgman, MessageView * mv)
295 GList *node;
296 node = msgman->priv->views;
297 while (node)
299 AnjutaMsgmanPage *page;
300 page = node->data;
301 g_assert (page);
302 if (page->widget == GTK_WIDGET (mv))
303 return page;
304 node = g_list_next (node);
306 return NULL;
309 static void
310 on_message_view_destroy (MessageView *view, AnjutaMsgman *msgman)
312 AnjutaMsgmanPage *page;
313 gint page_num;
315 page = anjuta_msgman_page_from_widget (msgman, view);
317 g_signal_handlers_disconnect_by_func (G_OBJECT (view),
318 G_CALLBACK (on_message_view_destroy), msgman);
320 g_signal_handlers_block_by_func (GTK_OBJECT (msgman),
321 GTK_SIGNAL_FUNC
322 (on_notebook_switch_page), msgman);
324 page_num =
325 gtk_notebook_page_num (GTK_NOTEBOOK (msgman),
326 GTK_WIDGET (view));
327 msgman->priv->views = g_list_remove (msgman->priv->views, page);
328 anjuta_msgman_page_destroy (page);
330 // gtk_notebook_remove_page (GTK_NOTEBOOK (msgman), page_num);
332 /* This is called to set the next active document */
333 if (GTK_NOTEBOOK (msgman)->children == NULL)
334 anjuta_msgman_set_current_view (msgman, NULL);
336 g_signal_handlers_unblock_by_func (GTK_OBJECT (msgman),
337 GTK_SIGNAL_FUNC
338 (on_notebook_switch_page), msgman);
341 static void
342 anjuta_msgman_append_view (AnjutaMsgman * msgman, GtkWidget *mv,
343 const gchar * name, const gchar * pixmap)
345 AnjutaMsgmanPage *page;
347 g_return_if_fail (msgman != NULL);
348 g_return_if_fail (mv != NULL);
349 g_return_if_fail (name != NULL);
351 gtk_widget_show_all (mv);
352 page = anjuta_msgman_page_new (mv, name, pixmap, msgman);
353 gtk_widget_show_all (page->box);
355 g_signal_handlers_block_by_func (GTK_OBJECT (msgman),
356 GTK_SIGNAL_FUNC
357 (on_notebook_switch_page), msgman);
358 msgman->priv->views =
359 g_list_prepend (msgman->priv->views, (gpointer) page);
361 gtk_notebook_prepend_page (GTK_NOTEBOOK (msgman), mv, page->box);
362 gtk_notebook_set_current_page (GTK_NOTEBOOK (msgman), 0);
364 g_signal_connect (G_OBJECT (mv), "destroy",
365 G_CALLBACK (on_message_view_destroy), msgman);
366 g_signal_handlers_unblock_by_func (GTK_OBJECT (msgman),
367 GTK_SIGNAL_FUNC
368 (on_notebook_switch_page), msgman);
369 g_signal_emit_by_name(G_OBJECT(msgman), "view_changed");
372 MessageView *
373 anjuta_msgman_add_view (AnjutaMsgman * msgman,
374 const gchar * name, const gchar * pixmap)
376 GtkWidget *mv;
378 g_return_val_if_fail (msgman != NULL, NULL);
379 g_return_val_if_fail (name != NULL, NULL);
381 mv = message_view_new (msgman->priv->preferences, msgman->priv->popup_menu);
382 g_return_val_if_fail (mv != NULL, NULL);
383 g_object_set (G_OBJECT (mv), "highlite", TRUE, "label", name,
384 "pixmap", pixmap, NULL);
385 anjuta_msgman_append_view (msgman, mv, name, pixmap);
386 return MESSAGE_VIEW (mv);
389 void
390 anjuta_msgman_remove_view (AnjutaMsgman * msgman, MessageView *passed_view)
392 MessageView *view;
394 view = passed_view;
395 if (!view)
396 view = anjuta_msgman_get_current_view (msgman);
398 g_return_if_fail (view != NULL);
399 gtk_widget_destroy (GTK_WIDGET (view));
400 anjuta_msgman_set_current_view(msgman, NULL);
403 void
404 anjuta_msgman_remove_all_views (AnjutaMsgman * msgman)
406 GList *views, *node;
407 AnjutaMsgmanPage *page;
409 g_signal_handlers_block_by_func (GTK_OBJECT (msgman),
410 GTK_SIGNAL_FUNC
411 (on_notebook_switch_page), msgman);
412 views = NULL;
413 node = msgman->priv->views;
414 while (node)
416 page = node->data;
417 views = g_list_prepend (views, page->widget);
418 node = g_list_next (node);
420 node = views;
421 while (node)
423 gtk_widget_destroy (GTK_WIDGET (node->data));
424 node = g_list_next (node);
427 g_list_free (msgman->priv->views);
428 g_list_free (views);
430 msgman->priv->views = NULL;
431 anjuta_msgman_set_current_view (msgman, NULL);
432 g_signal_handlers_unblock_by_func (GTK_OBJECT (msgman),
433 GTK_SIGNAL_FUNC
434 (on_notebook_switch_page), msgman);
437 MessageView *
438 anjuta_msgman_get_current_view (AnjutaMsgman * msgman)
440 gint current_page = gtk_notebook_get_current_page (GTK_NOTEBOOK(msgman));
441 return MESSAGE_VIEW (gtk_notebook_get_nth_page (GTK_NOTEBOOK(msgman),
442 current_page));
445 MessageView *
446 anjuta_msgman_get_view_by_name (AnjutaMsgman * msgman, const gchar * name)
448 GList *node;
450 g_return_val_if_fail (msgman != NULL, NULL);
451 g_return_val_if_fail (name != NULL, NULL);
453 node = msgman->priv->views;
454 while (node)
456 AnjutaMsgmanPage *page;
457 page = node->data;
458 g_assert (page);
459 if (strcmp (gtk_label_get_text (GTK_LABEL (page->label)),
460 name) == 0)
462 return MESSAGE_VIEW (page->widget);
464 node = g_list_next (node);
466 return NULL;
469 void
470 anjuta_msgman_set_current_view (AnjutaMsgman * msgman, MessageView * mv)
472 g_return_if_fail (msgman != NULL);
473 AnjutaMsgmanPage *page;
474 gint page_num;
476 if (mv)
478 page = anjuta_msgman_page_from_widget (msgman, mv);
479 page_num =
480 gtk_notebook_page_num (GTK_NOTEBOOK (msgman),
481 GTK_WIDGET (mv));
482 gtk_notebook_set_page (GTK_NOTEBOOK (msgman), page_num);
484 g_signal_emit_by_name(G_OBJECT(msgman), "view_changed");
487 GList *
488 anjuta_msgman_get_all_views (AnjutaMsgman * msgman)
490 return msgman->priv->views;
493 void
494 anjuta_msgman_set_view_title (AnjutaMsgman *msgman, MessageView *view,
495 const gchar *title)
497 AnjutaMsgmanPage *page;
499 g_return_if_fail (title != NULL);
501 page = anjuta_msgman_page_from_widget (msgman, view);
502 g_return_if_fail (page != NULL);
504 gtk_label_set_text (GTK_LABEL (page->label), title);
507 gboolean
508 anjuta_msgman_serialize (AnjutaMsgman *msgman, AnjutaSerializer *serializer)
510 GList *node;
512 if (!anjuta_serializer_write_int (serializer, "views",
513 g_list_length (msgman->priv->views)))
514 return FALSE;
516 node = msgman->priv->views;
517 while (node)
519 AnjutaMsgmanPage *page = (AnjutaMsgmanPage*)node->data;
520 if (!message_view_serialize (MESSAGE_VIEW (page->widget), serializer))
521 return FALSE;
522 node = g_list_next (node);
524 return TRUE;
527 gboolean
528 anjuta_msgman_deserialize (AnjutaMsgman *msgman, AnjutaSerializer *serializer)
530 gint views, i;
532 if (!anjuta_serializer_read_int (serializer, "views", &views))
533 return FALSE;
535 for (i = 0; i < views; i++)
537 gchar *label, *pixmap;
538 GtkWidget *view;
539 view = message_view_new (msgman->priv->preferences,
540 msgman->priv->popup_menu);
541 g_return_val_if_fail (view != NULL, FALSE);
542 if (!message_view_deserialize (MESSAGE_VIEW (view), serializer))
544 gtk_widget_destroy (view);
545 return FALSE;
547 g_object_get (view, "label", &label, "pixmap", &pixmap, NULL);
548 anjuta_msgman_append_view (msgman, view, label, pixmap);
549 g_free (label);
550 g_free (pixmap);
552 return TRUE;