diff --git a/xed/Makefile.am b/xed/Makefile.am new file mode 100644 index 0000000..eb648a6 --- /dev/null +++ b/xed/Makefile.am @@ -0,0 +1,209 @@ +## Process this file with automake to produce Makefile.in + +bin_PROGRAMS = xed + +pkglib_LTLIBRARIES = libxed.la + +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + -I$(srcdir) \ + $(XED_CFLAGS) \ + $(WARN_CFLAGS) \ + $(INTROSPECTION_CFLAGS) \ + $(DISABLE_DEPRECATED_CFLAGS) \ + -DDATADIR=\""$(datadir)"\" \ + -DLIBDIR=\""$(libdir)"\" + +xed_SOURCES = \ + xed.c + +xed_LDADD = \ + libxed.la \ + $(XED_LIBS) \ + $(INTROSPECTION_LIBS) + +xed_LDFLAGS = -export-dynamic -no-undefined -export-symbols-regex "^[[^_]].*" + +libxed_la_LDFLAGS = -avoid-version -export-dynamic -no-undefined -export-symbols-regex "^[^_].*" + +# XED_LIBS must be the last to ensure correct order on some platforms +libxed_la_LIBADD = $(XED_LIBS) + +BUILT_SOURCES = \ + xed-enum-types.c \ + xed-enum-types.h \ + xed-marshal.c \ + xed-marshal.h + + +NOINST_H_FILES = \ + xed-close-button.h \ + xed-close-confirmation-dialog.h \ + xed-dirs.h \ + xed-document-private.h \ + xed-documents-panel.h \ + xed-encodings-dialog.h \ + xed-highlight-mode-dialog.h \ + xed-highlight-mode-selector.h \ + xed-history-entry.h \ + xed-io-error-info-bar.h \ + xed-metadata-manager.h \ + xed-paned.h \ + xed-plugins-engine.h \ + xed-preferences-dialog.h \ + xed-print-job.h \ + xed-print-preview.h \ + xed-settings.h \ + xed-status-menu-button.h \ + xed-tab-label.h \ + xed-ui.h \ + xed-utils.h \ + xed-view-frame.h \ + xed-view-gutter-renderer.h \ + xed-window-private.h + +INST_H_FILES = \ + xed-app.h \ + xed-app-activatable.h \ + xed-commands.h \ + xed-debug.h \ + xed-document.h \ + xed-encodings-combo-box.h \ + xed-file-chooser-dialog.h \ + xed-message-bus.h \ + xed-message-type.h \ + xed-message.h \ + xed-notebook.h \ + xed-panel.h \ + xed-progress-info-bar.h \ + xed-searchbar.h \ + xed-statusbar.h \ + xed-tab.h \ + xed-view.h \ + xed-view-activatable.h \ + xed-window.h \ + xed-window-activatable.h + +headerdir = $(prefix)/include/xed + +header_DATA = \ + $(INST_H_FILES) + +BUILT_SOURCES_PRIVATE = \ + xed-resources.c + +libxed_c_files = \ + xed-app.c \ + xed-app-activatable.c \ + xed-view-activatable.c \ + xed-window-activatable.c \ + xed-resources.c \ + xed-close-button.c \ + xed-close-confirmation-dialog.c \ + xed-commands-documents.c \ + xed-commands-edit.c \ + xed-commands-file.c \ + xed-commands-file-print.c \ + xed-commands-help.c \ + xed-commands-search.c \ + xed-commands-view.c \ + xed-debug.c \ + xed-dirs.c \ + xed-document.c \ + xed-documents-panel.c \ + xed-encodings-combo-box.c \ + xed-encodings-dialog.c \ + xed-file-chooser-dialog.c \ + xed-highlight-mode-dialog.c \ + xed-highlight-mode-selector.c \ + xed-history-entry.c \ + xed-io-error-info-bar.c \ + xed-message-bus.c \ + xed-message-type.c \ + xed-message.c \ + xed-metadata-manager.c \ + xed-notebook.c \ + xed-paned.c \ + xed-panel.c \ + xed-plugins-engine.c \ + xed-preferences-dialog.c \ + xed-print-job.c \ + xed-print-preview.c \ + xed-progress-info-bar.c \ + xed-settings.c \ + xed-searchbar.c \ + xed-statusbar.c \ + xed-status-menu-button.c \ + xed-tab.c \ + xed-tab-label.c \ + xed-utils.c \ + xed-view.c \ + xed-view-frame.c \ + xed-view-gutter-renderer.c \ + xed-window.c + +libxed_la_SOURCES = \ + $(BUILT_SOURCES) \ + $(libxed_c_files) \ + $(POSIXIO_FILES) \ + $(NOINST_H_FILES) \ + $(INST_H_FILES) + +xed-enum-types.h: xed-enum-types.h.template $(INST_H_FILES) $(GLIB_MKENUMS) + $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template xed-enum-types.h.template $(INST_H_FILES)) > $@ + +xed-enum-types.c: xed-enum-types.c.template $(INST_H_FILES) $(GLIB_MKENUMS) + $(AM_V_GEN) (cd $(srcdir) && $(GLIB_MKENUMS) --template xed-enum-types.c.template $(INST_H_FILES)) > $@ + +xed-marshal.h: xed-marshal.list $(GLIB_GENMARSHAL) + $(AM_V_GEN) $(GLIB_GENMARSHAL) $< --header --prefix=xed_marshal > $@ + +xed-marshal.c: xed-marshal.list $(GLIB_GENMARSHAL) + $(AM_V_GEN) echo "#include \"xed-marshal.h\"" > $@ && \ + $(GLIB_GENMARSHAL) $< --body --prefix=xed_marshal >> $@ + +xed-resources.c: resources/xed.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(srcdir)/resources --generate-dependencies $(srcdir)/resources/xed.gresource.xml) + $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(srcdir)/resources --generate-source $(srcdir)/resources/xed.gresource.xml + +EXTRA_DIST = \ + xed-enum-types.h.template \ + xed-enum-types.c.template \ + xed-marshal.list \ + xed.rc \ + resources/xed.gresource.xml \ + resources/ui/xed-ui.xml \ + resources/ui/xed-encodings-dialog.ui \ + resources/ui/xed-preferences-dialog.ui \ + resources/ui/xed-print-preferences.ui \ + resources/ui/xed-searchbar.ui \ + resources/ui/xed-view-frame.ui + +CLEANFILES = $(BUILT_SOURCES) $(BUILT_SOURCES_PRIVATE) + +if HAVE_INTROSPECTION +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_GIRS = Xed-1.0.gir + +Xed-1.0.gir: xed +INTROSPECTION_SCANNER_ARGS = -I$(top_srcdir) --warn-all +Xed_1_0_gir_NAMESPACE = Xed +Xed_1_0_gir_VERSION = 1.0 +Xed_1_0_gir_PROGRAM = $(builddir)/xed +Xed_1_0_gir_FILES = $(INST_H_FILES) $(libxed_c_files) $(BUILT_SOURCES) +Xed_1_0_gir_INCLUDES = Gtk-3.0 GtkSource-3.0 + +girdir = $(datadir)/xed/gir-1.0 +gir_DATA = $(INTROSPECTION_GIRS) + +typelibdir = $(libdir)/xed/girepository-1.0 +typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) + +CLEANFILES += \ + $(gir_DATA) \ + $(typelib_DATA) +endif + +dist-hook: + cd $(distdir); rm -f $(BUILT_SOURCES) $(BUILT_SOURCES_PRIVATE) + +-include $(top_srcdir)/git.mk diff --git a/xed/meson.build b/xed/meson.build index 81b9e46..848b005 100644 --- a/xed/meson.build +++ b/xed/meson.build @@ -9,6 +9,8 @@ private_headers = [ 'xed-document-private.h', 'xed-documents-panel.h', 'xed-encodings-dialog.h', + 'xed-highlight-mode-dialog.h', + 'xed-highlight-mode-selector.h', 'xed-history-entry.h', 'xed-io-error-info-bar.h', 'xed-metadata-manager.h', @@ -18,7 +20,7 @@ private_headers = [ 'xed-print-job.h', 'xed-print-preview.h', 'xed-settings.h', - 'xed-status-combo-box.h', + 'xed-status-menu-button.h', 'xed-tab-label.h', 'xed-ui.h', 'xed-utils.h', @@ -71,6 +73,8 @@ libxed_sources = [ 'xed-encodings-combo-box.c', 'xed-encodings-dialog.c', 'xed-file-chooser-dialog.c', + 'xed-highlight-mode-dialog.c', + 'xed-highlight-mode-selector.c', 'xed-history-entry.c', 'xed-io-error-info-bar.c', 'xed-message-bus.c', @@ -88,7 +92,7 @@ libxed_sources = [ 'xed-settings.c', 'xed-searchbar.c', 'xed-statusbar.c', - 'xed-status-combo-box.c', + 'xed-status-menu-button.c', 'xed-tab.c', 'xed-tab-label.c', 'xed-utils.c', diff --git a/xed/resources/ui/xed-highlight-mode-dialog.ui b/xed/resources/ui/xed-highlight-mode-dialog.ui new file mode 100644 index 0000000..ff2cf74 --- /dev/null +++ b/xed/resources/ui/xed-highlight-mode-dialog.ui @@ -0,0 +1,90 @@ + + + + + diff --git a/xed/resources/ui/xed-highlight-mode-selector.ui b/xed/resources/ui/xed-highlight-mode-selector.ui new file mode 100644 index 0000000..d820742 --- /dev/null +++ b/xed/resources/ui/xed-highlight-mode-selector.ui @@ -0,0 +1,83 @@ + + + + + + + + + + + + + liststore + + + diff --git a/xed/resources/ui/xed-status-menu-button.ui b/xed/resources/ui/xed-status-menu-button.ui new file mode 100644 index 0000000..183ff66 --- /dev/null +++ b/xed/resources/ui/xed-status-menu-button.ui @@ -0,0 +1,51 @@ + + + + + diff --git a/xed/resources/ui/xed-ui.xml b/xed/resources/ui/xed-ui.xml index 3b6e38b..e9f9dfd 100644 --- a/xed/resources/ui/xed-ui.xml +++ b/xed/resources/ui/xed-ui.xml @@ -60,10 +60,7 @@ - - - - + diff --git a/xed/resources/xed.gresource.xml b/xed/resources/xed.gresource.xml index 29a9aed..ae42ccd 100644 --- a/xed/resources/xed.gresource.xml +++ b/xed/resources/xed.gresource.xml @@ -5,8 +5,11 @@ ui/xed-encodings-dialog.ui ui/xed-preferences-dialog.ui ui/xed-print-preferences.ui + ui/xed-highlight-mode-dialog.ui + ui/xed-highlight-mode-selector.ui ui/xed-searchbar.ui ui/xed-shortcuts.ui + ui/xed-status-menu-button.ui ui/xed-view-frame.ui css/xed-style.css css/xed.adwaita.css diff --git a/xed/xed-commands-view.c b/xed/xed-commands-view.c index 2a48e43..50d3540 100644 --- a/xed/xed-commands-view.c +++ b/xed/xed-commands-view.c @@ -39,6 +39,8 @@ #include "xed-window-private.h" #include "xed-paned.h" #include "xed-view-frame.h" +#include "xed-highlight-mode-dialog.h" +#include "xed-highlight-mode-selector.h" void _xed_cmd_view_show_toolbar (GtkAction *action, @@ -210,3 +212,41 @@ _xed_cmd_view_leave_fullscreen_mode (GtkAction *action, _xed_window_unfullscreen (window); g_signal_handlers_unblock_by_func (view_action, G_CALLBACK (_xed_cmd_view_toggle_fullscreen_mode), window); } + +static void +on_language_selected (XedHighlightModeSelector *sel, + GtkSourceLanguage *language, + XedWindow *window) +{ + XedDocument *doc; + + doc = xed_window_get_active_document (window); + if (doc) + { + xed_document_set_language (doc, language); + } +} + +void +_xed_cmd_view_change_highlight_mode (GtkAction *action, + XedWindow *window) +{ + GtkWidget *dlg; + XedHighlightModeSelector *sel; + XedDocument *doc; + + dlg = xed_highlight_mode_dialog_new (GTK_WINDOW (window)); + sel = xed_highlight_mode_dialog_get_selector (XED_HIGHLIGHT_MODE_DIALOG (dlg)); + + doc = xed_window_get_active_document (XED_WINDOW (window)); + if (doc) + { + xed_highlight_mode_selector_select_language (sel, + xed_document_get_language (doc)); + } + + g_signal_connect (sel, "language-selected", + G_CALLBACK (on_language_selected), window); + + gtk_widget_show (GTK_WIDGET (dlg)); +} diff --git a/xed/xed-commands.h b/xed/xed-commands.h index 005e64a..eb6c451 100644 --- a/xed/xed-commands.h +++ b/xed/xed-commands.h @@ -51,6 +51,7 @@ void _xed_cmd_view_toggle_overview_map (GtkAction *action, XedWindow *window); void _xed_cmd_view_toggle_fullscreen_mode (GtkAction *action, XedWindow *window); void _xed_cmd_view_toggle_word_wrap (GtkAction *action, XedWindow *window); void _xed_cmd_view_leave_fullscreen_mode (GtkAction *action, XedWindow *window); +void _xed_cmd_view_change_highlight_mode (GtkAction *action, XedWindow *window); void _xed_cmd_search_find (GtkAction *action, XedWindow *window); diff --git a/xed/xed-highlight-mode-dialog.c b/xed/xed-highlight-mode-dialog.c new file mode 100644 index 0000000..38644df --- /dev/null +++ b/xed/xed-highlight-mode-dialog.c @@ -0,0 +1,103 @@ +/* + * xed-highlight-mode-dialog.c + * This file is part of xed + * + * Copyright (C) 2013 - Ignacio Casal Quinteiro + * + * xed is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with xed. If not, see . + */ + +#include "xed-highlight-mode-dialog.h" + +#include + +struct _XedHighlightModeDialog +{ + GtkDialog parent_instance; + + XedHighlightModeSelector *selector; + gulong on_language_selected_id; +}; + +G_DEFINE_TYPE (XedHighlightModeDialog, xed_highlight_mode_dialog, GTK_TYPE_DIALOG) + +static void +xed_highlight_mode_dialog_response (GtkDialog *dialog, + gint response_id) +{ + XedHighlightModeDialog *dlg = XED_HIGHLIGHT_MODE_DIALOG (dialog); + + if (response_id == GTK_RESPONSE_OK) + { + g_signal_handler_block (dlg->selector, dlg->on_language_selected_id); + xed_highlight_mode_selector_activate_selected_language (dlg->selector); + g_signal_handler_unblock (dlg->selector, dlg->on_language_selected_id); + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); +} + +static void +on_language_selected (XedHighlightModeSelector *sel, + GtkSourceLanguage *language, + XedHighlightModeDialog *dlg) +{ + g_signal_handler_block (dlg->selector, dlg->on_language_selected_id); + xed_highlight_mode_selector_activate_selected_language (dlg->selector); + g_signal_handler_unblock (dlg->selector, dlg->on_language_selected_id); + + gtk_widget_destroy (GTK_WIDGET (dlg)); +} + +static void +xed_highlight_mode_dialog_class_init (XedHighlightModeDialogClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass); + + dialog_class->response = xed_highlight_mode_dialog_response; + + /* Bind class to template */ + gtk_widget_class_set_template_from_resource (widget_class, + "/org/x/editor/ui/xed-highlight-mode-dialog.ui"); + gtk_widget_class_bind_template_child (widget_class, XedHighlightModeDialog, selector); +} + +static void +xed_highlight_mode_dialog_init (XedHighlightModeDialog *dlg) +{ + gtk_widget_init_template (GTK_WIDGET (dlg)); + gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK); + + dlg->on_language_selected_id = g_signal_connect (dlg->selector, "language-selected", + G_CALLBACK (on_language_selected), dlg); +} + +GtkWidget * +xed_highlight_mode_dialog_new (GtkWindow *parent) +{ + return GTK_WIDGET (g_object_new (XED_TYPE_HIGHLIGHT_MODE_DIALOG, + "transient-for", parent, + NULL)); +} + +XedHighlightModeSelector * +xed_highlight_mode_dialog_get_selector (XedHighlightModeDialog *dlg) +{ + g_return_val_if_fail (XED_IS_HIGHLIGHT_MODE_DIALOG (dlg), NULL); + + return dlg->selector; +} + +/* ex:set ts=8 noet: */ diff --git a/xed/xed-highlight-mode-dialog.h b/xed/xed-highlight-mode-dialog.h new file mode 100644 index 0000000..d549beb --- /dev/null +++ b/xed/xed-highlight-mode-dialog.h @@ -0,0 +1,42 @@ +/* + * xed-highlight-mode-dialog.h + * This file is part of xed + * + * Copyright (C) 2013 - Ignacio Casal Quinteiro + * + * xed is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with xed. If not, see . + */ + + +#ifndef XED_HIGHLIGHT_MODE_DIALOG_H +#define XED_HIGHLIGHT_MODE_DIALOG_H + +#include +#include "xed-highlight-mode-selector.h" + +G_BEGIN_DECLS + +#define XED_TYPE_HIGHLIGHT_MODE_DIALOG (xed_highlight_mode_dialog_get_type ()) + +G_DECLARE_FINAL_TYPE (XedHighlightModeDialog, xed_highlight_mode_dialog, XED, HIGHLIGHT_MODE_DIALOG, GtkDialog) + +GtkWidget *xed_highlight_mode_dialog_new (GtkWindow *parent); + +XedHighlightModeSelector *xed_highlight_mode_dialog_get_selector (XedHighlightModeDialog *dlg); + +G_END_DECLS + +#endif /* XED_HIGHLIGHT_MODE_DIALOG_H */ + +/* ex:set ts=8 noet: */ diff --git a/xed/xed-highlight-mode-selector.c b/xed/xed-highlight-mode-selector.c new file mode 100644 index 0000000..8639bef --- /dev/null +++ b/xed/xed-highlight-mode-selector.c @@ -0,0 +1,378 @@ +/* + * xed-highlight-mode-selector.c + * This file is part of xed + * + * Copyright (C) 2013 - Ignacio Casal Quinteiro + * + * xed is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with xed. If not, see . + */ + +#include "xed-highlight-mode-selector.h" + +#include +#include +#include + +enum +{ + COLUMN_NAME, + COLUMN_LANG, + N_COLUMNS +}; + +struct _XedHighlightModeSelector +{ + GtkGrid parent_instance; + + GtkWidget *treeview; + GtkWidget *entry; + GtkListStore *liststore; + GtkTreeModelFilter *treemodelfilter; + GtkTreeSelection *treeview_selection; +}; + +/* Signals */ +enum +{ + LANGUAGE_SELECTED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (XedHighlightModeSelector, xed_highlight_mode_selector, GTK_TYPE_GRID) + +static void +xed_highlight_mode_selector_language_selected (XedHighlightModeSelector *widget, + GtkSourceLanguage *language) +{ +} + +static void +xed_highlight_mode_selector_class_init (XedHighlightModeSelectorClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + signals[LANGUAGE_SELECTED] = + g_signal_new_class_handler ("language-selected", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_CALLBACK (xed_highlight_mode_selector_language_selected), + NULL, NULL, NULL, + G_TYPE_NONE, + 1, + GTK_SOURCE_TYPE_LANGUAGE); + + /* Bind class to template */ + gtk_widget_class_set_template_from_resource (widget_class, + "/org/x/editor/ui/xed-highlight-mode-selector.ui"); + gtk_widget_class_bind_template_child (widget_class, XedHighlightModeSelector, treeview); + gtk_widget_class_bind_template_child (widget_class, XedHighlightModeSelector, entry); + gtk_widget_class_bind_template_child (widget_class, XedHighlightModeSelector, liststore); + gtk_widget_class_bind_template_child (widget_class, XedHighlightModeSelector, treemodelfilter); + gtk_widget_class_bind_template_child (widget_class, XedHighlightModeSelector, treeview_selection); +} + +static gboolean +visible_func (GtkTreeModel *model, + GtkTreeIter *iter, + XedHighlightModeSelector *selector) +{ + const gchar *entry_text; + gchar *name; + gchar *name_normalized; + gchar *name_casefolded; + gchar *text_normalized; + gchar *text_casefolded; + gboolean visible = FALSE; + + entry_text = gtk_entry_get_text (GTK_ENTRY (selector->entry)); + + if (*entry_text == '\0') + { + return TRUE; + } + + gtk_tree_model_get (model, iter, COLUMN_NAME, &name, -1); + + name_normalized = g_utf8_normalize (name, -1, G_NORMALIZE_ALL); + g_free (name); + + name_casefolded = g_utf8_casefold (name_normalized, -1); + g_free (name_normalized); + + text_normalized = g_utf8_normalize (entry_text, -1, G_NORMALIZE_ALL); + text_casefolded = g_utf8_casefold (text_normalized, -1); + g_free (text_normalized); + + if (strstr (name_casefolded, text_casefolded) != NULL) + { + visible = TRUE; + } + + g_free (name_casefolded); + g_free (text_casefolded); + + return visible; +} + +static void +on_entry_activate (GtkEntry *entry, + XedHighlightModeSelector *selector) +{ + xed_highlight_mode_selector_activate_selected_language (selector); +} + +static void +on_entry_changed (GtkEntry *entry, + XedHighlightModeSelector *selector) +{ + GtkTreeIter iter; + + gtk_tree_model_filter_refilter (selector->treemodelfilter); + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (selector->treemodelfilter), &iter)) + { + gtk_tree_selection_select_iter (selector->treeview_selection, &iter); + } +} + +static gboolean +move_selection (XedHighlightModeSelector *selector, + gint howmany) +{ + GtkTreeIter iter; + GtkTreePath *path; + gint *indices; + gint ret = FALSE; + + if (!gtk_tree_selection_get_selected (selector->treeview_selection, NULL, &iter) && + !gtk_tree_model_get_iter_first (GTK_TREE_MODEL (selector->treemodelfilter), &iter)) + { + return FALSE; + } + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (selector->treemodelfilter), &iter); + indices = gtk_tree_path_get_indices (path); + + if (indices) + { + gint num; + gint idx; + GtkTreePath *new_path; + + idx = indices[0]; + num = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (selector->treemodelfilter), NULL); + + if ((idx + howmany) < 0) + { + idx = 0; + } + else if ((idx + howmany) >= num) + { + idx = num - 1; + } + else + { + idx = idx + howmany; + } + + new_path = gtk_tree_path_new_from_indices (idx, -1); + gtk_tree_selection_select_path (selector->treeview_selection, new_path); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (selector->treeview), + new_path, NULL, TRUE, 0.5, 0); + gtk_tree_path_free (new_path); + + ret = TRUE; + } + + gtk_tree_path_free (path); + + return ret; +} + +static gboolean +on_entry_key_press_event (GtkWidget *entry, + GdkEventKey *event, + XedHighlightModeSelector *selector) +{ + if (event->keyval == GDK_KEY_Down) + { + return move_selection (selector, 1); + } + else if (event->keyval == GDK_KEY_Up) + { + return move_selection (selector, -1); + } + else if (event->keyval == GDK_KEY_Page_Down) + { + return move_selection (selector, 5); + } + else if (event->keyval == GDK_KEY_Page_Up) + { + return move_selection (selector, -5); + } + + return FALSE; +} + +static void +on_row_activated (GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + XedHighlightModeSelector *selector) +{ + xed_highlight_mode_selector_activate_selected_language (selector); +} + +static void +xed_highlight_mode_selector_init (XedHighlightModeSelector *selector) +{ + GtkSourceLanguageManager *lm; + const gchar * const *ids; + gint i; + GtkTreeIter iter; + + selector = xed_highlight_mode_selector_get_instance_private (selector); + + gtk_widget_init_template (GTK_WIDGET (selector)); + + gtk_tree_model_filter_set_visible_func (selector->treemodelfilter, + (GtkTreeModelFilterVisibleFunc)visible_func, + selector, + NULL); + + g_signal_connect (selector->entry, "activate", + G_CALLBACK (on_entry_activate), selector); + g_signal_connect (selector->entry, "changed", + G_CALLBACK (on_entry_changed), selector); + g_signal_connect (selector->entry, "key-press-event", + G_CALLBACK (on_entry_key_press_event), selector); + + g_signal_connect (selector->treeview, "row-activated", + G_CALLBACK (on_row_activated), selector); + + /* Populate tree model */ + gtk_list_store_append (selector->liststore, &iter); + gtk_list_store_set (selector->liststore, &iter, + COLUMN_NAME, _("Plain Text"), + COLUMN_LANG, NULL, + -1); + + lm = gtk_source_language_manager_get_default (); + ids = gtk_source_language_manager_get_language_ids (lm); + + for (i = 0; ids[i] != NULL; i++) + { + GtkSourceLanguage *lang; + + lang = gtk_source_language_manager_get_language (lm, ids[i]); + + if (!gtk_source_language_get_hidden (lang)) + { + gtk_list_store_append (selector->liststore, &iter); + gtk_list_store_set (selector->liststore, &iter, + COLUMN_NAME, gtk_source_language_get_name (lang), + COLUMN_LANG, lang, + -1); + } + } + + /* select first item */ + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (selector->treemodelfilter), &iter)) + { + gtk_tree_selection_select_iter (selector->treeview_selection, &iter); + } +} + +XedHighlightModeSelector * +xed_highlight_mode_selector_new () +{ + return g_object_new (XED_TYPE_HIGHLIGHT_MODE_SELECTOR, NULL); +} + +void +xed_highlight_mode_selector_select_language (XedHighlightModeSelector *selector, + GtkSourceLanguage *language) +{ + GtkTreeIter iter; + + g_return_if_fail (XED_IS_HIGHLIGHT_MODE_SELECTOR (selector)); + + if (language == NULL) + { + return; + } + + if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (selector->treemodelfilter), &iter)) + { + do + { + GtkSourceLanguage *lang; + + gtk_tree_model_get (GTK_TREE_MODEL (selector->treemodelfilter), + &iter, + COLUMN_LANG, &lang, + -1); + + if (lang != NULL) + { + gboolean equal = (lang == language); + + g_object_unref (lang); + + if (equal) + { + GtkTreePath *path; + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (selector->treemodelfilter), &iter); + + gtk_tree_selection_select_iter (selector->treeview_selection, &iter); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (selector->treeview), + path, NULL, TRUE, 0.5, 0); + gtk_tree_path_free (path); + break; + } + } + } + while (gtk_tree_model_iter_next (GTK_TREE_MODEL (selector->treemodelfilter), &iter)); + } +} + +void +xed_highlight_mode_selector_activate_selected_language (XedHighlightModeSelector *selector) +{ + GtkSourceLanguage *lang; + GtkTreeIter iter; + + g_return_if_fail (XED_IS_HIGHLIGHT_MODE_SELECTOR (selector)); + + if (!gtk_tree_selection_get_selected (selector->treeview_selection, NULL, &iter)) + { + return; + } + + gtk_tree_model_get (GTK_TREE_MODEL (selector->treemodelfilter), &iter, + COLUMN_LANG, &lang, + -1); + + g_signal_emit (G_OBJECT (selector), signals[LANGUAGE_SELECTED], 0, lang); + + if (lang != NULL) + { + g_object_unref (lang); + } +} + +/* ex:set ts=8 noet: */ diff --git a/xed/xed-highlight-mode-selector.h b/xed/xed-highlight-mode-selector.h new file mode 100644 index 0000000..fff7e2d --- /dev/null +++ b/xed/xed-highlight-mode-selector.h @@ -0,0 +1,46 @@ +/* + * xed-highlight-mode-selector.h + * This file is part of xed + * + * Copyright (C) 2013 - Ignacio Casal Quinteiro + * + * xed is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xed is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with xed. If not, see . + */ + +#ifndef XED_HIGHLIGHT_MODE_SELECTOR_H +#define XED_HIGHLIGHT_MODE_SELECTOR_H + +#include +#include +#include "xed-window.h" + +G_BEGIN_DECLS + +#define XED_TYPE_HIGHLIGHT_MODE_SELECTOR (xed_highlight_mode_selector_get_type ()) + +G_DECLARE_FINAL_TYPE (XedHighlightModeSelector, xed_highlight_mode_selector, XED, HIGHLIGHT_MODE_SELECTOR, GtkGrid) + +XedHighlightModeSelector *xed_highlight_mode_selector_new (void); + +void xed_highlight_mode_selector_select_language (XedHighlightModeSelector *selector, + GtkSourceLanguage *language); + +void xed_highlight_mode_selector_activate_selected_language + (XedHighlightModeSelector *selector); + +G_END_DECLS + +#endif /* XED_HIGHLIGHT_MODE_SELECTOR_H */ + +/* ex:set ts=8 noet: */ diff --git a/xed/xed-settings.c b/xed/xed-settings.c index 6f9d5ff..ce9774f 100644 --- a/xed/xed-settings.c +++ b/xed/xed-settings.c @@ -287,7 +287,7 @@ on_syntax_highlighting_changed (GSettings *settings, const gchar *key, XedSettings *xs) { - GList *docs, *windows, *l; + GList *docs, *l; gboolean enable; enable = g_settings_get_boolean (settings, key); @@ -300,22 +300,6 @@ on_syntax_highlighting_changed (GSettings *settings, } g_list_free (docs); - - /* update the sensitivity of the Higlight Mode menu item */ - windows = xed_app_get_main_windows (XED_APP (g_application_get_default ())); - for (l = windows; l != NULL; l = g_list_next (l)) - { - GtkUIManager *ui; - GtkAction *a; - - ui = xed_window_get_ui_manager (XED_WINDOW (l->data)); - - a = gtk_ui_manager_get_action (ui, "/MenuBar/ViewMenu/ViewHighlightModeMenu"); - - gtk_action_set_sensitive (a, enable); - } - - g_list_free (windows); } static void diff --git a/xed/xed-status-combo-box.c b/xed/xed-status-combo-box.c deleted file mode 100644 index ea195cc..0000000 --- a/xed/xed-status-combo-box.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * xed-status-combo-box.c - * This file is part of xed - * - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "xed-status-combo-box.h" - -#define COMBO_BOX_TEXT_DATA "XedStatusComboBoxTextData" - -#define XED_STATUS_COMBO_BOX_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), XED_TYPE_STATUS_COMBO_BOX, XedStatusComboBoxPrivate)) - -static void menu_deactivate (GtkMenu *menu, XedStatusComboBox *combo); - -struct _XedStatusComboBoxPrivate -{ - GtkWidget *button; - GtkWidget *hbox; - GtkWidget *label; - GtkWidget *item; - GtkWidget *arrow; - - GtkWidget *menu; - GtkWidget *current_item; -}; - -struct _XedStatusComboBoxClassPrivate -{ - GtkCssProvider *css; -}; - -/* Signals */ -enum -{ - CHANGED, - NUM_SIGNALS -}; - -/* Properties */ -enum -{ - PROP_0, - - PROP_LABEL -}; - -static guint signals[NUM_SIGNALS] = { 0 }; - -G_DEFINE_TYPE_WITH_CODE (XedStatusComboBox, xed_status_combo_box, GTK_TYPE_EVENT_BOX, - g_type_add_class_private (g_define_type_id, sizeof (XedStatusComboBoxClassPrivate))) - -static void -xed_status_combo_box_finalize (GObject *object) -{ - G_OBJECT_CLASS (xed_status_combo_box_parent_class)->finalize (object); -} - -static void -xed_status_combo_box_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - XedStatusComboBox *obj = XED_STATUS_COMBO_BOX (object); - - switch (prop_id) - { - case PROP_LABEL: - g_value_set_string (value, xed_status_combo_box_get_label (obj)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_status_combo_box_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - XedStatusComboBox *obj = XED_STATUS_COMBO_BOX (object); - - switch (prop_id) - { - case PROP_LABEL: - xed_status_combo_box_set_label (obj, g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -xed_status_combo_box_destroy (GtkWidget *widget) -{ - XedStatusComboBox *combo = XED_STATUS_COMBO_BOX (widget); - - if (combo->priv->menu) - { - g_signal_handlers_disconnect_by_func (combo->priv->menu, menu_deactivate, combo); - gtk_menu_detach (GTK_MENU (combo->priv->menu)); - } - - GTK_WIDGET_CLASS (xed_status_combo_box_parent_class)->destroy (widget); -} - -static void -xed_status_combo_box_changed (XedStatusComboBox *combo, - GtkMenuItem *item) -{ - const gchar *text; - - text = g_object_get_data (G_OBJECT (item), COMBO_BOX_TEXT_DATA); - - if (text != NULL) - { - gtk_label_set_markup (GTK_LABEL (combo->priv->item), text); - combo->priv->current_item = GTK_WIDGET (item); - } -} - -static void -xed_status_combo_box_class_init (XedStatusComboBoxClass *klass) -{ - static const gchar style[] = - "* {\n" - "padding: 2px;\n" - "}"; - - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - - object_class->finalize = xed_status_combo_box_finalize; - object_class->get_property = xed_status_combo_box_get_property; - object_class->set_property = xed_status_combo_box_set_property; - - widget_class->destroy = xed_status_combo_box_destroy; - - klass->changed = xed_status_combo_box_changed; - - signals[CHANGED] = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (XedStatusComboBoxClass, - changed), NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - GTK_TYPE_MENU_ITEM); - - g_object_class_install_property (object_class, PROP_LABEL, - g_param_spec_string ("label", - "LABEL", - "The label", - NULL, - G_PARAM_READWRITE)); - - g_type_class_add_private (object_class, sizeof(XedStatusComboBoxPrivate)); - - klass->priv = G_TYPE_CLASS_GET_PRIVATE (klass, XED_TYPE_STATUS_COMBO_BOX, XedStatusComboBoxClassPrivate); - - klass->priv->css = gtk_css_provider_new (); - gtk_css_provider_load_from_data (klass->priv->css, style, -1, NULL); -} - -static void -menu_deactivate (GtkMenu *menu, - XedStatusComboBox *combo) -{ - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (combo->priv->button), FALSE); -} - -static void -menu_position_func (GtkMenu *menu, - gint *x, - gint *y, - gboolean *push_in, - XedStatusComboBox *combo) -{ - GtkRequisition request; - GtkAllocation allocation; - - *push_in = FALSE; - - gtk_widget_get_preferred_size (gtk_widget_get_toplevel (GTK_WIDGET (menu)), &request, NULL); - - /* get the origin... */ - gdk_window_get_origin (gtk_widget_get_window (GTK_WIDGET (combo)), x, y); - gtk_widget_get_allocation (GTK_WIDGET (combo), &allocation); - - /* make the menu as wide as the widget */ - if (request.width < allocation.width) - { - gtk_widget_set_size_request (GTK_WIDGET (menu), allocation.width, -1); - } - - /* position it above the widget */ - *y -= request.height; -} - -static void -show_menu (XedStatusComboBox *combo, - guint button, - guint32 time) -{ - GtkRequisition request; - gint max_height; - GtkAllocation allocation; - - gtk_widget_get_preferred_size (combo->priv->menu, &request, NULL); - - /* do something relative to our own height here, maybe we can do better */ - gtk_widget_get_allocation (GTK_WIDGET (combo), &allocation); - max_height = allocation.height * 20; - - if (request.height > max_height) - { - gtk_widget_set_size_request (combo->priv->menu, -1, max_height); - gtk_widget_set_size_request (gtk_widget_get_toplevel (combo->priv->menu), -1, max_height); - } - - gtk_menu_popup (GTK_MENU (combo->priv->menu), - NULL, - NULL, - (GtkMenuPositionFunc)menu_position_func, - combo, - button, - time); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (combo->priv->button), TRUE); - - if (combo->priv->current_item) - { - gtk_menu_shell_select_item (GTK_MENU_SHELL (combo->priv->menu), combo->priv->current_item); - } -} - -static void -menu_detached (GtkWidget *widget, - GtkMenu *menu) -{ - XedStatusComboBox *combo = XED_STATUS_COMBO_BOX (widget); - - g_return_if_fail (GTK_MENU (combo->priv->menu) == menu); - - combo->priv->menu = NULL; -} - -static gboolean -button_press_event (GtkWidget *widget, - GdkEventButton *event, - XedStatusComboBox *combo) -{ - if (event->type == GDK_BUTTON_PRESS && event->button == 1) - { - show_menu (combo, event->button, event->time); - return TRUE; - } - - return FALSE; -} - -static void -xed_status_combo_box_init (XedStatusComboBox *self) -{ - GtkStyleContext *context; - - self->priv = XED_STATUS_COMBO_BOX_GET_PRIVATE (self); - - gtk_event_box_set_visible_window (GTK_EVENT_BOX (self), TRUE); - - self->priv->button = gtk_toggle_button_new (); - gtk_button_set_relief (GTK_BUTTON (self->priv->button), GTK_RELIEF_NONE); - gtk_widget_show (self->priv->button); - - self->priv->hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); - gtk_widget_show (self->priv->hbox); - - gtk_container_add (GTK_CONTAINER (self), self->priv->button); - gtk_container_add (GTK_CONTAINER (self->priv->button), self->priv->hbox); - - self->priv->label = gtk_label_new (""); - gtk_widget_show (self->priv->label); - - gtk_label_set_single_line_mode (GTK_LABEL (self->priv->label), TRUE); - gtk_widget_set_halign (GTK_WIDGET (self->priv->label), GTK_ALIGN_START); - - gtk_box_pack_start (GTK_BOX (self->priv->hbox), self->priv->label, FALSE, TRUE, 0); - - self->priv->item = gtk_label_new (""); - gtk_widget_show (self->priv->item); - - gtk_label_set_single_line_mode (GTK_LABEL (self->priv->item), TRUE); - gtk_widget_set_halign (self->priv->item, GTK_ALIGN_START); - - gtk_box_pack_start (GTK_BOX (self->priv->hbox), self->priv->item, TRUE, TRUE, 0); - - self->priv->arrow = gtk_image_new_from_icon_name ("pan-down-symbolic", GTK_ICON_SIZE_MENU); - gtk_widget_show (self->priv->arrow); - - gtk_widget_set_halign (self->priv->arrow, GTK_ALIGN_CENTER); - gtk_widget_set_valign (self->priv->arrow, GTK_ALIGN_CENTER); - - gtk_box_pack_start (GTK_BOX (self->priv->hbox), self->priv->arrow, FALSE, TRUE, 0); - - self->priv->menu = gtk_menu_new (); - gtk_menu_attach_to_widget (GTK_MENU (self->priv->menu), GTK_WIDGET (self), menu_detached); - - g_signal_connect (self->priv->button, "button-press-event", - G_CALLBACK (button_press_event), self); - g_signal_connect (self->priv->menu, "deactivate", - G_CALLBACK (menu_deactivate), self); - - context = gtk_widget_get_style_context (GTK_WIDGET (self->priv->button)); - gtk_style_context_add_provider (context, - GTK_STYLE_PROVIDER (XED_STATUS_COMBO_BOX_GET_CLASS (self)->priv->css), - GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); -} - -/* public functions */ - -/** - * xed_status_combo_box_new: - * @label: (allow-none): - */ -GtkWidget * -xed_status_combo_box_new (const gchar *label) -{ - return g_object_new (XED_TYPE_STATUS_COMBO_BOX, "label", label, NULL); -} - -/** - * xed_status_combo_box_set_label: - * @combo: - * @label: (allow-none): - */ -void -xed_status_combo_box_set_label (XedStatusComboBox *combo, - const gchar *label) -{ - gchar *text; - - g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); - - text = g_strconcat (" ", label, ": ", NULL); - gtk_label_set_markup (GTK_LABEL (combo->priv->label), text); - g_free (text); -} - -const gchar * -xed_status_combo_box_get_label (XedStatusComboBox *combo) -{ - g_return_val_if_fail (XED_IS_STATUS_COMBO_BOX (combo), NULL); - - return gtk_label_get_label (GTK_LABEL (combo->priv->label)); -} - -static void -item_activated (GtkMenuItem *item, - XedStatusComboBox *combo) -{ - xed_status_combo_box_set_item (combo, item); -} - -/** - * xed_status_combo_box_add_item: - * @combo: - * @item: - * @text: (allow-none): - */ -void -xed_status_combo_box_add_item (XedStatusComboBox *combo, - GtkMenuItem *item, - const gchar *text) -{ - g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); - g_return_if_fail (GTK_IS_MENU_ITEM (item)); - - gtk_menu_shell_append (GTK_MENU_SHELL (combo->priv->menu), GTK_WIDGET (item)); - - xed_status_combo_box_set_item_text (combo, item, text); - g_signal_connect (item, "activate", G_CALLBACK (item_activated), combo); -} - -void -xed_status_combo_box_remove_item (XedStatusComboBox *combo, - GtkMenuItem *item) -{ - g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); - g_return_if_fail (GTK_IS_MENU_ITEM (item)); - - gtk_container_remove (GTK_CONTAINER (combo->priv->menu), GTK_WIDGET (item)); -} - - -/** - * xed_status_combo_box_get_items: - * @combo: - * - * Returns: (element-type Gtk.Widget) (transfer container): - */ -GList * -xed_status_combo_box_get_items (XedStatusComboBox *combo) -{ - g_return_val_if_fail (XED_IS_STATUS_COMBO_BOX (combo), NULL); - - return gtk_container_get_children (GTK_CONTAINER (combo->priv->menu)); -} - -const gchar * -xed_status_combo_box_get_item_text (XedStatusComboBox *combo, - GtkMenuItem *item) -{ - const gchar *ret = NULL; - - g_return_val_if_fail (XED_IS_STATUS_COMBO_BOX (combo), NULL); - g_return_val_if_fail (GTK_IS_MENU_ITEM (item), NULL); - - ret = g_object_get_data (G_OBJECT (item), COMBO_BOX_TEXT_DATA); - - return ret; -} - -/** - * xed_status_combo_box_set_item_text: - * @combo: - * @item: - * @text: (allow-none): - */ -void -xed_status_combo_box_set_item_text (XedStatusComboBox *combo, - GtkMenuItem *item, - const gchar *text) -{ - g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); - g_return_if_fail (GTK_IS_MENU_ITEM (item)); - - g_object_set_data_full (G_OBJECT (item), COMBO_BOX_TEXT_DATA, - g_strdup (text), (GDestroyNotify)g_free); -} - -void -xed_status_combo_box_set_item (XedStatusComboBox *combo, - GtkMenuItem *item) -{ - g_return_if_fail (XED_IS_STATUS_COMBO_BOX (combo)); - g_return_if_fail (GTK_IS_MENU_ITEM (item)); - - g_signal_emit (combo, signals[CHANGED], 0, item, NULL); -} - -GtkLabel * -xed_status_combo_box_get_item_label (XedStatusComboBox *combo) -{ - g_return_val_if_fail (XED_IS_STATUS_COMBO_BOX (combo), NULL); - - return GTK_LABEL (combo->priv->item); -} - diff --git a/xed/xed-status-combo-box.h b/xed/xed-status-combo-box.h deleted file mode 100644 index 5bf1b17..0000000 --- a/xed/xed-status-combo-box.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * xed-status-combo-box.h - * This file is part of xed - * - * Copyright (C) 2008 - Jesse van den Kieboom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __XED_STATUS_COMBO_BOX_H__ -#define __XED_STATUS_COMBO_BOX_H__ - -#include - -G_BEGIN_DECLS - -#define XED_TYPE_STATUS_COMBO_BOX (xed_status_combo_box_get_type ()) -#define XED_STATUS_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_STATUS_COMBO_BOX, XedStatusComboBox)) -#define XED_STATUS_COMBO_BOX_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XED_TYPE_STATUS_COMBO_BOX, XedStatusComboBox const)) -#define XED_STATUS_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XED_TYPE_STATUS_COMBO_BOX, XedStatusComboBoxClass)) -#define XED_IS_STATUS_COMBO_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XED_TYPE_STATUS_COMBO_BOX)) -#define XED_IS_STATUS_COMBO_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XED_TYPE_STATUS_COMBO_BOX)) -#define XED_STATUS_COMBO_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XED_TYPE_STATUS_COMBO_BOX, XedStatusComboBoxClass)) - -typedef struct _XedStatusComboBox XedStatusComboBox; -typedef struct _XedStatusComboBoxPrivate XedStatusComboBoxPrivate; -typedef struct _XedStatusComboBoxClass XedStatusComboBoxClass; -typedef struct _XedStatusComboBoxClassPrivate XedStatusComboBoxClassPrivate; - -struct _XedStatusComboBox -{ - GtkEventBox parent; - - XedStatusComboBoxPrivate *priv; -}; - -struct _XedStatusComboBoxClass -{ - GtkEventBoxClass parent_class; - - XedStatusComboBoxClassPrivate *priv; - - void (*changed) (XedStatusComboBox *combo, - GtkMenuItem *item); -}; - -GType xed_status_combo_box_get_type (void) G_GNUC_CONST; -GtkWidget *xed_status_combo_box_new (const gchar *label); - -const gchar *xed_status_combo_box_get_label (XedStatusComboBox *combo); -void xed_status_combo_box_set_label (XedStatusComboBox *combo, - const gchar *label); - -void xed_status_combo_box_add_item (XedStatusComboBox *combo, - GtkMenuItem *item, - const gchar *text); -void xed_status_combo_box_remove_item (XedStatusComboBox *combo, - GtkMenuItem *item); - -GList *xed_status_combo_box_get_items (XedStatusComboBox *combo); -const gchar *xed_status_combo_box_get_item_text (XedStatusComboBox *combo, - GtkMenuItem *item); -void xed_status_combo_box_set_item_text (XedStatusComboBox *combo, - GtkMenuItem *item, - const gchar *text); - -void xed_status_combo_box_set_item (XedStatusComboBox *combo, - GtkMenuItem *item); - -GtkLabel *xed_status_combo_box_get_item_label (XedStatusComboBox *combo); - -G_END_DECLS - -#endif /* __XED_STATUS_COMBO_BOX_H__ */ diff --git a/xed/xed-status-menu-button.c b/xed/xed-status-menu-button.c new file mode 100644 index 0000000..585a62a --- /dev/null +++ b/xed/xed-status-menu-button.c @@ -0,0 +1,163 @@ +/* + * xed-status-menu-button.c + * This file is part of xed + * + * Copyright (C) 2008 - Jesse van den Kieboom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include "xed-status-menu-button.h" + +struct _XedStatusMenuButton +{ + GtkMenuButton parent_instance; + + GtkWidget *label; +}; + +typedef struct +{ + GtkCssProvider *css; +} XedStatusMenuButtonClassPrivate; + +enum +{ + PROP_0, + PROP_LABEL, + LAST_PROP +}; + +G_DEFINE_TYPE_WITH_CODE (XedStatusMenuButton, + xed_status_menu_button, + GTK_TYPE_MENU_BUTTON, + g_type_add_class_private (g_define_type_id, sizeof (XedStatusMenuButtonClassPrivate))) + +static void +xed_status_menu_button_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XedStatusMenuButton *obj = XED_STATUS_MENU_BUTTON (object); + + switch (prop_id) + { + case PROP_LABEL: + g_value_set_string (value, xed_status_menu_button_get_label (obj)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_status_menu_button_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XedStatusMenuButton *obj = XED_STATUS_MENU_BUTTON (object); + + switch (prop_id) + { + case PROP_LABEL: + xed_status_menu_button_set_label (obj, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xed_status_menu_button_class_init (XedStatusMenuButtonClass *klass) +{ + static const gchar style[] = + "* {\n" + "padding: 1px 8px 2px 4px;\n" + "border: 0;\n" + "outline-width: 0;\n" + "}"; + + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + XedStatusMenuButtonClassPrivate *class_priv; + + object_class->get_property = xed_status_menu_button_get_property; + object_class->set_property = xed_status_menu_button_set_property; + + g_object_class_override_property (object_class, PROP_LABEL, "label"); + + /* Bind class to template */ + gtk_widget_class_set_template_from_resource (widget_class, + "/org/x/editor/ui/xed-status-menu-button.ui"); + gtk_widget_class_bind_template_child_internal (widget_class, XedStatusMenuButton, label); + + /* Store the CSS provider in the class private data so it is shared among all instances */ + class_priv = G_TYPE_CLASS_GET_PRIVATE (klass, XED_TYPE_STATUS_MENU_BUTTON, XedStatusMenuButtonClassPrivate); + class_priv->css = gtk_css_provider_new (); + gtk_css_provider_load_from_data (class_priv->css, style, -1, NULL); +} + +static void +xed_status_menu_button_init (XedStatusMenuButton *self) +{ + GtkStyleContext *context; + XedStatusMenuButtonClassPrivate *class_priv; + + gtk_widget_init_template (GTK_WIDGET (self)); + + /* make it as small as possible */ + context = gtk_widget_get_style_context (GTK_WIDGET (self)); + class_priv = G_TYPE_CLASS_GET_PRIVATE (G_TYPE_INSTANCE_GET_CLASS (self, XED_TYPE_STATUS_MENU_BUTTON, XedStatusMenuButtonClass), + XED_TYPE_STATUS_MENU_BUTTON, + XedStatusMenuButtonClassPrivate); + gtk_style_context_add_provider (context, + GTK_STYLE_PROVIDER (class_priv->css), + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); +} + +/** + * xed_status_menu_button_new: + * @label: (allow-none): + */ +GtkWidget * +xed_status_menu_button_new (void) +{ + return g_object_new (XED_TYPE_STATUS_MENU_BUTTON, NULL); +} + +/* we cannot rely on gtk_button_set_label since it manually replaces + * the internal child instead of just setting the property :( */ + +void +xed_status_menu_button_set_label (XedStatusMenuButton *button, + const gchar *label) +{ + g_return_if_fail (XED_IS_STATUS_MENU_BUTTON (button)); + + gtk_label_set_markup (GTK_LABEL (button->label), label); +} + +const gchar * +xed_status_menu_button_get_label (XedStatusMenuButton *button) +{ + g_return_val_if_fail (XED_IS_STATUS_MENU_BUTTON (button), NULL); + + return gtk_label_get_label (GTK_LABEL (button->label)); +} + +/* ex:set ts=8 noet: */ diff --git a/xed/xed-status-menu-button.h b/xed/xed-status-menu-button.h new file mode 100644 index 0000000..4ccc72e --- /dev/null +++ b/xed/xed-status-menu-button.h @@ -0,0 +1,43 @@ +/* + * xed-status-menu-button.h + * This file is part of xed + * + * Copyright (C) 2008 - Jesse van den Kieboom + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef XED_STATUS_MENU_BUTTON_H +#define XED_STATUS_MENU_BUTTON_H + +#include + +G_BEGIN_DECLS + +#define XED_TYPE_STATUS_MENU_BUTTON (xed_status_menu_button_get_type ()) + +G_DECLARE_FINAL_TYPE (XedStatusMenuButton, xed_status_menu_button, XED, STATUS_MENU_BUTTON, GtkMenuButton) + +GtkWidget *xed_status_menu_button_new (void); + +void xed_status_menu_button_set_label (XedStatusMenuButton *button, + const gchar *label); + +const gchar *xed_status_menu_button_get_label (XedStatusMenuButton *button); + +G_END_DECLS + +#endif /* XED_STATUS_MENU_BUTTON_H */ + +/* ex:set ts=8 noet: */ diff --git a/xed/xed-ui.h b/xed/xed-ui.h index 2aa9a04..59b733a 100644 --- a/xed/xed-ui.h +++ b/xed/xed-ui.h @@ -104,7 +104,9 @@ static const GtkActionEntry xed_menu_entries[] = N_("Select the entire document"), G_CALLBACK (_xed_cmd_edit_select_all) }, /* View menu */ - { "ViewHighlightMode", NULL, N_("_Highlight Mode") }, + { "ViewHighlightMode", NULL, N_("_Highlight Mode"), NULL, + N_("Change syntax hightlight mode"), + G_CALLBACK (_xed_cmd_view_change_highlight_mode) }, /* Search menu */ { "SearchFind", "edit-find-symbolic", N_("_Find"), "F", diff --git a/xed/xed-window-private.h b/xed/xed-window-private.h index 691779c..03c05b1 100644 --- a/xed/xed-window-private.h +++ b/xed/xed-window-private.h @@ -55,8 +55,10 @@ struct _XedWindowPrivate GtkWidget *hpaned; GtkWidget *vpaned; - GtkWidget *tab_width_combo; - GtkWidget *language_combo; + GtkWidget *tab_width_button; + GtkWidget *tab_width_menu; + GtkWidget *language_button; + GtkWidget *language_popover; GtkWidget *show_side_pane_button; GtkWidget *show_bottom_pane_button; GtkWidget *bottom_pane_button_revealer; @@ -88,7 +90,6 @@ struct _XedWindowPrivate GtkActionGroup *close_action_group; GtkActionGroup *quit_action_group; GtkActionGroup *panes_action_group; - GtkActionGroup *languages_action_group; GtkActionGroup *documents_list_action_group; guint documents_list_menu_ui_id; GtkWidget *toolbar; diff --git a/xed/xed-window.c b/xed/xed-window.c index 560670a..273f9bd 100644 --- a/xed/xed-window.c +++ b/xed/xed-window.c @@ -25,7 +25,8 @@ #include "xed-window-activatable.h" #include "xed-enum-types.h" #include "xed-dirs.h" -#include "xed-status-combo-box.h" +#include "xed-status-menu-button.h" +#include "xed-highlight-mode-selector.h" #include "xed-settings.h" #define LANGUAGE_NONE (const gchar *)"LangNone" @@ -666,265 +667,6 @@ set_sensitivity_according_to_tab (XedWindow *window, peas_extension_set_call (window->priv->extensions, "update_state"); } -static void -language_toggled (GtkToggleAction *action, - XedWindow *window) -{ - XedDocument *doc; - GtkSourceLanguage *lang; - const gchar *lang_id; - - if (gtk_toggle_action_get_active (action) == FALSE) - { - return; - } - - doc = xed_window_get_active_document (window); - if (doc == NULL) - { - return; - } - - lang_id = gtk_action_get_name (GTK_ACTION(action)); - - if (strcmp (lang_id, LANGUAGE_NONE) == 0) - { - /* Normal (no highlighting) */ - lang = NULL; - } - else - { - lang = gtk_source_language_manager_get_language (gtk_source_language_manager_get_default (), lang_id); - if (lang == NULL) - { - g_warning("Could not get language %s\n", lang_id); - } - } - - xed_document_set_language (doc, lang); -} - -static gchar * -escape_section_name (const gchar *name) -{ - gchar *ret; - ret = g_markup_escape_text (name, -1); - /* Replace '/' with '-' to avoid problems in xml paths */ - g_strdelimit (ret, "/", '-'); - return ret; -} - -static void -create_language_menu_item (GtkSourceLanguage *lang, - gint index, - guint ui_id, - XedWindow *window) -{ - GtkAction *section_action; - GtkRadioAction *action; - GtkAction *normal_action; - GSList *group; - const gchar *section; - gchar *escaped_section; - const gchar *lang_id; - const gchar *lang_name; - gchar *escaped_lang_name; - gchar *tip; - gchar *path; - - section = gtk_source_language_get_section (lang); - escaped_section = escape_section_name (section); - - /* check if the section submenu exists or create it */ - section_action = gtk_action_group_get_action (window->priv->languages_action_group, escaped_section); - - if (section_action == NULL) - { - gchar *section_name; - section_name = xed_utils_escape_underscores (section, -1); - section_action = gtk_action_new (escaped_section, section_name, NULL, - NULL); - - g_free (section_name); - - gtk_action_group_add_action (window->priv->languages_action_group, section_action); - g_object_unref (section_action); - - gtk_ui_manager_add_ui (window->priv->manager, ui_id, - "/MenuBar/ViewMenu/ViewHighlightModeMenu/LanguagesMenuPlaceholder", escaped_section, - escaped_section, GTK_UI_MANAGER_MENU, FALSE); - } - - /* now add the language item to the section */ - lang_name = gtk_source_language_get_name (lang); - lang_id = gtk_source_language_get_id (lang); - - escaped_lang_name = xed_utils_escape_underscores (lang_name, -1); - - tip = g_strdup_printf (_("Use %s highlight mode"), lang_name); - path = g_strdup_printf ("/MenuBar/ViewMenu/ViewHighlightModeMenu/LanguagesMenuPlaceholder/%s", escaped_section); - - action = gtk_radio_action_new (lang_id, escaped_lang_name, tip, NULL, index); - - g_free (escaped_lang_name); - - /* Action is added with a NULL accel to make the accel overridable */ - gtk_action_group_add_action_with_accel (window->priv->languages_action_group, GTK_ACTION(action), NULL); - g_object_unref (action); - - /* add the action to the same radio group of the "Normal" action */ - normal_action = gtk_action_group_get_action (window->priv->languages_action_group, LANGUAGE_NONE); - group = gtk_radio_action_get_group (GTK_RADIO_ACTION(normal_action)); - gtk_radio_action_set_group (action, group); - - g_signal_connect(action, "activate", G_CALLBACK (language_toggled), window); - - gtk_ui_manager_add_ui (window->priv->manager, ui_id, path, lang_id, lang_id, GTK_UI_MANAGER_MENUITEM, FALSE); - - g_free (path); - g_free (tip); - g_free (escaped_section); -} - -static gint -language_compare (GtkSourceLanguage *lang1, - GtkSourceLanguage *lang2) -{ - const gchar *section1, *section2, *name1, *name2; - gchar *tmp1, *tmp2; - gint ret; - - section1 = gtk_source_language_get_section (lang1); - section2 = gtk_source_language_get_section (lang2); - name1 = gtk_source_language_get_name (lang1); - name2 = gtk_source_language_get_name (lang2); - - /* we collate the concatenation so that they are - * sorted first by section and then by name */ - tmp1 = g_strconcat (section1, "::", name1, NULL); - tmp2 = g_strconcat (section2, "::", name2, NULL); - - ret = g_utf8_collate (tmp1, tmp2); - - g_free(tmp1); - g_free(tmp2); - - return ret; -} - -static GSList * -get_languages_sorted_by_section (XedWindow *window) -{ - GtkSourceLanguageManager *lm; - const gchar * const *ids; - gint i; - GSList *languages = NULL; - - lm = gtk_source_language_manager_get_default (); - ids = gtk_source_language_manager_get_language_ids (lm); - - for (i = 0; ids[i] != NULL; i++) - { - GtkSourceLanguage *lang; - - lang = gtk_source_language_manager_get_language (lm, ids[i]); - - if (!gtk_source_language_get_hidden (lang)) - { - languages = g_slist_prepend (languages, lang); - } - } - - return g_slist_sort (languages, (GCompareFunc)language_compare); -} - -static void -create_languages_menu (XedWindow *window) -{ - GtkRadioAction *action_none; - GSList *languages; - GSList *l; - guint id; - gint i; - - xed_debug (DEBUG_WINDOW); - - /* add the "Plain Text" item before all the others */ - - /* Translators: "Plain Text" means that no highlight mode is selected in the - * "View->Highlight Mode" submenu and so syntax highlighting is disabled */ - action_none = gtk_radio_action_new (LANGUAGE_NONE, _("Plain Text"), _("Disable syntax highlighting"), NULL, -1); - - gtk_action_group_add_action (window->priv->languages_action_group, GTK_ACTION(action_none)); - g_object_unref (action_none); - - g_signal_connect(action_none, "activate", G_CALLBACK (language_toggled), window); - - id = gtk_ui_manager_new_merge_id (window->priv->manager); - - gtk_ui_manager_add_ui (window->priv->manager, id, - "/MenuBar/ViewMenu/ViewHighlightModeMenu/LanguagesMenuPlaceholder", - LANGUAGE_NONE, LANGUAGE_NONE, GTK_UI_MANAGER_MENUITEM, TRUE); - - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action_none), TRUE); - - /* now add all the known languages */ - languages = get_languages_sorted_by_section (window); - - for (l = languages, i = 0; l != NULL; l = l->next) - { - create_language_menu_item (l->data, i, id, window); - } - - g_slist_free (languages); -} - -static void -update_languages_menu (XedWindow *window) -{ - XedDocument *doc; - GList *actions; - GList *l; - GtkAction *action; - GtkSourceLanguage *lang; - const gchar *lang_id; - - doc = xed_window_get_active_document (window); - if (doc == NULL) - { - return; - } - - lang = xed_document_get_language (doc); - if (lang != NULL) - { - lang_id = gtk_source_language_get_id (lang); - } - else - { - lang_id = LANGUAGE_NONE; - } - - actions = gtk_action_group_list_actions (window->priv->languages_action_group); - - /* prevent recursion */ - for (l = actions; l != NULL; l = l->next) - { - g_signal_handlers_block_by_func(GTK_ACTION (l->data), G_CALLBACK (language_toggled), window); - } - - action = gtk_action_group_get_action (window->priv->languages_action_group, lang_id); - - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION(action), TRUE); - - for (l = actions; l != NULL; l = l->next) - { - g_signal_handlers_unblock_by_func(GTK_ACTION (l->data), G_CALLBACK (language_toggled), window); - } - - g_list_free (actions); -} - void _xed_recent_add (XedWindow *window, GFile *location, @@ -1279,14 +1021,6 @@ create_menu_bar_and_toolbar (XedWindow *window, window); update_recent_files_menu (window); - /* languages menu */ - action_group = gtk_action_group_new ("LanguagesActions"); - gtk_action_group_set_translation_domain (action_group, NULL); - window->priv->languages_action_group = action_group; - gtk_ui_manager_insert_action_group (manager, action_group, 0); - g_object_unref (action_group); - create_languages_menu (window); - /* list of open documents menu */ action_group = gtk_action_group_new ("DocumentsListActions"); gtk_action_group_set_translation_domain (action_group, NULL); @@ -1558,8 +1292,7 @@ statusbar_visibility_changed (GtkWidget *statusbar, } static void -tab_width_combo_changed (XedStatusComboBox *combo, - GtkMenuItem *item, +tab_width_button_clicked (GtkMenuItem *item, XedWindow *window) { XedView *view; @@ -1579,9 +1312,7 @@ tab_width_combo_changed (XedStatusComboBox *combo, return; } - g_signal_handler_block (view, window->priv->tab_width_id); gtk_source_view_set_tab_width (GTK_SOURCE_VIEW(view), width_data); - g_signal_handler_unblock (view, window->priv->tab_width_id); } static void @@ -1615,28 +1346,6 @@ use_spaces_toggled (GtkCheckMenuItem *item, g_signal_handler_unblock (view, window->priv->spaces_instead_of_tabs_id); } -static void -language_combo_changed (XedStatusComboBox *combo, - GtkMenuItem *item, - XedWindow *window) -{ - XedDocument *doc; - GtkSourceLanguage *language; - - doc = xed_window_get_active_document (window); - - if (!doc) - { - return; - } - - language = GTK_SOURCE_LANGUAGE(g_object_get_data (G_OBJECT (item), LANGUAGE_DATA)); - - g_signal_handler_block (doc, window->priv->language_changed_id); - xed_document_set_language (doc, language); - g_signal_handler_unblock (doc, window->priv->language_changed_id); -} - typedef struct { const gchar *label; @@ -1644,22 +1353,26 @@ typedef struct } TabWidthDefinition; static void -fill_tab_width_combo (XedWindow *window) +setup_tab_width_menu (XedWindow *window) { static TabWidthDefinition defs[] = { { "2", 2 }, { "4", 4 }, { "8", 8 }, { "", 0 }, /* custom size */ { NULL, 0 } }; - XedStatusComboBox *combo = XED_STATUS_COMBO_BOX (window->priv->tab_width_combo); guint i = 0; GtkWidget *item; gboolean use_spaces; + window->priv->tab_width_menu = gtk_menu_new (); + while (defs[i].label != NULL) { item = gtk_menu_item_new_with_label (defs[i].label); g_object_set_data (G_OBJECT(item), TAB_WIDTH_DATA, GINT_TO_POINTER (defs[i].width)); - xed_status_combo_box_add_item (combo, GTK_MENU_ITEM (item), defs[i].label); + gtk_menu_shell_append (GTK_MENU_SHELL (window->priv->tab_width_menu), item); + + g_signal_connect(G_OBJECT (item), "activate", + G_CALLBACK (tab_width_button_clicked), window); if (defs[i].width != 0) { @@ -1670,11 +1383,11 @@ fill_tab_width_combo (XedWindow *window) } item = gtk_separator_menu_item_new (); - xed_status_combo_box_add_item (combo, GTK_MENU_ITEM(item), NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (window->priv->tab_width_menu), item); gtk_widget_show (item); item = gtk_check_menu_item_new_with_label (_("Use Spaces")); - xed_status_combo_box_add_item (combo, GTK_MENU_ITEM(item), NULL); + gtk_menu_shell_append (GTK_MENU_SHELL (window->priv->tab_width_menu), item); gtk_widget_show (item); g_signal_connect(item, "toggled", G_CALLBACK (use_spaces_toggled), window); @@ -1684,44 +1397,35 @@ fill_tab_width_combo (XedWindow *window) } static void -fill_language_combo (XedWindow *window) +on_language_selector_shown (XedHighlightModeSelector *sel, + XedWindow *window) { - GtkSourceLanguageManager *lm; - const gchar * const *ids; - const gchar *name; - GtkWidget *menu_item; - gint i; + XedDocument *doc; - name = _("Plain Text"); - menu_item = gtk_menu_item_new_with_label (name); - gtk_widget_show (menu_item); - - g_object_set_data (G_OBJECT(menu_item), LANGUAGE_DATA, NULL); - xed_status_combo_box_add_item (XED_STATUS_COMBO_BOX (window->priv->language_combo), GTK_MENU_ITEM (menu_item), name); - - lm = gtk_source_language_manager_get_default (); - ids = gtk_source_language_manager_get_language_ids (lm); - - for (i = 0; ids[i] != NULL; i++) + doc = xed_window_get_active_document (window); + if (doc) { - GtkSourceLanguage *lang; - - lang = gtk_source_language_manager_get_language (lm, ids[i]); - - if (!gtk_source_language_get_hidden (lang)) - { - name = gtk_source_language_get_name (lang); - menu_item = gtk_menu_item_new_with_label (name); - gtk_widget_show (menu_item); - - g_object_set_data_full (G_OBJECT (menu_item), LANGUAGE_DATA, g_object_ref (lang), - (GDestroyNotify) g_object_unref); - xed_status_combo_box_add_item (XED_STATUS_COMBO_BOX (window->priv->language_combo), - GTK_MENU_ITEM (menu_item), name); - } + xed_highlight_mode_selector_select_language (sel, + xed_document_get_language (doc)); } } +static void +on_language_selected (XedHighlightModeSelector *sel, + GtkSourceLanguage *language, + XedWindow *window) +{ + XedDocument *doc; + + doc = xed_window_get_active_document (window); + if (doc) + { + xed_document_set_language (doc, language); + } + + gtk_widget_hide (GTK_WIDGET (window->priv->language_popover)); +} + static void create_statusbar (XedWindow *window, GtkWidget *main_box) @@ -1729,6 +1433,7 @@ create_statusbar (XedWindow *window, GtkWidget *image; GtkWidget *button_box; GtkAction *action; + XedHighlightModeSelector *sel; xed_debug (DEBUG_WINDOW); @@ -1745,27 +1450,39 @@ create_statusbar (XedWindow *window, gtk_widget_set_margin_start (GTK_WIDGET (window->priv->statusbar), 0); gtk_widget_set_margin_end (GTK_WIDGET (window->priv->statusbar), 0); - window->priv->tab_width_combo = xed_status_combo_box_new (NULL); - gtk_widget_show (window->priv->tab_width_combo); - gtk_box_pack_end (GTK_BOX (window->priv->statusbar), window->priv->tab_width_combo, FALSE, FALSE, 0); - gtk_widget_set_margin_bottom (GTK_WIDGET (window->priv->tab_width_combo), 2); - gtk_widget_set_margin_top (GTK_WIDGET (window->priv->tab_width_combo), 2); + window->priv->tab_width_button = xed_status_menu_button_new (); + gtk_widget_show (window->priv->tab_width_button); + gtk_box_pack_end (GTK_BOX (window->priv->statusbar), window->priv->tab_width_button, FALSE, FALSE, 0); + gtk_widget_set_margin_bottom (GTK_WIDGET (window->priv->tab_width_button), 2); + gtk_widget_set_margin_top (GTK_WIDGET (window->priv->tab_width_button), 2); - fill_tab_width_combo (window); + setup_tab_width_menu (window); - g_signal_connect(G_OBJECT (window->priv->tab_width_combo), "changed", - G_CALLBACK (tab_width_combo_changed), window); + gtk_menu_button_set_popup (GTK_MENU_BUTTON (window->priv->tab_width_button), + window->priv->tab_width_menu); - window->priv->language_combo = xed_status_combo_box_new (NULL); - gtk_widget_show (window->priv->language_combo); - gtk_widget_set_margin_bottom (GTK_WIDGET (window->priv->language_combo), 2); - gtk_widget_set_margin_top (GTK_WIDGET (window->priv->language_combo), 2); - gtk_box_pack_end (GTK_BOX(window->priv->statusbar), window->priv->language_combo, FALSE, FALSE, 0); + window->priv->language_button = xed_status_menu_button_new (); + gtk_widget_show (window->priv->language_button); + gtk_widget_set_margin_bottom (GTK_WIDGET (window->priv->language_button), 2); + gtk_widget_set_margin_top (GTK_WIDGET (window->priv->language_button), 2); + gtk_box_pack_end (GTK_BOX(window->priv->statusbar), window->priv->language_button, FALSE, FALSE, 0); - fill_language_combo (window); + window->priv->language_popover = gtk_popover_new (window->priv->language_button); + gtk_menu_button_set_popover (GTK_MENU_BUTTON (window->priv->language_button), + window->priv->language_popover); - g_signal_connect(G_OBJECT (window->priv->language_combo), "changed", - G_CALLBACK (language_combo_changed), window); + sel = xed_highlight_mode_selector_new (); + g_signal_connect (sel, + "show", + G_CALLBACK (on_language_selector_shown), + window); + g_signal_connect (sel, + "language-selected", + G_CALLBACK (on_language_selected), + window); + + gtk_container_add (GTK_CONTAINER (window->priv->language_popover), GTK_WIDGET (sel)); + gtk_widget_show (GTK_WIDGET (sel)); button_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); gtk_widget_set_margin_top (button_box, 4); @@ -2043,9 +1760,9 @@ static void set_tab_width_item_blocked (XedWindow *window, GtkMenuItem *item) { - g_signal_handlers_block_by_func(window->priv->tab_width_combo, tab_width_combo_changed, window); - xed_status_combo_box_set_item (XED_STATUS_COMBO_BOX(window->priv->tab_width_combo), item); - g_signal_handlers_unblock_by_func(window->priv->tab_width_combo, tab_width_combo_changed, window); + g_signal_handlers_block_by_func(item, tab_width_button_clicked, window); + gtk_menu_shell_select_item (GTK_MENU_SHELL (window->priv->tab_width_menu), GTK_WIDGET (item)); + g_signal_handlers_unblock_by_func(item, tab_width_button_clicked, window); } static void @@ -2055,7 +1772,7 @@ spaces_instead_of_tabs_changed (GObject *object, { XedView *view = XED_VIEW(object); gboolean active = gtk_source_view_get_insert_spaces_instead_of_tabs (GTK_SOURCE_VIEW(view)); - GList *children = xed_status_combo_box_get_items (XED_STATUS_COMBO_BOX(window->priv->tab_width_combo)); + GList *children = gtk_container_get_children (GTK_CONTAINER (window->priv->tab_width_menu)); GtkCheckMenuItem *item; item = GTK_CHECK_MENU_ITEM(g_list_last (children)->data); gtk_check_menu_item_set_active (item, active); @@ -2069,11 +1786,11 @@ tab_width_changed (GObject *object, { GList *items; GList *item; - XedStatusComboBox *combo = XED_STATUS_COMBO_BOX(window->priv->tab_width_combo); guint new_tab_width; + gchar *label; gboolean found = FALSE; - items = xed_status_combo_box_get_items (combo); + items = gtk_container_get_children (GTK_CONTAINER (window->priv->tab_width_menu)); new_tab_width = gtk_source_view_get_tab_width (GTK_SOURCE_VIEW(object)); @@ -2095,8 +1812,7 @@ tab_width_changed (GObject *object, gchar *text; text = g_strdup_printf ("%u", new_tab_width); - xed_status_combo_box_set_item_text (combo, GTK_MENU_ITEM(item->data), text); - gtk_label_set_text (GTK_LABEL(gtk_bin_get_child (GTK_BIN (item->data))), text); + gtk_menu_item_set_label (GTK_MENU_ITEM(item->data), text); set_tab_width_item_blocked (window, GTK_MENU_ITEM(item->data)); gtk_widget_show (GTK_WIDGET(item->data)); @@ -2110,6 +1826,10 @@ tab_width_changed (GObject *object, } } + label = g_strdup_printf (_("Tab Width: %u"), new_tab_width); + xed_status_menu_button_set_label (XED_STATUS_MENU_BUTTON (window->priv->tab_width_button), label); + + g_free (label); g_list_free (items); } @@ -2118,40 +1838,17 @@ language_changed (GObject *object, GParamSpec *pspec, XedWindow *window) { - GList *items; - GList *item; - XedStatusComboBox *combo = XED_STATUS_COMBO_BOX(window->priv->language_combo); GtkSourceLanguage *new_language; - const gchar *new_id; + const gchar *label; - items = xed_status_combo_box_get_items (combo); - - new_language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER(object)); + new_language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (object)); if (new_language) - { - new_id = gtk_source_language_get_id (new_language); - } + label = gtk_source_language_get_name (new_language); else - { - new_id = NULL; - } + label = _("Plain Text"); - for (item = items; item; item = item->next) - { - GtkSourceLanguage *lang = g_object_get_data (G_OBJECT(item->data), - LANGUAGE_DATA); - if ((new_id == NULL && lang == NULL) - || (new_id != NULL && lang != NULL && strcmp (gtk_source_language_get_id (lang), new_id) == 0)) - { - g_signal_handlers_block_by_func(window->priv->language_combo, language_combo_changed, window); - xed_status_combo_box_set_item (XED_STATUS_COMBO_BOX(window->priv->language_combo), - GTK_MENU_ITEM(item->data)); - g_signal_handlers_unblock_by_func(window->priv->language_combo, language_combo_changed, window); - } - } - - g_list_free (items); + xed_status_menu_button_set_label (XED_STATUS_MENU_BUTTON (window->priv->language_button), label); } static void @@ -2273,9 +1970,6 @@ notebook_switch_page (GtkNotebook *book, g_free (action_name); - /* update the syntax menu */ - update_languages_menu (window); - view = xed_tab_get_view (tab); map_frame = xed_view_frame_get_map_frame (XED_VIEW_FRAME (_xed_tab_get_view_frame (tab))); @@ -2284,8 +1978,8 @@ notebook_switch_page (GtkNotebook *book, xed_statusbar_set_overwrite (XED_STATUSBAR (window->priv->statusbar), gtk_text_view_get_overwrite (GTK_TEXT_VIEW(view))); - gtk_widget_show (window->priv->tab_width_combo); - gtk_widget_show (window->priv->language_combo); + gtk_widget_show (window->priv->tab_width_button); + gtk_widget_show (window->priv->language_button); window->priv->tab_width_id = g_signal_connect(view, "notify::tab-width", G_CALLBACK (tab_width_changed), window); @@ -2865,7 +2559,6 @@ sync_languages_menu (XedDocument *doc, GParamSpec *pspec, XedWindow *window) { - update_languages_menu (window); peas_extension_set_call (window->priv->extensions, "update_state"); } @@ -3021,8 +2714,8 @@ notebook_tab_removed (XedNotebook *notebook, xed_statusbar_clear_overwrite (XED_STATUSBAR(window->priv->statusbar)); /* hide the combos */ - gtk_widget_hide (window->priv->tab_width_combo); - gtk_widget_hide (window->priv->language_combo); + gtk_widget_hide (window->priv->tab_width_button); + gtk_widget_hide (window->priv->language_button); } if (!window->priv->removing_tabs)