From bdcbeb7878b691b398a1d55282eb472a760fe302 Mon Sep 17 00:00:00 2001 From: Yevgen Muntyan <17531749+muntyan@users.noreply.github.com> Date: Mon, 26 Nov 2007 00:13:17 -0600 Subject: [PATCH] Added encodings menu item into the notebook popup menu --- moo/mooedit/mooedit-private.h | 5 +- moo/mooedit/mooedit.c | 18 ++++-- moo/mooedit/mooeditfileops.c | 12 +++- moo/mooedit/mooeditwindow.c | 49 +++++++++++++++ moo/mooutils/mooencodings.c | 110 ++++++++++++++++++++++++---------- moo/mooutils/mooencodings.h | 9 ++- 6 files changed, 163 insertions(+), 40 deletions(-) diff --git a/moo/mooedit/mooedit-private.h b/moo/mooedit/mooedit-private.h index 702b3a70..034c6acb 100644 --- a/moo/mooedit/mooedit-private.h +++ b/moo/mooedit/mooedit-private.h @@ -79,9 +79,12 @@ void _moo_edit_apply_prefs (MooEdit *edit); /* File operations */ -void _moo_edit_set_filename (MooEdit *edit, +void _moo_edit_set_filename (MooEdit *edit, const char *file, const char *encoding); +void _moo_edit_set_encoding (MooEdit *edit, + const char *encoding); +char *_moo_edit_get_default_encoding (void); void _moo_edit_stop_file_watch (MooEdit *edit); diff --git a/moo/mooedit/mooedit.c b/moo/mooedit/mooedit.c index c508aaa7..a1d9a83c 100644 --- a/moo/mooedit/mooedit.c +++ b/moo/mooedit/mooedit.c @@ -454,8 +454,8 @@ _moo_edit_set_status (MooEdit *edit, MooEditFileInfo* -moo_edit_file_info_new (const char *filename, - const char *encoding) +moo_edit_file_info_new (const char *filename, + const char *encoding) { MooEditFileInfo *info = g_new0 (MooEditFileInfo, 1); info->filename = g_strdup (filename); @@ -465,7 +465,7 @@ moo_edit_file_info_new (const char *filename, MooEditFileInfo* -moo_edit_file_info_copy (const MooEditFileInfo *info) +moo_edit_file_info_copy (const MooEditFileInfo *info) { MooEditFileInfo *copy; g_return_val_if_fail (info != NULL, NULL); @@ -476,7 +476,7 @@ moo_edit_file_info_copy (const MooEditFileInfo *info) } void -moo_edit_file_info_free (MooEditFileInfo *info) +moo_edit_file_info_free (MooEditFileInfo *info) { if (info) { @@ -655,6 +655,16 @@ moo_edit_get_encoding (MooEdit *edit) return edit->priv->encoding; } +void +_moo_edit_set_encoding (MooEdit *edit, + const char *encoding) +{ + g_return_if_fail (MOO_IS_EDIT (edit)); + g_return_if_fail (encoding != NULL); + g_free (edit->priv->encoding); + edit->priv->encoding = g_strdup (encoding); +} + static GtkTextBuffer * get_buffer (MooEdit *edit) diff --git a/moo/mooedit/mooeditfileops.c b/moo/mooedit/mooeditfileops.c index 361bc473..812c4369 100644 --- a/moo/mooedit/mooeditfileops.c +++ b/moo/mooedit/mooeditfileops.c @@ -1192,6 +1192,13 @@ add_untitled (MooEdit *edit) } +char * +_moo_edit_get_default_encoding (void) +{ + return g_strdup (moo_prefs_get_string (moo_edit_setting (MOO_EDIT_PREFS_ENCODING_SAVE))); +} + + void _moo_edit_set_filename (MooEdit *edit, const char *file, @@ -1236,8 +1243,9 @@ _moo_edit_set_filename (MooEdit *edit, } if (!encoding) - encoding = moo_prefs_get_string (moo_edit_setting (MOO_EDIT_PREFS_ENCODING_SAVE)); - edit->priv->encoding = g_strdup (encoding); + edit->priv->encoding = _moo_edit_get_default_encoding (); + else + edit->priv->encoding = g_strdup (encoding); g_signal_emit_by_name (edit, "filename-changed", edit->priv->filename, NULL); moo_edit_status_changed (edit); diff --git a/moo/mooedit/mooeditwindow.c b/moo/mooedit/mooeditwindow.c index 880eefe0..7fe3dfe7 100644 --- a/moo/mooedit/mooeditwindow.c +++ b/moo/mooedit/mooeditwindow.c @@ -1959,6 +1959,49 @@ notebook_switch_page (G_GNUC_UNUSED MooNotebook *notebook, } +static void +doc_encoding_menu_item_activated (const char *encoding, + gpointer data) +{ + _moo_edit_set_encoding (data, encoding); +} + +static GtkWidget * +create_doc_encoding_menu_item (MooEdit *doc) +{ + GtkWidget *item, *menu, *enc_item; + const char *enc, *display_enc; + char *freeme = NULL; + + enc = moo_edit_get_encoding (doc); + + if (!enc) + { + freeme = _moo_edit_get_default_encoding (); + enc = freeme; + } + + display_enc = _moo_encoding_get_display_name (enc); + + /* Translators: do not translate the part before | */ + item = gtk_menu_item_new_with_label (Q_("Item in the notebook popup menu|Encoding")); + gtk_widget_show (item); + menu = _moo_encodings_menu_new (doc_encoding_menu_item_activated, doc, + enc, FALSE); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu); + + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), + g_object_new (GTK_TYPE_SEPARATOR_MENU_ITEM, + "visible", TRUE, NULL)); + + enc_item = gtk_radio_menu_item_new_with_label (NULL, display_enc); + gtk_widget_show (enc_item); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), enc_item); + + g_free (freeme); + return item; +} + static gboolean notebook_populate_popup (MooNotebook *notebook, GtkWidget *child, @@ -2009,6 +2052,12 @@ notebook_populate_popup (MooNotebook *notebook, window); } + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + g_object_new (GTK_TYPE_SEPARATOR_MENU_ITEM, + "visible", TRUE, NULL)); + item = create_doc_encoding_menu_item (edit); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + return FALSE; } diff --git a/moo/mooutils/mooencodings.c b/moo/mooutils/mooencodings.c index 0fe48f8e..8208b27e 100644 --- a/moo/mooutils/mooencodings.c +++ b/moo/mooutils/mooencodings.c @@ -46,7 +46,6 @@ typedef struct { GtkWidget *menu; MooEncodingsMenuFunc func; gpointer func_data; - GDestroyNotify data_notify; } MenuData; typedef struct { @@ -74,7 +73,9 @@ static void combo_changed (GtkComboBox *combo, static void enc_mgr_load (EncodingsManager *enc_mgr); static void enc_mgr_add_used (EncodingsManager *enc_mgr, Encoding *enc); -static void sync_recent_menu (MenuData *menu); +static void sync_recent_menu (MenuData *menu, + const char *exclude, + gboolean need_separator); static Encoding * @@ -284,6 +285,22 @@ get_enc_mgr (void) } +const char * +_moo_encoding_get_display_name (const char *enc_name) +{ + EncodingsManager *mgr; + Encoding *enc; + + g_return_val_if_fail (enc_name != NULL, NULL); + + mgr = get_enc_mgr (); + enc = get_encoding (mgr, enc_name); + g_return_val_if_fail (enc != NULL, enc_name); + + return enc->display_name; +} + + static void enc_mgr_save (EncodingsManager *enc_mgr) { @@ -495,7 +512,7 @@ update_menu_idle (EncodingsManager *mgr) for (l = mgr->menus; l != NULL; l = l->next) { MenuData *menu = l->data; - sync_recent_menu (menu); + sync_recent_menu (menu, NULL, FALSE); } enc_mgr_save (mgr); @@ -915,6 +932,12 @@ _moo_encodings_equal (const char *enc1_name, } +static void +menu_data_free (MenuData *menu_data) +{ + g_free (menu_data); +} + static void menu_destroyed (GtkWidget *widget, MenuData *menu) @@ -926,10 +949,7 @@ menu_destroyed (GtkWidget *widget, g_signal_handlers_disconnect_by_func (widget, (gpointer) menu_destroyed, menu); mgr->menus = g_slist_remove (mgr->menus, menu); - if (menu->data_notify) - menu->data_notify (menu->func_data); - - g_free (menu); + menu_data_free (menu); } static void @@ -939,14 +959,13 @@ menu_item_activated (GtkWidget *item, EncodingsManager *mgr = get_enc_mgr (); Encoding *enc; - g_return_if_fail (g_slist_find (mgr->menus, menu) != NULL); - enc = g_object_get_data (G_OBJECT (item), "moo-encoding"); g_return_if_fail (enc != NULL); menu->func (enc->name, menu->func_data); - enc_mgr_add_used (mgr, enc); + if (g_slist_find (mgr->menus, menu) != NULL) + enc_mgr_add_used (mgr, enc); } static GtkWidget * @@ -970,11 +989,14 @@ create_menu_item (Encoding *enc, } static void -sync_recent_menu (MenuData *menu) +sync_recent_menu (MenuData *menu, + const char *exclude, + gboolean need_separator) { EncodingsManager *mgr = get_enc_mgr (); GList *children, *l; GSList *recent_items; + gboolean have_separator = FALSE; children = gtk_container_get_children (GTK_CONTAINER (menu->menu)); for (l = children; l != NULL; l = l->next) @@ -987,32 +1009,58 @@ sync_recent_menu (MenuData *menu) while (recent_items) { Encoding *enc = recent_items->data; - GtkWidget *item = create_menu_item (enc, menu, TRUE); - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu->menu), item); + + if (!exclude || strcmp (enc->name, exclude) != 0) + { + GtkWidget *item; + + if (need_separator && !have_separator) + { + item = gtk_separator_menu_item_new (); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu->menu), item); + have_separator = TRUE; + } + + item = create_menu_item (enc, menu, TRUE); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu->menu), item); + } + recent_items = g_slist_delete_link (recent_items, recent_items); } } -static GtkWidget * -_moo_encodings_menu_new (MooEncodingsMenuFunc func, - gpointer data, - GDestroyNotify notify) +GtkWidget * +_moo_encodings_menu_new (MooEncodingsMenuFunc func, + gpointer data, + const char *exclude, + gboolean sync) { - MenuData *menu; + MenuData *menu_data = NULL; + GtkWidget *widget; EncodingsManager *mgr; guint cgr; g_return_val_if_fail (func != NULL, NULL); mgr = get_enc_mgr (); - menu = g_new0 (MenuData, 1); - menu->func = func; - menu->func_data = data; - menu->data_notify = notify; - mgr->menus = g_slist_prepend (mgr->menus, menu); - menu->menu = gtk_menu_new (); - g_signal_connect (menu->menu, "destroy", G_CALLBACK (menu_destroyed), menu); + menu_data = g_new0 (MenuData, 1); + menu_data->func = func; + menu_data->func_data = data; + + widget = gtk_menu_new (); + menu_data->menu = widget; + + if (sync) + { + mgr->menus = g_slist_prepend (mgr->menus, menu_data); + g_signal_connect (widget, "destroy", G_CALLBACK (menu_destroyed), menu_data); + } + else + { + g_object_set_data_full (G_OBJECT (widget), "moo-menu-data", menu_data, + (GDestroyNotify) menu_data_free); + } for (cgr = 0; cgr < mgr->n_groups; ++cgr) { @@ -1021,22 +1069,22 @@ _moo_encodings_menu_new (MooEncodingsMenuFunc func, guint i; item = gtk_menu_item_new_with_label (grp->name); - gtk_menu_shell_append (GTK_MENU_SHELL (menu->menu), item); + gtk_menu_shell_append (GTK_MENU_SHELL (widget), item); submenu = gtk_menu_new (); gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); for (i = 0; i < grp->n_encodings; ++i) { Encoding *enc = grp->encodings[i]; - item = create_menu_item (enc, menu, FALSE); + item = create_menu_item (enc, menu_data, FALSE); gtk_menu_shell_append (GTK_MENU_SHELL (submenu), item); } } - sync_recent_menu (menu); + sync_recent_menu (menu_data, exclude, TRUE); - gtk_widget_show_all (menu->menu); - return menu->menu; + gtk_widget_show_all (widget); + return widget; } typedef struct { @@ -1076,7 +1124,7 @@ moo_encodings_menu_action_create_menu_item (GtkAction *gtkaction) GtkWidget *menu_item, *menu; menu_item = GTK_ACTION_CLASS (moo_encodings_menu_action_parent_class)->create_menu_item (gtkaction); - menu = _moo_encodings_menu_new (action_item_activated, action, NULL); + menu = _moo_encodings_menu_new (action_item_activated, action, NULL, TRUE); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu); return menu_item; diff --git a/moo/mooutils/mooencodings.h b/moo/mooutils/mooencodings.h index 2b69cf41..a221c6ae 100644 --- a/moo/mooutils/mooencodings.h +++ b/moo/mooutils/mooencodings.h @@ -48,10 +48,15 @@ GtkAction *_moo_encodings_menu_action_new (const char *id, const char *label, MooEncodingsMenuFunc func, gpointer data); +GtkWidget *_moo_encodings_menu_new (MooEncodingsMenuFunc func, + gpointer data, + const char *exclude, + gboolean sync); const char *_moo_encoding_locale (void); -gboolean _moo_encodings_equal (const char *enc1, - const char *enc2); +gboolean _moo_encodings_equal (const char *enc1, + const char *enc2); +const char *_moo_encoding_get_display_name (const char *enc); G_END_DECLS