Commit d599eaf3 authored by Sébastien Wilmet's avatar Sébastien Wilmet

TextView: make language context menu re-usable

It will be used for both GtkTextView and GtkEntry.
parent 57496c2c
......@@ -32,6 +32,7 @@ IGNORE_HFILES = \
gspell.h \
gspellregion.h \
gspell-checker-private.h \
gspell-context-menu.h \
gspell-entry-private.h \
gspell-entry-utils.h \
gspell-init.h \
......
......@@ -46,6 +46,7 @@ gspell_private_headers = \
gconstructor.h \
gspellregion.h \
gspell-checker-private.h \
gspell-context-menu.h \
gspell-entry-private.h \
gspell-entry-utils.h \
gspell-init.h \
......@@ -55,6 +56,7 @@ gspell_private_headers = \
gspell_private_c_files = \
gspellregion.c \
gspell-context-menu.c \
gspell-entry-utils.c \
gspell-init.c \
gspell-inline-checker-text-buffer.c \
......
/*
* This file is part of gspell, a spell-checking library.
*
* Copyright 2016 - Sébastien Wilmet
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gspell-context-menu.h"
#include <glib/gi18n-lib.h>
#define LANGUAGE_DATA_KEY "gspell-language-data-key"
typedef struct _LanguageData LanguageData;
struct _LanguageData
{
const GspellLanguage *lang;
GspellLanguageActivatedCallback callback;
gpointer user_data;
};
static void
activate_language_cb (GtkWidget *menu_item)
{
LanguageData *data;
data = g_object_get_data (G_OBJECT (menu_item), LANGUAGE_DATA_KEY);
g_return_if_fail (data != NULL);
if (data->callback != NULL)
{
data->callback (data->lang, data->user_data);
}
}
static GtkWidget *
get_language_menu (const GspellLanguage *current_language,
GspellLanguageActivatedCallback callback,
gpointer user_data)
{
GtkWidget *menu;
const GList *languages;
const GList *l;
menu = gtk_menu_new ();
languages = gspell_language_get_available ();
for (l = languages; l != NULL; l = l->next)
{
const GspellLanguage *lang = l->data;
const gchar *lang_name;
GtkWidget *menu_item;
LanguageData *data;
lang_name = gspell_language_get_name (lang);
if (lang == current_language)
{
/* Do not create a group. Just mark the current language
* as active.
*
* With a group, the first language in the list gets
* activated, which changes the GspellChecker language
* before we arrive to the current_language.
*
* Also, having a bullet only for the current_language is
* sufficient (to be like in Firefox), the menu is
* anyway ephemeral. No need to have an empty bullet for
* all the other languages.
*/
menu_item = gtk_radio_menu_item_new_with_label (NULL, lang_name);
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
}
else
{
menu_item = gtk_menu_item_new_with_label (lang_name);
}
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
data = g_new0 (LanguageData, 1);
data->lang = lang;
data->callback = callback;
data->user_data = user_data;
g_object_set_data_full (G_OBJECT (menu_item),
LANGUAGE_DATA_KEY,
data,
g_free);
g_signal_connect (menu_item,
"activate",
G_CALLBACK (activate_language_cb),
NULL);
}
return menu;
}
GtkMenuItem *
_gspell_context_menu_get_language_menu_item (const GspellLanguage *current_language,
GspellLanguageActivatedCallback callback,
gpointer user_data)
{
GtkWidget *lang_menu;
GtkMenuItem *menu_item;
lang_menu = get_language_menu (current_language, callback, user_data);
menu_item = GTK_MENU_ITEM (gtk_menu_item_new_with_mnemonic (_("_Language")));
gtk_menu_item_set_submenu (menu_item, lang_menu);
gtk_widget_show_all (GTK_WIDGET (menu_item));
return menu_item;
}
/* ex:set ts=8 noet: */
/*
* This file is part of gspell, a spell-checking library.
*
* Copyright 2016 - Sébastien Wilmet
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GSPELL_CONTEXT_MENU_H
#define GSPELL_CONTEXT_MENU_H
#include <gtk/gtk.h>
#include "gspell-language.h"
G_BEGIN_DECLS
typedef void (*GspellLanguageActivatedCallback) (const GspellLanguage *lang,
gpointer user_data);
G_GNUC_INTERNAL
GtkMenuItem * _gspell_context_menu_get_language_menu_item (const GspellLanguage *current_language,
GspellLanguageActivatedCallback callback,
gpointer user_data);
G_END_DECLS
#endif /* GSPELL_CONTEXT_MENU_H */
/* ex:set ts=8 noet: */
......@@ -24,6 +24,7 @@
#include "gspell-checker.h"
#include "gspell-language.h"
#include "gspell-text-buffer.h"
#include "gspell-context-menu.h"
/**
* SECTION:text-view
......@@ -73,8 +74,7 @@ enum
PROP_ENABLE_LANGUAGE_MENU,
};
#define GSPELL_TEXT_VIEW_KEY "gspell-text-view-key"
#define LANGUAGE_KEY "gspell-language-key"
#define GSPELL_TEXT_VIEW_KEY "gspell-text-view-key"
G_DEFINE_TYPE_WITH_PRIVATE (GspellTextView, gspell_text_view, G_TYPE_OBJECT)
......@@ -133,22 +133,19 @@ notify_buffer_cb (GtkTextView *gtk_view,
}
static void
activate_language_cb (GtkWidget *menu_item,
GspellTextView *gspell_view)
language_activated_cb (const GspellLanguage *lang,
gpointer user_data)
{
GspellTextView *gspell_view;
GspellTextViewPrivate *priv;
const GspellLanguage *lang;
GtkTextBuffer *gtk_buffer;
GspellTextBuffer *gspell_buffer;
GspellChecker *checker;
priv = gspell_text_view_get_instance_private (gspell_view);
g_return_if_fail (GSPELL_IS_TEXT_VIEW (user_data));
lang = g_object_get_data (G_OBJECT (menu_item), LANGUAGE_KEY);
if (lang == NULL)
{
g_return_if_reached ();
}
gspell_view = GSPELL_TEXT_VIEW (user_data);
priv = gspell_text_view_get_instance_private (gspell_view);
gtk_buffer = gtk_text_view_get_buffer (priv->view);
gspell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (gtk_buffer);
......@@ -158,7 +155,7 @@ activate_language_cb (GtkWidget *menu_item,
}
static const GspellLanguage *
get_active_language (GspellTextView *gspell_view)
get_current_language (GspellTextView *gspell_view)
{
GspellTextViewPrivate *priv;
GtkTextBuffer *gtk_buffer;
......@@ -179,65 +176,6 @@ get_active_language (GspellTextView *gspell_view)
return gspell_checker_get_language (checker);
}
static GtkWidget *
get_language_menu (GspellTextView *gspell_view)
{
GtkWidget *menu;
const GspellLanguage *active_lang;
const GList *languages;
const GList *l;
menu = gtk_menu_new ();
active_lang = get_active_language (gspell_view);
languages = gspell_language_get_available ();
for (l = languages; l != NULL; l = l->next)
{
const GspellLanguage *lang = l->data;
const gchar *lang_name;
GtkWidget *menu_item;
lang_name = gspell_language_get_name (lang);
if (lang == active_lang)
{
/* Do not create a group. Just mark the current language
* as active.
*
* With a group, the first language in the list gets
* activated, which changes the GspellChecker language
* before we arrive to the active_lang.
*
* Also, having a bullet only for the active_lang is
* sufficient (to be like in Firefox), the menu is
* anyway ephemeral. No need to have an empty bullet for
* all the other languages.
*/
menu_item = gtk_radio_menu_item_new_with_label (NULL, lang_name);
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), TRUE);
}
else
{
menu_item = gtk_menu_item_new_with_label (lang_name);
}
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
g_object_set_data (G_OBJECT (menu_item),
LANGUAGE_KEY,
(gpointer) lang);
g_signal_connect_object (menu_item,
"activate",
G_CALLBACK (activate_language_cb),
gspell_view,
0);
}
return menu;
}
static void
populate_popup_cb (GtkTextView *gtk_view,
GtkWidget *popup,
......@@ -269,12 +207,17 @@ populate_popup_cb (GtkTextView *gtk_view,
if (priv->enable_language_menu)
{
const GspellLanguage *current_language;
GtkMenuItem *lang_menu_item;
current_language = get_current_language (gspell_view);
lang_menu_item = _gspell_context_menu_get_language_menu_item (current_language,
language_activated_cb,
gspell_view);
/* Prepend language sub-menu */
menu_item = gtk_menu_item_new_with_mnemonic (_("_Language"));
gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item);
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item),
get_language_menu (gspell_view));
gtk_widget_show_all (menu_item);
gtk_menu_shell_prepend (GTK_MENU_SHELL (menu),
GTK_WIDGET (lang_menu_item));
}
if (priv->inline_checker != NULL)
......
# List of source files containing translatable strings.
gspell/gspell-checker.c
gspell/gspell-checker-dialog.c
gspell/gspell-context-menu.c
gspell/gspell-entry.c
gspell/gspell-entry-buffer.c
gspell/gspell-entry-utils.c
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment