[gnome-text-editor] session: allow opening documents with specific encoding
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-text-editor] session: allow opening documents with specific encoding
- Date: Tue, 22 Jun 2021 23:39:17 +0000 (UTC)
commit bd25fba6f2232499eeebe7cc634e0c3bcc00822f
Author: Christian Hergert <chergert redhat com>
Date: Tue Jun 22 16:39:12 2021 -0700
session: allow opening documents with specific encoding
And also keep that encoding when saving back to disk if it was specified.
src/editor-document-private.h | 2 ++
src/editor-document.c | 37 ++++++++++++++++++++++++++
src/editor-page.c | 2 +-
src/editor-session.c | 6 +++--
src/editor-session.h | 3 ++-
src/editor-sidebar-item.c | 3 ++-
src/editor-window-actions.c | 60 +++++++++++++++++++++++++++++++++++++++++--
src/editor-window-dnd.c | 2 +-
8 files changed, 107 insertions(+), 8 deletions(-)
---
diff --git a/src/editor-document-private.h b/src/editor-document-private.h
index c44b398..b6efa25 100644
--- a/src/editor-document-private.h
+++ b/src/editor-document-private.h
@@ -38,6 +38,8 @@ void _editor_document_set_externally_modified (EditorDocument *
gboolean _editor_document_get_was_restored (EditorDocument *self);
void _editor_document_set_was_restored (EditorDocument *self,
gboolean was_restored);
+void _editor_document_set_encoding (EditorDocument *document,
+ const char *encoding);
void _editor_document_load_async (EditorDocument *self,
EditorWindow *window,
GCancellable *cancellable,
diff --git a/src/editor-document.c b/src/editor-document.c
index 88a6ccd..b5d7f14 100644
--- a/src/editor-document.c
+++ b/src/editor-document.c
@@ -43,6 +43,7 @@ struct _EditorDocument
GtkSourceFile *file;
gchar *draft_id;
GtkTextTag *line_spacing_tag;
+ char *encoding;
guint busy_count;
gdouble busy_progress;
@@ -311,6 +312,7 @@ editor_document_finalize (GObject *object)
g_clear_object (&self->monitor);
g_clear_object (&self->file);
g_clear_pointer (&self->draft_id, g_free);
+ g_clear_pointer (&self->encoding, g_free);
G_OBJECT_CLASS (editor_document_parent_class)->finalize (object);
}
@@ -616,6 +618,12 @@ _editor_document_save_draft_async (EditorDocument *self,
(GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS |
GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME));
+ if (self->encoding != NULL)
+ {
+ const GtkSourceEncoding *encoding = gtk_source_encoding_get_from_charset (self->encoding);
+ gtk_source_file_saver_set_encoding (saver, encoding);
+ }
+
/* TODO: Probably want to make this async. We can just create an
* async variant in editor-utils.c for this.
*/
@@ -853,6 +861,12 @@ _editor_document_save_async (EditorDocument *self,
(GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS |
GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME));
+ if (self->encoding != NULL)
+ {
+ const GtkSourceEncoding *encoding = gtk_source_encoding_get_from_charset (self->encoding);
+ gtk_source_file_saver_set_encoding (saver, encoding);
+ }
+
_editor_document_mark_busy (self);
editor_document_set_busy_progress (self, 0, 2, .25);
@@ -1110,6 +1124,13 @@ editor_document_do_load (EditorDocument *self,
loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (self), file);
+ if (self->encoding != NULL)
+ {
+ const GtkSourceEncoding *encoding = gtk_source_encoding_get_from_charset (self->encoding);
+ GSList encodings = { .next = NULL, .data = (gpointer)encoding };
+ gtk_source_file_loader_set_candidate_encodings (loader, &encodings);
+ }
+
gtk_source_file_loader_load_async (loader,
G_PRIORITY_DEFAULT,
g_task_get_cancellable (task),
@@ -1600,3 +1621,19 @@ _editor_document_get_was_restored (EditorDocument *self)
return self->was_restored;
}
+
+void
+_editor_document_set_encoding (EditorDocument *self,
+ const char *encoding)
+{
+ g_return_if_fail (EDITOR_IS_DOCUMENT (self));
+
+ if (g_strcmp0 (encoding, "auto") == 0)
+ encoding = NULL;
+
+ if (g_strcmp0 (self->encoding, encoding) != 0)
+ {
+ g_free (self->encoding);
+ self->encoding = g_strdup (encoding);
+ }
+}
diff --git a/src/editor-page.c b/src/editor-page.c
index acacb39..b3407f2 100644
--- a/src/editor-page.c
+++ b/src/editor-page.c
@@ -346,7 +346,7 @@ editor_page_drop_target_drop (EditorPage *self,
EditorSession *session = editor_application_get_session (EDITOR_APPLICATION_DEFAULT);
EditorWindow *window = EDITOR_WINDOW (gtk_widget_get_root (GTK_WIDGET (self)));
- editor_session_open (session, window, file);
+ editor_session_open (session, window, file, NULL);
}
return FALSE;
diff --git a/src/editor-session.c b/src/editor-session.c
index 3404ed6..5f05e0d 100644
--- a/src/editor-session.c
+++ b/src/editor-session.c
@@ -1216,7 +1216,8 @@ get_draft_id_for_file (EditorSession *self,
EditorPage *
editor_session_open (EditorSession *self,
EditorWindow *window,
- GFile *file)
+ GFile *file,
+ const char *encoding)
{
g_autoptr(EditorDocument) document = NULL;
g_autofree gchar *uri = NULL;
@@ -1245,6 +1246,7 @@ editor_session_open (EditorSession *self,
remove = page;
document = editor_document_new_for_file (file);
+ _editor_document_set_encoding (document, encoding);
if ((draft_id = get_draft_id_for_file (self, file)))
_editor_document_set_draft_id (document, draft_id);
@@ -1268,7 +1270,7 @@ editor_session_open_files (EditorSession *self,
g_return_if_fail (EDITOR_IS_SESSION (self));
for (guint i = 0; i < n_files; i++)
- editor_session_open (self, NULL, files[i]);
+ editor_session_open (self, NULL, files[i], NULL);
}
/**
diff --git a/src/editor-session.h b/src/editor-session.h
index 1f77bb9..f7487e9 100644
--- a/src/editor-session.h
+++ b/src/editor-session.h
@@ -36,7 +36,8 @@ EditorWindow *editor_session_create_window (EditorSession *self);
GListModel *editor_session_get_recents (EditorSession *self);
EditorPage *editor_session_open (EditorSession *self,
EditorWindow *window,
- GFile *file);
+ GFile *file,
+ const char *encoding);
void editor_session_open_files (EditorSession *self,
GFile **files,
gint n_files);
diff --git a/src/editor-sidebar-item.c b/src/editor-sidebar-item.c
index 2873198..5bb25bc 100644
--- a/src/editor-sidebar-item.c
+++ b/src/editor-sidebar-item.c
@@ -485,7 +485,8 @@ _editor_sidebar_item_open (EditorSidebarItem *self,
if (self->page != NULL)
_editor_page_raise (self->page);
else if (self->file != NULL)
- editor_session_open (session, window, self->file);
+ /* TODO: This should stash the encoding and reuse it */
+ editor_session_open (session, window, self->file, NULL);
else if (self->draft_id != NULL)
_editor_session_open_draft (session, window, self->draft_id);
else
diff --git a/src/editor-window-actions.c b/src/editor-window-actions.c
index 660beee..9ad0ffa 100644
--- a/src/editor-window-actions.c
+++ b/src/editor-window-actions.c
@@ -306,13 +306,67 @@ editor_window_actions_open_response_cb (EditorWindow *self,
if (response_id == GTK_RESPONSE_ACCEPT)
{
g_autoptr(GFile) file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (native));
+ const char *encoding = gtk_file_chooser_get_choice (GTK_FILE_CHOOSER (native), "encoding");
- editor_session_open (EDITOR_SESSION_DEFAULT, self, file);
+ editor_session_open (EDITOR_SESSION_DEFAULT, self, file, encoding);
}
gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (native));
}
+static int
+sort_by_name (gconstpointer a,
+ gconstpointer b)
+{
+ return g_strcmp0 (gtk_source_encoding_get_name (a),
+ gtk_source_encoding_get_name (b));
+}
+
+static void
+editor_window_actions_add_encodings (GtkFileChooser *chooser)
+{
+ GPtrArray *choices;
+ GPtrArray *labels;
+ GSList *all;
+
+ g_assert (GTK_IS_FILE_CHOOSER (chooser));
+
+ all = g_slist_sort (gtk_source_encoding_get_all (), sort_by_name);
+ choices = g_ptr_array_new ();
+ labels = g_ptr_array_new_with_free_func (g_free);
+
+#define ADD_ENCODING(id, name) \
+ G_STMT_START { \
+ g_ptr_array_add(choices, (char *)id); \
+ g_ptr_array_add(labels, (char *)name); \
+ } G_STMT_END
+
+ ADD_ENCODING ("auto", g_strdup (N_("Automatically Detected")));
+
+ for (const GSList *l = all; l; l = l->next)
+ {
+ GtkSourceEncoding *encoding = l->data;
+ char *title = g_strdup_printf ("%s (%s)",
+ gtk_source_encoding_get_name (encoding),
+ gtk_source_encoding_get_charset (encoding));
+ ADD_ENCODING (gtk_source_encoding_get_charset (encoding), title);
+ }
+
+ ADD_ENCODING (NULL, NULL);
+#undef ADD_ENCODING
+
+ gtk_file_chooser_add_choice (chooser,
+ "encoding",
+ _("Character Encoding:"),
+ (const char **)(gpointer)choices->pdata,
+ (const char **)(gpointer)labels->pdata);
+ gtk_file_chooser_set_choice (chooser, "encoding", "auto");
+
+ g_slist_free (all);
+ g_clear_pointer (&choices, g_ptr_array_unref);
+ g_clear_pointer (&labels, g_ptr_array_unref);
+}
+
static void
editor_window_actions_open_cb (GtkWidget *widget,
const char *action_name,
@@ -357,12 +411,14 @@ editor_window_actions_open_cb (GtkWidget *widget,
gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), g_object_ref (text_files));
#ifdef __APPLE__
- /* Apple cotent-type detect is pretty bad */
+ /* Apple content-type detect is pretty bad */
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (native), all_files);
#else
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (native), text_files);
#endif
+ editor_window_actions_add_encodings (GTK_FILE_CHOOSER (native));
+
g_signal_connect_object (native,
"response",
G_CALLBACK (editor_window_actions_open_response_cb),
diff --git a/src/editor-window-dnd.c b/src/editor-window-dnd.c
index 1d1261e..607f1b5 100644
--- a/src/editor-window-dnd.c
+++ b/src/editor-window-dnd.c
@@ -50,7 +50,7 @@ editor_window_dnd_drag_data_received_cb (EditorWindow *self,
g_autoptr(GFile) file = g_file_new_for_uri (uris[i]);
if (file != NULL)
- editor_session_open (EDITOR_SESSION_DEFAULT, self, file);
+ editor_session_open (EDITOR_SESSION_DEFAULT, self, file, NULL);
}
gtk_window_present_with_time (GTK_WINDOW (self), time_);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]