message-view: bgo #727634 - Cannot copy build output
[anjuta.git] / plugins / message-view / anjuta-msgman.c
blobbe38694a3659051d1da9ea88163508e75c83ad95
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>
23 #include <libanjuta/anjuta-close-button.h>
24 #include <libanjuta/resources.h>
26 #include "message-view.h"
27 #include "anjuta-msgman.h"
29 struct _AnjutaMsgmanPriv
31 AnjutaPreferences *preferences;
32 GtkWidget* popup_menu;
33 GtkWidget* tab_popup;
34 GList *views;
36 GtkWidget* tabber;
37 GSList* button_group;
40 struct _AnjutaMsgmanPage
42 MessageView *view;
43 GtkWidget *pixmap;
44 GtkWidget *label;
45 GtkWidget *box;
46 GtkWidget *close_button;
47 AnjutaMsgman *msgman;
50 enum
52 VIEW_CHANGED,
53 LAST_SIGNAL
56 guint msgman_signal[LAST_SIGNAL];
58 typedef struct _AnjutaMsgmanPage AnjutaMsgmanPage;
60 static void
61 on_msgman_close_page (GtkButton* button,
62 AnjutaMsgmanPage *page)
64 anjuta_msgman_remove_view (page->msgman, page->view);
67 static void
68 on_msgman_button_release (GtkWidget *widget,
69 GdkEventButton *event,
70 AnjutaMsgmanPage *page)
72 /* close on middle click */
73 if (event->button == 2)
75 anjuta_msgman_remove_view (page->msgman, page->view);
79 static void
80 on_msgman_close_all(GtkMenuItem* item, AnjutaMsgman* msgman)
83 anjuta_msgman_remove_all_views(msgman);
86 static GtkWidget*
87 create_tab_popup_menu(AnjutaMsgman* msgman)
89 GtkWidget* menu;
90 GtkWidget* item_close_all;
92 menu = gtk_menu_new();
94 item_close_all = gtk_menu_item_new_with_label(_("Close all message tabs"));
95 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item_close_all);
96 g_signal_connect(G_OBJECT(item_close_all), "activate", G_CALLBACK(on_msgman_close_all),
97 msgman);
98 gtk_widget_show_all(menu);
100 gtk_menu_attach_to_widget(GTK_MENU(menu), GTK_WIDGET(msgman), NULL);
101 return menu;
104 static void
105 on_msgman_popup_menu(GtkWidget* widget, AnjutaMsgman* msgman)
107 gtk_menu_popup(GTK_MENU(msgman->priv->tab_popup),
108 NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
111 static gboolean
112 on_tab_button_press_event(GtkWidget* widget, GdkEventButton* event, AnjutaMsgman* msgman)
114 if (event->type == GDK_BUTTON_PRESS)
116 if (event->button == 3)
118 gtk_menu_popup(GTK_MENU(msgman->priv->tab_popup), NULL, NULL, NULL, NULL,
119 event->button, event->time);
120 return TRUE;
123 return FALSE;
126 static AnjutaMsgmanPage *
127 anjuta_msgman_page_new (MessageView* view, const gchar * name,
128 const gchar * pixmap, AnjutaMsgman * msgman)
130 AnjutaMsgmanPage *page;
131 GtkWidget *box;
133 g_return_val_if_fail (view != NULL, NULL);
135 page = g_new0 (AnjutaMsgmanPage, 1);
136 page->view = view;
137 page->msgman = msgman;
138 page->box = gtk_event_box_new();
139 gtk_event_box_set_visible_window (GTK_EVENT_BOX (page->box), FALSE);
141 page->label = gtk_label_new (name);
142 gtk_label_set_ellipsize (GTK_LABEL(page->label), PANGO_ELLIPSIZE_END);
143 box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
144 gtk_box_set_spacing (GTK_BOX (box), 5);
145 if (pixmap && strlen(pixmap))
147 GtkStockItem unused;
148 if (gtk_stock_lookup(pixmap, &unused))
150 page->pixmap = gtk_image_new_from_stock(pixmap, GTK_ICON_SIZE_MENU);
152 else
154 page->pixmap = anjuta_res_get_image_sized (pixmap, 16, 16);
156 gtk_box_pack_start (GTK_BOX (box), page->pixmap, FALSE, FALSE, 0);
158 gtk_box_pack_start (GTK_BOX (box), page->label, TRUE, TRUE, 0);
160 page->close_button = anjuta_close_button_new ();
162 g_signal_connect (page->close_button, "clicked",
163 G_CALLBACK(on_msgman_close_page),
164 page);
165 g_signal_connect (page->box, "button-release-event",
166 G_CALLBACK(on_msgman_button_release),
167 page);
169 gtk_box_pack_start (GTK_BOX(box), page->close_button, FALSE, FALSE, 0);
170 gtk_container_add (GTK_CONTAINER (page->box), box);
172 gtk_widget_show_all (page->box);
174 return page;
177 static void
178 anjuta_msgman_page_destroy (AnjutaMsgmanPage * page)
180 g_free (page);
183 static AnjutaMsgmanPage *
184 anjuta_msgman_page_from_widget (AnjutaMsgman * msgman, MessageView * mv)
186 GList *node;
187 node = msgman->priv->views;
188 while (node)
190 AnjutaMsgmanPage *page;
191 page = node->data;
192 g_assert (page);
193 if (page->view == mv)
194 return page;
195 node = g_list_next (node);
197 return NULL;
200 static gpointer parent_class;
202 static void
203 anjuta_msgman_dispose (GObject *obj)
205 G_OBJECT_CLASS (parent_class)->dispose (obj);
208 static void
209 anjuta_msgman_finalize (GObject *obj)
211 AnjutaMsgman *msgman = ANJUTA_MSGMAN (obj);
212 gtk_widget_destroy(msgman->priv->tab_popup);
214 G_OBJECT_CLASS (parent_class)->finalize (obj);
217 static void
218 anjuta_msgman_instance_init (AnjutaMsgman * msgman)
220 msgman->priv = G_TYPE_INSTANCE_GET_PRIVATE (msgman, ANJUTA_TYPE_MSGMAN,
221 AnjutaMsgmanPriv);
223 gtk_notebook_set_scrollable (GTK_NOTEBOOK (msgman), TRUE);
224 msgman->priv->views = NULL;
225 msgman->priv->tab_popup = create_tab_popup_menu(msgman);
226 msgman->priv->tabber = anjuta_tabber_new (GTK_NOTEBOOK (msgman));
227 msgman->priv->button_group = NULL;
229 g_signal_connect(msgman, "popup-menu",
230 G_CALLBACK(on_msgman_popup_menu), msgman);
231 g_signal_connect(msgman, "button-press-event",
232 G_CALLBACK(on_tab_button_press_event), msgman);
235 static void
236 anjuta_msgman_switch_page (GtkNotebook* notebook,
237 GtkWidget* page,
238 guint page_num)
240 GTK_NOTEBOOK_CLASS (parent_class)->switch_page (notebook, page, page_num);
242 g_signal_emit_by_name (ANJUTA_MSGMAN (notebook),
243 "view-changed");
246 static void
247 anjuta_msgman_class_init (AnjutaMsgmanClass * klass)
249 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
250 GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass);
252 parent_class = g_type_class_peek_parent (klass);
253 gobject_class->finalize = anjuta_msgman_finalize;
254 gobject_class->dispose = anjuta_msgman_dispose;
256 notebook_class->switch_page = anjuta_msgman_switch_page;
258 g_type_class_add_private (klass, sizeof (AnjutaMsgmanPriv));
262 * AnjutaMsgMan::view-changed:
263 * @msgman: #AnjutaMsgMan
265 * Emitted when the current view changes
268 msgman_signal[VIEW_CHANGED] = g_signal_new ("view-changed",
269 G_OBJECT_CLASS_TYPE (klass),
270 G_SIGNAL_RUN_LAST,
271 G_STRUCT_OFFSET (AnjutaMsgmanClass, view_changed),
272 NULL, NULL,
273 g_cclosure_marshal_VOID__VOID,
274 G_TYPE_NONE,
278 static void
279 set_message_tab(GSettings* settings, GtkNotebook *msgman)
281 gchar *tab_pos;
282 GtkPositionType pos;
284 tab_pos = g_settings_get_string (settings, MESSAGES_TABS_POS);
285 pos = GTK_POS_TOP;
286 if (tab_pos)
288 if (strcasecmp (tab_pos, "left") == 0)
289 pos = GTK_POS_LEFT;
290 else if (strcasecmp (tab_pos, "right") == 0)
291 pos = GTK_POS_RIGHT;
292 else if (strcasecmp (tab_pos, "bottom") == 0)
293 pos = GTK_POS_BOTTOM;
294 g_free (tab_pos);
296 gtk_notebook_set_tab_pos (msgman, pos);
299 void
300 on_notify_message_pref (GSettings *settings, const gchar* key,
301 gpointer user_data)
303 set_message_tab(settings, GTK_NOTEBOOK (user_data));
307 GtkWidget*
308 anjuta_msgman_new (GtkWidget *popup_menu)
310 GtkWidget *msgman = NULL;
311 msgman = gtk_widget_new (ANJUTA_TYPE_MSGMAN, "show-tabs", FALSE, NULL);
312 if (msgman)
314 ANJUTA_MSGMAN (msgman)->priv->popup_menu = popup_menu;
316 return msgman;
320 ANJUTA_TYPE_BEGIN (AnjutaMsgman, anjuta_msgman, GTK_TYPE_NOTEBOOK);
321 ANJUTA_TYPE_END;
323 static void
324 on_message_view_destroy (MessageView *view, AnjutaMsgman *msgman)
326 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);
333 msgman->priv->views = g_list_remove (msgman->priv->views, page);
334 anjuta_msgman_page_destroy (page);
338 static void
339 anjuta_msgman_append_view (AnjutaMsgman * msgman, MessageView *mv,
340 const gchar * name, const gchar * pixmap)
342 AnjutaMsgmanPage *page;
344 g_return_if_fail (msgman != NULL);
345 g_return_if_fail (mv != NULL);
346 g_return_if_fail (name != NULL);
348 gtk_widget_show_all (GTK_WIDGET (mv));
349 page = anjuta_msgman_page_new (mv, name, pixmap, msgman);
351 msgman->priv->views =
352 g_list_prepend (msgman->priv->views, (gpointer) page);
354 gtk_notebook_append_page (GTK_NOTEBOOK (msgman), GTK_WIDGET (mv), NULL);
356 g_signal_emit_by_name (msgman, "view-changed");
358 anjuta_tabber_add_tab (ANJUTA_TABBER(msgman->priv->tabber), page->box);
360 g_signal_connect (G_OBJECT (mv), "destroy",
361 G_CALLBACK (on_message_view_destroy), msgman);
364 MessageView *
365 anjuta_msgman_add_view (AnjutaMsgman * msgman,
366 const gchar * name, const gchar * pixmap)
368 MessageView *mv;
370 g_return_val_if_fail (msgman != NULL, NULL);
371 g_return_val_if_fail (name != NULL, NULL);
373 mv = MESSAGE_VIEW (message_view_new (msgman->priv->popup_menu));
374 g_return_val_if_fail (mv != NULL, NULL);
375 g_object_set (G_OBJECT (mv), "highlite", TRUE, "label", name,
376 "pixmap", pixmap, NULL);
377 anjuta_msgman_append_view (msgman, mv, name, pixmap);
378 return mv;
381 void
382 anjuta_msgman_remove_view (AnjutaMsgman * msgman, MessageView *view)
384 if (!view)
385 view = anjuta_msgman_get_current_view (msgman);
387 g_return_if_fail (view != NULL);
388 gtk_widget_destroy (GTK_WIDGET (view));
390 g_signal_emit_by_name (msgman, "view-changed");
393 void
394 anjuta_msgman_remove_all_views (AnjutaMsgman * msgman)
396 GList *views, *node;
397 AnjutaMsgmanPage *page;
399 views = NULL;
400 node = msgman->priv->views;
401 while (node)
403 page = node->data;
404 views = g_list_prepend (views, page->view);
405 node = g_list_next (node);
407 node = views;
408 while (node)
410 gtk_widget_destroy (GTK_WIDGET (node->data));
411 node = g_list_next (node);
414 g_list_free (msgman->priv->views);
415 g_list_free (views);
417 g_signal_emit_by_name (msgman, "view-changed");
419 msgman->priv->views = NULL;
422 MessageView *
423 anjuta_msgman_get_current_view (AnjutaMsgman * msgman)
425 gint page = gtk_notebook_get_current_page (GTK_NOTEBOOK(msgman));
426 if (page != -1)
427 return MESSAGE_VIEW (gtk_notebook_get_nth_page (GTK_NOTEBOOK(msgman), page));
428 else
429 return NULL;
432 MessageView *
433 anjuta_msgman_get_view_by_name (AnjutaMsgman * msgman, const gchar * name)
435 GList *node;
437 g_return_val_if_fail (msgman != NULL, NULL);
438 g_return_val_if_fail (name != NULL, NULL);
440 node = msgman->priv->views;
441 while (node)
443 AnjutaMsgmanPage *page;
444 page = node->data;
445 g_assert (page);
446 if (strcmp (gtk_label_get_text (GTK_LABEL (page->label)),
447 name) == 0)
449 return page->view;
451 node = g_list_next (node);
453 return NULL;
456 void
457 anjuta_msgman_set_current_view (AnjutaMsgman * msgman, MessageView * mv)
459 g_return_if_fail (msgman != NULL);
460 gint page_num;
462 if (mv)
464 page_num =
465 gtk_notebook_page_num (GTK_NOTEBOOK (msgman),
466 GTK_WIDGET (mv));
467 gtk_notebook_set_current_page (GTK_NOTEBOOK (msgman), page_num);
471 GList *
472 anjuta_msgman_get_all_views (AnjutaMsgman * msgman)
474 return msgman->priv->views;
477 void
478 anjuta_msgman_set_view_title (AnjutaMsgman *msgman, MessageView *view,
479 const gchar *title)
481 AnjutaMsgmanPage *page;
483 g_return_if_fail (title != NULL);
485 page = anjuta_msgman_page_from_widget (msgman, view);
486 g_return_if_fail (page != NULL);
488 gtk_label_set_text (GTK_LABEL (page->label), title);
491 void
492 anjuta_msgman_set_view_icon (AnjutaMsgman *msgman, MessageView *view,
493 GdkPixbufAnimation *icon)
495 AnjutaMsgmanPage *page;
497 g_return_if_fail (icon != NULL);
499 page = anjuta_msgman_page_from_widget (msgman, view);
500 g_return_if_fail (page != NULL);
502 gtk_image_set_from_animation (GTK_IMAGE (page->pixmap), icon);
505 void
506 anjuta_msgman_set_view_icon_from_stock (AnjutaMsgman *msgman, MessageView *view,
507 const gchar *icon)
509 AnjutaMsgmanPage *page;
511 g_return_if_fail (icon != NULL);
513 page = anjuta_msgman_page_from_widget (msgman, view);
514 g_return_if_fail (page != NULL);
516 gtk_image_set_from_stock (GTK_IMAGE (page->pixmap), icon,
517 GTK_ICON_SIZE_MENU);
520 gboolean
521 anjuta_msgman_serialize (AnjutaMsgman *msgman, AnjutaSerializer *serializer)
523 GList *node;
525 if (!anjuta_serializer_write_int (serializer, "views",
526 g_list_length (msgman->priv->views)))
527 return FALSE;
529 node = msgman->priv->views;
530 while (node)
532 AnjutaMsgmanPage *page = (AnjutaMsgmanPage*)node->data;
533 if (!message_view_serialize (page->view, serializer))
534 return FALSE;
535 node = g_list_next (node);
537 return TRUE;
540 gboolean
541 anjuta_msgman_deserialize (AnjutaMsgman *msgman, AnjutaSerializer *serializer)
543 gint views, i;
545 if (!anjuta_serializer_read_int (serializer, "views", &views))
546 return FALSE;
548 for (i = 0; i < views; i++)
550 gchar *label, *pixmap;
551 MessageView *view;
552 view = MESSAGE_VIEW (message_view_new (msgman->priv->popup_menu));
553 g_return_val_if_fail (view != NULL, FALSE);
554 if (!message_view_deserialize (view, serializer))
556 gtk_widget_destroy (GTK_WIDGET (view));
557 return FALSE;
559 g_object_get (view, "label", &label, "pixmap", &pixmap, NULL);
560 anjuta_msgman_append_view (msgman, view, label, pixmap);
561 g_free (label);
562 g_free (pixmap);
564 return TRUE;
567 GtkWidget* anjuta_msgman_get_tabber (AnjutaMsgman* msgman)
569 return msgman->priv->tabber;