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.
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
;
39 struct _AnjutaMsgmanPage
45 GtkWidget
*close_button
;
46 GtkWidget
*close_icon
;
55 guint msgman_signal
[LAST_SIGNAL
];
57 typedef struct _AnjutaMsgmanPage AnjutaMsgmanPage
;
60 on_msgman_close_page (GtkButton
* button
,
63 MessageView
*view
= MESSAGE_VIEW (g_object_get_data (G_OBJECT (button
),
65 anjuta_msgman_remove_view (msgman
, view
);
69 on_msgman_close_all(GtkMenuItem
* item
, AnjutaMsgman
* msgman
)
72 anjuta_msgman_remove_all_views(msgman
);
76 create_tab_popup_menu(AnjutaMsgman
* msgman
)
79 GtkWidget
* item_close_all
;
81 menu
= gtk_menu_new();
83 item_close_all
= gtk_menu_item_new_with_label(_("Close all message tabs"));
84 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item_close_all
);
85 g_signal_connect(G_OBJECT(item_close_all
), "activate", G_CALLBACK(on_msgman_close_all
),
87 gtk_widget_show_all(menu
);
89 gtk_menu_attach_to_widget(GTK_MENU(menu
), GTK_WIDGET(msgman
), NULL
);
94 on_msgman_popup_menu(GtkWidget
* widget
, AnjutaMsgman
* msgman
)
96 gtk_menu_popup(GTK_MENU(msgman
->priv
->tab_popup
),
97 NULL
, NULL
, NULL
, NULL
, 0, gtk_get_current_event_time());
101 on_tab_button_press_event(GtkWidget
* widget
, GdkEventButton
* event
, AnjutaMsgman
* msgman
)
103 if (event
->type
== GDK_BUTTON_PRESS
)
105 if (event
->button
== 3)
107 gtk_menu_popup(GTK_MENU(msgman
->priv
->tab_popup
), NULL
, NULL
, NULL
, NULL
,
108 event
->button
, event
->time
);
115 static AnjutaMsgmanPage
*
116 anjuta_msgman_page_new (GtkWidget
* view
, const gchar
* name
,
117 const gchar
* pixmap
, AnjutaMsgman
* msgman
)
119 AnjutaMsgmanPage
*page
;
123 g_return_val_if_fail (view
!= NULL
, NULL
);
125 page
= g_new0 (AnjutaMsgmanPage
, 1);
126 page
->widget
= GTK_WIDGET (view
);
128 page
->label
= gtk_label_new (name
);
129 gtk_misc_set_alignment (GTK_MISC(page
->label
), 0.0, 0.5);
130 gtk_label_set_ellipsize (GTK_LABEL(page
->label
), PANGO_ELLIPSIZE_END
);
131 box
= gtk_hbox_new (FALSE
, 0);
132 gtk_box_set_spacing (GTK_BOX (box
), 5);
133 if (pixmap
&& strlen(pixmap
))
136 if (gtk_stock_lookup(pixmap
, &unused
))
138 page
->pixmap
= gtk_image_new_from_stock(pixmap
, GTK_ICON_SIZE_MENU
);
142 page
->pixmap
= anjuta_res_get_image_sized (pixmap
, 16, 16);
144 gtk_box_pack_start (GTK_BOX (box
), page
->pixmap
, FALSE
, FALSE
, 0);
146 gtk_box_pack_start (GTK_BOX (box
), page
->label
, TRUE
, TRUE
, 0);
147 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU
, &w
, &h
);
148 page
->close_icon
= gtk_image_new_from_stock(GTK_STOCK_CLOSE
,
150 gtk_widget_set_size_request(page
->close_icon
, w
, h
);
152 page
->close_button
= gtk_button_new();
153 gtk_container_add(GTK_CONTAINER(page
->close_button
), page
->close_icon
);
154 gtk_widget_set_size_request (page
->close_button
, w
, h
);
155 gtk_button_set_focus_on_click (GTK_BUTTON (page
->close_button
), FALSE
);
156 gtk_button_set_relief(GTK_BUTTON(page
->close_button
), GTK_RELIEF_NONE
);
157 /* This style is created int the document-manager which we simply
158 * assume is loaded before this plugin
160 gtk_widget_set_name (page
->close_button
, "anjuta-tab-close-button");
162 g_object_set_data (G_OBJECT (page
->close_button
), "message_view", page
->widget
);
163 g_signal_connect (page
->close_button
, "clicked",
164 G_CALLBACK(on_msgman_close_page
),
168 page
->box
= gtk_hbox_new (FALSE
, 0);
169 gtk_box_pack_start (GTK_BOX(page
->box
), box
, TRUE
, TRUE
, 0);
170 gtk_box_pack_start (GTK_BOX(page
->box
), page
->close_button
, FALSE
, FALSE
, 0);
172 gtk_widget_show_all (page
->box
);
178 anjuta_msgman_page_destroy (AnjutaMsgmanPage
* page
)
183 static AnjutaMsgmanPage
*
184 anjuta_msgman_page_from_widget (AnjutaMsgman
* msgman
, MessageView
* mv
)
187 node
= msgman
->priv
->views
;
190 AnjutaMsgmanPage
*page
;
193 if (page
->widget
== GTK_WIDGET (mv
))
195 node
= g_list_next (node
);
200 static gpointer parent_class
;
203 anjuta_msgman_dispose (GObject
*obj
)
205 G_OBJECT_CLASS (parent_class
)->dispose (obj
);
209 anjuta_msgman_finalize (GObject
*obj
)
211 AnjutaMsgman
*msgman
= ANJUTA_MSGMAN (obj
);
212 gtk_widget_destroy(msgman
->priv
->tab_popup
);
215 g_free (msgman
->priv
);
218 G_OBJECT_CLASS (parent_class
)->finalize (obj
);
222 anjuta_msgman_instance_init (AnjutaMsgman
* msgman
)
224 gtk_notebook_set_scrollable (GTK_NOTEBOOK (msgman
), TRUE
);
225 msgman
->priv
= g_new0(AnjutaMsgmanPriv
, 1);
226 msgman
->priv
->views
= NULL
;
227 msgman
->priv
->tab_popup
= create_tab_popup_menu(msgman
);
228 msgman
->priv
->tabber
= anjuta_tabber_new (GTK_NOTEBOOK (msgman
));
229 msgman
->priv
->button_group
= NULL
;
231 g_signal_connect(msgman
, "popup-menu",
232 G_CALLBACK(on_msgman_popup_menu
), msgman
);
233 g_signal_connect(msgman
, "button-press-event",
234 G_CALLBACK(on_tab_button_press_event
), msgman
);
238 anjuta_msgman_switch_page (GtkNotebook
* notebook
,
242 GTK_NOTEBOOK_CLASS (parent_class
)->switch_page (notebook
, page
, page_num
);
244 g_signal_emit_by_name (ANJUTA_MSGMAN (notebook
),
249 anjuta_msgman_class_init (AnjutaMsgmanClass
* klass
)
251 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
252 GtkNotebookClass
*notebook_class
= GTK_NOTEBOOK_CLASS (klass
);
254 parent_class
= g_type_class_peek_parent (klass
);
255 gobject_class
->finalize
= anjuta_msgman_finalize
;
256 gobject_class
->dispose
= anjuta_msgman_dispose
;
258 notebook_class
->switch_page
= anjuta_msgman_switch_page
;
261 * AnjutaMsgMan::view-changed:
262 * @msgman: #AnjutaMsgMan
264 * Emitted when the current view changes
267 msgman_signal
[VIEW_CHANGED
] = g_signal_new ("view-changed",
268 G_OBJECT_CLASS_TYPE (klass
),
270 G_STRUCT_OFFSET (AnjutaMsgmanClass
, view_changed
),
272 g_cclosure_marshal_VOID__VOID
,
278 set_message_tab(GSettings
* settings
, GtkNotebook
*msgman
)
283 tab_pos
= g_settings_get_string (settings
, MESSAGES_TABS_POS
);
287 if (strcasecmp (tab_pos
, "left") == 0)
289 else if (strcasecmp (tab_pos
, "right") == 0)
291 else if (strcasecmp (tab_pos
, "bottom") == 0)
292 pos
= GTK_POS_BOTTOM
;
295 gtk_notebook_set_tab_pos (msgman
, pos
);
299 on_notify_message_pref (GSettings
*settings
, const gchar
* key
,
302 set_message_tab(settings
, GTK_NOTEBOOK (user_data
));
307 anjuta_msgman_new (GtkWidget
*popup_menu
)
309 GtkWidget
*msgman
= NULL
;
310 msgman
= gtk_widget_new (ANJUTA_TYPE_MSGMAN
, "show-tabs", FALSE
, NULL
);
313 ANJUTA_MSGMAN (msgman
)->priv
->popup_menu
= popup_menu
;
319 ANJUTA_TYPE_BEGIN (AnjutaMsgman
, anjuta_msgman
, GTK_TYPE_NOTEBOOK
);
323 on_message_view_destroy (MessageView
*view
, AnjutaMsgman
*msgman
)
325 AnjutaMsgmanPage
*page
;
328 page
= anjuta_msgman_page_from_widget (msgman
, view
);
330 g_signal_handlers_disconnect_by_func (G_OBJECT (view
),
331 G_CALLBACK (on_message_view_destroy
), msgman
);
334 gtk_notebook_page_num (GTK_NOTEBOOK (msgman
),
336 msgman
->priv
->views
= g_list_remove (msgman
->priv
->views
, page
);
337 anjuta_msgman_page_destroy (page
);
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
);
354 msgman
->priv
->views
=
355 g_list_prepend (msgman
->priv
->views
, (gpointer
) page
);
357 gtk_notebook_append_page (GTK_NOTEBOOK (msgman
), mv
, NULL
);
359 g_signal_emit_by_name (msgman
, "view-changed");
361 anjuta_tabber_add_tab (ANJUTA_TABBER(msgman
->priv
->tabber
), page
->box
);
363 g_signal_connect (G_OBJECT (mv
), "destroy",
364 G_CALLBACK (on_message_view_destroy
), msgman
);
368 anjuta_msgman_add_view (AnjutaMsgman
* msgman
,
369 const gchar
* name
, const gchar
* pixmap
)
373 g_return_val_if_fail (msgman
!= NULL
, NULL
);
374 g_return_val_if_fail (name
!= NULL
, NULL
);
376 mv
= message_view_new (msgman
->priv
->popup_menu
);
377 g_return_val_if_fail (mv
!= NULL
, NULL
);
378 g_object_set (G_OBJECT (mv
), "highlite", TRUE
, "label", name
,
379 "pixmap", pixmap
, NULL
);
380 anjuta_msgman_append_view (msgman
, mv
, name
, pixmap
);
381 return MESSAGE_VIEW (mv
);
385 anjuta_msgman_remove_view (AnjutaMsgman
* msgman
, MessageView
*view
)
388 view
= anjuta_msgman_get_current_view (msgman
);
390 g_return_if_fail (view
!= NULL
);
391 gtk_widget_destroy (GTK_WIDGET (view
));
393 g_signal_emit_by_name (msgman
, "view-changed");
397 anjuta_msgman_remove_all_views (AnjutaMsgman
* msgman
)
400 AnjutaMsgmanPage
*page
;
403 node
= msgman
->priv
->views
;
407 views
= g_list_prepend (views
, page
->widget
);
408 node
= g_list_next (node
);
413 gtk_widget_destroy (GTK_WIDGET (node
->data
));
414 node
= g_list_next (node
);
417 g_list_free (msgman
->priv
->views
);
420 g_signal_emit_by_name (msgman
, "view-changed");
422 msgman
->priv
->views
= NULL
;
426 anjuta_msgman_get_current_view (AnjutaMsgman
* msgman
)
428 gint page
= gtk_notebook_get_current_page (GTK_NOTEBOOK(msgman
));
430 return MESSAGE_VIEW (gtk_notebook_get_nth_page (GTK_NOTEBOOK(msgman
), page
));
436 anjuta_msgman_get_view_by_name (AnjutaMsgman
* msgman
, const gchar
* name
)
440 g_return_val_if_fail (msgman
!= NULL
, NULL
);
441 g_return_val_if_fail (name
!= NULL
, NULL
);
443 node
= msgman
->priv
->views
;
446 AnjutaMsgmanPage
*page
;
449 if (strcmp (gtk_label_get_text (GTK_LABEL (page
->label
)),
452 return MESSAGE_VIEW (page
->widget
);
454 node
= g_list_next (node
);
460 anjuta_msgman_set_current_view (AnjutaMsgman
* msgman
, MessageView
* mv
)
462 g_return_if_fail (msgman
!= NULL
);
463 AnjutaMsgmanPage
*page
;
468 page
= anjuta_msgman_page_from_widget (msgman
, mv
);
470 gtk_notebook_page_num (GTK_NOTEBOOK (msgman
),
472 gtk_notebook_set_current_page (GTK_NOTEBOOK (msgman
), page_num
);
477 anjuta_msgman_get_all_views (AnjutaMsgman
* msgman
)
479 return msgman
->priv
->views
;
483 anjuta_msgman_set_view_title (AnjutaMsgman
*msgman
, MessageView
*view
,
486 AnjutaMsgmanPage
*page
;
488 g_return_if_fail (title
!= NULL
);
490 page
= anjuta_msgman_page_from_widget (msgman
, view
);
491 g_return_if_fail (page
!= NULL
);
493 gtk_label_set_text (GTK_LABEL (page
->label
), title
);
497 anjuta_msgman_set_view_icon (AnjutaMsgman
*msgman
, MessageView
*view
,
498 GdkPixbufAnimation
*icon
)
500 AnjutaMsgmanPage
*page
;
502 g_return_if_fail (icon
!= NULL
);
504 page
= anjuta_msgman_page_from_widget (msgman
, view
);
505 g_return_if_fail (page
!= NULL
);
507 gtk_image_set_from_animation (GTK_IMAGE (page
->pixmap
), icon
);
511 anjuta_msgman_set_view_icon_from_stock (AnjutaMsgman
*msgman
, MessageView
*view
,
514 AnjutaMsgmanPage
*page
;
516 g_return_if_fail (icon
!= NULL
);
518 page
= anjuta_msgman_page_from_widget (msgman
, view
);
519 g_return_if_fail (page
!= NULL
);
521 gtk_image_set_from_stock (GTK_IMAGE (page
->pixmap
), icon
,
526 anjuta_msgman_serialize (AnjutaMsgman
*msgman
, AnjutaSerializer
*serializer
)
530 if (!anjuta_serializer_write_int (serializer
, "views",
531 g_list_length (msgman
->priv
->views
)))
534 node
= msgman
->priv
->views
;
537 AnjutaMsgmanPage
*page
= (AnjutaMsgmanPage
*)node
->data
;
538 if (!message_view_serialize (MESSAGE_VIEW (page
->widget
), serializer
))
540 node
= g_list_next (node
);
546 anjuta_msgman_deserialize (AnjutaMsgman
*msgman
, AnjutaSerializer
*serializer
)
550 if (!anjuta_serializer_read_int (serializer
, "views", &views
))
553 for (i
= 0; i
< views
; i
++)
555 gchar
*label
, *pixmap
;
557 view
= message_view_new (msgman
->priv
->popup_menu
);
558 g_return_val_if_fail (view
!= NULL
, FALSE
);
559 if (!message_view_deserialize (MESSAGE_VIEW (view
), serializer
))
561 gtk_widget_destroy (view
);
564 g_object_get (view
, "label", &label
, "pixmap", &pixmap
, NULL
);
565 anjuta_msgman_append_view (msgman
, view
, label
, pixmap
);
572 GtkWidget
* anjuta_msgman_get_tabber (AnjutaMsgman
* msgman
)
574 return msgman
->priv
->tabber
;