message-view: Remove trailing spaces
[anjuta.git] / plugins / message-view / anjuta-msgman.c
blobdbdf9af23227236f50685d1cae23dcedc07c86d7
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 enum
51 VIEW_CHANGED,
52 LAST_SIGNAL
55 guint msgman_signal[LAST_SIGNAL];
57 typedef struct _AnjutaMsgmanPage AnjutaMsgmanPage;
59 static void
60 on_msgman_close_page (GtkButton* button,
61 AnjutaMsgman *msgman)
63 MessageView *view = MESSAGE_VIEW (g_object_get_data (G_OBJECT (button),
64 "message_view"));
65 anjuta_msgman_remove_view (msgman, view);
68 static void
69 on_msgman_close_all(GtkMenuItem* item, AnjutaMsgman* msgman)
72 anjuta_msgman_remove_all_views(msgman);
75 static GtkWidget*
76 create_tab_popup_menu(AnjutaMsgman* msgman)
78 GtkWidget* menu;
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),
86 msgman);
87 gtk_widget_show_all(menu);
89 gtk_menu_attach_to_widget(GTK_MENU(menu), GTK_WIDGET(msgman), NULL);
90 return menu;
93 static void
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());
100 static gboolean
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);
109 return TRUE;
112 return FALSE;
115 static AnjutaMsgmanPage *
116 anjuta_msgman_page_new (GtkWidget * view, const gchar * name,
117 const gchar * pixmap, AnjutaMsgman * msgman)
119 AnjutaMsgmanPage *page;
120 int h, w;
121 GtkWidget* box;
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))
135 GtkStockItem unused;
136 if (gtk_stock_lookup(pixmap, &unused))
138 page->pixmap = gtk_image_new_from_stock(pixmap, GTK_ICON_SIZE_MENU);
140 else
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,
149 GTK_ICON_SIZE_MENU);
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),
165 msgman);
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);
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->widget == GTK_WIDGET (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);
213 if (msgman->priv)
215 g_free (msgman->priv);
216 msgman->priv = NULL;
218 G_OBJECT_CLASS (parent_class)->finalize (obj);
221 static void
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);
237 static void
238 anjuta_msgman_switch_page (GtkNotebook* notebook,
239 GtkWidget* page,
240 guint page_num)
242 GTK_NOTEBOOK_CLASS (parent_class)->switch_page (notebook, page, page_num);
244 g_signal_emit_by_name (ANJUTA_MSGMAN (notebook),
245 "view-changed");
248 static void
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),
269 G_SIGNAL_RUN_LAST,
270 G_STRUCT_OFFSET (AnjutaMsgmanClass, view_changed),
271 NULL, NULL,
272 g_cclosure_marshal_VOID__VOID,
273 G_TYPE_NONE,
277 static void
278 set_message_tab(GSettings* settings, GtkNotebook *msgman)
280 gchar *tab_pos;
281 GtkPositionType pos;
283 tab_pos = g_settings_get_string (settings, MESSAGES_TABS_POS);
284 pos = GTK_POS_TOP;
285 if (tab_pos)
287 if (strcasecmp (tab_pos, "left") == 0)
288 pos = GTK_POS_LEFT;
289 else if (strcasecmp (tab_pos, "right") == 0)
290 pos = GTK_POS_RIGHT;
291 else if (strcasecmp (tab_pos, "bottom") == 0)
292 pos = GTK_POS_BOTTOM;
293 g_free (tab_pos);
295 gtk_notebook_set_tab_pos (msgman, pos);
298 void
299 on_notify_message_pref (GSettings *settings, const gchar* key,
300 gpointer user_data)
302 set_message_tab(settings, GTK_NOTEBOOK (user_data));
306 GtkWidget*
307 anjuta_msgman_new (GtkWidget *popup_menu)
309 GtkWidget *msgman = NULL;
310 msgman = gtk_widget_new (ANJUTA_TYPE_MSGMAN, "show-tabs", FALSE, NULL);
311 if (msgman)
313 ANJUTA_MSGMAN (msgman)->priv->popup_menu = popup_menu;
315 return msgman;
319 ANJUTA_TYPE_BEGIN (AnjutaMsgman, anjuta_msgman, GTK_TYPE_NOTEBOOK);
320 ANJUTA_TYPE_END;
322 static void
323 on_message_view_destroy (MessageView *view, AnjutaMsgman *msgman)
325 AnjutaMsgmanPage *page;
326 gint page_num;
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 page_num =
334 gtk_notebook_page_num (GTK_NOTEBOOK (msgman),
335 GTK_WIDGET (view));
336 msgman->priv->views = g_list_remove (msgman->priv->views, page);
337 anjuta_msgman_page_destroy (page);
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);
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);
367 MessageView *
368 anjuta_msgman_add_view (AnjutaMsgman * msgman,
369 const gchar * name, const gchar * pixmap)
371 GtkWidget *mv;
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);
384 void
385 anjuta_msgman_remove_view (AnjutaMsgman * msgman, MessageView *view)
387 if (!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");
396 void
397 anjuta_msgman_remove_all_views (AnjutaMsgman * msgman)
399 GList *views, *node;
400 AnjutaMsgmanPage *page;
402 views = NULL;
403 node = msgman->priv->views;
404 while (node)
406 page = node->data;
407 views = g_list_prepend (views, page->widget);
408 node = g_list_next (node);
410 node = views;
411 while (node)
413 gtk_widget_destroy (GTK_WIDGET (node->data));
414 node = g_list_next (node);
417 g_list_free (msgman->priv->views);
418 g_list_free (views);
420 g_signal_emit_by_name (msgman, "view-changed");
422 msgman->priv->views = NULL;
425 MessageView *
426 anjuta_msgman_get_current_view (AnjutaMsgman * msgman)
428 gint page = gtk_notebook_get_current_page (GTK_NOTEBOOK(msgman));
429 if (page != -1)
430 return MESSAGE_VIEW (gtk_notebook_get_nth_page (GTK_NOTEBOOK(msgman), page));
431 else
432 return NULL;
435 MessageView *
436 anjuta_msgman_get_view_by_name (AnjutaMsgman * msgman, const gchar * name)
438 GList *node;
440 g_return_val_if_fail (msgman != NULL, NULL);
441 g_return_val_if_fail (name != NULL, NULL);
443 node = msgman->priv->views;
444 while (node)
446 AnjutaMsgmanPage *page;
447 page = node->data;
448 g_assert (page);
449 if (strcmp (gtk_label_get_text (GTK_LABEL (page->label)),
450 name) == 0)
452 return MESSAGE_VIEW (page->widget);
454 node = g_list_next (node);
456 return NULL;
459 void
460 anjuta_msgman_set_current_view (AnjutaMsgman * msgman, MessageView * mv)
462 g_return_if_fail (msgman != NULL);
463 AnjutaMsgmanPage *page;
464 gint page_num;
466 if (mv)
468 page = anjuta_msgman_page_from_widget (msgman, mv);
469 page_num =
470 gtk_notebook_page_num (GTK_NOTEBOOK (msgman),
471 GTK_WIDGET (mv));
472 gtk_notebook_set_current_page (GTK_NOTEBOOK (msgman), page_num);
476 GList *
477 anjuta_msgman_get_all_views (AnjutaMsgman * msgman)
479 return msgman->priv->views;
482 void
483 anjuta_msgman_set_view_title (AnjutaMsgman *msgman, MessageView *view,
484 const gchar *title)
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);
496 void
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);
510 void
511 anjuta_msgman_set_view_icon_from_stock (AnjutaMsgman *msgman, MessageView *view,
512 const gchar *icon)
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,
522 GTK_ICON_SIZE_MENU);
525 gboolean
526 anjuta_msgman_serialize (AnjutaMsgman *msgman, AnjutaSerializer *serializer)
528 GList *node;
530 if (!anjuta_serializer_write_int (serializer, "views",
531 g_list_length (msgman->priv->views)))
532 return FALSE;
534 node = msgman->priv->views;
535 while (node)
537 AnjutaMsgmanPage *page = (AnjutaMsgmanPage*)node->data;
538 if (!message_view_serialize (MESSAGE_VIEW (page->widget), serializer))
539 return FALSE;
540 node = g_list_next (node);
542 return TRUE;
545 gboolean
546 anjuta_msgman_deserialize (AnjutaMsgman *msgman, AnjutaSerializer *serializer)
548 gint views, i;
550 if (!anjuta_serializer_read_int (serializer, "views", &views))
551 return FALSE;
553 for (i = 0; i < views; i++)
555 gchar *label, *pixmap;
556 GtkWidget *view;
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);
562 return FALSE;
564 g_object_get (view, "label", &label, "pixmap", &pixmap, NULL);
565 anjuta_msgman_append_view (msgman, view, label, pixmap);
566 g_free (label);
567 g_free (pixmap);
569 return TRUE;
572 GtkWidget* anjuta_msgman_get_tabber (AnjutaMsgman* msgman)
574 return msgman->priv->tabber;