From 34cb31bbed2aef45bf0f85d34a87aea9d4eb0846 Mon Sep 17 00:00:00 2001 From: Matthew Brush Date: Fri, 7 Oct 2011 05:45:14 -0700 Subject: [PATCH] Add filetype selection popup menu to statusbar. --- mousepad/mousepad-statusbar.c | 75 ++++++++++++++++++++++++-- mousepad/mousepad-window.c | 99 +++++++++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+), 4 deletions(-) diff --git a/mousepad/mousepad-statusbar.c b/mousepad/mousepad-statusbar.c index bdeac76..0967ebc 100644 --- a/mousepad/mousepad-statusbar.c +++ b/mousepad/mousepad-statusbar.c @@ -25,15 +25,20 @@ -static gboolean mousepad_statusbar_overwrite_clicked (GtkWidget *widget, - GdkEventButton *event, - MousepadStatusbar *statusbar); +static gboolean mousepad_statusbar_overwrite_clicked (GtkWidget *widget, + GdkEventButton *event, + MousepadStatusbar *statusbar); + +static gboolean mousepad_statusbar_filetype_clicked (GtkWidget *widget, + GdkEventButton *event, + MousepadStatusbar *statusbar); enum { ENABLE_OVERWRITE, + POPULATE_FILETYPE_POPUP, LAST_SIGNAL, }; @@ -87,6 +92,14 @@ mousepad_statusbar_class_init (MousepadStatusbarClass *klass) 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + + statusbar_signals[POPULATE_FILETYPE_POPUP] = + g_signal_new (I_("populate-filetype-popup"), + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_MENU); } @@ -121,9 +134,17 @@ mousepad_statusbar_init (MousepadStatusbar *statusbar) gtk_box_pack_start (GTK_BOX (box), separator, FALSE, FALSE, 0); gtk_widget_show (separator); + /* language/filetype event box */ + ebox = gtk_event_box_new (); + gtk_box_pack_start (GTK_BOX (box), ebox, FALSE, TRUE, 0); + gtk_event_box_set_visible_window (GTK_EVENT_BOX (ebox), FALSE); + mousepad_widget_set_tooltip_text (ebox, _("Choose a filetype")); + g_signal_connect (G_OBJECT (ebox), "button-press-event", G_CALLBACK (mousepad_statusbar_filetype_clicked), statusbar); + gtk_widget_show (ebox); + /* language/filetype */ statusbar->language = gtk_label_new (_("Filetype: None")); - gtk_box_pack_start (GTK_BOX (box), statusbar->language, FALSE, TRUE, 0); + gtk_container_add (GTK_CONTAINER (ebox), statusbar->language); gtk_widget_show (statusbar->language); /* separator */ @@ -179,6 +200,52 @@ mousepad_statusbar_overwrite_clicked (GtkWidget *widget, +static gboolean +mousepad_statusbar_filetype_clicked (GtkWidget *widget, + GdkEventButton *event, + MousepadStatusbar *statusbar) +{ + GtkMenu *menu; + GList *children; + gint n_children = 0; + + mousepad_return_val_if_fail (MOUSEPAD_IS_STATUSBAR (statusbar), FALSE); + + /* only respond on the left button click */ + if (event->type != GDK_BUTTON_PRESS || event->button != 1) + return FALSE; + + /* create the popup menu */ + menu = GTK_MENU (gtk_menu_new ()); + + /* send the signal to fill the menu */ + g_signal_emit (G_OBJECT (statusbar), statusbar_signals[POPULATE_FILETYPE_POPUP], 0, menu); + + /* get the number of items in the menu */ + children = gtk_container_get_children (GTK_CONTAINER (menu)); + n_children = g_list_length (children); + g_list_free (children); + + /* make sure there's at least one item in the menu */ + if (n_children) + { + /* cleanup the menu once a selection is made or the menu is cancelled */ + g_signal_connect (menu, "selection-done", G_CALLBACK (gtk_widget_destroy), NULL); + + /* show the menu */ + gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button, event->time); + } + else + { + /* since the menu wasn't shown, just destroy it straight-away */ + gtk_widget_destroy (GTK_WIDGET (menu)); + } + + return TRUE; +} + + + void mousepad_statusbar_set_language (MousepadStatusbar *statusbar, GtkSourceLanguage *language) diff --git a/mousepad/mousepad-window.c b/mousepad/mousepad-window.c index db3a69e..3067788 100644 --- a/mousepad/mousepad-window.c +++ b/mousepad/mousepad-window.c @@ -97,6 +97,11 @@ static gboolean mousepad_window_open_file (MousepadW static gboolean mousepad_window_close_document (MousepadWindow *window, MousepadDocument *document); static void mousepad_window_set_title (MousepadWindow *window); +static void mousepad_window_populate_statusbar_popup (MousepadWindow *window, + GtkMenu *menu, + MousepadStatusbar *statusbar); +static void mousepad_window_statusbar_filetype_toggled (GtkCheckMenuItem *item, + MousepadWindow *window); /* notebook signals */ static void mousepad_window_notebook_switch_page (GtkNotebook *notebook, @@ -1302,6 +1307,96 @@ mousepad_window_set_title (MousepadWindow *window) +static void +mousepad_window_statusbar_filetype_toggled (GtkCheckMenuItem *item, + MousepadWindow *window) +{ + const gchar *language_id; + GtkSourceLanguage *language; + GtkSourceLanguageManager *manager; + + mousepad_return_if_fail (MOUSEPAD_IS_WINDOW (window)); + mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (window->active)); + + manager = gtk_source_language_manager_get_default (); + language_id = g_object_get_data (G_OBJECT (item), "language_id"); + + /* check if None was selected */ + if (!language_id || g_strcmp0 (language_id, "none") == 0) + { + gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (window->active->buffer), NULL); + gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (window->active->buffer), FALSE); + return; + } + + /* set to a non-None language */ + language = gtk_source_language_manager_get_language (manager, language_id); + gtk_source_buffer_set_highlight_syntax (GTK_SOURCE_BUFFER (window->active->buffer), TRUE); + gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (window->active->buffer), language); +} + + + +static void +mousepad_window_populate_statusbar_popup (MousepadWindow *window, + GtkMenu *menu, + MousepadStatusbar *statusbar) +{ + GSList *group = NULL; + GSList *sections, *s_iter; + GSList *languages, *l_iter; + GtkWidget *item; + GtkWidget *submenu; + GtkSourceLanguage *active; + + mousepad_return_if_fail (MOUSEPAD_IS_WINDOW (window)); + mousepad_return_if_fail (MOUSEPAD_IS_DOCUMENT (window->active)); + + active = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (window->active->buffer)); + + item = gtk_radio_menu_item_new_with_label (group, _("None")); + group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); + g_object_set_data (G_OBJECT (item), "language_id", "none"); + g_signal_connect (item, "toggled", G_CALLBACK (mousepad_window_statusbar_filetype_toggled), window); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + + if (!active) + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); + + item = gtk_separator_menu_item_new (); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show (item); + + sections = mousepad_util_language_sections_get_sorted (); + + for (s_iter = sections ; s_iter != NULL; s_iter = g_slist_next (s_iter)) + { + item = gtk_menu_item_new_with_label (s_iter->data); + gtk_widget_show (item); + submenu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); + gtk_widget_show (submenu); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + + languages = mousepad_util_languages_get_sorted_for_section (s_iter->data); + for (l_iter = languages; l_iter != NULL; l_iter = g_slist_next (l_iter)) + { + item = gtk_radio_menu_item_new_with_label (group, gtk_source_language_get_name (l_iter->data)); + group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item)); + g_object_set_data (G_OBJECT (item), "language_id", (gpointer) gtk_source_language_get_id (l_iter->data)); + g_signal_connect (item, "toggled", G_CALLBACK (mousepad_window_statusbar_filetype_toggled), window); + gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); + gtk_widget_show (item); + + if (active == l_iter->data) + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); + } + } +} + + + /** * Notebook Signal Functions **/ @@ -4510,6 +4605,10 @@ mousepad_window_action_statusbar (GtkToggleAction *action, g_signal_connect_swapped (G_OBJECT (window->statusbar), "enable-overwrite", G_CALLBACK (mousepad_window_action_statusbar_overwrite), window); + /* populate filetype popup menu signal */ + g_signal_connect_swapped (G_OBJECT (window->statusbar), "populate-filetype-popup", + G_CALLBACK (mousepad_window_populate_statusbar_popup), window); + /* update the statusbar items */ if (window->active) {