! Please note that this is a snapshot of our old Bugzilla server, which is read only since May 29, 2020. Please go to gitlab.xfce.org for our new server !
Dynamic encoding changing
Status:
RESOLVED: FIXED
Severity:
enhancement
Product:
Xfce4-terminal
Component:
General

Comments

Description Morarenko Kirill 2007-02-03 20:54:51 CET
I'm just start using your excellent terminal emulator - xfce Terminal. But there was no dynamic encoding changing support, so I've added it.
Please, look at this small patch - may be it have a chance to be included in release.

Available encoding list hardcoded in two arrays - radio_action_entries and radio_action_encoding_names, which sizes must be the same (of course, data may be wrapped in one structure, but it's not done for the simplicity).
Also, position of menu items may be changed simplify by modifying Terminal.ui and terminal-screen.c (correct path to Encoding menu).

I'm not guru in *nix-programming, so default encoding get from ENCODING env. var. Probably, it should be rewritten. 


--- terminal-screen.c.old	2007-02-02 17:28:08.000000000 +0300
+++ terminal-screen.c	2007-02-02 17:27:47.000000000 +0300
@@ -1523,3 +1523,16 @@
   return result;
 }
 
+/**
+ * terminal_screen_set_encoding
+ * @screen    : A #TerminalScreen.
+ * @encoding  : encoding to set
+ *
+ * Return value:
+ **/
+void
+terminal_screen_set_encoding (TerminalScreen *screen,
+                               const char    *encoding)
+{
+  g_return_if_fail (TERMINAL_IS_SCREEN (screen));
+  vte_terminal_set_encoding(VTE_TERMINAL (screen->terminal), encoding);
+}



--- terminal-screen.h.old	2007-02-02 17:28:09.000000000 +0300
+++ terminal-screen.h	2007-02-02 17:27:33.000000000 +0300
@@ -85,6 +85,9 @@
 
 GList     *terminal_screen_get_restart_command        (TerminalScreen *screen);
 
+void         terminal_screen_set_encoding             (TerminalScreen *screen,
+                                                       const char    *encoding);
+
 G_END_DECLS;
 
 #endif /* !__TERMINAL_SCREEN_H__ */


--- Terminal.ui.original	2007-02-02 17:31:19.000000000 +0300
+++ Terminal.ui	2007-02-02 12:43:59.000000000 +0300
@@ -41,6 +41,10 @@
       <menuitem action="reset"/>
       <menuitem action="reset-and-clear"/>
     </menu>
+    
+    <menu name="Encoding" action="encoding-menu">
+    </menu>
+
     <menu action="go-menu">
       <menuitem action="prev-tab"/>
       <menuitem action="next-tab"/>



--- terminal-window.c.original	2007-02-02 17:08:04.000000000 +0300
+++ terminal-window.c	2007-02-02 17:15:58.000000000 +0300
@@ -33,6 +33,12 @@
 #ifdef HAVE_TIME_H
 #include <time.h>
 #endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -169,7 +175,9 @@
 static void            terminal_window_action_about             (GtkAction       *action,
                                                                  TerminalWindow  *window);
 
-
+static void            terminal_window_action_set_encoding      (GtkRadioAction       *action,
+                                                                 GtkRadioAction       *current,
+                                                                 TerminalWindow  *window);
 
 struct _TerminalWindow
 {
@@ -181,6 +189,7 @@
   GtkWidget           *preferences_dialog;
 
   GtkActionGroup      *action_group;
+  GtkActionGroup      *encoding_action_group;
   GtkUIManager        *ui_manager;
   
   GtkWidget           *menubar;
@@ -226,6 +235,7 @@
   { "report-bug", TERMINAL_STOCK_REPORTBUG, N_ ("_Report a bug"), NULL, N_ ("Report a bug in Terminal"), G_CALLBACK (terminal_window_action_report_bug), },
   { "about", GTK_STOCK_ABOUT, N_ ("_About"), NULL, N_ ("Display information about Terminal"), G_CALLBACK (terminal_window_action_about), },
   { "input-methods", NULL, N_ ("_Input Methods"), NULL, NULL, NULL, },
+  { "encoding-menu", NULL, N_ ("_Encoding"), NULL, NULL, NULL, },
 };
 
 static const GtkToggleActionEntry toggle_action_entries[] =
@@ -236,7 +246,23 @@
   { "fullscreen", TERMINAL_STOCK_FULLSCREEN, N_ ("_Fullscreen"), NULL, N_ ("Toggle fullscreen mode"), G_CALLBACK (terminal_window_action_fullscreen), FALSE, },
 };
 
+static const GtkRadioActionEntry radio_action_entries[] =
+{
+    { "encoding-utf8", NULL, N_ ("UTF-8"), NULL, NULL, 0, },
+    { "encoding-cp1251", NULL, N_ ("Russian (CP1251)"), NULL, NULL, 1, },
+    { "encoding-koi8r", NULL, N_ ("Russian (KOI8-R)"), NULL, NULL, 2, },
+};
+
+static const gchar* radio_action_encoding_names[] = 
+{
+    "UTF-8",
+    "CP1251",
+    "KOI8-R",
+};
+
 
+static GHashTable* enc2widget;
+static GHashTable* term2enc;
 
 G_DEFINE_TYPE (TerminalWindow, terminal_window, GTK_TYPE_WINDOW);
 
@@ -244,7 +270,7 @@
 
 static void
 terminal_window_class_init (TerminalWindowClass *klass)
-{
+{ 
   GtkWidgetClass *gtkwidget_class;
   GObjectClass   *gobject_class;
   
@@ -255,6 +281,10 @@
   gtkwidget_class = GTK_WIDGET_CLASS (klass);
   gtkwidget_class->show = terminal_window_show;
 
+  //initializing hash tables
+  enc2widget = g_hash_table_new(NULL, NULL);
+  term2enc = g_hash_table_new(NULL, NULL);
+
   /**
    * TerminalWindow::new-window
    **/
@@ -282,8 +312,6 @@
                   G_TYPE_OBJECT);
 }
 
-
-
 static void
 terminal_window_init (TerminalWindow *window)
 {
@@ -309,8 +337,11 @@
                             G_CALLBACK (terminal_window_update_mnemonics), window);
 
   window->action_group = gtk_action_group_new ("terminal-window");
+  window->encoding_action_group = gtk_action_group_new ("terminal-window-encoding");
   gtk_action_group_set_translation_domain (window->action_group,
                                            GETTEXT_PACKAGE);
+  gtk_action_group_set_translation_domain (window->encoding_action_group,
+                                           GETTEXT_PACKAGE);
   gtk_action_group_add_actions (window->action_group,
                                 action_entries,
                                 G_N_ELEMENTS (action_entries),
@@ -319,9 +350,17 @@
                                        toggle_action_entries,
                                        G_N_ELEMENTS (toggle_action_entries),
                                        GTK_WIDGET (window));
-
+  
+  gtk_action_group_add_radio_actions (window->encoding_action_group,
+                                       radio_action_entries,
+                                       G_N_ELEMENTS (radio_action_entries),
+                                       0,
+                                       G_CALLBACK (terminal_window_action_set_encoding),
+                                       GTK_WIDGET (window));
+  
   window->ui_manager = gtk_ui_manager_new ();
   gtk_ui_manager_insert_action_group (window->ui_manager, window->action_group, 0);
+  gtk_ui_manager_insert_action_group (window->ui_manager, window->encoding_action_group, 0);      
 
   xfce_resource_push_path (XFCE_RESOURCE_DATA, DATADIR);
   file = xfce_resource_lookup (XFCE_RESOURCE_DATA, "Terminal/Terminal.ui");
@@ -329,11 +368,37 @@
 
   if (G_LIKELY (file != NULL))
     {
+        
       if (gtk_ui_manager_add_ui_from_file (window->ui_manager, file, &error) == 0)
-        {
-          g_warning ("Unable to load %s: %s", file, error->message);
-          g_error_free (error);
-        }
+          {
+              g_warning ("Unable to load %s: %s", file, error->message);
+              g_error_free (error);
+          }
+
+      {
+          int i;
+          for (i = 0; i < G_N_ELEMENTS(radio_action_entries); i++)
+              {
+                  gint new_id;
+                  GString* path;
+                  GtkWidget* menu_item_widget;
+
+                  new_id = gtk_ui_manager_new_merge_id(window->ui_manager);
+                  gtk_ui_manager_add_ui(window->ui_manager, 
+                                        new_id,
+                                        "/main-menu/Encoding", 
+                                        radio_action_entries[i].label,
+                                        radio_action_entries[i].name,
+                                        GTK_UI_MANAGER_MENUITEM,
+                                        FALSE);
+
+                  path = g_string_new("/main-menu/Encoding/");
+                  g_string_append(path, radio_action_entries[i].label);
+                  menu_item_widget = gtk_ui_manager_get_widget(window->ui_manager,
+                                                                        path->str);
+                  g_hash_table_insert(enc2widget, (gpointer)radio_action_encoding_names[i], (gpointer)menu_item_widget);
+              }
+      }
       gtk_ui_manager_ensure_update (window->ui_manager);
       g_free (file);
     }
@@ -452,10 +517,14 @@
 
   g_object_unref (G_OBJECT (window->preferences));
   g_object_unref (G_OBJECT (window->action_group));
+  g_object_unref (G_OBJECT (window->encoding_action_group));
   g_object_unref (G_OBJECT (window->ui_manager));
 
   g_free (window->startup_id);
 
+  g_hash_table_destroy(enc2widget);
+  g_hash_table_destroy(term2enc);
+
   (*G_OBJECT_CLASS (terminal_window_parent_class)->finalize) (object);
 }
 
@@ -886,10 +955,34 @@
   TerminalScreen *terminal;
   gint            grid_width;
   gint            grid_height;
+  gpointer       *encoding;
+  
 
   terminal = terminal_window_get_active (window);
   if (G_LIKELY (terminal != NULL))
     {
+        GtkWidget* encoding_menu_item;
+
+        //restoring current terminal encoding info
+        encoding = g_hash_table_lookup(term2enc, (gconstpointer)terminal);
+        if (encoding == NULL){
+            const char* current_encoding_var = getenv("ENCODING");
+            if (current_encoding_var != NULL){
+                int i = 0;
+                for (i = 0; i < G_N_ELEMENTS(radio_action_encoding_names); i++)
+                    if (strcmp(radio_action_encoding_names[i], current_encoding_var) == 0){
+                        encoding = (gpointer)radio_action_encoding_names[i];
+                    }
+            }
+            if (encoding == NULL)
+                encoding = (gpointer)radio_action_encoding_names[0];
+            g_hash_table_insert(term2enc, (gpointer)terminal, encoding);
+        }
+        encoding_menu_item = g_hash_table_lookup(enc2widget, encoding);
+        if (GTK_IS_WIDGET(encoding_menu_item))
+            gtk_menu_item_activate(GTK_MENU_ITEM(encoding_menu_item));
+
+
       /* FIXME: This isn't really needed anymore, instead we
        * could grab the grid size of the previously selected
        * page and apply that to the newly selected page.
@@ -1078,6 +1171,7 @@
   gint            npages;
   gint            grid_width;
   gint            grid_height;
+ 
 
   npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
   if (G_UNLIKELY (npages == 0))
@@ -1098,6 +1192,8 @@
       active = terminal_window_get_active (window);
       if (G_LIKELY (active != NULL))
         {
+            g_hash_table_remove(term2enc, (gpointer)active);
+
           terminal_screen_get_size (screen, &grid_width, &grid_height);
           terminal_window_set_size_force_grid (window, active, grid_width, grid_height);
         }
@@ -1218,6 +1314,21 @@
     terminal_screen_paste_clipboard (terminal);
 }
 
+static void
+terminal_window_action_set_encoding (GtkRadioAction       *action,
+                                      GtkRadioAction      *current,
+                                     TerminalWindow  *window)
+{
+  TerminalScreen *terminal;
+  
+  terminal = terminal_window_get_active (window);
+  if (G_LIKELY (terminal != NULL))
+  {
+    gint current_value = gtk_radio_action_get_current_value(action);
+    terminal_screen_set_encoding (terminal, radio_action_encoding_names[current_value]);
+    g_hash_table_insert(term2enc, (gpointer)terminal, (gpointer)radio_action_encoding_names[current_value]);
+  }
+}
 
 
 static void
@@ -1822,3 +1933,4 @@
 
   return result;
 }
+
Comment 1 Morarenko Kirill 2007-02-03 20:56:08 CET
Created attachment 980 
screen.c diff
Comment 2 Morarenko Kirill 2007-02-03 20:56:24 CET
Created attachment 981 
screen.h patch
Comment 3 Morarenko Kirill 2007-02-03 20:56:36 CET
Created attachment 982 
terminal.c diff
Comment 4 Morarenko Kirill 2007-02-03 20:56:56 CET
Created attachment 983 
Terminal.ui diff
Comment 5 Nick Schermer editbugs 2009-07-06 10:53:58 CEST
*** Bug 4762 has been marked as a duplicate of this bug. ***
Comment 6 Yves-Alexis Perez editbugs 2011-04-11 10:26:20 CEST
I'm quite sure the attached patches don't apply anymore against master, but what's the status on this?
Comment 7 Nick Schermer editbugs 2012-12-19 21:53:26 CET
Fixed.

Bug #2860

Reported by:
Morarenko Kirill
Reported on: 2007-02-03
Last modified on: 2012-12-19
Duplicates (1):
  • 4762 Enable charset selection on current terminal tab

People

Assignee:
Nick Schermer
CC List:
2 users

Version

Version:
unspecified

Attachments

screen.c diff (522 bytes, patch)
2007-02-03 20:56 CET , Morarenko Kirill
no flags
screen.h patch (440 bytes, patch)
2007-02-03 20:56 CET , Morarenko Kirill
no flags
terminal.c diff (9.31 KB, patch)
2007-02-03 20:56 CET , Morarenko Kirill
no flags
Terminal.ui diff (398 bytes, patch)
2007-02-03 20:56 CET , Morarenko Kirill
no flags

Additional information