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
;
35 struct _AnjutaMsgmanPage
42 GtkWidget
*close_icon
;
45 typedef struct _AnjutaMsgmanPage AnjutaMsgmanPage
;
48 on_msgman_close_page (GtkButton
* button
,
51 MessageView
*view
= MESSAGE_VIEW (g_object_get_data (G_OBJECT (button
),
53 anjuta_msgman_remove_view (msgman
, view
);
57 on_msgman_close_all(GtkMenuItem
* item
, AnjutaMsgman
* msgman
)
60 anjuta_msgman_remove_all_views(msgman
);
64 create_tab_popup_menu(AnjutaMsgman
* msgman
)
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
),
75 gtk_widget_show_all(menu
);
77 gtk_menu_attach_to_widget(GTK_MENU(menu
), GTK_WIDGET(msgman
), NULL
);
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());
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
);
103 static AnjutaMsgmanPage
*
104 anjuta_msgman_page_new (GtkWidget
* view
, const gchar
* name
,
105 const gchar
* pixmap
, AnjutaMsgman
* msgman
)
107 AnjutaMsgmanPage
*page
;
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
))
122 if (gtk_stock_lookup(pixmap
, &unused
))
124 page
->pixmap
= gtk_image_new_from_stock(pixmap
, GTK_ICON_SIZE_MENU
);
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
,
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
),
158 anjuta_msgman_page_destroy (AnjutaMsgmanPage
* page
)
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
;
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
);
189 anjuta_msgman_finalize (GObject
*obj
)
191 AnjutaMsgman
*msgman
= ANJUTA_MSGMAN (obj
);
192 gtk_widget_destroy(msgman
->priv
->tab_popup
);
195 g_free (msgman
->priv
);
198 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
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
);
217 anjuta_msgman_class_init (AnjutaMsgmanClass
* klass
)
219 static gboolean initialized
= FALSE
;
220 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
224 g_signal_new ("view-changed",
227 G_STRUCT_OFFSET (AnjutaMsgman
, view_changed
),
229 g_cclosure_marshal_VOID__VOID
,
238 parent_class
= g_type_class_peek_parent (klass
);
239 gobject_class
->finalize
= anjuta_msgman_finalize
;
240 gobject_class
->dispose
= anjuta_msgman_dispose
;
244 set_message_tab(AnjutaPreferences
*pref
, GtkNotebook
*msgman
)
249 tab_pos
= anjuta_preferences_get (pref
, MESSAGES_TABS_POS
);
253 if (strcasecmp (tab_pos
, "left") == 0)
255 else if (strcasecmp (tab_pos
, "right") == 0)
257 else if (strcasecmp (tab_pos
, "bottom") == 0)
258 pos
= GTK_POS_BOTTOM
;
261 gtk_notebook_set_tab_pos (msgman
, pos
);
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
));
276 anjuta_msgman_new (AnjutaPreferences
*pref
, GtkWidget
*popup_menu
)
278 GtkWidget
*msgman
= NULL
;
279 msgman
= gtk_widget_new (ANJUTA_TYPE_MSGMAN
, NULL
);
282 ANJUTA_MSGMAN (msgman
)->priv
->preferences
= pref
;
283 ANJUTA_MSGMAN (msgman
)->priv
->popup_menu
= popup_menu
;
289 ANJUTA_TYPE_BEGIN (AnjutaMsgman
, anjuta_msgman
, GTK_TYPE_NOTEBOOK
);
292 static AnjutaMsgmanPage
*
293 anjuta_msgman_page_from_widget (AnjutaMsgman
* msgman
, MessageView
* mv
)
296 node
= msgman
->priv
->views
;
299 AnjutaMsgmanPage
*page
;
302 if (page
->widget
== GTK_WIDGET (mv
))
304 node
= g_list_next (node
);
310 on_message_view_destroy (MessageView
*view
, AnjutaMsgman
*msgman
)
312 AnjutaMsgmanPage
*page
;
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
),
322 (on_notebook_switch_page
), msgman
);
325 gtk_notebook_page_num (GTK_NOTEBOOK (msgman
),
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
),
338 (on_notebook_switch_page
), msgman
);
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
),
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
),
368 (on_notebook_switch_page
), msgman
);
369 g_signal_emit_by_name(G_OBJECT(msgman
), "view_changed");
373 anjuta_msgman_add_view (AnjutaMsgman
* msgman
,
374 const gchar
* name
, const gchar
* pixmap
)
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
);
390 anjuta_msgman_remove_view (AnjutaMsgman
* msgman
, MessageView
*passed_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
);
404 anjuta_msgman_remove_all_views (AnjutaMsgman
* msgman
)
407 AnjutaMsgmanPage
*page
;
409 g_signal_handlers_block_by_func (GTK_OBJECT (msgman
),
411 (on_notebook_switch_page
), msgman
);
413 node
= msgman
->priv
->views
;
417 views
= g_list_prepend (views
, page
->widget
);
418 node
= g_list_next (node
);
423 gtk_widget_destroy (GTK_WIDGET (node
->data
));
424 node
= g_list_next (node
);
427 g_list_free (msgman
->priv
->views
);
430 msgman
->priv
->views
= NULL
;
431 anjuta_msgman_set_current_view (msgman
, NULL
);
432 g_signal_handlers_unblock_by_func (GTK_OBJECT (msgman
),
434 (on_notebook_switch_page
), msgman
);
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
),
446 anjuta_msgman_get_view_by_name (AnjutaMsgman
* msgman
, const gchar
* name
)
450 g_return_val_if_fail (msgman
!= NULL
, NULL
);
451 g_return_val_if_fail (name
!= NULL
, NULL
);
453 node
= msgman
->priv
->views
;
456 AnjutaMsgmanPage
*page
;
459 if (strcmp (gtk_label_get_text (GTK_LABEL (page
->label
)),
462 return MESSAGE_VIEW (page
->widget
);
464 node
= g_list_next (node
);
470 anjuta_msgman_set_current_view (AnjutaMsgman
* msgman
, MessageView
* mv
)
472 g_return_if_fail (msgman
!= NULL
);
473 AnjutaMsgmanPage
*page
;
478 page
= anjuta_msgman_page_from_widget (msgman
, mv
);
480 gtk_notebook_page_num (GTK_NOTEBOOK (msgman
),
482 gtk_notebook_set_page (GTK_NOTEBOOK (msgman
), page_num
);
484 g_signal_emit_by_name(G_OBJECT(msgman
), "view_changed");
488 anjuta_msgman_get_all_views (AnjutaMsgman
* msgman
)
490 return msgman
->priv
->views
;
494 anjuta_msgman_set_view_title (AnjutaMsgman
*msgman
, MessageView
*view
,
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
);
508 anjuta_msgman_serialize (AnjutaMsgman
*msgman
, AnjutaSerializer
*serializer
)
512 if (!anjuta_serializer_write_int (serializer
, "views",
513 g_list_length (msgman
->priv
->views
)))
516 node
= msgman
->priv
->views
;
519 AnjutaMsgmanPage
*page
= (AnjutaMsgmanPage
*)node
->data
;
520 if (!message_view_serialize (MESSAGE_VIEW (page
->widget
), serializer
))
522 node
= g_list_next (node
);
528 anjuta_msgman_deserialize (AnjutaMsgman
*msgman
, AnjutaSerializer
*serializer
)
532 if (!anjuta_serializer_read_int (serializer
, "views", &views
))
535 for (i
= 0; i
< views
; i
++)
537 gchar
*label
, *pixmap
;
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
);
547 g_object_get (view
, "label", &label
, "pixmap", &pixmap
, NULL
);
548 anjuta_msgman_append_view (msgman
, view
, label
, pixmap
);