diff -Nru gedit-40.1/build-aux/flatpak/org.gnome.gedit.yml gedit-41.0/build-aux/flatpak/org.gnome.gedit.yml
--- gedit-40.1/build-aux/flatpak/org.gnome.gedit.yml 2021-04-17 05:45:33.348500000 +0000
+++ gedit-41.0/build-aux/flatpak/org.gnome.gedit.yml 2022-02-14 13:58:26.000000000 +0000
@@ -59,17 +59,12 @@
url: https://download.gnome.org/sources/gspell/1.9/gspell-1.9.1.tar.xz
sha256: dcbb769dfdde8e3c0a8ed3102ce7e661abbf7ddf85df08b29915e92cd723abdd
- - name: amtk
- buildsystem: meson
- sources:
- - type: git
- url: https://gitlab.gnome.org/GNOME/amtk.git
-
- - name: tepl
- buildsystem: meson
+ - name: uchardet
+ buildsystem: cmake-ninja
sources:
- - type: git
- url: https://gitlab.gnome.org/GNOME/tepl.git
+ - type: archive
+ url: https://www.freedesktop.org/software/uchardet/releases/uchardet-0.0.6.tar.xz
+ sha256: 8351328cdfbcb2432e63938721dd781eb8c11ebc56e3a89d0f84576b96002c61
- name: gedit
buildsystem: meson
diff -Nru gedit-40.1/build-aux/snap/snapcraft.yaml gedit-41.0/build-aux/snap/snapcraft.yaml
--- gedit-40.1/build-aux/snap/snapcraft.yaml 2021-04-17 05:45:35.024535200 +0000
+++ gedit-41.0/build-aux/snap/snapcraft.yaml 2022-02-14 13:58:26.000000000 +0000
@@ -41,33 +41,10 @@
GTK_USE_PORTAL: 1
parts:
- amtk:
- source: https://gitlab.gnome.org/GNOME/amtk.git
- source-type: git
- plugin: autotools
- configflags:
- - --prefix=/usr
- - --enable-introspection=no
- organize:
- snap/gedit/current/usr: usr
-
- tepl:
- after: [amtk, gtksourceview]
- source: https://gitlab.gnome.org/GNOME/tepl.git
- source-type: git
- plugin: meson
- meson-parameters:
- - --prefix=/usr
- organize:
- snap/gedit/current/usr: usr
- build-packages:
- - libuchardet-dev
- stage-packages:
- - libuchardet0
-
gtksourceview:
source: https://gitlab.gnome.org/GNOME/gtksourceview.git
source-type: git
+ source-branch: gtksourceview-4-8
plugin: meson
meson-parameters:
- --prefix=/usr
@@ -94,7 +71,7 @@
cp $SNAPCRAFT_PART_INSTALL/usr/share/vala/vapi/gtksource* /usr/share/vala/vapi
gedit:
- after: [gtksourceview, tepl]
+ after: [gtksourceview]
source: .
source-type: git
parse-info: [usr/share/metainfo/org.gnome.gedit.appdata.xml]
@@ -102,6 +79,7 @@
meson-parameters:
- --prefix=/usr
- -Dvala_args="--vapidir=$SNAPCRAFT_STAGE/usr/share/vala/vapi"
+
build-environment:
- C_INCLUDE_PATH: $SNAPCRAFT_STAGE/usr/include/gtksourceview-4
override-build: |
diff -Nru gedit-40.1/data/gedit.1 gedit-41.0/data/gedit.1
--- gedit-40.1/data/gedit.1 2021-04-17 05:45:35.024535200 +0000
+++ gedit-41.0/data/gedit.1 2022-02-14 13:58:26.000000000 +0000
@@ -76,11 +76,11 @@
.B gedit will read from stdin
.TP
\fB+LINE\fR
-For the first file, go to the line specified by LINE (do not insert a space between the "+" sign and the number).
+For all the files specified on command line, go to the line specified by LINE (do not insert a space between the "+" sign and the number).
If LINE is missing, go to the last line.
.TP
\fBCOLUMN\fR
-For the first file, go to the column specified by COLUMN.
+For all the files specified on command line, go to the column specified by COLUMN.
If COLUMN is missing, go to the first column.
.SH BUGS
diff -Nru gedit-40.1/data/meson.build gedit-41.0/data/meson.build
--- gedit-40.1/data/meson.build 2021-04-17 05:45:35.136537600 +0000
+++ gedit-41.0/data/meson.build 2022-02-14 13:58:26.000000000 +0000
@@ -4,7 +4,6 @@
appdata = 'org.gnome.gedit.appdata.xml'
appdata_file = i18n.merge_file(
- appdata,
input: appdata + '.in',
output: appdata,
po_dir: '../po/',
@@ -23,7 +22,6 @@
desktop_file = 'org.gnome.gedit.desktop'
desktop_output_file = i18n.merge_file(
- desktop_file,
type: 'desktop',
input: desktop_file + '.in',
output: desktop_file,
@@ -45,6 +43,7 @@
'docinfo',
'filebrowser',
'modelines',
+ 'openlinks',
'sort',
'spell',
]
diff -Nru gedit-40.1/data/org.gnome.gedit.appdata.xml.in gedit-41.0/data/org.gnome.gedit.appdata.xml.in
--- gedit-40.1/data/org.gnome.gedit.appdata.xml.in 2021-04-17 05:45:35.400543200 +0000
+++ gedit-41.0/data/org.gnome.gedit.appdata.xml.in 2022-02-14 13:58:26.000000000 +0000
@@ -28,7 +28,7 @@
https://wiki.gnome.org/Apps/Gedithttps://gitlab.gnome.org/GNOME/gedit/issues
- https://liberapay.com/gedit/
+ https://www.gnome.org/donate/https://help.gnome.org/users/gedit/stable/https://wiki.gnome.org/TranslationProjectjmas@softcatala.org
@@ -36,6 +36,7 @@
gedit
+
diff -Nru gedit-40.1/data/org.gnome.gedit.gschema.xml.in gedit-41.0/data/org.gnome.gedit.gschema.xml.in
--- gedit-40.1/data/org.gnome.gedit.gschema.xml.in 2021-04-17 05:45:35.400543200 +0000
+++ gedit-41.0/data/org.gnome.gedit.gschema.xml.in 2022-02-14 13:58:26.000000000 +0000
@@ -126,6 +126,11 @@
Right Margin PositionSpecifies the position of the right margin.
+
+ false
+ Display Overview Map
+ Whether gedit should display the overview map for the document.
+ 'none'Document background pattern type
diff -Nru gedit-40.1/debian/changelog gedit-41.0/debian/changelog
--- gedit-40.1/debian/changelog 2021-11-22 10:19:49.000000000 +0000
+++ gedit-41.0/debian/changelog 2022-03-02 12:34:07.000000000 +0000
@@ -1,3 +1,24 @@
+gedit (41.0-3) unstable; urgency=medium
+
+ * debian/patches/gitlab_openlinks_fix.patch:
+ - don't try to convert an array of gunicode to a gchar, fix the build
+ fixed on s390x
+
+ -- Sebastien Bacher Wed, 02 Mar 2022 13:34:07 +0100
+
+gedit (41.0-2) unstable; urgency=medium
+
+ * Restore fix_ftbfs_nonlinux.patch: accidentally left out of 41.0 release
+
+ -- Jeremy Bicha Mon, 14 Feb 2022 12:29:08 -0500
+
+gedit (41.0-1) unstable; urgency=medium
+
+ * New upstream release
+ * Drop all patches except our Debian multiarch patch: applied in new release
+
+ -- Jeremy Bicha Mon, 14 Feb 2022 09:28:53 -0500
+
gedit (40.1-3) unstable; urgency=medium
* d/control.in: Add libglib2.0-dev and libgtk-3-dev dependencies to gedit-dev
diff -Nru gedit-40.1/debian/patches/08_multiarch_fallback.patch gedit-41.0/debian/patches/08_multiarch_fallback.patch
--- gedit-40.1/debian/patches/08_multiarch_fallback.patch 2021-11-22 10:19:49.000000000 +0000
+++ gedit-41.0/debian/patches/08_multiarch_fallback.patch 2022-03-02 12:34:07.000000000 +0000
@@ -9,9 +9,11 @@
gedit/gedit-plugins-engine.c | 5 +++++
3 files changed, 18 insertions(+)
+diff --git a/gedit/gedit-dirs.c b/gedit/gedit-dirs.c
+index 81f32c2..964e0a8 100644
--- a/gedit/gedit-dirs.c
+++ b/gedit/gedit-dirs.c
-@@ -33,6 +33,7 @@ static gchar *user_plugins_dir = N
+@@ -33,6 +33,7 @@ static gchar *user_plugins_dir = NULL;
static gchar *gedit_locale_dir = NULL;
static gchar *gedit_lib_dir = NULL;
static gchar *gedit_plugins_dir = NULL;
@@ -37,22 +39,24 @@
g_clear_pointer (&gedit_plugins_data_dir, g_free);
}
-@@ -168,6 +173,12 @@ gedit_dirs_get_gedit_plugins_dir (void)
+@@ -167,6 +172,12 @@ gedit_dirs_get_gedit_plugins_dir (void)
+ return gedit_plugins_dir;
}
- const gchar *
++const gchar *
+gedit_dirs_get_gedit_fallback_plugins_dir (void)
+{
+ return gedit_fallback_plugins_dir;
+}
+
-+const gchar *
+ const gchar *
gedit_dirs_get_gedit_plugins_data_dir (void)
{
- return gedit_plugins_data_dir;
+diff --git a/gedit/gedit-dirs.h b/gedit/gedit-dirs.h
+index 3fc7ab5..7f0126c 100644
--- a/gedit/gedit-dirs.h
+++ b/gedit/gedit-dirs.h
-@@ -46,6 +46,8 @@ const gchar *gedit_dirs_get_gedit_lib_di
+@@ -46,6 +46,8 @@ const gchar *gedit_dirs_get_gedit_lib_dir (void);
const gchar *gedit_dirs_get_gedit_plugins_dir (void);
@@ -61,9 +65,11 @@
const gchar *gedit_dirs_get_gedit_plugins_data_dir (void);
G_END_DECLS
+diff --git a/gedit/gedit-plugins-engine.c b/gedit/gedit-plugins-engine.c
+index 28e6096..f47f369 100644
--- a/gedit/gedit-plugins-engine.c
+++ b/gedit/gedit-plugins-engine.c
-@@ -93,6 +93,11 @@ gedit_plugins_engine_init (GeditPluginsE
+@@ -93,6 +93,11 @@ gedit_plugins_engine_init (GeditPluginsEngine *engine)
gedit_dirs_get_gedit_plugins_dir (),
gedit_dirs_get_gedit_plugins_data_dir ());
diff -Nru gedit-40.1/debian/patches/fix_ftbfs_nonlinux.patch gedit-41.0/debian/patches/fix_ftbfs_nonlinux.patch
--- gedit-40.1/debian/patches/fix_ftbfs_nonlinux.patch 2021-11-22 10:19:49.000000000 +0000
+++ gedit-41.0/debian/patches/fix_ftbfs_nonlinux.patch 2022-03-02 12:34:07.000000000 +0000
@@ -1,13 +1,74 @@
-Index: gedit-40.1/meson.build
-===================================================================
---- gedit-40.1.orig/meson.build
-+++ gedit-40.1/meson.build
-@@ -75,7 +75,7 @@ config_h.set_quoted('DATADIR', join_path
- config_h.set_quoted('VERSION', meson.project_version())
-
- enable_gvfs_metadata = get_option('enable-gvfs-metadata')
--if enable_gvfs_metadata == 'yes' or (enable_gvfs_metadata == 'auto' and host_machine.system() == 'linux')
-+if enable_gvfs_metadata == 'yes' or (enable_gvfs_metadata == 'auto' and ['linux', 'gnu', 'gnu/kfreebsd'].contains(host_machine.system()))
- enable_gvfs_metadata = true
- else
- enable_gvfs_metadata = false
+From: Laurent Bigonville
+Date: Mon, 22 Nov 2021 13:03:48 +0100
+Subject: Revert "gedit-dirs: remove get_user_cache_dir() (no longer used)"
+
+This also revert the move of the metadata file ("gedit-metadata.xml")
+from user_data_dir to user_cache_dir when not using GVFS to store the
+metadata
+
+This reverts commit f641a246fbaff482e216197d21e2e51397b1cb26.
+
+Fixes: https://gitlab.gnome.org/GNOME/gedit/-/issues/467
+(cherry picked from commit ba2662ff9ee99ef0d85023b06053792fd3eb9272)
+(cherry picked from commit 741be1b11b977abd529aa2f633e50c2e80864afc)
+---
+ gedit/gedit-dirs.c | 11 +++++++++++
+ gedit/gedit-dirs.h | 2 ++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/gedit/gedit-dirs.c b/gedit/gedit-dirs.c
+index 964e0a8..91a4ce4 100644
+--- a/gedit/gedit-dirs.c
++++ b/gedit/gedit-dirs.c
+@@ -26,6 +26,7 @@
+ #include
+ #endif
+
++static gchar *user_cache_dir = NULL;
+ static gchar *user_config_dir = NULL;
+ static gchar *user_data_dir = NULL;
+ static gchar *user_styles_dir = NULL;
+@@ -96,6 +97,9 @@ gedit_dirs_init ()
+ NULL);
+ }
+
++ user_cache_dir = g_build_filename (g_get_user_cache_dir (),
++ "gedit",
++ NULL);
+ user_config_dir = g_build_filename (g_get_user_config_dir (),
+ "gedit",
+ NULL);
+@@ -119,6 +123,7 @@ gedit_dirs_init ()
+ void
+ gedit_dirs_shutdown ()
+ {
++ g_clear_pointer (&user_cache_dir, g_free);
+ g_clear_pointer (&user_config_dir, g_free);
+ g_clear_pointer (&user_data_dir, g_free);
+ g_clear_pointer (&user_styles_dir, g_free);
+@@ -130,6 +135,12 @@ gedit_dirs_shutdown ()
+ g_clear_pointer (&gedit_plugins_data_dir, g_free);
+ }
+
++const gchar *
++gedit_dirs_get_user_cache_dir (void)
++{
++ return user_cache_dir;
++}
++
+ const gchar *
+ gedit_dirs_get_user_config_dir (void)
+ {
+diff --git a/gedit/gedit-dirs.h b/gedit/gedit-dirs.h
+index 7f0126c..acd2424 100644
+--- a/gedit/gedit-dirs.h
++++ b/gedit/gedit-dirs.h
+@@ -32,6 +32,8 @@ void gedit_dirs_init (void);
+ void gedit_dirs_shutdown (void);
+
+
++const gchar *gedit_dirs_get_user_cache_dir (void);
++
+ const gchar *gedit_dirs_get_user_config_dir (void);
+
+ const gchar *gedit_dirs_get_user_data_dir (void);
diff -Nru gedit-40.1/debian/patches/gitlab_openlinks_fix.patch gedit-41.0/debian/patches/gitlab_openlinks_fix.patch
--- gedit-40.1/debian/patches/gitlab_openlinks_fix.patch 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/debian/patches/gitlab_openlinks_fix.patch 2022-03-02 12:34:07.000000000 +0000
@@ -0,0 +1,52 @@
+From a51cafc7de9187150e56299866ea4452a8f38c5e Mon Sep 17 00:00:00 2001
+From: Sebastien Bacher
+Date: Wed, 2 Mar 2022 12:02:24 +0100
+Subject: [PATCH] Fix the openlinks test by properly converting gunicode to
+ gchar
+
+---
+ plugins/openlinks/gedit-open-links-plugin.c | 14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/plugins/openlinks/gedit-open-links-plugin.c b/plugins/openlinks/gedit-open-links-plugin.c
+index 9d7562881..5193511a4 100644
+--- a/plugins/openlinks/gedit-open-links-plugin.c
++++ b/plugins/openlinks/gedit-open-links-plugin.c
+@@ -85,8 +85,8 @@ gedit_open_links_plugin_get_uri (GtkTextIter *start,
+ GString **uri)
+ {
+ GtkTextIter *end;
+- gunichar uri_test[2];
+- uri_test[1] = '\0';
++ gchar uri_test[6];
++ gint len;
+
+ end = g_malloc (sizeof (GtkTextIter));
+ memcpy (end, start, sizeof (GtkTextIter));
+@@ -95,8 +95,9 @@ gedit_open_links_plugin_get_uri (GtkTextIter *start,
+ gtk_text_iter_backward_char (end);
+ while (gtk_text_iter_forward_char (end))
+ {
+- uri_test[0] = gtk_text_iter_get_char (end);
+- if (!g_regex_match (uri_char_regex, (const gchar *) &uri_test, 0, NULL))
++ len = g_unichar_to_utf8 (gtk_text_iter_get_char (end), uri_test);
++ uri_test[len] = '\0';
++ if (!g_regex_match (uri_char_regex, uri_test, 0, NULL))
+ {
+ break;
+ }
+@@ -104,8 +105,9 @@ gedit_open_links_plugin_get_uri (GtkTextIter *start,
+
+ while (gtk_text_iter_backward_char (start))
+ {
+- uri_test[0] = gtk_text_iter_get_char (start);
+- if (!g_regex_match (uri_char_regex, (const gchar *) &uri_test, 0, NULL))
++ len = g_unichar_to_utf8 (gtk_text_iter_get_char (start), uri_test);
++ uri_test[len] = '\0';
++ if (!g_regex_match (uri_char_regex, uri_test, 0, NULL))
+ {
+ gtk_text_iter_forward_char (start);
+ break;
+--
+2.32.0
+
diff -Nru gedit-40.1/debian/patches/series gedit-41.0/debian/patches/series
--- gedit-40.1/debian/patches/series 2021-11-22 10:19:49.000000000 +0000
+++ gedit-41.0/debian/patches/series 2022-03-02 12:34:07.000000000 +0000
@@ -1,3 +1,3 @@
08_multiarch_fallback.patch
-upstream-fa587e0-deteplification.patch
fix_ftbfs_nonlinux.patch
+gitlab_openlinks_fix.patch
diff -Nru gedit-40.1/debian/patches/upstream-fa587e0-deteplification.patch gedit-41.0/debian/patches/upstream-fa587e0-deteplification.patch
--- gedit-40.1/debian/patches/upstream-fa587e0-deteplification.patch 2021-11-22 10:19:49.000000000 +0000
+++ gedit-41.0/debian/patches/upstream-fa587e0-deteplification.patch 1970-01-01 00:00:00.000000000 +0000
@@ -1,12537 +0,0 @@
-From fa587e033c97fac65dacdb3c9520635beca68fbc Mon Sep 17 00:00:00 2001
-From: Zander Brown
-Date: Tue, 13 Apr 2021 04:53:21 +0000
-Subject: [PATCH] deteplification: the mega commit
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-This commit is a reverse patch of a rebased version of gedit with
-commits related to tepl/amtk removed
-
-Sébastien Wilmet has stopped development of these libraries, relevant
-commits:
-
-https://gitlab.gnome.org/GNOME/amtk/-/commit/34a1171298808e5d9bd50540ee194b8be35bce9d
-https://gitlab.gnome.org/GNOME/tepl/-/commit/457b5c37ebcb2ebb23cae10cd47f1342db45a98e
-
-As a result usage is being dropped in favour simplifing gedit
-dependencies, because there are not enough developers, and too many bugs.
-Do you prefer a rock-solid text editor? Or a text editor with some shiny
-and non-essential dependencies that complicate the build, at the expense
-of more bugs?
-
-Tracked at: https://gitlab.gnome.org/Infrastructure/Infrastructure/-/issues/564
-
-Commits Dropped:
-cfeb7cb6c build: add Tepl dependency, second try
-872fb4809 Utils: use str truncate functions from Tepl
-9a121d523 Utils: deprecate str_end_truncate()
-e0e602799 No longer use gedit_utils_str_end_truncate()
-657ce9f7a Utils: deprecate str_middle_truncate()
-6eefa74c2 No longer use gedit_utils_str_middle_truncate()
-169c1594e main: call tepl_init() and tepl_finalize()
-ec31f0c22 snap: Fixed build failures by added tepl part
-76cf5562d Document: remove metadata implementation
-75cdb6a77 Document: second pass to remove metadata implementation
-d6b158ca6 App: remove the GeditMetadataManager
-6eccd6672 Remove GeditMetadataManager
-03929157e build: remove enable-gvfs-metadata option
-1dad3bce2 build: remove libxml dependency
-8c0825424 metadata: adapt key names for TeplFileMetadata
-c2904aa80 Document: metadata: create an internal TeplFile
-9c8ede1e2 App: setup Tepl metadata manager
-91bc04efc App: remove leftover comment
-b39dd0201 Document: use TeplFileMetadata to re-implement set/get_metadata()
-494677bfc Utils: use tepl_utils_replace_home_dir_with_tilde()
-aaaa28a87 docs: gtk-doc fixxref: fix the path for gtk and add path for tepl
-8710e89d8 Remove GeditViewCentering
-5e0909c19 ViewFrame: disable overlay scrolling for the GtkScrolledWindow
-7c7296b0e Remove overview map: remove from preferences dialog
-26899e0ba Remove overview map
-27f54a9ae replace-open-button: remove OpenDocumentSelector
-504ced5a9 replace-open-button: Window: remove open document popover
-3a8c5bbc2 replace-open-button: remove open button UI
-abab6529f replace-open-button: re-create a simple Open button
-1ee984a41 replace-open-button: re-create simple Open Recent menu button (UI)
-f1a58a70b replace-open-button: set Open Recent menu with Amtk
-020e0b340 replace-open-button: re-handle the fullscreen mode
-4dfd2104e Window: remove dead code (#defines)
-0caf371b1 Window: make the code a little clearer wrt fullscreen mode
-584aeb202 Window: rename fullscreen_controls -> fullscreen_revealer
-75705bf1d Window: some code cleanup wrt fullscreen mode
-cf0d62617 Window: simplify setting the state of the fullscreen revealer
-8706e5624 Window: fullscreen mode: remove idle function
-6361b281c Window: fullscreen mode: remove no longer needed code
-8d3e6faf2 Window: fullscreen mode: fix headerbar shown/hidden "stuttering"
-a437e5245 Window: fullscreen mode: add comment about the "stuttering" fix
-d064c5f88 Window: remove useless #include
-15833e5c7 build: list of deps: simplify
-007caff57 build: list of deps: simplify version requirements
-72dc3a477 build: avoid the use of a variable
-4a49c8562 flatpak: update Amtk to 5.0.2
-9ab7b0f0a utils: remove GBOOLEAN_TO_POINTER() and GPOINTER_TO_BOOLEAN()
-55c5f1423 Utils: deprecate gedit_warning()
-cbdd3a85d PreferencesDialog: use tepl_utils_show_warning_dialog()
-7a442c766 Utils: deprecate decode_uri(), use the tepl one
-bf3d57003 Use tepl_utils_decode_uri()
-2e45bb03f io-error-info-bar: remove useless #include's
-092411115 io-error-info-bar: use TeplInfoBar for the file_already_open_warning
-8ccb4566f io-error-info-bar: file_already_open_warning moved to Tepl
-8bfe0559a io-error-info-bar: use TeplInfoBar for no_backup_saving_error
-ca582d2c7 io-error-info-bar: fix fixme in no_backup_saving_error
-fa1758081 io-error-info-bar: no_backup_saving_error: show also error->message
-321eccdd7 io-error-info-bar: no_back_saving_error moved to Tepl
-7bb880114 io-error-info-bar: tepl function renamed to have a shorter name
-d1a14a063 io-error-info-bar: externally_modified: use TeplInfoBar
-bf60cc1af io-error-info-bar: invalid_character: TeplInfoBar + other improvements
-44cff9798 io-error-info-bar: externally_modified: remove unneeded code
-873ed25f1 io-error-info-bar: externally_modified: further simplify the code
-a8a4724fc io-error-info-bar: externally_modified: moved to Tepl
-ec8d8c717 io-error-info-bar: invalid_character: moved to Tepl
-2aae17c31 flatpak: switch Tepl to Meson
-9caaddeda Window: fix RTL bug for Open buttons in the headerbar
-82d8c507d View: subclass TeplView
-e23569c59 View: deprecate lots of functions, use the TeplView ones
-291eb9c8e commands-edit: use TeplView functions
-00f8c5e63 Use tepl_view_scroll_to_cursor()
-5fdeaee22 Document: deprecate goto_line() and goto_line_offset()
-d87bf25ba commands-file: use tepl_view_goto_line*()
-fd5500d90 Tab: use tepl_view_goto_line_offset()
-3c8a1dcb8 ViewFrame: use tepl_view_goto_line*()
-079f9699e pkg-config file: add Tepl as public dep
-cf6281d04 docs: document that gedit is in the process of using more Tepl features
-9ac62a6fd build: require Tepl 5
-3f84484d8 App: port to new Tepl metadata API
-9b9fa6c77 Document: port to new Tepl metadata API
-491280c04 docs: roadmap: link to new Tepl roadmap
-49db2a666 PreferencesDialog: use TeplStyleSchemeChooserWidget to fix several bugs
-94c3b70cb PreferencesDialog: improvements to color scheme management
-53cfa1715 PreferencesDialog: fix some bugs when (un)installing color schemes
-da5b9af9f snap: the tepl build is meson only now
-012a07cb7 snap: use the correct option to specify parameters
-325aa857c Factory: class skeleton
-7b8579770 Factory: implement ::create_metadata_manager_file vfunc
-d5a43cece Factory: create it in main() and set it as the TeplAbstractFactory
-392545195 App: use tepl_application_handle_metadata()
-8b2fa9092 Keep default buttons orientation for TeplInfoBars
-efe48bbe8 flatpak: remove uchardet, Tepl no longer depends on it
-5e588d978 PreferencesDialog: improve code to install extra style scheme
-eada68d97 PreferencesDialog: use GtkFileChooserNative, not GeditFileChooserDialog
-55fc5973c FileChooserDialog: remove hide() (now dead code)
-4f5a5681b FileChooserDialog: remove add_pattern_filter() (now dead code)
-105ca1ded File choosers: remove GeditFileChooserFlags
-ff1e9c27c Update Romanian translation
-b4a52f479 Merge branch 'master' of gitlab.gnome.org:GNOME/gedit
-21d94f23b Remove all the deprecated API
-4b5838b1e docs: update path to Amtk docs for the gtk-doc fixxref_args
-a4cf3ac57 Use tepl_pango_font_description_to_css()
-205bfc855 Window: port to TeplLanguageChooserWidget
-ffedbc882 commands-view: port to TeplLanguageChooserDialog
-1dc325294 Remove GeditHighlightModeSelector and GeditHighlightModeDialog
-e487680b2 Use Tepl 6 (currently 5.99)
-ee465ef0c Tab: port to TeplProgressInfoBar
-bc992e11e Remove GeditProgressInfoBar, replaced by TeplProgressInfoBar
-fa9d6aeaa docs: document the GeditProgressInfoBar removal
-bb4ba5543 docs: document that all deprecated APIs have been removed
-325351805 GeditDocument: subclass TeplBuffer
-8b01acace GeditDocument: remove the ::cursor-moved signal
-b938c50f8 Use the TeplBuffer::tepl-cursor-moved signal
-6b6a6e595 GeditDocument: bind GtkSourceFile and TeplFile :location properties
-f73828fe1 GeditDocument: remove unused instance variable
-01d8a1577 flatpak: build amtk from git master, not from an archive
-6e78a57c9 GeditDocument: use tepl_file_get_short_name()
-49749c38a GeditDocument: remove untitled_number handling
-844f6185a Tab: use TeplFile:short-name property notification
-49c0c814a GeditDocument: remove the :shortname property
-a4670d7ce help: "Untitled Document" -> "Untitled File"
-4d4d5d48c Use tepl_buffer_is_untouched()
-b0f67d391 GeditDocument: remove is_untouched()
-85b007052 GeditDocument: use the TeplFile location in is_untitled()
-4df850fb6 View: use TeplSignalGroup
-ef0d0ca9b View: minor code changes
-284e6c05c View: make set_font() private
-6b1e782d9 View: code refactorings for set_font()
-ce790b510 View: use tepl_utils_override_font()
-79b3e3011 GeditSettings: remove no longer needed code
-da4b3e61a GeditSettings: minor code change: removed unused function param
-13033affa GeditSettings: rework fonts changes handling, add ::fonts-changed signal
-878ceb988 GeditSettings: minor code change, improve get_system_font()
-1e89921a3 GeditSettings: add get_selected_font()
-9ef4cf7ed View: simplify the code to update the font
-3a3de93bd debug: remove DEBUG_METADATA (dead code)
-43925dac7 recent: use the TeplFile
-2f7c4a691 recent: move some functions to gedit-recent-osx
-87b1f50d4 recent-osx: add TODO comment
-
-Brought to you by GitLens, which honesntly has been very useful
-unpicking all this and sticking it back together again
----
- NEWS | 12 +
- build-aux/flatpak/org.gnome.gedit.yml | 15 +-
- build-aux/snap/snapcraft.yaml | 27 +-
- data/org.gnome.gedit.gschema.xml.in | 5 +
- docs/gedit-development-getting-started.md | 8 +-
- docs/reference/api-breaks.xml | 50 +
- docs/reference/gedit-docs.xml | 1 +
- docs/reference/gedit-sections.txt | 36 +
- docs/reference/meson.build | 6 +-
- docs/roadmap-done.md | 56 -
- docs/roadmap.md | 19 +-
- gedit/Gedit-3.0.metadata | 1 +
- gedit/gedit-app-osx.m | 4 +-
- gedit/gedit-app-private.h | 3 +
- gedit/gedit-app.c | 54 +-
- gedit/gedit-commands-edit.c | 28 +-
- gedit/gedit-commands-file.c | 26 +-
- gedit/gedit-commands-search.c | 7 +-
- gedit/gedit-commands-view.c | 42 +-
- gedit/gedit-debug.c | 4 +
- gedit/gedit-debug.h | 2 +
- gedit/gedit-document-private.h | 12 +-
- gedit/gedit-document.c | 534 ++++++-
- gedit/gedit-document.h | 18 +-
- gedit/gedit-documents-panel.c | 3 +-
- gedit/gedit-factory.c | 50 -
- gedit/gedit-factory.h | 53 -
- gedit/gedit-file-chooser-dialog-gtk.c | 72 +-
- gedit/gedit-file-chooser-dialog-gtk.h | 9 +-
- gedit/gedit-file-chooser-dialog.c | 40 +-
- gedit/gedit-file-chooser-dialog.h | 17 +
- gedit/gedit-highlight-mode-dialog.c | 102 ++
- gedit/gedit-highlight-mode-dialog.h | 41 +
- gedit/gedit-highlight-mode-selector.c | 375 +++++
- gedit/gedit-highlight-mode-selector.h | 44 +
- gedit/gedit-io-error-info-bar.c | 362 ++++-
- gedit/gedit-io-error-info-bar.h | 10 +
- gedit/gedit-metadata-manager.c | 650 ++++++++
- gedit/gedit-metadata-manager.h | 49 +
- gedit/gedit-open-document-selector-helper.c | 103 ++
- gedit/gedit-open-document-selector-helper.h | 103 ++
- gedit/gedit-open-document-selector-store.c | 820 +++++++++++
- gedit/gedit-open-document-selector-store.h | 68 +
- gedit/gedit-open-document-selector.c | 1304 +++++++++++++++++
- gedit/gedit-open-document-selector.h | 44 +
- gedit/gedit-pango.c | 230 +++
- gedit/gedit-pango.h | 28 +
- gedit/gedit-preferences-dialog.c | 447 +++---
- gedit/gedit-print-job.c | 4 +-
- gedit/gedit-progress-info-bar.c | 177 +++
- gedit/gedit-progress-info-bar.h | 53 +
- gedit/gedit-recent-osx.c | 249 ----
- gedit/gedit-recent-osx.h | 54 -
- gedit/gedit-recent.c | 231 ++-
- gedit/gedit-recent.h | 23 +-
- gedit/gedit-settings.c | 177 ++-
- gedit/gedit-settings.h | 7 +-
- gedit/gedit-tab.c | 115 +-
- gedit/gedit-utils.c | 333 ++++-
- gedit/gedit-utils.h | 21 +-
- gedit/gedit-view-centering.c | 495 +++++++
- gedit/gedit-view-centering.h | 67 +
- gedit/gedit-view-frame.c | 37 +-
- gedit/gedit-view-frame.h | 4 +
- gedit/gedit-view.c | 322 +++-
- gedit/gedit-view.h | 24 +-
- gedit/gedit-window-private.h | 15 +-
- gedit/gedit-window.c | 380 ++---
- gedit/gedit.c | 8 +-
- gedit/meson.build | 23 +-
- gedit/resources/css/gedit-style.css | 12 +
- gedit/resources/css/gedit.adwaita.css | 25 +
- gedit/resources/gedit.gresource.xml.in | 4 +
- .../ui/gedit-highlight-mode-dialog.ui | 87 ++
- .../ui/gedit-highlight-mode-selector.ui | 83 ++
- .../ui/gedit-open-document-selector.ui | 115 ++
- .../resources/ui/gedit-preferences-dialog.ui | 30 +-
- gedit/resources/ui/gedit-progress-info-bar.ui | 88 ++
- gedit/resources/ui/gedit-view-frame.ui | 30 +-
- gedit/resources/ui/gedit-window.ui | 87 +-
- help/C/gedit-tab-groups.page | 4 +-
- meson.build | 34 +-
- meson_options.txt | 7 +
- plugins/snippets/snippets/document.py | 10 +-
- plugins/spell/gedit-spell-plugin.c | 9 +-
- po/POTFILES.in | 8 +-
- 86 files changed, 8160 insertions(+), 1286 deletions(-)
- delete mode 100644 docs/roadmap-done.md
- delete mode 100644 gedit/gedit-factory.c
- delete mode 100644 gedit/gedit-factory.h
- create mode 100644 gedit/gedit-highlight-mode-dialog.c
- create mode 100644 gedit/gedit-highlight-mode-dialog.h
- create mode 100644 gedit/gedit-highlight-mode-selector.c
- create mode 100644 gedit/gedit-highlight-mode-selector.h
- create mode 100644 gedit/gedit-metadata-manager.c
- create mode 100644 gedit/gedit-metadata-manager.h
- create mode 100644 gedit/gedit-open-document-selector-helper.c
- create mode 100644 gedit/gedit-open-document-selector-helper.h
- create mode 100644 gedit/gedit-open-document-selector-store.c
- create mode 100644 gedit/gedit-open-document-selector-store.h
- create mode 100644 gedit/gedit-open-document-selector.c
- create mode 100644 gedit/gedit-open-document-selector.h
- create mode 100644 gedit/gedit-pango.c
- create mode 100644 gedit/gedit-pango.h
- create mode 100644 gedit/gedit-progress-info-bar.c
- create mode 100644 gedit/gedit-progress-info-bar.h
- delete mode 100644 gedit/gedit-recent-osx.c
- delete mode 100644 gedit/gedit-recent-osx.h
- create mode 100644 gedit/gedit-view-centering.c
- create mode 100644 gedit/gedit-view-centering.h
- create mode 100644 gedit/resources/ui/gedit-highlight-mode-dialog.ui
- create mode 100644 gedit/resources/ui/gedit-highlight-mode-selector.ui
- create mode 100644 gedit/resources/ui/gedit-open-document-selector.ui
- create mode 100644 gedit/resources/ui/gedit-progress-info-bar.ui
-
-diff --git a/NEWS b/NEWS
-index d1f17abd1..fabc374cd 100644
---- a/NEWS
-+++ b/NEWS
-@@ -1,3 +1,15 @@
-+News in [unreleased]
-+----------------------------
-+* Deteplification:
-+ - The tepl maintainer has "frozen" the project until further notice
-+ - Moving things to tepl introduced some breakage, such as translation of the
-+ default filename
-+ - gedit didn't use much of the API anyway
-+ - Used even less of amtk
-+ - Revert all usage of amtk and tepl
-+ - Unfortunatly a couple bug fixes may have been lost
-+ - Plugin API is essentially reverted to 3.36
-+
- News in 40.1, 2021-04-17
- ------------------------
- * Use document folder when opening new files
-diff --git a/build-aux/flatpak/org.gnome.gedit.yml b/build-aux/flatpak/org.gnome.gedit.yml
-index 1438abd07..d3b535176 100644
---- a/build-aux/flatpak/org.gnome.gedit.yml
-+++ b/build-aux/flatpak/org.gnome.gedit.yml
-@@ -59,17 +59,12 @@ modules:
- url: https://download.gnome.org/sources/gspell/1.9/gspell-1.9.1.tar.xz
- sha256: dcbb769dfdde8e3c0a8ed3102ce7e661abbf7ddf85df08b29915e92cd723abdd
-
-- - name: amtk
-- buildsystem: meson
-+ - name: uchardet
-+ buildsystem: cmake-ninja
- sources:
-- - type: git
-- url: https://gitlab.gnome.org/GNOME/amtk.git
--
-- - name: tepl
-- buildsystem: meson
-- sources:
-- - type: git
-- url: https://gitlab.gnome.org/GNOME/tepl.git
-+ - type: archive
-+ url: https://www.freedesktop.org/software/uchardet/releases/uchardet-0.0.6.tar.xz
-+ sha256: 8351328cdfbcb2432e63938721dd781eb8c11ebc56e3a89d0f84576b96002c61
-
- - name: gedit
- buildsystem: meson
-diff --git a/build-aux/snap/snapcraft.yaml b/build-aux/snap/snapcraft.yaml
-index fc49c3949..43db5e027 100644
---- a/build-aux/snap/snapcraft.yaml
-+++ b/build-aux/snap/snapcraft.yaml
-@@ -41,30 +41,6 @@ apps:
- GTK_USE_PORTAL: 1
-
- parts:
-- amtk:
-- source: https://gitlab.gnome.org/GNOME/amtk.git
-- source-type: git
-- plugin: autotools
-- configflags:
-- - --prefix=/usr
-- - --enable-introspection=no
-- organize:
-- snap/gedit/current/usr: usr
--
-- tepl:
-- after: [amtk, gtksourceview]
-- source: https://gitlab.gnome.org/GNOME/tepl.git
-- source-type: git
-- plugin: meson
-- meson-parameters:
-- - --prefix=/usr
-- organize:
-- snap/gedit/current/usr: usr
-- build-packages:
-- - libuchardet-dev
-- stage-packages:
-- - libuchardet0
--
- gtksourceview:
- source: https://gitlab.gnome.org/GNOME/gtksourceview.git
- source-type: git
-@@ -94,7 +70,7 @@ parts:
- cp $SNAPCRAFT_PART_INSTALL/usr/share/vala/vapi/gtksource* /usr/share/vala/vapi
-
- gedit:
-- after: [gtksourceview, tepl]
-+ after: [gtksourceview]
- source: .
- source-type: git
- parse-info: [usr/share/metainfo/org.gnome.gedit.appdata.xml]
-@@ -102,6 +78,7 @@ parts:
- meson-parameters:
- - --prefix=/usr
- - -Dvala_args="--vapidir=$SNAPCRAFT_STAGE/usr/share/vala/vapi"
-+
- build-environment:
- - C_INCLUDE_PATH: $SNAPCRAFT_STAGE/usr/include/gtksourceview-4
- override-build: |
-diff --git a/data/org.gnome.gedit.gschema.xml.in b/data/org.gnome.gedit.gschema.xml.in
-index b797d843c..59325f4ef 100644
---- a/data/org.gnome.gedit.gschema.xml.in
-+++ b/data/org.gnome.gedit.gschema.xml.in
-@@ -126,6 +126,11 @@
- Right Margin Position
- Specifies the position of the right margin.
-
-+
-+ false
-+ Display Overview Map
-+ Whether gedit should display the overview map for the document.
-+
-
- 'none'
- Document background pattern type
-diff --git a/docs/gedit-development-getting-started.md b/docs/gedit-development-getting-started.md
-index 4f930afc7..774bc180f 100644
---- a/docs/gedit-development-getting-started.md
-+++ b/docs/gedit-development-getting-started.md
-@@ -31,11 +31,9 @@ editor. To learn that widget API, read the excellent
- mostly valid). But GtkTextView is not enough for source code edition. gedit
- actually uses the
- [GtkSourceView](https://wiki.gnome.org/Projects/GtkSourceView) library, which
--contains a subclass of GtkTextView with many features useful for a text editor
--or an IDE. But GtkSourceView is not enough to have a full-blown text editor,
--gedit is actually in the process of using more features from the
--[Tepl](https://wiki.gnome.org/Projects/Tepl) library, and to further develop
--Tepl alongside gedit.
-+contains a subclass of GtkTextView with syntax highlighting, a completion
-+framework, the search and replace, and many other features useful for a text
-+editor or an IDE.
-
- For its plugin system, gedit uses the
- [libpeas](https://wiki.gnome.org/Projects/Libpeas) library.
-diff --git a/docs/reference/api-breaks.xml b/docs/reference/api-breaks.xml
-index f631761a6..f03c35975 100644
---- a/docs/reference/api-breaks.xml
-+++ b/docs/reference/api-breaks.xml
-@@ -21,6 +21,56 @@
- index of deprecated symbols.
-
-
-+
-+ 40 -> 41
-+
-+
-+
-+ The GeditProgressInfoBar class has been restored
-+
-+
-+
-+
-+ GeditDocument is no longer a subclass
-+ of TeplBuffer.
-+
-+
-+
-+
-+ The GeditDocument::cursor-moved signal has been restored.
-+
-+
-+
-+
-+ The GeditDocument:shortname property has been restored.
-+
-+
-+
-+
-+ The gedit_document_is_untouched() function has been
-+ restored.
-+
-+
-+
-+
-+ The gedit_view_set_font() function has been restored.
-+
-+
-+
-+
-+ DEBUG_METADATA has been restored.
-+
-+
-+
-+
-+ The GBOOLEAN_TO_POINTER() and
-+ GPOINTER_TO_BOOLEAN() macros have been restored to
-+ gedit-utils.h.
-+
-+
-+
-+
-+
-
- 3.38 -> 40
-
-diff --git a/docs/reference/gedit-docs.xml b/docs/reference/gedit-docs.xml
-index a0dc624cf..9e32e5469 100644
---- a/docs/reference/gedit-docs.xml
-+++ b/docs/reference/gedit-docs.xml
-@@ -16,6 +16,7 @@
-
-
-
-+
-
-
-
-diff --git a/docs/reference/gedit-sections.txt b/docs/reference/gedit-sections.txt
-index cec055fce..a71e00faa 100644
---- a/docs/reference/gedit-sections.txt
-+++ b/docs/reference/gedit-sections.txt
-@@ -54,7 +54,10 @@ gedit_document_new
- gedit_document_get_file
- gedit_document_get_short_name_for_display
- gedit_document_get_mime_type
-+gedit_document_is_untouched
- gedit_document_is_untitled
-+gedit_document_goto_line
-+gedit_document_goto_line_offset
- gedit_document_set_language
- gedit_document_get_content_type
- gedit_document_get_metadata
-@@ -148,6 +151,26 @@ GEDIT_MESSAGE_GET_CLASS
- GeditMessagePrivate
-
-
-+
-+gedit-progress-info-bar
-+GeditProgressInfoBar
-+GeditProgressInfoBar
-+gedit_progress_info_bar_new
-+gedit_progress_info_bar_set_icon_name
-+gedit_progress_info_bar_set_markup
-+gedit_progress_info_bar_set_text
-+gedit_progress_info_bar_set_fraction
-+gedit_progress_info_bar_pulse
-+
-+GEDIT_PROGRESS_INFO_BAR
-+GEDIT_IS_PROGRESS_INFO_BAR
-+GEDIT_TYPE_PROGRESS_INFO_BAR
-+gedit_progress_info_bar_get_type
-+GEDIT_PROGRESS_INFO_BAR_CLASS
-+GEDIT_IS_PROGRESS_INFO_BAR_CLASS
-+GEDIT_PROGRESS_INFO_BAR_GET_CLASS
-+
-+
-
- gedit-statusbar
- GeditStatusbar
-@@ -199,6 +222,13 @@ GeditViewPrivate
- GeditView
- GeditView
- gedit_view_new
-+gedit_view_cut_clipboard
-+gedit_view_copy_clipboard
-+gedit_view_paste_clipboard
-+gedit_view_delete_selection
-+gedit_view_select_all
-+gedit_view_scroll_to_cursor
-+gedit_view_set_font
-
- GEDIT_VIEW
- GEDIT_IS_VIEW
-@@ -291,6 +321,7 @@ DEBUG_DOCUMENT
- DEBUG_COMMANDS
- DEBUG_APP
- DEBUG_UTILS
-+DEBUG_METADATA
- gedit_debug_init
- gedit_debug
- gedit_debug_message
-@@ -321,9 +352,14 @@ gedit_menu_extension_get_type
-
-
- gedit-utils
-+GBOOLEAN_TO_POINTER
-+GPOINTER_TO_BOOLEAN
- gedit_utils_menu_position_under_tree_view
- gedit_utils_set_atk_name_description
-+gedit_warning
-+gedit_utils_replace_home_dir_with_tilde
- gedit_utils_basename_for_display
-+gedit_utils_decode_uri
- gedit_utils_drop_get_uris
- gedit_utils_get_compression_type_from_content_type
- gedit_utils_is_valid_location
-diff --git a/docs/reference/meson.build b/docs/reference/meson.build
-index 9a9c414dc..ed85f9cec 100644
---- a/docs/reference/meson.build
-+++ b/docs/reference/meson.build
-@@ -6,14 +6,12 @@ gio_docpath = dependency('gio-2.0').get_pkgconfig_variable('prefix') / 'share/gt
- gdk_docpath = dependency('gdk-3.0').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/gdk3'
- gtk_docpath = dependency('gtk+-3.0').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/gtk3'
- gsv_docpath = dependency('gtksourceview-4').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/gtksourceview-4.0'
--amtk_docpath = dependency('amtk-5').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/amtk-5'
--tepl_docpath = dependency('tepl-6').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/tepl-6'
- libpeas_docpath = dependency('libpeas-1.0').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/libpeas'
-
- gedit_doc_dep = declare_dependency(
- link_with: libgedit_shared_lib,
- include_directories: root_include_dir,
-- dependencies: deps_basic_list,
-+ dependencies: deps_basic_list + [libxml_dep],
- )
-
- gnome.gtkdoc(
-@@ -30,8 +28,6 @@ gnome.gtkdoc(
- '--extra-dir=@0@'.format(gdk_docpath),
- '--extra-dir=@0@'.format(gtk_docpath),
- '--extra-dir=@0@'.format(gsv_docpath),
-- '--extra-dir=@0@'.format(amtk_docpath),
-- '--extra-dir=@0@'.format(tepl_docpath),
- '--extra-dir=@0@'.format(libpeas_docpath),
- ],
- content_files: [
-diff --git a/docs/roadmap-done.md b/docs/roadmap-done.md
-deleted file mode 100644
-index 7f210e49b..000000000
---- a/docs/roadmap-done.md
-+++ /dev/null
-@@ -1,56 +0,0 @@
--gedit roadmap - done tasks
--==========================
--
--Tepl-ification of the gedit core
----------------------------------
--
--- gedit 3.36:
-- - Start to use the Tepl library.
-- - Use some Tepl utility functions.
-- - Use TeplFileMetadata, remove GeditMetadataManager.
--- gedit 3.38:
-- - Move some utility functions to the Tepl library.
-- - Refactor and move some I/O error infobars to Tepl.
-- - GeditView now inherits from TeplView.
-- - Port to the new Tepl metadata API.
-- - Use TeplStyleSchemeChooserWidget in the preferences dialog.
-- - Create GeditFactory class, subclass of TeplAbstractFactory.
--- gedit 40:
-- - Use `tepl_pango_font_description_to_css()`.
-- - Use TeplLanguageChooser's, for choosing a language for the syntax
-- highlighting. Remove GeditHighlightModeSelector and
-- GeditHighlightModeDialog.
-- - Use TeplProgressInfoBar. Remove GeditProgressInfoBar.
-- - GeditDocument now inherits from TeplBuffer, start to use the
-- TeplBuffer and TeplFile APIs.
--
--Links:
--- https://wiki.gnome.org/Projects/Tepl
--
--Tepl-ification of the gedit plugins
-------------------------------------
--
--- gedit 40:
-- - Draw Spaces plugin: new implementation based on TeplSpaceDrawerPrefs.
--
--Other done tasks in gedit plugins
-----------------------------------
--
--- gedit 40:
-- - Smart Spaces plugin: new implementation based on a GtkSourceView
-- feature.
--
--New version of gedit on Windows
---------------------------------
--
--[gedit is now available on the Microsoft Store](https://www.microsoft.com/store/apps/9PL1J21XF0PT).
--It was done during the GNOME 3.38 development cycle. The integration with
--Windows is not perfect, but it works. It is planned to improve gedit for
--Windows over time.
--
--Documentation for contributors
--------------------------------
--
--Write a guide to get started with gedit development.
--
--Done during the GNOME 3.34 development cycle.
-diff --git a/docs/roadmap.md b/docs/roadmap.md
-index 44a2f00b7..ec9445712 100644
---- a/docs/roadmap.md
-+++ b/docs/roadmap.md
-@@ -4,27 +4,10 @@ gedit roadmap
- This page contains the plans for major code changes we hope to get done in the
- future.
-
--See the [roadmap-done.md](roadmap-done.md) file for done tasks.
-+See also the [GtkSourceView](https://wiki.gnome.org/Projects/GtkSourceView/RoadMap).
-
- See the [NEWS file](../NEWS) for a detailed history.
-
--See also the
--[Tepl roadmap](https://gitlab.gnome.org/GNOME/tepl/blob/master/docs/roadmap.md).
--
--Continue to make the gedit source code more re-usable
-------------------------------------------------------
--
--Status: **in progress** (this is an ongoing effort)
--
--Next steps:
--- Use more features from the Tepl library, and develop Tepl alongside gedit.
-- The goal is to reduce the amount of code in gedit, by having re-usable code
-- in Tepl instead.
--
--Links:
--- https://wiki.gnome.org/Apps/Gedit/ReusableCode
--- https://wiki.gnome.org/Projects/Tepl
--
- Improve gedit on Windows
- ------------------------
-
-diff --git a/gedit/Gedit-3.0.metadata b/gedit/Gedit-3.0.metadata
-index e36d7cb30..1a5b45a3a 100644
---- a/gedit/Gedit-3.0.metadata
-+++ b/gedit/Gedit-3.0.metadata
-@@ -6,6 +6,7 @@ EncodingsComboBox cheader_filename="gedit/gedit-encodings-combo-box.h"
- MenuExtension cheader_filename="gedit/gedit-menu-extension.h"
- Message cheader_filename="gedit/gedit-message.h"
- MessageBus cheader_filename="gedit/gedit-message-bus.h"
-+ProgressInfoBar cheader_filename="gedit/gedit-progress-info-bar.h"
- Statusbar cheader_filename="gedit/gedit-statusbar.h"
- Tab cheader_filename="gedit/gedit-tab.h"
- TabState cheader_filename="gedit/gedit-tab.h"
-diff --git a/gedit/gedit-app-osx.m b/gedit/gedit-app-osx.m
-index b02e9a28b..5df1b94da 100644
---- a/gedit/gedit-app-osx.m
-+++ b/gedit/gedit-app-osx.m
-@@ -31,7 +31,7 @@
- #include "gedit-debug.h"
- #include "gedit-commands.h"
- #include "gedit-commands-private.h"
--#include "gedit-recent-osx.h"
-+#include "gedit-recent.h"
- #import
-
- NSWindow *gdk_quartz_window_get_nswindow(GdkWindow *window);
-@@ -286,7 +286,7 @@ gedit_app_osx_set_window_title_impl (GeditApp *app,
- g_free (uri);
- }
-
-- ismodified = !tepl_buffer_is_untouched (TEPL_BUFFER (document));
-+ ismodified = !gedit_document_is_untouched (document);
- [native setDocumentEdited:ismodified];
- }
- else
-diff --git a/gedit/gedit-app-private.h b/gedit/gedit-app-private.h
-index 6e1278a3b..e9c58cc27 100644
---- a/gedit/gedit-app-private.h
-+++ b/gedit/gedit-app-private.h
-@@ -22,6 +22,7 @@
- #define GEDIT_APP_PRIVATE_H
-
- #include "gedit-app.h"
-+#include "gedit-metadata-manager.h"
- #include "gedit-menu-extension.h"
-
- G_BEGIN_DECLS
-@@ -34,6 +35,8 @@ GtkPrintSettings *_gedit_app_get_default_print_settings (GeditApp *app);
- void _gedit_app_set_default_print_settings (GeditApp *app,
- GtkPrintSettings *settings);
-
-+GeditMetadataManager *_gedit_app_get_metadata_manager (GeditApp *app);
-+
- GMenuModel *_gedit_app_get_hamburger_menu (GeditApp *app);
-
- GMenuModel *_gedit_app_get_notebook_menu (GeditApp *app);
-diff --git a/gedit/gedit-app.c b/gedit/gedit-app.c
-index 5532d5975..27d71a87a 100644
---- a/gedit/gedit-app.c
-+++ b/gedit/gedit-app.c
-@@ -28,8 +28,9 @@
- #include
-
- #include
-+#include
- #include
--#include
-+#include
-
- #include "gedit-commands-private.h"
- #include "gedit-notebook.h"
-@@ -44,6 +45,10 @@
- #include "gedit-preferences-dialog.h"
- #include "gedit-tab.h"
-
-+#ifndef ENABLE_GVFS_METADATA
-+#include "gedit-metadata-manager.h"
-+#endif
-+
- #define GEDIT_PAGE_SETUP_FILE "gedit-page-setup"
- #define GEDIT_PRINT_SETTINGS_FILE "gedit-print-settings"
-
-@@ -51,6 +56,10 @@ typedef struct
- {
- GeditPluginsEngine *engine;
-
-+#ifndef ENABLE_GVFS_METADATA
-+ GeditMetadataManager *metadata_manager;
-+#endif
-+
- GtkCssProvider *theme_provider;
-
- GtkPageSetup *page_setup;
-@@ -145,6 +154,10 @@ gedit_app_dispose (GObject *object)
-
- priv = gedit_app_get_instance_private (GEDIT_APP (object));
-
-+#ifndef ENABLE_GVFS_METADATA
-+ g_clear_object (&priv->metadata_manager);
-+#endif
-+
- g_clear_object (&priv->ui_settings);
- g_clear_object (&priv->window_settings);
-
-@@ -643,6 +656,10 @@ gedit_app_startup (GApplication *application)
- GeditAppPrivate *priv;
- GtkCssProvider *css_provider;
- GtkSourceStyleSchemeManager *manager;
-+#ifndef ENABLE_GVFS_METADATA
-+ const gchar *cache_dir;
-+ gchar *metadata_filename;
-+#endif
-
- priv = gedit_app_get_instance_private (GEDIT_APP (application));
-
-@@ -654,6 +671,13 @@ gedit_app_startup (GApplication *application)
-
- setup_theme_extensions (GEDIT_APP (application));
-
-+#ifndef ENABLE_GVFS_METADATA
-+ cache_dir = gedit_dirs_get_user_cache_dir ();
-+ metadata_filename = g_build_filename (cache_dir, "gedit-metadata.xml", NULL);
-+ priv->metadata_manager = gedit_metadata_manager_new (metadata_filename);
-+ g_free (metadata_filename);
-+#endif
-+
- /* Load/init settings */
- _gedit_settings_get_singleton ();
- priv->ui_settings = g_settings_new ("org.gnome.gedit.preferences.ui");
-@@ -1114,6 +1138,10 @@ gedit_app_shutdown (GApplication *app)
- save_page_setup (GEDIT_APP (app));
- save_print_settings (GEDIT_APP (app));
-
-+ /* GTK+ can still hold references to some gedit objects, for example
-+ * GeditDocument for the clipboard. So the metadata-manager should be
-+ * shutdown after.
-+ */
- G_APPLICATION_CLASS (gedit_app_parent_class)->shutdown (app);
- }
-
-@@ -1253,15 +1281,10 @@ load_print_settings (GeditApp *app)
- static void
- gedit_app_init (GeditApp *app)
- {
-- TeplApplication *tepl_app;
--
- g_set_application_name ("gedit");
- gtk_window_set_default_icon_name ("org.gnome.gedit");
-
- g_application_add_main_option_entries (G_APPLICATION (app), options);
--
-- tepl_app = tepl_application_get_from_gtk_application (GTK_APPLICATION (app));
-- tepl_application_handle_metadata (tepl_app);
- }
-
- /**
-@@ -1571,6 +1594,25 @@ _gedit_app_set_default_print_settings (GeditApp *app,
- priv->print_settings = g_object_ref (settings);
- }
-
-+
-+GeditMetadataManager *
-+_gedit_app_get_metadata_manager (GeditApp *app)
-+{
-+#ifndef ENABLE_GVFS_METADATA
-+ GeditAppPrivate *priv;
-+
-+ g_return_val_if_fail (GEDIT_IS_APP (app), NULL);
-+
-+ priv = gedit_app_get_instance_private (app);
-+
-+ return priv->metadata_manager;
-+#else
-+ g_assert_not_reached ();
-+ return NULL;
-+#endif
-+}
-+
-+
- GMenuModel *
- _gedit_app_get_hamburger_menu (GeditApp *app)
- {
-diff --git a/gedit/gedit-commands-edit.c b/gedit/gedit-commands-edit.c
-index 66ea0174b..978440150 100644
---- a/gedit/gedit-commands-edit.c
-+++ b/gedit/gedit-commands-edit.c
-@@ -44,13 +44,13 @@ _gedit_cmd_edit_undo (GSimpleAction *action,
- gedit_debug (DEBUG_COMMANDS);
-
- active_view = gedit_window_get_active_view (window);
-- g_return_if_fail (active_view != NULL);
-+ g_return_if_fail (active_view);
-
- active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
-
- gtk_source_buffer_undo (active_document);
-
-- tepl_view_scroll_to_cursor (TEPL_VIEW (active_view));
-+ gedit_view_scroll_to_cursor (active_view);
-
- gtk_widget_grab_focus (GTK_WIDGET (active_view));
- }
-@@ -67,13 +67,13 @@ _gedit_cmd_edit_redo (GSimpleAction *action,
- gedit_debug (DEBUG_COMMANDS);
-
- active_view = gedit_window_get_active_view (window);
-- g_return_if_fail (active_view != NULL);
-+ g_return_if_fail (active_view);
-
- active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
-
- gtk_source_buffer_redo (active_document);
-
-- tepl_view_scroll_to_cursor (TEPL_VIEW (active_view));
-+ gedit_view_scroll_to_cursor (active_view);
-
- gtk_widget_grab_focus (GTK_WIDGET (active_view));
- }
-@@ -89,9 +89,9 @@ _gedit_cmd_edit_cut (GSimpleAction *action,
- gedit_debug (DEBUG_COMMANDS);
-
- active_view = gedit_window_get_active_view (window);
-- g_return_if_fail (active_view != NULL);
-+ g_return_if_fail (active_view);
-
-- tepl_view_cut_clipboard (TEPL_VIEW (active_view));
-+ gedit_view_cut_clipboard (active_view);
-
- gtk_widget_grab_focus (GTK_WIDGET (active_view));
- }
-@@ -107,9 +107,9 @@ _gedit_cmd_edit_copy (GSimpleAction *action,
- gedit_debug (DEBUG_COMMANDS);
-
- active_view = gedit_window_get_active_view (window);
-- g_return_if_fail (active_view != NULL);
-+ g_return_if_fail (active_view);
-
-- tepl_view_copy_clipboard (TEPL_VIEW (active_view));
-+ gedit_view_copy_clipboard (active_view);
-
- gtk_widget_grab_focus (GTK_WIDGET (active_view));
- }
-@@ -125,9 +125,9 @@ _gedit_cmd_edit_paste (GSimpleAction *action,
- gedit_debug (DEBUG_COMMANDS);
-
- active_view = gedit_window_get_active_view (window);
-- g_return_if_fail (active_view != NULL);
-+ g_return_if_fail (active_view);
-
-- tepl_view_paste_clipboard (TEPL_VIEW (active_view));
-+ gedit_view_paste_clipboard (active_view);
-
- gtk_widget_grab_focus (GTK_WIDGET (active_view));
- }
-@@ -143,9 +143,9 @@ _gedit_cmd_edit_delete (GSimpleAction *action,
- gedit_debug (DEBUG_COMMANDS);
-
- active_view = gedit_window_get_active_view (window);
-- g_return_if_fail (active_view != NULL);
-+ g_return_if_fail (active_view);
-
-- tepl_view_delete_selection (TEPL_VIEW (active_view));
-+ gedit_view_delete_selection (active_view);
-
- gtk_widget_grab_focus (GTK_WIDGET (active_view));
- }
-@@ -161,9 +161,9 @@ _gedit_cmd_edit_select_all (GSimpleAction *action,
- gedit_debug (DEBUG_COMMANDS);
-
- active_view = gedit_window_get_active_view (window);
-- g_return_if_fail (active_view != NULL);
-+ g_return_if_fail (active_view);
-
-- tepl_view_select_all (TEPL_VIEW (active_view));
-+ gedit_view_select_all (active_view);
-
- gtk_widget_grab_focus (GTK_WIDGET (active_view));
- }
-diff --git a/gedit/gedit-commands-file.c b/gedit/gedit-commands-file.c
-index 91798b95f..001899b0c 100644
---- a/gedit/gedit-commands-file.c
-+++ b/gedit/gedit-commands-file.c
-@@ -27,7 +27,6 @@
- #include "gedit-commands-private.h"
-
- #include
--#include
-
- #include "gedit-app.h"
- #include "gedit-debug.h"
-@@ -44,10 +43,6 @@
- #include "gedit-file-chooser-open.h"
- #include "gedit-close-confirmation-dialog.h"
-
--/* useful macro */
--#define GBOOLEAN_TO_POINTER(i) (GINT_TO_POINTER ((i) ? 2 : 1))
--#define GPOINTER_TO_BOOLEAN(i) ((gboolean) ((GPOINTER_TO_INT(i) == 2) ? TRUE : FALSE))
--
- #define GEDIT_IS_CLOSING_ALL "gedit-is-closing-all"
- #define GEDIT_NOTEBOOK_TO_CLOSE "gedit-notebook-to-close"
- #define GEDIT_IS_QUITTING "gedit-is-quitting"
-@@ -150,24 +145,26 @@ load_file_list (GeditWindow *window,
- {
- if (l == files)
- {
-- TeplView *view;
-+ GeditDocument *doc;
-
- gedit_window_set_active_tab (window, tab);
- jump_to = FALSE;
-- view = TEPL_VIEW (gedit_tab_get_view (tab));
-+ doc = gedit_tab_get_document (tab);
-
- if (line_pos > 0)
- {
- if (column_pos > 0)
- {
-- tepl_view_goto_line_offset (view,
-- line_pos - 1,
-- column_pos - 1);
-+ gedit_document_goto_line_offset (doc,
-+ line_pos - 1,
-+ column_pos - 1);
- }
- else
- {
-- tepl_view_goto_line (view, line_pos - 1);
-+ gedit_document_goto_line (doc, line_pos - 1);
- }
-+
-+ gedit_view_scroll_to_cursor (gedit_tab_get_view (tab));
- }
- }
-
-@@ -194,7 +191,7 @@ load_file_list (GeditWindow *window,
-
- doc = gedit_tab_get_document (tab);
-
-- if (tepl_buffer_is_untouched (TEPL_BUFFER (doc)) &&
-+ if (gedit_document_is_untouched (doc) &&
- gedit_tab_get_state (tab) == GEDIT_TAB_STATE_NORMAL)
- {
- _gedit_tab_load (tab,
-@@ -513,7 +510,7 @@ replace_read_only_file (GtkWindow *parent,
- * though the dialog uses wrapped text, if the name doesn't contain
- * white space then the text-wrapping code is too stupid to wrap it.
- */
-- name_for_display = tepl_utils_str_middle_truncate (parse_name, 50);
-+ name_for_display = gedit_utils_str_middle_truncate (parse_name, 50);
- g_free (parse_name);
-
- dialog = gtk_message_dialog_new (parent,
-@@ -565,7 +562,7 @@ change_compression (GtkWindow *parent,
- * though the dialog uses wrapped text, if the name doesn't contain
- * white space then the text-wrapping code is too stupid to wrap it.
- */
-- name_for_display = tepl_utils_str_middle_truncate (parse_name, 50);
-+ name_for_display = gedit_utils_str_middle_truncate (parse_name, 50);
- g_free (parse_name);
-
- if (compressed)
-@@ -827,6 +824,7 @@ save_as_tab_async (GeditTab *tab,
- /* Translators: "Save As" is the title of the file chooser window. */
- save_dialog = gedit_file_chooser_dialog_create (C_("window title", "Save As"),
- GTK_WINDOW (window),
-+ GEDIT_FILE_CHOOSER_FLAG_SAVE,
- _("_Save"),
- _("_Cancel"));
-
-diff --git a/gedit/gedit-commands-search.c b/gedit/gedit-commands-search.c
-index 22703985e..f120b8bad 100644
---- a/gedit/gedit-commands-search.c
-+++ b/gedit/gedit-commands-search.c
-@@ -29,7 +29,6 @@
- #include
- #include
- #include
--#include
-
- #include "gedit-debug.h"
- #include "gedit-statusbar.h"
-@@ -132,7 +131,7 @@ text_not_found (GeditWindow *window,
- gchar *truncated_text;
-
- search_text = gedit_replace_dialog_get_search_text (replace_dialog);
-- truncated_text = tepl_utils_str_end_truncate (search_text, MAX_MSG_LENGTH);
-+ truncated_text = gedit_utils_str_end_truncate (search_text, MAX_MSG_LENGTH);
-
- gedit_statusbar_flash_message (GEDIT_STATUSBAR (window->priv->statusbar),
- window->priv->generic_message_cid,
-@@ -188,7 +187,7 @@ forward_search_finished (GtkSourceSearchContext *search_context,
- &match_start,
- &match_end);
-
-- tepl_view_scroll_to_cursor (TEPL_VIEW (view));
-+ gedit_view_scroll_to_cursor (view);
- }
- else
- {
-@@ -294,7 +293,7 @@ backward_search_finished (GtkSourceSearchContext *search_context,
- &match_start,
- &match_end);
-
-- tepl_view_scroll_to_cursor (TEPL_VIEW (view));
-+ gedit_view_scroll_to_cursor (view);
- }
- else
- {
-diff --git a/gedit/gedit-commands-view.c b/gedit/gedit-commands-view.c
-index 71785b78f..369bc93b0 100644
---- a/gedit/gedit-commands-view.c
-+++ b/gedit/gedit-commands-view.c
-@@ -21,11 +21,16 @@
- */
-
- #include "config.h"
-+
- #include "gedit-commands.h"
- #include "gedit-commands-private.h"
--#include
-+
-+#include
-+
- #include "gedit-debug.h"
- #include "gedit-window.h"
-+#include "gedit-highlight-mode-dialog.h"
-+#include "gedit-highlight-mode-selector.h"
-
- void
- _gedit_cmd_view_focus_active (GSimpleAction *action,
-@@ -121,9 +126,9 @@ _gedit_cmd_view_leave_fullscreen_mode (GSimpleAction *action,
- }
-
- static void
--language_activated_cb (TeplLanguageChooserDialog *dialog,
-- GtkSourceLanguage *language,
-- GeditWindow *window)
-+language_selected_cb (GeditHighlightModeSelector *selector,
-+ GtkSourceLanguage *language,
-+ GeditWindow *window)
- {
- GeditDocument *active_document;
-
-@@ -132,16 +137,6 @@ language_activated_cb (TeplLanguageChooserDialog *dialog,
- {
- gedit_document_set_language (active_document, language);
- }
--
-- gtk_widget_destroy (GTK_WIDGET (dialog));
--}
--
--static void
--language_chooser_dialog_response_after_cb (TeplLanguageChooserDialog *dialog,
-- gint response_id,
-- gpointer user_data)
--{
-- gtk_widget_destroy (GTK_WIDGET (dialog));
- }
-
- void
-@@ -150,10 +145,12 @@ _gedit_cmd_view_highlight_mode (GSimpleAction *action,
- gpointer user_data)
- {
- GeditWindow *window = GEDIT_WINDOW (user_data);
-- TeplLanguageChooserDialog *dialog;
-+ GeditHighlightModeDialog *dialog;
-+ GeditHighlightModeSelector *selector;
- GeditDocument *active_document;
-
-- dialog = tepl_language_chooser_dialog_new (GTK_WINDOW (window));
-+ dialog = GEDIT_HIGHLIGHT_MODE_DIALOG (gedit_highlight_mode_dialog_new (GTK_WINDOW (window)));
-+ selector = gedit_highlight_mode_dialog_get_selector (dialog);
-
- active_document = gedit_window_get_active_document (window);
- if (active_document != NULL)
-@@ -161,20 +158,15 @@ _gedit_cmd_view_highlight_mode (GSimpleAction *action,
- GtkSourceLanguage *language;
-
- language = gedit_document_get_language (active_document);
-- tepl_language_chooser_select_language (TEPL_LANGUAGE_CHOOSER (dialog), language);
-+ gedit_highlight_mode_selector_select_language (selector, language);
- }
-
-- g_signal_connect_object (dialog,
-- "language-activated",
-- G_CALLBACK (language_activated_cb),
-+ g_signal_connect_object (selector,
-+ "language-selected",
-+ G_CALLBACK (language_selected_cb),
- window,
- 0);
-
-- g_signal_connect_after (dialog,
-- "response",
-- G_CALLBACK (language_chooser_dialog_response_after_cb),
-- NULL);
--
- gtk_widget_show (GTK_WIDGET (dialog));
- }
-
-diff --git a/gedit/gedit-debug.c b/gedit/gedit-debug.c
-index 5aa82fa51..396dc140f 100644
---- a/gedit/gedit-debug.c
-+++ b/gedit/gedit-debug.c
-@@ -100,6 +100,10 @@ gedit_debug_init (void)
- {
- enabled_sections |= GEDIT_DEBUG_UTILS;
- }
-+ if (g_getenv ("GEDIT_DEBUG_METADATA") != NULL)
-+ {
-+ enabled_sections |= GEDIT_DEBUG_METADATA;
-+ }
-
- out:
-
-diff --git a/gedit/gedit-debug.h b/gedit/gedit-debug.h
-index a9d7caf37..49e5127e1 100644
---- a/gedit/gedit-debug.h
-+++ b/gedit/gedit-debug.h
-@@ -48,6 +48,7 @@ typedef enum {
- GEDIT_DEBUG_COMMANDS = 1 << 7,
- GEDIT_DEBUG_APP = 1 << 8,
- GEDIT_DEBUG_UTILS = 1 << 9,
-+ GEDIT_DEBUG_METADATA = 1 << 10,
- } GeditDebugSection;
-
- #define DEBUG_VIEW GEDIT_DEBUG_VIEW, __FILE__, __LINE__, G_STRFUNC
-@@ -60,6 +61,7 @@ typedef enum {
- #define DEBUG_COMMANDS GEDIT_DEBUG_COMMANDS,__FILE__, __LINE__, G_STRFUNC
- #define DEBUG_APP GEDIT_DEBUG_APP, __FILE__, __LINE__, G_STRFUNC
- #define DEBUG_UTILS GEDIT_DEBUG_UTILS, __FILE__, __LINE__, G_STRFUNC
-+#define DEBUG_METADATA GEDIT_DEBUG_METADATA,__FILE__, __LINE__, G_STRFUNC
-
- void gedit_debug_init (void);
-
-diff --git a/gedit/gedit-document-private.h b/gedit/gedit-document-private.h
-index 62444cc76..574c0bb89 100644
---- a/gedit/gedit-document-private.h
-+++ b/gedit/gedit-document-private.h
-@@ -28,9 +28,15 @@
-
- G_BEGIN_DECLS
-
--#define GEDIT_METADATA_ATTRIBUTE_POSITION "gedit-position"
--#define GEDIT_METADATA_ATTRIBUTE_ENCODING "gedit-encoding"
--#define GEDIT_METADATA_ATTRIBUTE_LANGUAGE "gedit-language"
-+#ifdef G_OS_WIN32
-+#define GEDIT_METADATA_ATTRIBUTE_POSITION "position"
-+#define GEDIT_METADATA_ATTRIBUTE_ENCODING "encoding"
-+#define GEDIT_METADATA_ATTRIBUTE_LANGUAGE "language"
-+#else
-+#define GEDIT_METADATA_ATTRIBUTE_POSITION "metadata::gedit-position"
-+#define GEDIT_METADATA_ATTRIBUTE_ENCODING "metadata::gedit-encoding"
-+#define GEDIT_METADATA_ATTRIBUTE_LANGUAGE "metadata::gedit-language"
-+#endif
-
- G_GNUC_INTERNAL
- glong _gedit_document_get_seconds_since_last_save_or_load (GeditDocument *doc);
-diff --git a/gedit/gedit-document.c b/gedit/gedit-document.c
-index 54c11a96c..4cb08ee03 100644
---- a/gedit/gedit-document.c
-+++ b/gedit/gedit-document.c
-@@ -5,7 +5,7 @@
- * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
- * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
- * Copyright (C) 2002-2005 Paolo Maggi
-- * Copyright (C) 2014-2020 Sébastien Wilmet
-+ * Copyright (C) 2014-2015 Sébastien Wilmet
- *
- * 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
-@@ -22,13 +22,21 @@
- */
-
- #include "config.h"
-+
- #include "gedit-document.h"
- #include "gedit-document-private.h"
-+
- #include
- #include
-+
-+#include "gedit-app.h"
-+#include "gedit-app-private.h"
- #include "gedit-settings.h"
- #include "gedit-debug.h"
- #include "gedit-utils.h"
-+#include "gedit-metadata-manager.h"
-+
-+#define METADATA_QUERY "metadata::*"
-
- #define NO_LANGUAGE_NAME "_NORMAL_"
-
-@@ -43,7 +51,11 @@ typedef struct
- {
- GtkSourceFile *file;
-
-- TeplMetadata *metadata;
-+ GSettings *editor_settings;
-+
-+ gint untitled_number;
-+
-+ GFileInfo *metadata_info;
-
- gchar *content_type;
-
-@@ -54,7 +66,12 @@ typedef struct
- */
- GtkSourceSearchContext *search_context;
-
-+ GeditMetadataManager *metadata_manager;
-+
-+ guint user_action;
-+
- guint language_set_by_user : 1;
-+ guint use_gvfs_metadata : 1;
-
- /* The search is empty if there is no search context, or if the
- * search text is empty. It is used for the sensitivity of some menu
-@@ -71,9 +88,11 @@ typedef struct
- enum
- {
- PROP_0,
-+ PROP_SHORTNAME,
- PROP_CONTENT_TYPE,
- PROP_MIME_TYPE,
- PROP_EMPTY_SEARCH,
-+ PROP_USE_GVFS_METADATA,
- LAST_PROP
- };
-
-@@ -81,6 +100,7 @@ static GParamSpec *properties[LAST_PROP];
-
- enum
- {
-+ CURSOR_MOVED,
- LOAD,
- LOADED,
- SAVE,
-@@ -90,40 +110,41 @@ enum
-
- static guint document_signals[LAST_SIGNAL];
-
--G_DEFINE_TYPE_WITH_PRIVATE (GeditDocument, gedit_document, TEPL_TYPE_BUFFER)
-+static GHashTable *allocated_untitled_numbers = NULL;
-
--static void
--load_metadata_from_metadata_manager (GeditDocument *doc)
-+G_DEFINE_TYPE_WITH_PRIVATE (GeditDocument, gedit_document, GTK_SOURCE_TYPE_BUFFER)
-+
-+static gint
-+get_untitled_number (void)
- {
-- GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
-- GFile *location;
-+ gint i = 1;
-
-- location = gtk_source_file_get_location (priv->file);
-+ if (allocated_untitled_numbers == NULL)
-+ allocated_untitled_numbers = g_hash_table_new (NULL, NULL);
-
-- if (location != NULL)
-+ g_return_val_if_fail (allocated_untitled_numbers != NULL, -1);
-+
-+ while (TRUE)
- {
-- TeplMetadataManager *manager;
-+ if (g_hash_table_lookup (allocated_untitled_numbers, GINT_TO_POINTER (i)) == NULL)
-+ {
-+ g_hash_table_insert (allocated_untitled_numbers,
-+ GINT_TO_POINTER (i),
-+ GINT_TO_POINTER (i));
-
-- manager = tepl_metadata_manager_get_singleton ();
-- tepl_metadata_manager_copy_from (manager, location, priv->metadata);
-+ return i;
-+ }
-+
-+ ++i;
- }
- }
-
- static void
--save_metadata_into_metadata_manager (GeditDocument *doc)
-+release_untitled_number (gint n)
- {
-- GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
-- GFile *location;
--
-- location = gtk_source_file_get_location (priv->file);
--
-- if (location != NULL)
-- {
-- TeplMetadataManager *manager;
-+ g_return_if_fail (allocated_untitled_numbers != NULL);
-
-- manager = tepl_metadata_manager_get_singleton ();
-- tepl_metadata_manager_merge_into (manager, location, priv->metadata);
-- }
-+ g_hash_table_remove (allocated_untitled_numbers, GINT_TO_POINTER (n));
- }
-
- static void
-@@ -195,16 +216,17 @@ gedit_document_dispose (GObject *object)
- /* Metadata must be saved here and not in finalize because the language
- * is gone by the time finalize runs.
- */
-- if (priv->metadata != NULL)
-+ if (priv->file != NULL)
- {
- save_metadata (doc);
-
-- g_object_unref (priv->metadata);
-- priv->metadata = NULL;
-+ g_object_unref (priv->file);
-+ priv->file = NULL;
- }
-
-- g_clear_object (&priv->file);
-+ g_clear_object (&priv->metadata_info);
- g_clear_object (&priv->search_context);
-+ g_clear_object (&priv->metadata_manager);
-
- G_OBJECT_CLASS (gedit_document_parent_class)->dispose (object);
- }
-@@ -212,10 +234,17 @@ gedit_document_dispose (GObject *object)
- static void
- gedit_document_finalize (GObject *object)
- {
-- GeditDocumentPrivate *priv = gedit_document_get_instance_private (GEDIT_DOCUMENT (object));
-+ GeditDocumentPrivate *priv;
-
- gedit_debug (DEBUG_DOCUMENT);
-
-+ priv = gedit_document_get_instance_private (GEDIT_DOCUMENT (object));
-+
-+ if (priv->untitled_number > 0)
-+ {
-+ release_untitled_number (priv->untitled_number);
-+ }
-+
- g_free (priv->content_type);
-
- if (priv->time_of_last_save_or_load != NULL)
-@@ -239,6 +268,10 @@ gedit_document_get_property (GObject *object,
-
- switch (prop_id)
- {
-+ case PROP_SHORTNAME:
-+ g_value_take_string (value, gedit_document_get_short_name_for_display (doc));
-+ break;
-+
- case PROP_CONTENT_TYPE:
- g_value_take_string (value, gedit_document_get_content_type (doc));
- break;
-@@ -251,6 +284,10 @@ gedit_document_get_property (GObject *object,
- g_value_set_boolean (value, priv->empty_search);
- break;
-
-+ case PROP_USE_GVFS_METADATA:
-+ g_value_set_boolean (value, priv->use_gvfs_metadata);
-+ break;
-+
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
-@@ -264,6 +301,7 @@ gedit_document_set_property (GObject *object,
- GParamSpec *pspec)
- {
- GeditDocument *doc = GEDIT_DOCUMENT (object);
-+ GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
-
- switch (prop_id)
- {
-@@ -271,22 +309,97 @@ gedit_document_set_property (GObject *object,
- set_content_type (doc, g_value_get_string (value));
- break;
-
-+ case PROP_USE_GVFS_METADATA:
-+ priv->use_gvfs_metadata = g_value_get_boolean (value);
-+ break;
-+
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
- }
-
-+static void
-+gedit_document_begin_user_action (GtkTextBuffer *buffer)
-+{
-+ GeditDocumentPrivate *priv;
-+
-+ priv = gedit_document_get_instance_private (GEDIT_DOCUMENT (buffer));
-+
-+ ++priv->user_action;
-+
-+ if (GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->begin_user_action != NULL)
-+ {
-+ GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->begin_user_action (buffer);
-+ }
-+}
-+
-+static void
-+gedit_document_end_user_action (GtkTextBuffer *buffer)
-+{
-+ GeditDocumentPrivate *priv;
-+
-+ priv = gedit_document_get_instance_private (GEDIT_DOCUMENT (buffer));
-+
-+ --priv->user_action;
-+
-+ if (GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->end_user_action != NULL)
-+ {
-+ GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->end_user_action (buffer);
-+ }
-+}
-+
-+static void
-+gedit_document_mark_set (GtkTextBuffer *buffer,
-+ const GtkTextIter *iter,
-+ GtkTextMark *mark)
-+{
-+ GeditDocument *doc = GEDIT_DOCUMENT (buffer);
-+ GeditDocumentPrivate *priv;
-+
-+ priv = gedit_document_get_instance_private (doc);
-+
-+ if (GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->mark_set != NULL)
-+ {
-+ GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->mark_set (buffer, iter, mark);
-+ }
-+
-+ if (mark == gtk_text_buffer_get_insert (buffer) && (priv->user_action == 0))
-+ {
-+ g_signal_emit (doc, document_signals[CURSOR_MOVED], 0);
-+ }
-+}
-+
-+static void
-+gedit_document_changed (GtkTextBuffer *buffer)
-+{
-+ g_signal_emit (GEDIT_DOCUMENT (buffer), document_signals[CURSOR_MOVED], 0);
-+
-+ GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->changed (buffer);
-+}
-+
- static void
- gedit_document_constructed (GObject *object)
- {
- GeditDocument *doc = GEDIT_DOCUMENT (object);
-+ GeditDocumentPrivate *priv;
- GeditSettings *settings;
- GSettings *editor_settings;
-
-+ priv = gedit_document_get_instance_private (doc);
-+
- settings = _gedit_settings_get_singleton ();
- editor_settings = _gedit_settings_peek_editor_settings (settings);
-
-+ if (!priv->use_gvfs_metadata)
-+ {
-+ GeditMetadataManager *metadata_manager;
-+
-+ metadata_manager = _gedit_app_get_metadata_manager (GEDIT_APP (g_application_get_default ()));
-+ g_assert (GEDIT_IS_METADATA_MANAGER (metadata_manager));
-+ priv->metadata_manager = g_object_ref (metadata_manager);
-+ }
-+
- /* Bind construct properties. */
- g_settings_bind (editor_settings, GEDIT_SETTINGS_ENSURE_TRAILING_NEWLINE,
- doc, "implicit-trailing-newline",
-@@ -299,6 +412,7 @@ static void
- gedit_document_class_init (GeditDocumentClass *klass)
- {
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-+ GtkTextBufferClass *buf_class = GTK_TEXT_BUFFER_CLASS (klass);
-
- object_class->dispose = gedit_document_dispose;
- object_class->finalize = gedit_document_finalize;
-@@ -306,9 +420,26 @@ gedit_document_class_init (GeditDocumentClass *klass)
- object_class->set_property = gedit_document_set_property;
- object_class->constructed = gedit_document_constructed;
-
-+ buf_class->begin_user_action = gedit_document_begin_user_action;
-+ buf_class->end_user_action = gedit_document_end_user_action;
-+ buf_class->mark_set = gedit_document_mark_set;
-+ buf_class->changed = gedit_document_changed;
-+
- klass->loaded = gedit_document_loaded_real;
- klass->saved = gedit_document_saved_real;
-
-+ /**
-+ * GeditDocument:shortname:
-+ *
-+ * The document's short name.
-+ */
-+ properties[PROP_SHORTNAME] =
-+ g_param_spec_string ("shortname",
-+ "Short Name",
-+ "The document's short name",
-+ NULL,
-+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-+
- /**
- * GeditDocument:content-type:
- *
-@@ -348,8 +479,44 @@ gedit_document_class_init (GeditDocumentClass *klass)
- TRUE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
-+ /**
-+ * GeditDocument:use-gvfs-metadata:
-+ *
-+ * Whether to use GVFS metadata. If %FALSE, use the gedit metadata
-+ * manager that stores the metadata in an XML file in the user cache
-+ * directory.
-+ *
-+ *
-+ * The property is used internally by gedit. It must not be used in a
-+ * gedit plugin. The property can be modified or removed at any time.
-+ *
-+ */
-+ properties[PROP_USE_GVFS_METADATA] =
-+ g_param_spec_boolean ("use-gvfs-metadata",
-+ "Use GVFS metadata",
-+ "",
-+ TRUE,
-+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-+
- g_object_class_install_properties (object_class, LAST_PROP, properties);
-
-+ /* This signal is used to update the cursor position in the statusbar,
-+ * it's emitted either when the insert mark is moved explicitely or
-+ * when the buffer changes (insert/delete).
-+ * FIXME When the replace_all was implemented in gedit, this signal was
-+ * not emitted during the replace_all to improve performance. Now the
-+ * replace_all is implemented in GtkSourceView, so the signal is
-+ * emitted.
-+ */
-+ document_signals[CURSOR_MOVED] =
-+ g_signal_new ("cursor-moved",
-+ G_OBJECT_CLASS_TYPE (object_class),
-+ G_SIGNAL_RUN_LAST,
-+ G_STRUCT_OFFSET (GeditDocumentClass, cursor_moved),
-+ NULL, NULL, NULL,
-+ G_TYPE_NONE,
-+ 0);
-+
- /**
- * GeditDocument::load:
- * @document: the #GeditDocument.
-@@ -632,20 +799,79 @@ on_location_changed (GtkSourceFile *file,
- GParamSpec *pspec,
- GeditDocument *doc)
- {
-+ GeditDocumentPrivate *priv;
-+ GFile *location;
-+
- gedit_debug (DEBUG_DOCUMENT);
-- load_metadata_from_metadata_manager (doc);
-+
-+ priv = gedit_document_get_instance_private (doc);
-+
-+ location = gtk_source_file_get_location (file);
-+
-+ if (location != NULL && priv->untitled_number > 0)
-+ {
-+ release_untitled_number (priv->untitled_number);
-+ priv->untitled_number = 0;
-+ }
-+
-+ g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_SHORTNAME]);
-+
-+ /* Load metadata for this location: we load sync since metadata is
-+ * always local so it should be fast and we need the information
-+ * right after the location was set.
-+ * TODO: do async I/O for the metadata.
-+ */
-+ if (priv->use_gvfs_metadata && location != NULL)
-+ {
-+ GError *error = NULL;
-+
-+ if (priv->metadata_info != NULL)
-+ {
-+ g_object_unref (priv->metadata_info);
-+ }
-+
-+ priv->metadata_info = g_file_query_info (location,
-+ METADATA_QUERY,
-+ G_FILE_QUERY_INFO_NONE,
-+ NULL,
-+ &error);
-+
-+ if (error != NULL)
-+ {
-+ /* Do not complain about metadata if we are opening a
-+ * non existing file.
-+ */
-+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_ISDIR) &&
-+ !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR) &&
-+ !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
-+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-+ {
-+ g_warning ("%s", error->message);
-+ }
-+
-+ g_error_free (error);
-+ }
-+
-+ if (priv->metadata_info == NULL)
-+ {
-+ priv->metadata_info = g_file_info_new ();
-+ }
-+ }
- }
-
- static void
- gedit_document_init (GeditDocument *doc)
- {
- GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
-- TeplFile *tepl_file;
- GeditSettings *settings;
- GSettings *editor_settings;
-
- gedit_debug (DEBUG_DOCUMENT);
-
-+ settings = _gedit_settings_get_singleton ();
-+ editor_settings = _gedit_settings_peek_editor_settings (settings);
-+
-+ priv->untitled_number = get_untitled_number ();
- priv->content_type = get_default_content_type ();
- priv->language_set_by_user = FALSE;
- priv->empty_search = TRUE;
-@@ -653,13 +879,7 @@ gedit_document_init (GeditDocument *doc)
- update_time_of_last_save_or_load (doc);
-
- priv->file = gtk_source_file_new ();
-- tepl_file = tepl_buffer_get_file (TEPL_BUFFER (doc));
--
-- g_object_bind_property (priv->file, "location",
-- tepl_file, "location",
-- G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
--
-- priv->metadata = tepl_metadata_new ();
-+ priv->metadata_info = g_file_info_new ();
-
- g_signal_connect_object (priv->file,
- "notify::location",
-@@ -667,9 +887,6 @@ gedit_document_init (GeditDocument *doc)
- doc,
- 0);
-
-- settings = _gedit_settings_get_singleton ();
-- editor_settings = _gedit_settings_peek_editor_settings (settings);
--
- g_settings_bind (editor_settings, GEDIT_SETTINGS_MAX_UNDO_ACTIONS,
- doc, "max-undo-levels",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
-@@ -699,7 +916,17 @@ gedit_document_init (GeditDocument *doc)
- GeditDocument *
- gedit_document_new (void)
- {
-- return g_object_new (GEDIT_TYPE_DOCUMENT, NULL);
-+ gboolean use_gvfs_metadata;
-+
-+#ifdef ENABLE_GVFS_METADATA
-+ use_gvfs_metadata = TRUE;
-+#else
-+ use_gvfs_metadata = FALSE;
-+#endif
-+
-+ return g_object_new (GEDIT_TYPE_DOCUMENT,
-+ "use-gvfs-metadata", use_gvfs_metadata,
-+ NULL);
- }
-
- static gchar *
-@@ -814,17 +1041,19 @@ set_content_type (GeditDocument *doc,
- gchar *
- _gedit_document_get_uri_for_display (GeditDocument *doc)
- {
-- TeplFile *file;
-+ GeditDocumentPrivate *priv;
- GFile *location;
-
- g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), g_strdup (""));
-
-- file = tepl_buffer_get_file (TEPL_BUFFER (doc));
-- location = tepl_file_get_location (file);
-+ priv = gedit_document_get_instance_private (doc);
-+
-+ location = gtk_source_file_get_location (priv->file);
-
- if (location == NULL)
- {
-- return tepl_file_get_short_name (file);
-+ return g_strdup_printf (_("Untitled Document %d"),
-+ priv->untitled_number);
- }
- else
- {
-@@ -841,12 +1070,24 @@ _gedit_document_get_uri_for_display (GeditDocument *doc)
- gchar *
- gedit_document_get_short_name_for_display (GeditDocument *doc)
- {
-- TeplFile *file;
-+ GeditDocumentPrivate *priv;
-+ GFile *location;
-
- g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), g_strdup (""));
-
-- file = tepl_buffer_get_file (TEPL_BUFFER (doc));
-- return tepl_file_get_short_name (file);
-+ priv = gedit_document_get_instance_private (doc);
-+
-+ location = gtk_source_file_get_location (priv->file);
-+
-+ if (location == NULL)
-+ {
-+ return g_strdup_printf (_("Untitled Document %d"),
-+ priv->untitled_number);
-+ }
-+ else
-+ {
-+ return gedit_utils_basename_for_display (location);
-+ }
- }
-
- gchar *
-@@ -1032,15 +1273,31 @@ gedit_document_saved_real (GeditDocument *doc)
- doc);
- }
-
-+gboolean
-+gedit_document_is_untouched (GeditDocument *doc)
-+{
-+ GeditDocumentPrivate *priv;
-+ GFile *location;
-+
-+ g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), TRUE);
-+
-+ priv = gedit_document_get_instance_private (doc);
-+
-+ location = gtk_source_file_get_location (priv->file);
-+
-+ return location == NULL && !gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc));
-+}
-+
- gboolean
- gedit_document_is_untitled (GeditDocument *doc)
- {
-- TeplFile *file;
-+ GeditDocumentPrivate *priv;
-
- g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), TRUE);
-
-- file = tepl_buffer_get_file (TEPL_BUFFER (doc));
-- return tepl_file_get_location (file) == NULL;
-+ priv = gedit_document_get_instance_private (doc);
-+
-+ return gtk_source_file_get_location (priv->file) == NULL;
- }
-
- /*
-@@ -1072,6 +1329,51 @@ _gedit_document_needs_saving (GeditDocument *doc)
- return (externally_modified || deleted) && !priv->create;
- }
-
-+/* If @line is bigger than the lines of the document, the cursor is moved
-+ * to the last line and FALSE is returned.
-+ */
-+gboolean
-+gedit_document_goto_line (GeditDocument *doc,
-+ gint line)
-+{
-+ GtkTextIter iter;
-+
-+ gedit_debug (DEBUG_DOCUMENT);
-+
-+ g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
-+ g_return_val_if_fail (line >= -1, FALSE);
-+
-+ gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc),
-+ &iter,
-+ line);
-+
-+ gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
-+
-+ return gtk_text_iter_get_line (&iter) == line;
-+}
-+
-+gboolean
-+gedit_document_goto_line_offset (GeditDocument *doc,
-+ gint line,
-+ gint line_offset)
-+{
-+ GtkTextIter iter;
-+
-+ g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
-+ g_return_val_if_fail (line >= -1, FALSE);
-+ g_return_val_if_fail (line_offset >= -1, FALSE);
-+
-+ gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER (doc),
-+ &iter,
-+ line,
-+ line_offset);
-+
-+ gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
-+
-+ return (gtk_text_iter_get_line (&iter) == line &&
-+ gtk_text_iter_get_line_offset (&iter) == line_offset);
-+}
-+
- /**
- * gedit_document_set_language:
- * @doc:
-@@ -1130,6 +1432,64 @@ _gedit_document_get_seconds_since_last_save_or_load (GeditDocument *doc)
- return n_microseconds / (1000 * 1000);
- }
-
-+static gchar *
-+get_metadata_from_metadata_manager (GeditDocument *doc,
-+ const gchar *key)
-+{
-+ GeditDocumentPrivate *priv;
-+ GFile *location;
-+
-+ priv = gedit_document_get_instance_private (doc);
-+
-+ location = gtk_source_file_get_location (priv->file);
-+
-+ if (location != NULL)
-+ {
-+ return gedit_metadata_manager_get (priv->metadata_manager, location, key);
-+ }
-+
-+ return NULL;
-+}
-+
-+static gchar *
-+get_metadata_from_gvfs (GeditDocument *doc,
-+ const gchar *key)
-+{
-+ GeditDocumentPrivate *priv;
-+
-+ priv = gedit_document_get_instance_private (doc);
-+
-+ if (priv->metadata_info != NULL &&
-+ g_file_info_has_attribute (priv->metadata_info, key) &&
-+ g_file_info_get_attribute_type (priv->metadata_info, key) == G_FILE_ATTRIBUTE_TYPE_STRING)
-+ {
-+ return g_strdup (g_file_info_get_attribute_string (priv->metadata_info, key));
-+ }
-+
-+ return NULL;
-+}
-+
-+static void
-+set_gvfs_metadata (GFileInfo *info,
-+ const gchar *key,
-+ const gchar *value)
-+{
-+ g_return_if_fail (G_IS_FILE_INFO (info));
-+
-+ if (value != NULL)
-+ {
-+ g_file_info_set_attribute_string (info, key, value);
-+ }
-+ else
-+ {
-+ /* Unset the key */
-+ g_file_info_set_attribute (info,
-+ key,
-+ G_FILE_ATTRIBUTE_TYPE_INVALID,
-+ NULL);
-+ }
-+}
-+
- /**
- * gedit_document_get_metadata:
- * @doc: a #GeditDocument
-@@ -1150,12 +1510,12 @@ gedit_document_get_metadata (GeditDocument *doc,
-
- priv = gedit_document_get_instance_private (doc);
-
-- if (priv->metadata == NULL)
-+ if (priv->use_gvfs_metadata)
- {
-- return NULL;
-+ return get_metadata_from_gvfs (doc, key);
- }
-
-- return tepl_metadata_get (priv->metadata, key);
-+ return get_metadata_from_metadata_manager (doc, key);
- }
-
- /**
-@@ -1173,30 +1533,84 @@ gedit_document_set_metadata (GeditDocument *doc,
- ...)
- {
- GeditDocumentPrivate *priv;
-- va_list var_args;
-+ GFile *location;
- const gchar *key;
-+ va_list var_args;
-+ GFileInfo *info = NULL;
-
- g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
- g_return_if_fail (first_key != NULL);
-
- priv = gedit_document_get_instance_private (doc);
-
-- if (priv->metadata == NULL)
-+ location = gtk_source_file_get_location (priv->file);
-+
-+ /* With the metadata manager, can't set metadata for untitled documents.
-+ * With GVFS metadata, if the location is NULL the metadata is stored in
-+ * priv->metadata_info, so that it can be saved later if the document is
-+ * saved.
-+ */
-+ if (!priv->use_gvfs_metadata && location == NULL)
- {
- return;
- }
-
-+ if (priv->use_gvfs_metadata)
-+ {
-+ info = g_file_info_new ();
-+ }
-+
- va_start (var_args, first_key);
-
-- for (key = first_key; key != NULL; key = va_arg (var_args, const gchar *))
-+ for (key = first_key; key; key = va_arg (var_args, const gchar *))
- {
- const gchar *value = va_arg (var_args, const gchar *);
-- tepl_metadata_set (priv->metadata, key, value);
-+
-+ if (priv->use_gvfs_metadata)
-+ {
-+ set_gvfs_metadata (info, key, value);
-+ set_gvfs_metadata (priv->metadata_info, key, value);
-+ }
-+ else
-+ {
-+ gedit_metadata_manager_set (priv->metadata_manager, location, key, value);
-+ }
- }
-
- va_end (var_args);
-
-- save_metadata_into_metadata_manager (doc);
-+ if (priv->use_gvfs_metadata && location != NULL)
-+ {
-+ GError *error = NULL;
-+
-+ /* We save synchronously since metadata is always local so it
-+ * should be fast. Moreover this function can be called on
-+ * application shutdown, when the main loop has already exited,
-+ * so an async operation would not terminate.
-+ * https://bugzilla.gnome.org/show_bug.cgi?id=736591
-+ */
-+ g_file_set_attributes_from_info (location,
-+ info,
-+ G_FILE_QUERY_INFO_NONE,
-+ NULL,
-+ &error);
-+
-+ if (error != NULL)
-+ {
-+ /* Do not complain about metadata if we are closing a
-+ * document for a non existing file.
-+ */
-+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
-+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-+ {
-+ g_warning ("Set document metadata failed: %s", error->message);
-+ }
-+
-+ g_error_free (error);
-+ }
-+ }
-+
-+ g_clear_object (&info);
- }
-
- static void
-diff --git a/gedit/gedit-document.h b/gedit/gedit-document.h
-index 901d02dc0..ed52a42fb 100644
---- a/gedit/gedit-document.h
-+++ b/gedit/gedit-document.h
-@@ -5,7 +5,7 @@
- * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
- * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
- * Copyright (C) 2002-2005 Paolo Maggi
-- * Copyright (C) 2014-2020 Sébastien Wilmet
-+ * Copyright (C) 2014 Sébastien Wilmet
- *
- * 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
-@@ -24,19 +24,20 @@
- #ifndef GEDIT_DOCUMENT_H
- #define GEDIT_DOCUMENT_H
-
--#include
-+#include
-
- G_BEGIN_DECLS
-
- #define GEDIT_TYPE_DOCUMENT (gedit_document_get_type())
-
--G_DECLARE_DERIVABLE_TYPE (GeditDocument, gedit_document, GEDIT, DOCUMENT, TeplBuffer)
-+G_DECLARE_DERIVABLE_TYPE (GeditDocument, gedit_document, GEDIT, DOCUMENT, GtkSourceBuffer)
-
- struct _GeditDocumentClass
- {
-- TeplBufferClass parent_class;
-+ GtkSourceBufferClass parent_class;
-
- /* Signals */
-+ void (* cursor_moved) (GeditDocument *document);
-
- void (* load) (GeditDocument *document);
-
-@@ -57,8 +58,17 @@ gchar *gedit_document_get_content_type (GeditDocument *doc);
-
- gchar *gedit_document_get_mime_type (GeditDocument *doc);
-
-+gboolean gedit_document_is_untouched (GeditDocument *doc);
-+
- gboolean gedit_document_is_untitled (GeditDocument *doc);
-
-+gboolean gedit_document_goto_line (GeditDocument *doc,
-+ gint line);
-+
-+gboolean gedit_document_goto_line_offset (GeditDocument *doc,
-+ gint line,
-+ gint line_offset);
-+
- void gedit_document_set_language (GeditDocument *doc,
- GtkSourceLanguage *lang);
- GtkSourceLanguage
-diff --git a/gedit/gedit-documents-panel.c b/gedit/gedit-documents-panel.c
-index 98d84a98f..8033f944e 100644
---- a/gedit/gedit-documents-panel.c
-+++ b/gedit/gedit-documents-panel.c
-@@ -23,7 +23,6 @@
- #include "gedit-documents-panel.h"
-
- #include
--#include
-
- #include "gedit-debug.h"
- #include "gedit-document.h"
-@@ -447,7 +446,7 @@ doc_get_name (GeditDocument *doc)
- name = gedit_document_get_short_name_for_display (doc);
-
- /* Truncate the name so it doesn't get insanely wide. */
-- docname = tepl_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
-+ docname = gedit_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
-
- g_free (name);
-
-diff --git a/gedit/gedit-factory.c b/gedit/gedit-factory.c
-deleted file mode 100644
-index 409b3beb2..000000000
---- a/gedit/gedit-factory.c
-+++ /dev/null
-@@ -1,50 +0,0 @@
--/*
-- * This file is part of gedit
-- *
-- * Copyright (C) 2020 Sébastien Wilmet
-- *
-- * 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 "gedit-factory.h"
--#include "gedit-dirs.h"
--
--G_DEFINE_TYPE (GeditFactory, gedit_factory, TEPL_TYPE_ABSTRACT_FACTORY)
--
--static GFile *
--gedit_factory_create_metadata_manager_file (TeplAbstractFactory *factory)
--{
-- return g_file_new_build_filename (gedit_dirs_get_user_data_dir (),
-- "gedit-metadata.xml",
-- NULL);
--}
--
--static void
--gedit_factory_class_init (GeditFactoryClass *klass)
--{
-- TeplAbstractFactoryClass *factory_class = TEPL_ABSTRACT_FACTORY_CLASS (klass);
--
-- factory_class->create_metadata_manager_file = gedit_factory_create_metadata_manager_file;
--}
--
--static void
--gedit_factory_init (GeditFactory *factory)
--{
--}
--
--GeditFactory *
--gedit_factory_new (void)
--{
-- return g_object_new (GEDIT_TYPE_FACTORY, NULL);
--}
-diff --git a/gedit/gedit-factory.h b/gedit/gedit-factory.h
-deleted file mode 100644
-index 05e19f715..000000000
---- a/gedit/gedit-factory.h
-+++ /dev/null
-@@ -1,53 +0,0 @@
--/*
-- * This file is part of gedit
-- *
-- * Copyright (C) 2020 Sébastien Wilmet
-- *
-- * 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 GEDIT_FACTORY_H
--#define GEDIT_FACTORY_H
--
--#include
--
--G_BEGIN_DECLS
--
--#define GEDIT_TYPE_FACTORY (gedit_factory_get_type ())
--#define GEDIT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FACTORY, GeditFactory))
--#define GEDIT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_FACTORY, GeditFactoryClass))
--#define GEDIT_IS_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_FACTORY))
--#define GEDIT_IS_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_FACTORY))
--#define GEDIT_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_FACTORY, GeditFactoryClass))
--
--typedef struct _GeditFactory GeditFactory;
--typedef struct _GeditFactoryClass GeditFactoryClass;
--
--struct _GeditFactory
--{
-- TeplAbstractFactory parent;
--};
--
--struct _GeditFactoryClass
--{
-- TeplAbstractFactoryClass parent_class;
--};
--
--GType gedit_factory_get_type (void);
--
--GeditFactory * gedit_factory_new (void);
--
--G_END_DECLS
--
--#endif /* GEDIT_FACTORY_H */
-diff --git a/gedit/gedit-file-chooser-dialog-gtk.c b/gedit/gedit-file-chooser-dialog-gtk.c
-index 4b8b4dbb0..17671ff3e 100644
---- a/gedit/gedit-file-chooser-dialog-gtk.c
-+++ b/gedit/gedit-file-chooser-dialog-gtk.c
-@@ -192,6 +192,12 @@ chooser_show (GeditFileChooserDialog *dialog)
- gtk_widget_grab_focus (GTK_WIDGET (dialog));
- }
-
-+static void
-+chooser_hide (GeditFileChooserDialog *dialog)
-+{
-+ gtk_widget_hide (GTK_WIDGET (dialog));
-+}
-+
- static void
- chooser_destroy (GeditFileChooserDialog *dialog)
- {
-@@ -211,6 +217,26 @@ chooser_get_window (GeditFileChooserDialog *dialog)
- return GTK_WINDOW (dialog);
- }
-
-+static void
-+chooser_add_pattern_filter (GeditFileChooserDialog *dialog,
-+ const gchar *name,
-+ const gchar *pattern)
-+{
-+ GtkFileFilter *filter;
-+
-+ filter = gtk_file_filter_new ();
-+
-+ gtk_file_filter_set_name (filter, name);
-+ gtk_file_filter_add_pattern (filter, pattern);
-+
-+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
-+
-+ if (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == NULL)
-+ {
-+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
-+ }
-+}
-+
- static void
- gedit_file_chooser_dialog_gtk_chooser_init (gpointer g_iface,
- gpointer iface_data)
-@@ -229,9 +255,11 @@ gedit_file_chooser_dialog_gtk_chooser_init (gpointer g_iface,
- iface->get_file = chooser_get_file;
- iface->set_do_overwrite_confirmation = chooser_set_do_overwrite_confirmation;
- iface->show = chooser_show;
-+ iface->hide = chooser_hide;
- iface->destroy = chooser_destroy;
- iface->set_modal = chooser_set_modal;
- iface->get_window = chooser_get_window;
-+ iface->add_pattern_filter = chooser_add_pattern_filter;
- }
-
- static void
-@@ -253,7 +281,8 @@ gedit_file_chooser_dialog_gtk_class_init (GeditFileChooserDialogGtkClass *klass)
- }
-
- static void
--create_option_menu (GeditFileChooserDialogGtk *dialog)
-+create_option_menu (GeditFileChooserDialogGtk *dialog,
-+ GeditFileChooserFlags flags)
- {
- GtkWidget *label;
- GtkWidget *menu;
-@@ -262,7 +291,7 @@ create_option_menu (GeditFileChooserDialogGtk *dialog)
- label = gtk_label_new_with_mnemonic (_("C_haracter Encoding:"));
- gtk_widget_set_halign (label, GTK_ALIGN_START);
-
-- save_mode = TRUE;
-+ save_mode = (flags & GEDIT_FILE_CHOOSER_FLAG_SAVE) != 0;
- menu = gedit_encodings_combo_box_new (save_mode);
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), menu);
-@@ -374,13 +403,18 @@ create_newline_combo (GeditFileChooserDialogGtk *dialog)
- }
-
- static void
--create_extra_widget (GeditFileChooserDialogGtk *dialog)
-+create_extra_widget (GeditFileChooserDialogGtk *dialog,
-+ GeditFileChooserFlags flags)
- {
- dialog->extra_widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_widget_show (dialog->extra_widget);
-
-- create_option_menu (dialog);
-- create_newline_combo (dialog);
-+ create_option_menu (dialog, flags);
-+
-+ if ((flags & GEDIT_FILE_CHOOSER_FLAG_SAVE) != 0)
-+ {
-+ create_newline_combo (dialog);
-+ }
-
- gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), dialog->extra_widget);
- }
-@@ -421,21 +455,35 @@ gedit_file_chooser_dialog_gtk_init (GeditFileChooserDialogGtk *dialog)
- }
-
- GeditFileChooserDialog *
--gedit_file_chooser_dialog_gtk_create (const gchar *title,
-- GtkWindow *parent,
-- const gchar *accept_label,
-- const gchar *cancel_label)
-+gedit_file_chooser_dialog_gtk_create (const gchar *title,
-+ GtkWindow *parent,
-+ GeditFileChooserFlags flags,
-+ const gchar *accept_label,
-+ const gchar *cancel_label)
- {
- GeditFileChooserDialogGtk *result;
-+ GtkFileChooserAction action;
-+ gboolean select_multiple;
-+
-+ if ((flags & GEDIT_FILE_CHOOSER_FLAG_SAVE) != 0)
-+ {
-+ action = GTK_FILE_CHOOSER_ACTION_SAVE;
-+ select_multiple = FALSE;
-+ }
-+ else
-+ {
-+ action = GTK_FILE_CHOOSER_ACTION_OPEN;
-+ select_multiple = TRUE;
-+ }
-
- result = g_object_new (GEDIT_TYPE_FILE_CHOOSER_DIALOG_GTK,
- "title", title,
- "local-only", FALSE,
-- "action", GTK_FILE_CHOOSER_ACTION_SAVE,
-- "select-multiple", FALSE,
-+ "action", action,
-+ "select-multiple", select_multiple,
- NULL);
-
-- create_extra_widget (result);
-+ create_extra_widget (result, flags);
-
- g_signal_connect (result,
- "notify::action",
-diff --git a/gedit/gedit-file-chooser-dialog-gtk.h b/gedit/gedit-file-chooser-dialog-gtk.h
-index 0bf6a0d41..40726af54 100644
---- a/gedit/gedit-file-chooser-dialog-gtk.h
-+++ b/gedit/gedit-file-chooser-dialog-gtk.h
-@@ -33,10 +33,11 @@ G_DECLARE_FINAL_TYPE (GeditFileChooserDialogGtk, gedit_file_chooser_dialog_gtk,
- GEDIT, FILE_CHOOSER_DIALOG_GTK,
- GtkFileChooserDialog)
-
--GeditFileChooserDialog * gedit_file_chooser_dialog_gtk_create (const gchar *title,
-- GtkWindow *parent,
-- const gchar *accept_label,
-- const gchar *cancel_label);
-+GeditFileChooserDialog * gedit_file_chooser_dialog_gtk_create (const gchar *title,
-+ GtkWindow *parent,
-+ GeditFileChooserFlags flags,
-+ const gchar *accept_label,
-+ const gchar *cancel_label);
-
- G_END_DECLS
-
-diff --git a/gedit/gedit-file-chooser-dialog.c b/gedit/gedit-file-chooser-dialog.c
-index 56edbae3b..b4ce2fd9e 100644
---- a/gedit/gedit-file-chooser-dialog.c
-+++ b/gedit/gedit-file-chooser-dialog.c
-@@ -62,13 +62,15 @@ gedit_file_chooser_dialog_default_init (GeditFileChooserDialogInterface *iface)
- }
-
- GeditFileChooserDialog *
--gedit_file_chooser_dialog_create (const gchar *title,
-- GtkWindow *parent,
-- const gchar *accept_label,
-- const gchar *cancel_label)
-+gedit_file_chooser_dialog_create (const gchar *title,
-+ GtkWindow *parent,
-+ GeditFileChooserFlags flags,
-+ const gchar *accept_label,
-+ const gchar *cancel_label)
- {
- return gedit_file_chooser_dialog_gtk_create (title,
- parent,
-+ flags,
- accept_label,
- cancel_label);
- }
-@@ -211,6 +213,19 @@ gedit_file_chooser_dialog_show (GeditFileChooserDialog *dialog)
- iface->show (dialog);
- }
-
-+void
-+gedit_file_chooser_dialog_hide (GeditFileChooserDialog *dialog)
-+{
-+ GeditFileChooserDialogInterface *iface;
-+
-+ g_return_if_fail (GEDIT_IS_FILE_CHOOSER_DIALOG (dialog));
-+
-+ iface = GEDIT_FILE_CHOOSER_DIALOG_GET_IFACE (dialog);
-+ g_return_if_fail (iface->hide != NULL);
-+
-+ iface->hide (dialog);
-+}
-+
- void
- gedit_file_chooser_dialog_destroy (GeditFileChooserDialog *dialog)
- {
-@@ -255,4 +270,21 @@ gedit_file_chooser_dialog_get_window (GeditFileChooserDialog *dialog)
- return NULL;
- }
-
-+void
-+gedit_file_chooser_dialog_add_pattern_filter (GeditFileChooserDialog *dialog,
-+ const gchar *name,
-+ const gchar *pattern)
-+{
-+ GeditFileChooserDialogInterface *iface;
-+
-+ g_return_if_fail (GEDIT_IS_FILE_CHOOSER_DIALOG (dialog));
-+
-+ iface = GEDIT_FILE_CHOOSER_DIALOG_GET_IFACE (dialog);
-+
-+ if (iface->add_pattern_filter)
-+ {
-+ iface->add_pattern_filter (dialog, name, pattern);
-+ }
-+}
-+
- /* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-file-chooser-dialog.h b/gedit/gedit-file-chooser-dialog.h
-index b759c6566..633950e05 100644
---- a/gedit/gedit-file-chooser-dialog.h
-+++ b/gedit/gedit-file-chooser-dialog.h
-@@ -64,6 +64,7 @@ struct _GeditFileChooserDialogInterface
- gboolean overwrite_confirmation);
-
- void (*show) (GeditFileChooserDialog *dialog);
-+ void (*hide) (GeditFileChooserDialog *dialog);
-
- void (*destroy) (GeditFileChooserDialog *dialog);
-
-@@ -72,11 +73,22 @@ struct _GeditFileChooserDialogInterface
-
- GtkWindow *
- (*get_window) (GeditFileChooserDialog *dialog);
-+
-+ void (*add_pattern_filter) (GeditFileChooserDialog *dilaog,
-+ const gchar *name,
-+ const gchar *pattern);
- };
-
-+typedef enum
-+{
-+ GEDIT_FILE_CHOOSER_FLAG_SAVE = 1 << 0,
-+ GEDIT_FILE_CHOOSER_FLAG_OPEN = 1 << 1
-+} GeditFileChooserFlags;
-+
- GeditFileChooserDialog *
- gedit_file_chooser_dialog_create (const gchar *title,
- GtkWindow *parent,
-+ GeditFileChooserFlags flags,
- const gchar *accept_label,
- const gchar *cancel_label);
-
-@@ -110,12 +122,17 @@ void gedit_file_chooser_dialog_set_do_overwrite_confirmation (
- gboolean overwrite_confirmation);
-
- void gedit_file_chooser_dialog_show (GeditFileChooserDialog *dialog);
-+void gedit_file_chooser_dialog_hide (GeditFileChooserDialog *dialog);
-
- void gedit_file_chooser_dialog_set_modal (GeditFileChooserDialog *dialog,
- gboolean is_modal);
-
- GtkWindow *gedit_file_chooser_dialog_get_window (GeditFileChooserDialog *dialog);
-
-+void gedit_file_chooser_dialog_add_pattern_filter (GeditFileChooserDialog *dialog,
-+ const gchar *name,
-+ const gchar *pattern);
-+
- G_END_DECLS
-
- #endif /* GEDIT_FILE_CHOOSER_DIALOG_H */
-diff --git a/gedit/gedit-highlight-mode-dialog.c b/gedit/gedit-highlight-mode-dialog.c
-new file mode 100644
-index 000000000..a0661bfc3
---- /dev/null
-+++ b/gedit/gedit-highlight-mode-dialog.c
-@@ -0,0 +1,102 @@
-+/*
-+ * gedit-highlight-mode-dialog.c
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+#include "gedit-highlight-mode-dialog.h"
-+
-+struct _GeditHighlightModeDialog
-+{
-+ GtkDialog parent_instance;
-+
-+ GeditHighlightModeSelector *selector;
-+ gulong on_language_selected_id;
-+};
-+
-+G_DEFINE_TYPE (GeditHighlightModeDialog, gedit_highlight_mode_dialog, GTK_TYPE_DIALOG)
-+
-+static void
-+gedit_highlight_mode_dialog_response (GtkDialog *dialog,
-+ gint response_id)
-+{
-+ GeditHighlightModeDialog *dlg = GEDIT_HIGHLIGHT_MODE_DIALOG (dialog);
-+
-+ if (response_id == GTK_RESPONSE_OK)
-+ {
-+ g_signal_handler_block (dlg->selector, dlg->on_language_selected_id);
-+ gedit_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 (GeditHighlightModeSelector *sel,
-+ GtkSourceLanguage *language,
-+ GeditHighlightModeDialog *dlg)
-+{
-+ g_signal_handler_block (dlg->selector, dlg->on_language_selected_id);
-+ gedit_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
-+gedit_highlight_mode_dialog_class_init (GeditHighlightModeDialogClass *klass)
-+{
-+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-+ GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass);
-+
-+ dialog_class->response = gedit_highlight_mode_dialog_response;
-+
-+ /* Bind class to template */
-+ gtk_widget_class_set_template_from_resource (widget_class,
-+ "/org/gnome/gedit/ui/gedit-highlight-mode-dialog.ui");
-+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeDialog, selector);
-+}
-+
-+static void
-+gedit_highlight_mode_dialog_init (GeditHighlightModeDialog *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 *
-+gedit_highlight_mode_dialog_new (GtkWindow *parent)
-+{
-+ return GTK_WIDGET (g_object_new (GEDIT_TYPE_HIGHLIGHT_MODE_DIALOG,
-+ "transient-for", parent,
-+ "use-header-bar", TRUE,
-+ NULL));
-+}
-+
-+GeditHighlightModeSelector *
-+gedit_highlight_mode_dialog_get_selector (GeditHighlightModeDialog *dlg)
-+{
-+ g_return_val_if_fail (GEDIT_IS_HIGHLIGHT_MODE_DIALOG (dlg), NULL);
-+
-+ return dlg->selector;
-+}
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-highlight-mode-dialog.h b/gedit/gedit-highlight-mode-dialog.h
-new file mode 100644
-index 000000000..57d406bb3
---- /dev/null
-+++ b/gedit/gedit-highlight-mode-dialog.h
-@@ -0,0 +1,41 @@
-+/*
-+ * gedit-highlight-mode-dialog.h
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+
-+#ifndef GEDIT_HIGHLIGHT_MODE_DIALOG_H
-+#define GEDIT_HIGHLIGHT_MODE_DIALOG_H
-+
-+#include "gedit-highlight-mode-selector.h"
-+
-+G_BEGIN_DECLS
-+
-+#define GEDIT_TYPE_HIGHLIGHT_MODE_DIALOG (gedit_highlight_mode_dialog_get_type ())
-+
-+G_DECLARE_FINAL_TYPE (GeditHighlightModeDialog, gedit_highlight_mode_dialog, GEDIT, HIGHLIGHT_MODE_DIALOG, GtkDialog)
-+
-+GtkWidget *gedit_highlight_mode_dialog_new (GtkWindow *parent);
-+
-+GeditHighlightModeSelector *gedit_highlight_mode_dialog_get_selector (GeditHighlightModeDialog *dlg);
-+
-+G_END_DECLS
-+
-+#endif /* GEDIT_HIGHLIGHT_MODE_DIALOG_H */
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-highlight-mode-selector.c b/gedit/gedit-highlight-mode-selector.c
-new file mode 100644
-index 000000000..cb6bd466f
---- /dev/null
-+++ b/gedit/gedit-highlight-mode-selector.c
-@@ -0,0 +1,375 @@
-+/*
-+ * gedit-highlight-mode-selector.c
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+#include "gedit-highlight-mode-selector.h"
-+#include
-+
-+enum
-+{
-+ COLUMN_NAME,
-+ COLUMN_LANG,
-+ N_COLUMNS
-+};
-+
-+struct _GeditHighlightModeSelector
-+{
-+ 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 (GeditHighlightModeSelector, gedit_highlight_mode_selector, GTK_TYPE_GRID)
-+
-+static void
-+gedit_highlight_mode_selector_language_selected (GeditHighlightModeSelector *widget,
-+ GtkSourceLanguage *language)
-+{
-+}
-+
-+static void
-+gedit_highlight_mode_selector_class_init (GeditHighlightModeSelectorClass *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 (gedit_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/gnome/gedit/ui/gedit-highlight-mode-selector.ui");
-+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, treeview);
-+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, entry);
-+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, liststore);
-+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, treemodelfilter);
-+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, treeview_selection);
-+}
-+
-+static gboolean
-+visible_func (GtkTreeModel *model,
-+ GtkTreeIter *iter,
-+ GeditHighlightModeSelector *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,
-+ GeditHighlightModeSelector *selector)
-+{
-+ gedit_highlight_mode_selector_activate_selected_language (selector);
-+}
-+
-+static void
-+on_entry_changed (GtkEntry *entry,
-+ GeditHighlightModeSelector *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 (GeditHighlightModeSelector *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,
-+ GeditHighlightModeSelector *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,
-+ GeditHighlightModeSelector *selector)
-+{
-+ gedit_highlight_mode_selector_activate_selected_language (selector);
-+}
-+
-+static void
-+gedit_highlight_mode_selector_init (GeditHighlightModeSelector *selector)
-+{
-+ GtkSourceLanguageManager *lm;
-+ const gchar * const *ids;
-+ gint i;
-+ GtkTreeIter iter;
-+
-+ selector = gedit_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);
-+ }
-+}
-+
-+GeditHighlightModeSelector *
-+gedit_highlight_mode_selector_new ()
-+{
-+ return g_object_new (GEDIT_TYPE_HIGHLIGHT_MODE_SELECTOR, NULL);
-+}
-+
-+void
-+gedit_highlight_mode_selector_select_language (GeditHighlightModeSelector *selector,
-+ GtkSourceLanguage *language)
-+{
-+ GtkTreeIter iter;
-+
-+ g_return_if_fail (GEDIT_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
-+gedit_highlight_mode_selector_activate_selected_language (GeditHighlightModeSelector *selector)
-+{
-+ GtkSourceLanguage *lang;
-+ GtkTreeIter iter;
-+
-+ g_return_if_fail (GEDIT_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/gedit/gedit-highlight-mode-selector.h b/gedit/gedit-highlight-mode-selector.h
-new file mode 100644
-index 000000000..dc19e3cc4
---- /dev/null
-+++ b/gedit/gedit-highlight-mode-selector.h
-@@ -0,0 +1,44 @@
-+/*
-+ * gedit-highlight-mode-selector.h
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+#ifndef GEDIT_HIGHLIGHT_MODE_SELECTOR_H
-+#define GEDIT_HIGHLIGHT_MODE_SELECTOR_H
-+
-+#include
-+
-+G_BEGIN_DECLS
-+
-+#define GEDIT_TYPE_HIGHLIGHT_MODE_SELECTOR (gedit_highlight_mode_selector_get_type ())
-+
-+G_DECLARE_FINAL_TYPE (GeditHighlightModeSelector, gedit_highlight_mode_selector, GEDIT, HIGHLIGHT_MODE_SELECTOR, GtkGrid)
-+
-+GeditHighlightModeSelector *gedit_highlight_mode_selector_new (void);
-+
-+void gedit_highlight_mode_selector_select_language (GeditHighlightModeSelector *selector,
-+ GtkSourceLanguage *language);
-+
-+void gedit_highlight_mode_selector_activate_selected_language
-+ (GeditHighlightModeSelector *selector);
-+
-+G_END_DECLS
-+
-+#endif /* GEDIT_HIGHLIGHT_MODE_SELECTOR_H */
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-io-error-info-bar.c b/gedit/gedit-io-error-info-bar.c
-index 77ca04d7b..21e27e459 100644
---- a/gedit/gedit-io-error-info-bar.c
-+++ b/gedit/gedit-io-error-info-bar.c
-@@ -23,9 +23,16 @@
- */
-
- #include "gedit-io-error-info-bar.h"
-+
-+#include
-+#include
- #include
--#include
-+#include
-+
- #include "gedit-encodings-combo-box.h"
-+#include "gedit-settings.h"
-+#include "gedit-utils.h"
-+#include "gedit-document.h"
-
- #define MAX_URI_IN_DIALOG_LENGTH 50
-
-@@ -220,7 +227,7 @@ parse_gio_error (gint code,
- uri = g_file_get_uri (location);
- }
-
-- if (uri && tepl_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL))
-+ if (uri && gedit_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL))
- {
- if (hn != NULL)
- {
-@@ -323,8 +330,8 @@ gedit_unrecoverable_reverting_error_info_bar_new (GFile *location,
- * though the dialog uses wrapped text, if the URI doesn't contain
- * white space then the text-wrapping code is too stupid to wrap it.
- */
-- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
-- MAX_URI_IN_DIALOG_LENGTH);
-+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
-+ MAX_URI_IN_DIALOG_LENGTH);
- g_free (full_formatted_uri);
-
- uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
-@@ -534,8 +541,8 @@ gedit_io_loading_error_info_bar_new (GFile *location,
- * though the dialog uses wrapped text, if the URI doesn't contain
- * white space then the text-wrapping code is too stupid to wrap it.
- */
-- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
-- MAX_URI_IN_DIALOG_LENGTH);
-+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
-+ MAX_URI_IN_DIALOG_LENGTH);
- g_free (full_formatted_uri);
-
- uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
-@@ -655,8 +662,8 @@ gedit_conversion_error_while_saving_info_bar_new (GFile *locat
- * though the dialog uses wrapped text, if the URI doesn't contain
- * white space then the text-wrapping code is too stupid to wrap it.
- */
-- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
-- MAX_URI_IN_DIALOG_LENGTH);
-+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
-+ MAX_URI_IN_DIALOG_LENGTH);
- g_free (full_formatted_uri);
-
- uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
-@@ -700,6 +707,88 @@ gedit_conversion_error_info_bar_get_encoding (GtkWidget *info_bar)
- return NULL;
- }
-
-+GtkWidget *
-+gedit_file_already_open_warning_info_bar_new (GFile *location)
-+{
-+ GtkWidget *info_bar;
-+ GtkWidget *hbox_content;
-+ GtkWidget *vbox;
-+ gchar *primary_markup;
-+ gchar *secondary_markup;
-+ GtkWidget *primary_label;
-+ GtkWidget *secondary_label;
-+ gchar *primary_text;
-+ const gchar *secondary_text;
-+ gchar *full_formatted_uri;
-+ gchar *uri_for_display;
-+ gchar *temp_uri_for_display;
-+
-+ g_return_val_if_fail (G_IS_FILE (location), NULL);
-+
-+ full_formatted_uri = g_file_get_parse_name (location);
-+
-+ /* Truncate the URI so it doesn't get insanely wide. Note that even
-+ * though the dialog uses wrapped text, if the URI doesn't contain
-+ * white space then the text-wrapping code is too stupid to wrap it.
-+ */
-+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
-+ MAX_URI_IN_DIALOG_LENGTH);
-+ g_free (full_formatted_uri);
-+
-+ uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
-+ g_free (temp_uri_for_display);
-+
-+ info_bar = gtk_info_bar_new ();
-+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
-+ /* Translators: the access key chosen for this string should be
-+ different from other main menu access keys (Open, Edit, View...) */
-+ _("Edit Any_way"),
-+ GTK_RESPONSE_YES);
-+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
-+ /* Translators: the access key chosen for this string should be
-+ different from other main menu access keys (Open, Edit, View...) */
-+ _("D_on’t Edit"),
-+ GTK_RESPONSE_CANCEL);
-+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar),
-+ GTK_MESSAGE_WARNING);
-+
-+ hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
-+
-+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-+ gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
-+
-+ primary_text = g_strdup_printf (_("This file “%s” is already open in another window."), uri_for_display);
-+ g_free (uri_for_display);
-+
-+ primary_markup = g_strdup_printf ("%s", primary_text);
-+ g_free (primary_text);
-+ primary_label = gtk_label_new (primary_markup);
-+ g_free (primary_markup);
-+ gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
-+ gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
-+ gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
-+ gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
-+ gtk_widget_set_can_focus (primary_label, TRUE);
-+ gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
-+
-+ secondary_text = _("Do you want to edit it anyway?");
-+ secondary_markup = g_strdup_printf ("%s",
-+ secondary_text);
-+ secondary_label = gtk_label_new (secondary_markup);
-+ g_free (secondary_markup);
-+ gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
-+ gtk_widget_set_can_focus (secondary_label, TRUE);
-+ gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
-+ gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
-+ gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
-+ gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
-+
-+ gtk_widget_show_all (hbox_content);
-+ set_contents (info_bar, hbox_content);
-+
-+ return info_bar;
-+}
-+
- GtkWidget *
- gedit_externally_modified_saving_error_info_bar_new (GFile *location,
- const GError *error)
-@@ -728,8 +817,8 @@ gedit_externally_modified_saving_error_info_bar_new (GFile *location,
- * though the dialog uses wrapped text, if the URI doesn't contain
- * white space then the text-wrapping code is too stupid to wrap it.
- */
-- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
-- MAX_URI_IN_DIALOG_LENGTH);
-+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
-+ MAX_URI_IN_DIALOG_LENGTH);
- g_free (full_formatted_uri);
-
- uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
-@@ -788,6 +877,110 @@ gedit_externally_modified_saving_error_info_bar_new (GFile *location,
- return info_bar;
- }
-
-+GtkWidget *
-+gedit_no_backup_saving_error_info_bar_new (GFile *location,
-+ const GError *error)
-+{
-+ GtkWidget *info_bar;
-+ GtkWidget *hbox_content;
-+ GtkWidget *vbox;
-+ gchar *primary_markup;
-+ gchar *secondary_markup;
-+ GtkWidget *primary_label;
-+ GtkWidget *secondary_label;
-+ gchar *primary_text;
-+ const gchar *secondary_text;
-+ gchar *full_formatted_uri;
-+ gchar *uri_for_display;
-+ gchar *temp_uri_for_display;
-+ gboolean create_backup_copy;
-+ GSettings *editor_settings;
-+
-+ g_return_val_if_fail (G_IS_FILE (location), NULL);
-+ g_return_val_if_fail (error != NULL, NULL);
-+ g_return_val_if_fail (error->domain == G_IO_ERROR &&
-+ error->code == G_IO_ERROR_CANT_CREATE_BACKUP, NULL);
-+
-+ full_formatted_uri = g_file_get_parse_name (location);
-+
-+ /* Truncate the URI so it doesn't get insanely wide. Note that even
-+ * though the dialog uses wrapped text, if the URI doesn't contain
-+ * white space then the text-wrapping code is too stupid to wrap it.
-+ */
-+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
-+ MAX_URI_IN_DIALOG_LENGTH);
-+ g_free (full_formatted_uri);
-+
-+ uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
-+ g_free (temp_uri_for_display);
-+
-+ info_bar = gtk_info_bar_new ();
-+
-+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
-+ _("S_ave Anyway"),
-+ GTK_RESPONSE_YES);
-+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
-+ _("D_on’t Save"),
-+ GTK_RESPONSE_CANCEL);
-+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar),
-+ GTK_MESSAGE_WARNING);
-+
-+ hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
-+
-+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-+ gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
-+
-+ editor_settings = g_settings_new ("org.gnome.gedit.preferences.editor");
-+
-+ create_backup_copy = g_settings_get_boolean (editor_settings,
-+ GEDIT_SETTINGS_CREATE_BACKUP_COPY);
-+ g_object_unref (editor_settings);
-+
-+ /* FIXME: review this messages */
-+ if (create_backup_copy)
-+ {
-+ primary_text = g_strdup_printf (_("Could not create a backup file while saving “%s”"),
-+ uri_for_display);
-+ }
-+ else
-+ {
-+ primary_text = g_strdup_printf (_("Could not create a temporary backup file while saving “%s”"),
-+ uri_for_display);
-+ }
-+
-+ g_free (uri_for_display);
-+
-+ primary_markup = g_strdup_printf ("%s", primary_text);
-+ g_free (primary_text);
-+ primary_label = gtk_label_new (primary_markup);
-+ g_free (primary_markup);
-+ gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
-+ gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
-+ gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
-+ gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
-+ gtk_widget_set_can_focus (primary_label, TRUE);
-+ gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
-+
-+ secondary_text = _("Could not back up the old copy of the file before saving the new one. "
-+ "You can ignore this warning and save the file anyway, but if an error "
-+ "occurs while saving, you could lose the old copy of the file. Save anyway?");
-+ secondary_markup = g_strdup_printf ("%s",
-+ secondary_text);
-+ secondary_label = gtk_label_new (secondary_markup);
-+ g_free (secondary_markup);
-+ gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
-+ gtk_widget_set_can_focus (secondary_label, TRUE);
-+ gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
-+ gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
-+ gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
-+ gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
-+
-+ gtk_widget_show_all (hbox_content);
-+ set_contents (info_bar, hbox_content);
-+
-+ return info_bar;
-+}
-+
- GtkWidget *
- gedit_unrecoverable_saving_error_info_bar_new (GFile *location,
- const GError *error)
-@@ -812,8 +1005,8 @@ gedit_unrecoverable_saving_error_info_bar_new (GFile *location,
- * though the dialog uses wrapped text, if the URI doesn't contain
- * white space then the text-wrapping code is too stupid to wrap it.
- */
-- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
-- MAX_URI_IN_DIALOG_LENGTH);
-+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
-+ MAX_URI_IN_DIALOG_LENGTH);
- g_free (full_formatted_uri);
-
- uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
-@@ -917,4 +1110,149 @@ gedit_unrecoverable_saving_error_info_bar_new (GFile *location,
- return info_bar;
- }
-
-+GtkWidget *
-+gedit_externally_modified_info_bar_new (GFile *location,
-+ gboolean document_modified)
-+{
-+ gchar *full_formatted_uri;
-+ gchar *uri_for_display;
-+ gchar *temp_uri_for_display;
-+ gchar *primary_text;
-+ GtkWidget *info_bar;
-+
-+ g_return_val_if_fail (G_IS_FILE (location), NULL);
-+
-+ full_formatted_uri = g_file_get_parse_name (location);
-+
-+ /* Truncate the URI so it doesn't get insanely wide. Note that even
-+ * though the dialog uses wrapped text, if the URI doesn't contain
-+ * white space then the text-wrapping code is too stupid to wrap it.
-+ */
-+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
-+ MAX_URI_IN_DIALOG_LENGTH);
-+ g_free (full_formatted_uri);
-+
-+ uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
-+ g_free (temp_uri_for_display);
-+
-+ primary_text = g_strdup_printf (_("The file “%s” changed on disk."),
-+ uri_for_display);
-+ g_free (uri_for_display);
-+
-+ info_bar = gtk_info_bar_new ();
-+
-+ if (document_modified)
-+ {
-+ GtkWidget *box;
-+ GtkWidget *button;
-+ button = gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
-+ _("Drop Changes and _Reload"),
-+ GTK_RESPONSE_OK);
-+ box = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
-+ gtk_button_box_set_child_non_homogeneous (GTK_BUTTON_BOX (box),
-+ button,
-+ TRUE);
-+ }
-+ else
-+ {
-+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
-+ _("_Reload"),
-+ GTK_RESPONSE_OK);
-+ }
-+
-+ gtk_info_bar_set_show_close_button (GTK_INFO_BAR (info_bar), TRUE);
-+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar),
-+ GTK_MESSAGE_WARNING);
-+
-+ set_info_bar_text (info_bar,
-+ primary_text,
-+ NULL);
-+
-+ g_free (primary_text);
-+
-+ return info_bar;
-+}
-+
-+GtkWidget *
-+gedit_invalid_character_info_bar_new (GFile *location)
-+{
-+ GtkWidget *info_bar;
-+ GtkWidget *hbox_content;
-+ GtkWidget *vbox;
-+ GtkWidget *primary_label;
-+ GtkWidget *secondary_label;
-+ gchar *primary_markup;
-+ gchar *secondary_markup;
-+ gchar *primary_text;
-+ gchar *full_formatted_uri;
-+ gchar *uri_for_display;
-+ gchar *temp_uri_for_display;
-+ const gchar *secondary_text;
-+
-+ g_return_val_if_fail (G_IS_FILE (location), NULL);
-+
-+ full_formatted_uri = g_file_get_parse_name (location);
-+
-+ /* Truncate the URI so it doesn't get insanely wide. Note that even
-+ * though the dialog uses wrapped text, if the URI doesn't contain
-+ * white space then the text-wrapping code is too stupid to wrap it.
-+ */
-+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
-+ MAX_URI_IN_DIALOG_LENGTH);
-+ g_free (full_formatted_uri);
-+
-+ uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
-+ g_free (temp_uri_for_display);
-+
-+ info_bar = gtk_info_bar_new ();
-+
-+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
-+ _("S_ave Anyway"),
-+ GTK_RESPONSE_YES);
-+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
-+ _("D_on’t Save"),
-+ GTK_RESPONSE_CANCEL);
-+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar),
-+ GTK_MESSAGE_WARNING);
-+
-+ hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
-+
-+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
-+ gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
-+
-+ primary_text = g_strdup_printf (_("Some invalid chars have been detected while saving “%s”"),
-+ uri_for_display);
-+
-+ g_free (uri_for_display);
-+
-+ primary_markup = g_strdup_printf ("%s", primary_text);
-+ g_free (primary_text);
-+ primary_label = gtk_label_new (primary_markup);
-+ g_free (primary_markup);
-+ gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
-+ gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
-+ gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
-+ gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
-+ gtk_widget_set_can_focus (primary_label, TRUE);
-+ gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
-+
-+ secondary_text = _("If you continue saving this file you can corrupt the document. "
-+ " Save anyway?");
-+ secondary_markup = g_strdup_printf ("%s",
-+ secondary_text);
-+ secondary_label = gtk_label_new (secondary_markup);
-+ g_free (secondary_markup);
-+ gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
-+ gtk_widget_set_can_focus (secondary_label, TRUE);
-+ gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
-+ gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
-+ gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
-+ gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
-+
-+ gtk_widget_show_all (hbox_content);
-+ set_contents (info_bar, hbox_content);
-+
-+ return info_bar;
-+}
-+
- /* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-io-error-info-bar.h b/gedit/gedit-io-error-info-bar.h
-index 12780f7ae..9784652c7 100644
---- a/gedit/gedit-io-error-info-bar.h
-+++ b/gedit/gedit-io-error-info-bar.h
-@@ -39,12 +39,22 @@ GtkWidget *gedit_conversion_error_while_saving_info_bar_new (GFile
- const GtkSourceEncoding
- *gedit_conversion_error_info_bar_get_encoding (GtkWidget *info_bar);
-
-+GtkWidget *gedit_file_already_open_warning_info_bar_new (GFile *location);
-+
- GtkWidget *gedit_externally_modified_saving_error_info_bar_new (GFile *location,
- const GError *error);
-
-+GtkWidget *gedit_no_backup_saving_error_info_bar_new (GFile *location,
-+ const GError *error);
-+
- GtkWidget *gedit_unrecoverable_saving_error_info_bar_new (GFile *location,
- const GError *error);
-
-+GtkWidget *gedit_externally_modified_info_bar_new (GFile *location,
-+ gboolean document_modified);
-+
-+GtkWidget *gedit_invalid_character_info_bar_new (GFile *location);
-+
- G_END_DECLS
-
- #endif /* GEDIT_IO_ERROR_INFO_BAR_H */
-diff --git a/gedit/gedit-metadata-manager.c b/gedit/gedit-metadata-manager.c
-new file mode 100644
-index 000000000..8f858b286
---- /dev/null
-+++ b/gedit/gedit-metadata-manager.c
-@@ -0,0 +1,650 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-+/*
-+ * gedit-metadata-manager.c
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2003-2007 Paolo Maggi
-+ * Copyright (C) 2019 Canonical LTD
-+ *
-+ * 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 "gedit-metadata-manager.h"
-+#include
-+#include "gedit-debug.h"
-+
-+/*
-+#define GEDIT_METADATA_VERBOSE_DEBUG 1
-+*/
-+
-+#define MAX_ITEMS 50
-+
-+typedef struct _Item Item;
-+
-+struct _Item
-+{
-+ /* Time of last access in seconds since January 1, 1970 UTC. */
-+ gint64 atime;
-+
-+ GHashTable *values;
-+};
-+
-+struct _GeditMetadataManager
-+{
-+ GObject parent_instance;
-+
-+ /* It is true if the file has been read. */
-+ gboolean values_loaded;
-+
-+ guint timeout_id;
-+
-+ GHashTable *items;
-+
-+ gchar *metadata_filename;
-+};
-+
-+enum
-+{
-+ PROP_0,
-+ PROP_METADATA_FILENAME,
-+ LAST_PROP
-+};
-+
-+static GParamSpec *properties[LAST_PROP];
-+
-+G_DEFINE_TYPE (GeditMetadataManager, gedit_metadata_manager, G_TYPE_OBJECT);
-+
-+static gboolean gedit_metadata_manager_save (GeditMetadataManager *self);
-+
-+static void
-+item_free (gpointer data)
-+{
-+ Item *item;
-+
-+ g_return_if_fail (data != NULL);
-+
-+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
-+ gedit_debug (DEBUG_METADATA);
-+#endif
-+
-+ item = (Item *)data;
-+
-+ if (item->values != NULL)
-+ g_hash_table_destroy (item->values);
-+
-+ g_free (item);
-+}
-+
-+static void
-+gedit_metadata_manager_arm_timeout (GeditMetadataManager *self)
-+{
-+ if (self->timeout_id == 0)
-+ {
-+ self->timeout_id =
-+ g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE,
-+ 2,
-+ (GSourceFunc)gedit_metadata_manager_save,
-+ self,
-+ NULL);
-+ }
-+}
-+
-+static void
-+gedit_metadata_manager_parse_item (GeditMetadataManager *self,
-+ xmlDocPtr doc,
-+ xmlNodePtr cur)
-+{
-+ Item *item;
-+
-+ xmlChar *uri;
-+ xmlChar *atime;
-+
-+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
-+ gedit_debug (DEBUG_METADATA);
-+#endif
-+
-+ if (xmlStrcmp (cur->name, (const xmlChar *)"document") != 0)
-+ return;
-+
-+ uri = xmlGetProp (cur, (const xmlChar *)"uri");
-+ if (uri == NULL)
-+ return;
-+
-+ atime = xmlGetProp (cur, (const xmlChar *)"atime");
-+ if (atime == NULL)
-+ {
-+ xmlFree (uri);
-+ return;
-+ }
-+
-+ item = g_new0 (Item, 1);
-+
-+ item->atime = g_ascii_strtoll ((char *)atime, NULL, 0);
-+
-+ item->values = g_hash_table_new_full (g_str_hash,
-+ g_str_equal,
-+ g_free,
-+ g_free);
-+
-+ cur = cur->xmlChildrenNode;
-+
-+ while (cur != NULL)
-+ {
-+ if (xmlStrcmp (cur->name, (const xmlChar *)"entry") == 0)
-+ {
-+ xmlChar *key;
-+ xmlChar *value;
-+
-+ key = xmlGetProp (cur, (const xmlChar *)"key");
-+ value = xmlGetProp (cur, (const xmlChar *)"value");
-+
-+ if ((key != NULL) && (value != NULL))
-+ {
-+ g_hash_table_insert (item->values,
-+ g_strdup ((gchar *)key),
-+ g_strdup ((gchar *)value));
-+ }
-+
-+ if (key != NULL)
-+ xmlFree (key);
-+ if (value != NULL)
-+ xmlFree (value);
-+ }
-+
-+ cur = cur->next;
-+ }
-+
-+ g_hash_table_insert (self->items,
-+ g_strdup ((gchar *)uri),
-+ item);
-+
-+ xmlFree (uri);
-+ xmlFree (atime);
-+}
-+
-+/* Returns FALSE in case of error. */
-+static gboolean
-+gedit_metadata_manager_load_values (GeditMetadataManager *self)
-+{
-+ xmlDocPtr doc;
-+ xmlNodePtr cur;
-+
-+ gedit_debug (DEBUG_METADATA);
-+
-+ g_return_val_if_fail (self != NULL, FALSE);
-+ g_return_val_if_fail (self->values_loaded == FALSE, FALSE);
-+
-+ self->values_loaded = TRUE;
-+
-+ xmlKeepBlanksDefault (0);
-+
-+ if (self->metadata_filename == NULL)
-+ {
-+ return FALSE;
-+ }
-+
-+ /* TODO: avoid races */
-+ if (!g_file_test (self->metadata_filename, G_FILE_TEST_EXISTS))
-+ {
-+ return TRUE;
-+ }
-+
-+ doc = xmlParseFile (self->metadata_filename);
-+
-+ if (doc == NULL)
-+ {
-+ return FALSE;
-+ }
-+
-+ cur = xmlDocGetRootElement (doc);
-+ if (cur == NULL)
-+ {
-+ g_message ("The metadata file '%s' is empty",
-+ g_path_get_basename (self->metadata_filename));
-+ xmlFreeDoc (doc);
-+
-+ return TRUE;
-+ }
-+
-+ if (xmlStrcmp (cur->name, (const xmlChar *) "metadata"))
-+ {
-+ g_message ("File '%s' is of the wrong type",
-+ g_path_get_basename (self->metadata_filename));
-+ xmlFreeDoc (doc);
-+
-+ return FALSE;
-+ }
-+
-+ cur = xmlDocGetRootElement (doc);
-+ cur = cur->xmlChildrenNode;
-+
-+ while (cur != NULL)
-+ {
-+ gedit_metadata_manager_parse_item (self, doc, cur);
-+
-+ cur = cur->next;
-+ }
-+
-+ xmlFreeDoc (doc);
-+
-+ return TRUE;
-+}
-+
-+/**
-+ * gedit_metadata_manager_get:
-+ * @self: a #GeditMetadataManager.
-+ * @location: a #GFile.
-+ * @key: a key.
-+ *
-+ * Gets the value associated with the specified @key for the file @location.
-+ */
-+gchar *
-+gedit_metadata_manager_get (GeditMetadataManager *self,
-+ GFile *location,
-+ const gchar *key)
-+{
-+ Item *item;
-+ gchar *value;
-+ gchar *uri;
-+
-+ g_return_val_if_fail (GEDIT_IS_METADATA_MANAGER (self), NULL);
-+ g_return_val_if_fail (G_IS_FILE (location), NULL);
-+ g_return_val_if_fail (key != NULL, NULL);
-+
-+ uri = g_file_get_uri (location);
-+
-+ gedit_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key );
-+
-+ if (!self->values_loaded)
-+ {
-+ gboolean res;
-+
-+ res = gedit_metadata_manager_load_values (self);
-+
-+ if (!res)
-+ {
-+ g_free (uri);
-+ return NULL;
-+ }
-+ }
-+
-+ item = (Item *)g_hash_table_lookup (self->items, uri);
-+
-+ g_free (uri);
-+
-+ if (item == NULL)
-+ return NULL;
-+
-+ item->atime = g_get_real_time () / 1000;
-+
-+ if (item->values == NULL)
-+ return NULL;
-+
-+ value = g_hash_table_lookup (item->values, key);
-+
-+ if (value == NULL)
-+ return NULL;
-+ else
-+ return g_strdup (value);
-+}
-+
-+/**
-+ * gedit_metadata_manager_set:
-+ * @self: a #GeditMetadataManager.
-+ * @location: a #GFile.
-+ * @key: a key.
-+ * @value: the value associated with the @key.
-+ *
-+ * Sets the @key to contain the given @value for the file @location.
-+ */
-+void
-+gedit_metadata_manager_set (GeditMetadataManager *self,
-+ GFile *location,
-+ const gchar *key,
-+ const gchar *value)
-+{
-+ Item *item;
-+ gchar *uri;
-+
-+ g_return_if_fail (GEDIT_IS_METADATA_MANAGER (self));
-+ g_return_if_fail (G_IS_FILE (location));
-+ g_return_if_fail (key != NULL);
-+
-+ uri = g_file_get_uri (location);
-+
-+ gedit_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value);
-+
-+ if (!self->values_loaded)
-+ {
-+ gboolean ok;
-+
-+ ok = gedit_metadata_manager_load_values (self);
-+
-+ if (!ok)
-+ {
-+ g_free (uri);
-+ return;
-+ }
-+ }
-+
-+ item = (Item *)g_hash_table_lookup (self->items, uri);
-+
-+ if (item == NULL)
-+ {
-+ item = g_new0 (Item, 1);
-+
-+ g_hash_table_insert (self->items,
-+ g_strdup (uri),
-+ item);
-+ }
-+
-+ if (item->values == NULL)
-+ {
-+ item->values = g_hash_table_new_full (g_str_hash,
-+ g_str_equal,
-+ g_free,
-+ g_free);
-+ }
-+
-+ if (value != NULL)
-+ {
-+ g_hash_table_insert (item->values,
-+ g_strdup (key),
-+ g_strdup (value));
-+ }
-+ else
-+ {
-+ g_hash_table_remove (item->values,
-+ key);
-+ }
-+
-+ item->atime = g_get_real_time () / 1000;
-+
-+ g_free (uri);
-+
-+ gedit_metadata_manager_arm_timeout (self);
-+}
-+
-+static void
-+save_values (const gchar *key, const gchar *value, xmlNodePtr parent)
-+{
-+ xmlNodePtr xml_node;
-+
-+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
-+ gedit_debug (DEBUG_METADATA);
-+#endif
-+
-+ g_return_if_fail (key != NULL);
-+
-+ if (value == NULL)
-+ return;
-+
-+ xml_node = xmlNewChild (parent,
-+ NULL,
-+ (const xmlChar *)"entry",
-+ NULL);
-+
-+ xmlSetProp (xml_node,
-+ (const xmlChar *)"key",
-+ (const xmlChar *)key);
-+ xmlSetProp (xml_node,
-+ (const xmlChar *)"value",
-+ (const xmlChar *)value);
-+
-+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
-+ gedit_debug_message (DEBUG_METADATA, "entry: %s = %s", key, value);
-+#endif
-+}
-+
-+static void
-+save_item (const gchar *key, const gpointer *data, xmlNodePtr parent)
-+{
-+ xmlNodePtr xml_node;
-+ const Item *item = (const Item *)data;
-+ gchar *atime;
-+
-+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
-+ gedit_debug (DEBUG_METADATA);
-+#endif
-+
-+ g_return_if_fail (key != NULL);
-+
-+ if (item == NULL)
-+ return;
-+
-+ xml_node = xmlNewChild (parent, NULL, (const xmlChar *)"document", NULL);
-+
-+ xmlSetProp (xml_node, (const xmlChar *)"uri", (const xmlChar *)key);
-+
-+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
-+ gedit_debug_message (DEBUG_METADATA, "uri: %s", key);
-+#endif
-+
-+ atime = g_strdup_printf ("%" G_GINT64_FORMAT, item->atime);
-+ xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime);
-+
-+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
-+ gedit_debug_message (DEBUG_METADATA, "atime: %s", atime);
-+#endif
-+
-+ g_free (atime);
-+
-+ g_hash_table_foreach (item->values,
-+ (GHFunc)save_values,
-+ xml_node);
-+}
-+
-+static const gchar *
-+gedit_metadata_manager_get_oldest (GeditMetadataManager *self)
-+{
-+ GHashTableIter iter;
-+ gpointer key, value, key_to_remove = NULL;
-+ const Item *item_to_remove = NULL;
-+
-+ g_hash_table_iter_init (&iter, self->items);
-+ while (g_hash_table_iter_next (&iter, &key, &value))
-+ {
-+ const Item *item = (const Item *) value;
-+
-+ if (key_to_remove == NULL)
-+ {
-+ key_to_remove = key;
-+ item_to_remove = item;
-+ }
-+ else
-+ {
-+ g_return_val_if_fail (item_to_remove != NULL, NULL);
-+
-+ if (item->atime < item_to_remove->atime)
-+ key_to_remove = key;
-+ }
-+ }
-+
-+ return key_to_remove;
-+}
-+
-+static void
-+gedit_metadata_manager_resize_items (GeditMetadataManager *self)
-+{
-+ while (g_hash_table_size (self->items) > MAX_ITEMS)
-+ {
-+ const gchar *key_to_remove;
-+
-+ key_to_remove = gedit_metadata_manager_get_oldest (self);
-+ g_return_if_fail (key_to_remove != NULL);
-+ g_hash_table_remove (self->items,
-+ key_to_remove);
-+ }
-+}
-+
-+static gboolean
-+gedit_metadata_manager_save (GeditMetadataManager *self)
-+{
-+ xmlDocPtr doc;
-+ xmlNodePtr root;
-+
-+ gedit_debug (DEBUG_METADATA);
-+
-+ self->timeout_id = 0;
-+
-+ gedit_metadata_manager_resize_items (self);
-+
-+ xmlIndentTreeOutput = TRUE;
-+
-+ doc = xmlNewDoc ((const xmlChar *)"1.0");
-+ if (doc == NULL)
-+ return TRUE;
-+
-+ /* Create metadata root */
-+ root = xmlNewDocNode (doc, NULL, (const xmlChar *)"metadata", NULL);
-+ xmlDocSetRootElement (doc, root);
-+
-+ g_hash_table_foreach (self->items,
-+ (GHFunc)save_item,
-+ root);
-+
-+ /* FIXME: lock file - Paolo */
-+ if (self->metadata_filename != NULL)
-+ {
-+ gchar *cache_dir;
-+ int res;
-+
-+ /* make sure the cache dir exists */
-+ cache_dir = g_path_get_dirname (self->metadata_filename);
-+ res = g_mkdir_with_parents (cache_dir, 0755);
-+ if (res != -1)
-+ {
-+ xmlSaveFormatFile (self->metadata_filename,
-+ doc,
-+ 1);
-+ }
-+
-+ g_free (cache_dir);
-+ }
-+
-+ xmlFreeDoc (doc);
-+
-+ gedit_debug_message (DEBUG_METADATA, "DONE");
-+
-+ return FALSE;
-+}
-+
-+static void
-+gedit_metadata_manager_get_property (GObject *object,
-+ guint prop_id,
-+ GValue *value,
-+ GParamSpec *pspec)
-+{
-+ GeditMetadataManager *self = GEDIT_METADATA_MANAGER (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_METADATA_FILENAME:
-+ g_value_set_string (value, self->metadata_filename);
-+ break;
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ break;
-+ }
-+}
-+
-+
-+static void
-+gedit_metadata_manager_set_property (GObject *object,
-+ guint prop_id,
-+ const GValue *value,
-+ GParamSpec *pspec)
-+{
-+ GeditMetadataManager *self = GEDIT_METADATA_MANAGER (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_METADATA_FILENAME:
-+ self->metadata_filename = g_value_dup_string (value);
-+ break;
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ break;
-+ }
-+}
-+
-+static void
-+gedit_metadata_manager_init (GeditMetadataManager *self)
-+{
-+ gedit_debug (DEBUG_METADATA);
-+
-+ self->values_loaded = FALSE;
-+
-+ self->items =
-+ g_hash_table_new_full (g_str_hash,
-+ g_str_equal,
-+ g_free,
-+ item_free);
-+}
-+
-+static void
-+gedit_metadata_manager_dispose (GObject *object)
-+{
-+ GeditMetadataManager *self = GEDIT_METADATA_MANAGER (object);
-+
-+ gedit_debug (DEBUG_METADATA);
-+
-+ if (self->timeout_id)
-+ {
-+ g_source_remove (self->timeout_id);
-+ self->timeout_id = 0;
-+ gedit_metadata_manager_save (self);
-+ }
-+
-+ if (self->items != NULL)
-+ g_hash_table_destroy (self->items);
-+
-+ g_free (self->metadata_filename);
-+}
-+
-+static void
-+gedit_metadata_manager_class_init (GeditMetadataManagerClass *klass)
-+{
-+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
-+
-+ object_class->dispose = gedit_metadata_manager_dispose;
-+ object_class->get_property = gedit_metadata_manager_get_property;
-+ object_class->set_property = gedit_metadata_manager_set_property;
-+
-+ /**
-+ * GeditMetadataManager:metadata-filename:
-+ *
-+ * The filename where the metadata is stored.
-+ */
-+ properties[PROP_METADATA_FILENAME] =
-+ g_param_spec_string ("metadata-filename",
-+ "Metadata filename",
-+ "The filename where the metadata is stored",
-+ NULL,
-+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-+
-+ g_object_class_install_properties (object_class, LAST_PROP, properties);
-+}
-+
-+GeditMetadataManager *
-+gedit_metadata_manager_new (const gchar *metadata_filename)
-+{
-+ gedit_debug (DEBUG_METADATA);
-+
-+ return g_object_new (GEDIT_TYPE_METADATA_MANAGER,
-+ "metadata-filename", metadata_filename,
-+ NULL);
-+}
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-metadata-manager.h b/gedit/gedit-metadata-manager.h
-new file mode 100644
-index 000000000..49c2f05bf
---- /dev/null
-+++ b/gedit/gedit-metadata-manager.h
-@@ -0,0 +1,49 @@
-+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-+/*
-+ * gedit-metadata-manager.h
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2003 Paolo Maggi
-+ * Copyright (C) 2019 Canonical LTD
-+ *
-+ * 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 GEDIT_METADATA_MANAGER_H
-+#define GEDIT_METADATA_MANAGER_H
-+
-+#include
-+
-+G_BEGIN_DECLS
-+
-+#define GEDIT_TYPE_METADATA_MANAGER (gedit_metadata_manager_get_type())
-+
-+G_DECLARE_FINAL_TYPE (GeditMetadataManager, gedit_metadata_manager, GEDIT, METADATA_MANAGER, GObject)
-+
-+GeditMetadataManager *gedit_metadata_manager_new (const gchar *metadata_filename);
-+
-+gchar *gedit_metadata_manager_get (GeditMetadataManager *self,
-+ GFile *location,
-+ const gchar *key);
-+
-+void gedit_metadata_manager_set (GeditMetadataManager *self,
-+ GFile *location,
-+ const gchar *key,
-+ const gchar *value);
-+
-+G_END_DECLS
-+
-+#endif /* GEDIT_METADATA_MANAGER_H */
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-open-document-selector-helper.c b/gedit/gedit-open-document-selector-helper.c
-new file mode 100644
-index 000000000..369d12ea2
---- /dev/null
-+++ b/gedit/gedit-open-document-selector-helper.c
-@@ -0,0 +1,103 @@
-+/*
-+ * gedit-open-document-selector-helper.c
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2015 - Sébastien Lafargue
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+#include "gedit-open-document-selector-helper.h"
-+
-+void
-+gedit_open_document_selector_debug_print_list (const gchar *title,
-+ GList *fileitem_list)
-+{
-+ FileItem *item;
-+ GList *l;
-+ glong time_sec;
-+ glong time_usec;
-+
-+ g_print ("%s\n", title);
-+
-+ for (l = fileitem_list; l != NULL; l = l->next)
-+ {
-+ item = (FileItem *)l->data;
-+ time_sec = item->access_time.tv_sec;
-+ time_usec = item->access_time.tv_usec;
-+
-+ g_print ("%ld:%ld uri:%s (%s %s)\n",
-+ time_sec,
-+ time_usec,
-+ item->uri,
-+ item->name,
-+ item->path);
-+ }
-+}
-+
-+FileItem *
-+gedit_open_document_selector_create_fileitem_item (void)
-+{
-+ FileItem *item;
-+
-+ item = g_slice_new0 (FileItem);
-+
-+ return item;
-+}
-+
-+void
-+gedit_open_document_selector_free_fileitem_item (FileItem *item)
-+{
-+ g_free (item->uri);
-+ g_free (item->name);
-+ g_free (item->path);
-+
-+ g_slice_free (FileItem, item);
-+}
-+
-+FileItem *
-+gedit_open_document_selector_copy_fileitem_item (FileItem *item)
-+{
-+ FileItem *new_item;
-+
-+ new_item = gedit_open_document_selector_create_fileitem_item ();
-+
-+ new_item->uri = g_strdup (item->uri);
-+ new_item->name = g_strdup (item->name);
-+ new_item->path = g_strdup (item->path);
-+ new_item->access_time = item->access_time;
-+
-+ return new_item;
-+}
-+
-+inline GList *
-+gedit_open_document_selector_copy_file_items_list (const GList *file_items_list)
-+{
-+ GList *new_file_items_list;
-+
-+ new_file_items_list = g_list_copy_deep ((GList *)file_items_list,
-+ (GCopyFunc)gedit_open_document_selector_copy_fileitem_item,
-+ NULL);
-+
-+ return new_file_items_list;
-+}
-+
-+inline void
-+gedit_open_document_selector_free_file_items_list (GList *file_items_list)
-+{
-+ g_list_free_full (file_items_list,
-+ (GDestroyNotify)gedit_open_document_selector_free_fileitem_item);
-+}
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-open-document-selector-helper.h b/gedit/gedit-open-document-selector-helper.h
-new file mode 100644
-index 000000000..6feb65408
---- /dev/null
-+++ b/gedit/gedit-open-document-selector-helper.h
-@@ -0,0 +1,103 @@
-+/*
-+ * gedit-open-document-selector-helper.h
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2015 - Sébastien Lafargue
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+#ifndef GEDIT_OPEN_DOCUMENT_SELECTOR_HELPER_H
-+#define GEDIT_OPEN_DOCUMENT_SELECTOR_HELPER_H
-+
-+#include "gedit-open-document-selector.h"
-+
-+#include
-+
-+G_BEGIN_DECLS
-+
-+typedef struct
-+{
-+ gchar *uri;
-+ gchar *name;
-+ gchar *path;
-+ GTimeVal access_time;
-+} FileItem;
-+
-+typedef enum
-+{
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST = 0,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_HOME_DIR_LIST,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_DESKTOP_DIR_LIST,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_LOCAL_BOOKMARKS_DIR_LIST,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_FILE_BROWSER_ROOT_DIR_LIST,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_ACTIVE_DOC_DIR_LIST,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_CURRENT_DOCS_LIST,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_LIST_TYPE_NUM_OF_LISTS
-+} ListType;
-+
-+/* Use #if 1 and rebuild to activate selector debugging and timing */
-+#if 0
-+#define DEBUG_OPEN_DOCUMENT_SELECTOR
-+#endif
-+
-+#ifdef DEBUG_OPEN_DOCUMENT_SELECTOR
-+G_GNUC_UNUSED static const gchar *list_type_string[] =
-+{
-+ "RECENT_FILES_LIST",
-+ "HOME_DIR_LIST",
-+ "DESKTOP_DIR_LIST",
-+ "LOCAL_BOOKMARKS_DIR_LIST",
-+ "FILE_BROWSER_ROOT_DIR_LIST",
-+ "ACTIVE_DOC_DIR_LIST",
-+ "CURRENT_DOCS_LIST"
-+};
-+
-+#define DEBUG_SELECTOR(x) do { x; } while (0)
-+#define DEBUG_SELECTOR_TIMER_DECL G_GNUC_UNUSED GTimer *debug_timer;
-+#define DEBUG_SELECTOR_TIMER_NEW debug_timer = g_timer_new ();
-+#define DEBUG_SELECTOR_TIMER_DESTROY g_timer_destroy (debug_timer);
-+#define DEBUG_SELECTOR_TIMER_GET g_timer_elapsed (debug_timer, NULL)
-+#else
-+#define DEBUG_SELECTOR(x)
-+#define DEBUG_SELECTOR_TIMER_DECL
-+#define DEBUG_SELECTOR_TIMER_NEW
-+#define DEBUG_SELECTOR_TIMER_DESTROY
-+#define DEBUG_SELECTOR_TIMER_GET
-+#endif
-+
-+typedef struct
-+{
-+ GeditOpenDocumentSelector *selector;
-+ ListType type;
-+} PushMessage;
-+
-+void gedit_open_document_selector_debug_print_list (const gchar *title,
-+ GList *fileitem_list);
-+
-+GList *gedit_open_document_selector_copy_file_items_list (const GList *file_items_list);
-+
-+void gedit_open_document_selector_free_file_items_list (GList *file_items_list);
-+
-+FileItem *gedit_open_document_selector_create_fileitem_item (void);
-+
-+void gedit_open_document_selector_free_fileitem_item (FileItem *item);
-+
-+FileItem *gedit_open_document_selector_copy_fileitem_item (FileItem *item);
-+
-+G_END_DECLS
-+
-+#endif /* GEDIT_OPEN_DOCUMENT_SELECTOR_HELPER_H */
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-open-document-selector-store.c b/gedit/gedit-open-document-selector-store.c
-new file mode 100644
-index 000000000..e3454f12c
---- /dev/null
-+++ b/gedit/gedit-open-document-selector-store.c
-@@ -0,0 +1,820 @@
-+/*
-+ * gedit-open-document-selector-store.c
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2015 - Sébastien Lafargue
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+/* You need to call gedit_open_document_selector_store_get_default()
-+ * to get a singleton #GeditOpenDocumentSelectorStore object.
-+ * #GeditOpenDocumentSelectorStore is responsible of managing
-+ * the recent files list and computing others lists.
-+ *
-+ * The lists returned are lists of FileItem structs.
-+ *
-+ * #GeditOpenDocumentSelectorStore is destroyed automaticly at
-+ * the end of your application.
-+ *
-+ * Call gedit_open_document_selector_store_update_list_async() with
-+ * the corresponding ListType, then in your callback, call
-+ * gedit_open_document_selector_store_update_list_finish() to get
-+ * in return the list of FileItem structs.
-+ *
-+ * The recent files list can be filtered by calling
-+ * gedit_open_document_selector_store_set_filter()
-+ * and you can get the actual filter by calling
-+ * gedit_open_document_selector_store_get_filter()
-+ * ( this is in addition to the text mime type filter)
-+ *
-+ * The recent files list is not capped by Gedit settings like
-+ * in gedit_recent_get_items() but you still can get the limit
-+ * by calling gedit_open_document_selector_store_get_recent_limit().
-+ *
-+ * The original setting is stored in gsettings at :
-+ * org.gnome.gedit.preferences.ui
-+ * with the key : max-recents
-+ */
-+
-+#include "gedit-open-document-selector-store.h"
-+
-+#include
-+
-+#include
-+#include
-+
-+#include
-+#include
-+
-+#include "gedit-recent.h"
-+#include "gedit-utils.h"
-+#include "gedit-window.h"
-+#include "gedit-debug.h"
-+
-+struct _GeditOpenDocumentSelectorStore
-+{
-+ GObject parent_instance;
-+
-+ GSource *recent_source;
-+
-+ GeditRecentConfiguration recent_config;
-+ gchar *filter;
-+ GList *recent_items;
-+ gint recent_config_limit;
-+ gboolean recent_items_need_update;
-+};
-+
-+G_LOCK_DEFINE_STATIC (recent_files_filter_lock);
-+
-+G_DEFINE_TYPE (GeditOpenDocumentSelectorStore, gedit_open_document_selector_store, G_TYPE_OBJECT)
-+
-+G_DEFINE_QUARK (gedit-open-document-selector-store-error-quark,
-+ gedit_open_document_selector_store_error)
-+
-+static GList *
-+get_current_docs_list (GeditOpenDocumentSelectorStore *selector_store G_GNUC_UNUSED,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ GeditWindow *window;
-+ GList *docs;
-+ GList *l;
-+ GFile *file;
-+ GFileInfo *info;
-+ FileItem *item;
-+ GList *file_items_list = NULL;
-+
-+ window = gedit_open_document_selector_get_window (selector);
-+
-+ docs = gedit_window_get_documents (window);
-+ for (l = docs; l != NULL; l = l->next)
-+ {
-+ file = gtk_source_file_get_location (gedit_document_get_file (l->data));
-+ if (file == NULL)
-+ {
-+ /* In case of not saved docs */
-+ continue;
-+ }
-+
-+ info = g_file_query_info (file,
-+ "time::access,time::access-usec",
-+ G_FILE_QUERY_INFO_NONE,
-+ NULL,
-+ NULL);
-+ if (info == NULL)
-+ {
-+ continue;
-+ }
-+
-+ item = gedit_open_document_selector_create_fileitem_item ();
-+
-+ item->access_time.tv_sec = g_file_info_get_attribute_uint64 (info, "time::access");
-+ item->access_time.tv_usec = g_file_info_get_attribute_uint32 (info, "time::access-usec");
-+ item->uri = g_file_get_uri (file);
-+
-+ file_items_list = g_list_prepend (file_items_list, item);
-+
-+ g_object_unref (info);
-+ }
-+
-+ g_list_free (docs);
-+ return file_items_list;
-+}
-+
-+/* Notice that a content-type attribute must have been query to work */
-+static gboolean
-+check_mime_type (GFileInfo *info)
-+{
-+ const gchar *content_type;
-+ G_GNUC_UNUSED gchar *mime_type;
-+
-+ content_type = g_file_info_get_attribute_string (info, "standard::fast-content-type");
-+ if (content_type == NULL)
-+ {
-+ return FALSE;
-+ }
-+
-+#ifdef G_OS_WIN32
-+ if (g_content_type_is_a (content_type, "text"))
-+ {
-+ return TRUE;
-+ }
-+
-+ mime_type = g_content_type_get_mime_type (content_type);
-+ if (mime_type == NULL)
-+ {
-+ return FALSE;
-+ }
-+
-+ if (g_strcmp0 (mime_type, "text/plain") == 0)
-+ {
-+ g_free (mime_type);
-+ return TRUE;
-+ }
-+
-+ g_free (mime_type);
-+#else
-+ if (g_content_type_is_a (content_type, "text/plain"))
-+ {
-+ return TRUE;
-+ }
-+#endif
-+ return FALSE;
-+}
-+
-+static GList *
-+get_children_from_dir (GeditOpenDocumentSelectorStore *selector_store G_GNUC_UNUSED,
-+ GFile *dir)
-+{
-+ GList *file_items_list = NULL;
-+ GFileEnumerator *file_enum;
-+ GFileInfo *info;
-+ GFileType filetype;
-+ GFile *file;
-+ FileItem *item;
-+ gboolean is_text;
-+ gboolean is_correct_type;
-+
-+ g_return_val_if_fail (G_IS_FILE (dir), NULL);
-+
-+ file_enum = g_file_enumerate_children (dir,
-+ "standard::name,"
-+ "standard::type,"
-+ "standard::fast-content-type,"
-+ "time::access,time::access-usec",
-+ G_FILE_QUERY_INFO_NONE,
-+ NULL,
-+ NULL);
-+ if (file_enum == NULL)
-+ {
-+ return NULL;
-+ }
-+
-+ while ((info = g_file_enumerator_next_file (file_enum, NULL, NULL)))
-+ {
-+ filetype = g_file_info_get_file_type (info);
-+ is_text = check_mime_type (info);
-+ is_correct_type = (filetype == G_FILE_TYPE_REGULAR ||
-+ filetype == G_FILE_TYPE_SYMBOLIC_LINK ||
-+ filetype == G_FILE_TYPE_SHORTCUT);
-+
-+ if (is_text &&
-+ is_correct_type &&
-+ (file = g_file_enumerator_get_child (file_enum, info)) != NULL)
-+ {
-+ item = gedit_open_document_selector_create_fileitem_item ();
-+ item->uri = g_file_get_uri (file);
-+
-+ item->access_time.tv_sec = g_file_info_get_attribute_uint64 (info, "time::access");
-+ item->access_time.tv_usec = g_file_info_get_attribute_uint32 (info, "time::access-usec");
-+
-+ file_items_list = g_list_prepend (file_items_list, item);
-+ g_object_unref (file);
-+ }
-+
-+ g_object_unref (info);
-+ }
-+
-+ g_file_enumerator_close (file_enum, NULL, NULL);
-+ g_object_unref (file_enum);
-+
-+ return file_items_list;
-+}
-+
-+static GList *
-+get_active_doc_dir_list (GeditOpenDocumentSelectorStore *selector_store,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ GeditWindow *window;
-+ GeditDocument *active_doc;
-+ GtkSourceFile *source_file;
-+ GList *file_items_list = NULL;
-+
-+ window = gedit_open_document_selector_get_window (selector);
-+
-+ active_doc = gedit_window_get_active_document (window);
-+
-+ if (active_doc == NULL)
-+ {
-+ return NULL;
-+ }
-+
-+ source_file = gedit_document_get_file (active_doc);
-+ if (gtk_source_file_is_local (source_file))
-+ {
-+ GFile *location;
-+ GFile *parent_dir;
-+
-+ location = gtk_source_file_get_location (source_file);
-+ parent_dir = g_file_get_parent (location);
-+
-+ if (parent_dir != NULL)
-+ {
-+ file_items_list = get_children_from_dir (selector_store, parent_dir);
-+ g_object_unref (parent_dir);
-+ }
-+ }
-+
-+ return file_items_list;
-+}
-+
-+static GFile *
-+get_file_browser_root (GeditOpenDocumentSelectorStore *selector_store G_GNUC_UNUSED,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ GeditWindow *window;
-+ GeditMessageBus *bus;
-+ GeditMessage *msg;
-+ GFile *root = NULL;
-+
-+ window = gedit_open_document_selector_get_window (selector);
-+
-+ bus = gedit_window_get_message_bus (window);
-+ if (gedit_message_bus_is_registered (bus, "/plugins/filebrowser", "get_root"))
-+ {
-+ msg = gedit_message_bus_send_sync (bus, "/plugins/filebrowser", "get_root", NULL, NULL);
-+ g_object_get (msg, "location", &root, NULL);
-+ g_object_unref (msg);
-+ }
-+
-+ return root;
-+}
-+
-+static GList *
-+get_file_browser_root_dir_list (GeditOpenDocumentSelectorStore *selector_store,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ GFile *root;
-+ GList *file_items_list = NULL;
-+
-+ root = get_file_browser_root (selector_store, selector);
-+ if (root != NULL && g_file_is_native (root))
-+ {
-+ file_items_list = get_children_from_dir (selector_store, root);
-+ }
-+
-+ g_clear_object (&root);
-+ return file_items_list;
-+}
-+
-+/* Taken and adapted from gtk+ gtkbookmarksmanager.c */
-+static GList *
-+read_bookmarks_file (GFile *file)
-+{
-+ gchar *contents;
-+ gchar **lines, *space;
-+ GList *uri_list = NULL;
-+ gint i;
-+
-+ if (!g_file_load_contents (file, NULL, &contents, NULL, NULL, NULL))
-+ {
-+ return NULL;
-+ }
-+
-+ lines = g_strsplit (contents, "\n", -1);
-+
-+ for (i = 0; lines[i]; i++)
-+ {
-+ if (*lines[i] == '\0')
-+ {
-+ continue;
-+ }
-+
-+ if (!g_utf8_validate (lines[i], -1, NULL))
-+ {
-+ continue;
-+ }
-+
-+ if ((space = strchr (lines[i], ' ')) != NULL)
-+ {
-+ space[0] = '\0';
-+ }
-+
-+ uri_list = g_list_prepend (uri_list, g_strdup (lines[i]));
-+ }
-+
-+ g_strfreev (lines);
-+ g_free (contents);
-+
-+ return uri_list;
-+}
-+
-+static GList *
-+get_local_bookmarks_list (GeditOpenDocumentSelectorStore *selector_store,
-+ GeditOpenDocumentSelector *selector G_GNUC_UNUSED)
-+{
-+ GList *bookmarks_uri_list = NULL;
-+ GList *file_items_list = NULL;
-+ GList *new_file_items_list = NULL;
-+ GFile *bookmarks_file;
-+ GFile *file;
-+ gchar *filename;
-+ GList *l;
-+
-+ filename = g_build_filename (g_get_user_config_dir (), "gtk-3.0", "bookmarks", NULL);
-+ bookmarks_file = g_file_new_for_path (filename);
-+ g_free (filename);
-+
-+ bookmarks_uri_list = read_bookmarks_file (bookmarks_file);
-+ g_object_unref (bookmarks_file);
-+
-+ for (l = bookmarks_uri_list; l != NULL; l = l->next)
-+ {
-+ file = g_file_new_for_uri (l->data);
-+ if (g_file_is_native (file))
-+ {
-+ new_file_items_list = get_children_from_dir (selector_store, file);
-+ file_items_list = g_list_concat (file_items_list, new_file_items_list);
-+ }
-+
-+ g_object_unref (file);
-+ }
-+
-+ g_list_free_full (bookmarks_uri_list, g_free);
-+ return file_items_list;
-+}
-+
-+/* Taken and adapted from gtk+ gtkplacessidebar.c */
-+static gboolean
-+path_is_home_dir (const gchar *path)
-+{
-+ GFile *home_dir;
-+ GFile *location;
-+ const gchar *home_path;
-+ gboolean res;
-+
-+ home_path = g_get_home_dir ();
-+ if (home_path == NULL)
-+ {
-+ return FALSE;
-+ }
-+
-+ home_dir = g_file_new_for_path (home_path);
-+ location = g_file_new_for_path (path);
-+ res = g_file_equal (home_dir, location);
-+
-+ g_object_unref (home_dir);
-+ g_object_unref (location);
-+
-+ return res;
-+}
-+
-+static GList *
-+get_desktop_dir_list (GeditOpenDocumentSelectorStore *selector_store,
-+ GeditOpenDocumentSelector *selector G_GNUC_UNUSED)
-+{
-+ GList *file_items_list = NULL;
-+ const gchar *desktop_dir_name;
-+ gchar *desktop_uri;
-+ GFile *desktop_file;
-+
-+ desktop_dir_name = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
-+
-+ /* "To disable a directory, point it to the homedir."
-+ * See http://freedesktop.org/wiki/Software/xdg-user-dirs
-+ */
-+ if (path_is_home_dir (desktop_dir_name))
-+ {
-+ return NULL;
-+ }
-+
-+ desktop_uri = g_strconcat ("file://", desktop_dir_name, NULL);
-+ desktop_file = g_file_new_for_uri (desktop_uri);
-+ file_items_list = get_children_from_dir (selector_store, desktop_file);
-+
-+ g_free (desktop_uri);
-+ g_object_unref (desktop_file);
-+
-+ return file_items_list;
-+}
-+
-+static GList *
-+get_home_dir_list (GeditOpenDocumentSelectorStore *selector_store,
-+ GeditOpenDocumentSelector *selector G_GNUC_UNUSED)
-+{
-+ GList *file_items_list = NULL;
-+ const gchar *home_name;
-+ gchar *home_uri;
-+ GFile *home_file;
-+
-+ home_name = g_get_home_dir ();
-+ if (home_name == NULL)
-+ {
-+ return NULL;
-+ }
-+
-+ home_uri = g_strconcat ("file://", home_name, NULL);
-+ home_file = g_file_new_for_uri (home_uri);
-+ file_items_list = get_children_from_dir (selector_store, home_file);
-+
-+ g_free (home_uri);
-+ g_object_unref (home_file);
-+
-+ return file_items_list;
-+}
-+
-+static GList *
-+convert_recent_item_list_to_fileitem_list (GList *uri_list)
-+{
-+ GList *l;
-+ GList *fileitem_list = NULL;
-+
-+ for (l = uri_list; l != NULL; l = l->next)
-+ {
-+ gchar *uri;
-+ FileItem *item;
-+
-+ uri = g_strdup (gtk_recent_info_get_uri (l->data));
-+
-+ item = gedit_open_document_selector_create_fileitem_item ();
-+ item->uri = uri;
-+
-+ item->access_time.tv_sec = gtk_recent_info_get_visited (l->data);
-+ item->access_time.tv_usec = 0;
-+
-+ fileitem_list = g_list_prepend (fileitem_list, item);
-+ }
-+
-+ fileitem_list = g_list_reverse (fileitem_list);
-+ return fileitem_list;
-+}
-+
-+static GList *
-+get_recent_files_list (GeditOpenDocumentSelectorStore *selector_store,
-+ GeditOpenDocumentSelector *selector G_GNUC_UNUSED)
-+{
-+ GList *recent_items_list;
-+ GList *file_items_list;
-+
-+ G_LOCK (recent_files_filter_lock);
-+ recent_items_list = gedit_recent_get_items (&selector_store->recent_config);
-+ G_UNLOCK (recent_files_filter_lock);
-+
-+ file_items_list = convert_recent_item_list_to_fileitem_list (recent_items_list);
-+ g_list_free_full (recent_items_list, (GDestroyNotify)gtk_recent_info_unref);
-+
-+ return file_items_list;
-+}
-+
-+static void
-+update_list_cb (GeditOpenDocumentSelectorStore *selector_store,
-+ GAsyncResult *res,
-+ gpointer user_data G_GNUC_UNUSED)
-+{
-+ GList *list;
-+ GError *error;
-+ PushMessage *message;
-+ ListType type;
-+
-+ list = gedit_open_document_selector_store_update_list_finish (selector_store, res, &error);
-+
-+ message = g_task_get_task_data (G_TASK (res));
-+ type = message->type;
-+
-+ switch (type)
-+ {
-+ case GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST:
-+ gedit_open_document_selector_free_file_items_list (selector_store->recent_items);
-+ selector_store->recent_items = list;
-+
-+ DEBUG_SELECTOR (g_print ("\tStore(%p): update_list_cb: type:%s, length:%i\n",
-+ selector_store, list_type_string[type], g_list_length (list)););
-+
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+static void
-+on_recent_manager_changed (GtkRecentManager *manager G_GNUC_UNUSED,
-+ gpointer user_data)
-+{
-+ GeditOpenDocumentSelectorStore *selector_store = GEDIT_OPEN_DOCUMENT_SELECTOR_STORE (user_data);
-+
-+ selector_store->recent_items_need_update = TRUE;
-+ gedit_open_document_selector_store_update_list_async (selector_store,
-+ NULL,
-+ NULL,
-+ (GAsyncReadyCallback)update_list_cb,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST,
-+ NULL);
-+}
-+
-+static void
-+gedit_open_document_selector_store_dispose (GObject *object)
-+{
-+ GeditOpenDocumentSelectorStore *selector_store = GEDIT_OPEN_DOCUMENT_SELECTOR_STORE (object);
-+
-+ gedit_recent_configuration_destroy (&selector_store->recent_config);
-+
-+ g_clear_pointer (&selector_store->recent_source, g_source_destroy);
-+ g_clear_pointer (&selector_store->filter, g_free);
-+
-+ if (selector_store->recent_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector_store->recent_items);
-+ selector_store->recent_items = NULL;
-+ }
-+
-+ G_OBJECT_CLASS (gedit_open_document_selector_store_parent_class)->dispose (object);
-+}
-+
-+static void
-+gedit_open_document_selector_store_class_init (GeditOpenDocumentSelectorStoreClass *klass)
-+{
-+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-+
-+ gobject_class->dispose = gedit_open_document_selector_store_dispose;
-+}
-+
-+/* The order of functions pointers must be the same as in
-+ * ListType enum define in ./gedit-open-document-selector-helper.h
-+ */
-+static GList * (*list_func [])(GeditOpenDocumentSelectorStore *selector_store,
-+ GeditOpenDocumentSelector *selector) =
-+{
-+ get_recent_files_list,
-+ get_home_dir_list,
-+ get_desktop_dir_list,
-+ get_local_bookmarks_list,
-+ get_file_browser_root_dir_list,
-+ get_active_doc_dir_list,
-+ get_current_docs_list
-+};
-+
-+static gboolean
-+update_recent_list (gpointer user_data)
-+{
-+ GeditOpenDocumentSelectorStore *selector_store;
-+ GeditOpenDocumentSelector *selector;
-+ PushMessage *message;
-+ /* The type variable is only used when debug code activated */
-+ G_GNUC_UNUSED ListType type;
-+ GList *file_items_list;
-+ GTask *task = G_TASK(user_data);
-+
-+ selector_store = g_task_get_source_object (task);
-+ message = g_task_get_task_data (task);
-+ selector = message->selector;
-+ type = message->type;
-+
-+ DEBUG_SELECTOR_TIMER_DECL
-+ DEBUG_SELECTOR_TIMER_NEW
-+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: type:%s\n",
-+ selector, list_type_string[type]););
-+
-+ /* Update the recent list only when it changes, copy otherwise but keep it the first time */
-+ if (selector_store->recent_items != NULL && selector_store->recent_items_need_update == FALSE)
-+ {
-+ file_items_list = gedit_open_document_selector_copy_file_items_list (selector_store->recent_items);
-+
-+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: recent list copy\n", selector););
-+ }
-+ else
-+ {
-+ selector_store->recent_items_need_update = FALSE;
-+ file_items_list = get_recent_files_list (selector_store, selector);
-+
-+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: recent list compute\n", selector););
-+
-+ if (selector_store->recent_items == NULL)
-+ {
-+ selector_store->recent_items = gedit_open_document_selector_copy_file_items_list (file_items_list);
-+ }
-+ }
-+
-+ g_task_return_pointer (task,
-+ file_items_list,
-+ (GDestroyNotify)gedit_open_document_selector_free_file_items_list);
-+
-+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: type:%s, time:%lf\n",
-+ selector, list_type_string[type], DEBUG_SELECTOR_TIMER_GET););
-+ DEBUG_SELECTOR_TIMER_DESTROY
-+
-+ selector_store->recent_source = NULL;
-+ return G_SOURCE_REMOVE;
-+}
-+
-+static void
-+update_list_dispatcher (GTask *task,
-+ gpointer source_object,
-+ gpointer task_data,
-+ GCancellable *cancellable G_GNUC_UNUSED)
-+{
-+ GeditOpenDocumentSelectorStore *selector_store = source_object;
-+ GeditOpenDocumentSelector *selector;
-+ PushMessage *message;
-+ ListType type;
-+ GList *file_items_list;
-+
-+ message = task_data;
-+ selector = message->selector;
-+ type = message->type;
-+
-+ DEBUG_SELECTOR_TIMER_DECL
-+ DEBUG_SELECTOR_TIMER_NEW
-+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: Thread:%p, type:%s\n",
-+ selector, g_thread_self (), list_type_string[type]););
-+
-+ if (type >= GEDIT_OPEN_DOCUMENT_SELECTOR_LIST_TYPE_NUM_OF_LISTS)
-+ {
-+ g_task_return_new_error (task,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_ERROR, TYPE_OUT_OF_RANGE,
-+ "List Type out of range");
-+ g_object_unref (task);
-+ return;
-+ }
-+
-+ /* Here we call the corresponding list creator function */
-+ file_items_list = (*list_func[type]) (selector_store, selector);
-+
-+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: Thread:%p, type:%s, time:%lf\n",
-+ selector, g_thread_self (), list_type_string[type], DEBUG_SELECTOR_TIMER_GET););
-+ DEBUG_SELECTOR_TIMER_DESTROY
-+
-+ g_task_return_pointer (task,
-+ file_items_list,
-+ (GDestroyNotify)gedit_open_document_selector_free_file_items_list);
-+}
-+
-+GList *
-+gedit_open_document_selector_store_update_list_finish (GeditOpenDocumentSelectorStore *open_document_selector_store,
-+ GAsyncResult *result,
-+ GError **error)
-+{
-+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (open_document_selector_store), NULL);
-+ g_return_val_if_fail (g_task_is_valid (result, open_document_selector_store), NULL);
-+
-+ return g_task_propagate_pointer (G_TASK (result), error);
-+}
-+
-+void
-+gedit_open_document_selector_store_update_list_async (GeditOpenDocumentSelectorStore *selector_store,
-+ GeditOpenDocumentSelector *selector,
-+ GCancellable *cancellable,
-+ GAsyncReadyCallback callback,
-+ ListType type,
-+ gpointer user_data)
-+{
-+ GTask *task;
-+ PushMessage *message;
-+
-+ g_return_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (selector_store));
-+ g_return_if_fail (selector == NULL || GEDIT_IS_OPEN_DOCUMENT_SELECTOR (selector));
-+
-+ message = g_new (PushMessage, 1);
-+ message->selector = selector;
-+ message->type = type;
-+
-+ task = g_task_new (selector_store, cancellable, callback, user_data);
-+ g_task_set_source_tag (task, gedit_open_document_selector_store_update_list_async);
-+ g_task_set_priority (task, G_PRIORITY_DEFAULT);
-+ g_task_set_task_data (task, message, (GDestroyNotify)g_free);
-+
-+ if (type == GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST &&
-+ selector_store->recent_source == NULL)
-+ {
-+ selector_store->recent_source = g_idle_source_new ();
-+ g_task_attach_source (task, selector_store->recent_source, update_recent_list);
-+ }
-+ else
-+ {
-+ g_task_run_in_thread (task, update_list_dispatcher);
-+ }
-+
-+ g_object_unref (task);
-+}
-+
-+static void
-+gedit_open_document_selector_store_init (GeditOpenDocumentSelectorStore *selector_store)
-+{
-+ gedit_recent_configuration_init_default (&selector_store->recent_config);
-+
-+ /* We remove the recent files limit since we need the whole list but
-+ * we back it up as gedit_open_document_selector_store_get_recent_limit
-+ * use it
-+ */
-+ selector_store->recent_config_limit = selector_store->recent_config.limit;
-+ selector_store->recent_config.limit = -1;
-+
-+ g_signal_connect_object (selector_store->recent_config.manager,
-+ "changed",
-+ G_CALLBACK (on_recent_manager_changed),
-+ selector_store,
-+ 0);
-+
-+ selector_store->recent_items_need_update = TRUE;
-+}
-+
-+gint
-+gedit_open_document_selector_store_get_recent_limit (GeditOpenDocumentSelectorStore *selector_store)
-+{
-+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (selector_store), -1);
-+
-+ return selector_store->recent_config_limit;
-+}
-+
-+void
-+gedit_open_document_selector_store_set_filter (GeditOpenDocumentSelectorStore *selector_store,
-+ const gchar *filter)
-+{
-+ gchar *old_filter;
-+
-+ g_return_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (selector_store));
-+ g_return_if_fail (filter != NULL);
-+
-+ G_LOCK (recent_files_filter_lock);
-+
-+ old_filter = selector_store->filter;
-+ selector_store->filter = g_strdup (filter);
-+
-+ G_UNLOCK (recent_files_filter_lock);
-+ g_free (old_filter);
-+}
-+
-+gchar *
-+gedit_open_document_selector_store_get_filter (GeditOpenDocumentSelectorStore *selector_store)
-+{
-+ gchar *recent_filter;
-+
-+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (selector_store), NULL);
-+
-+ G_LOCK (recent_files_filter_lock);
-+ recent_filter = g_strdup (selector_store->filter);
-+ G_UNLOCK (recent_files_filter_lock);
-+
-+ return recent_filter;
-+}
-+
-+/* Gets a unique instance of #GeditOpenDocumentSelectorStore
-+ *
-+ * Returns: (transfer none): A unique #GeditOpenDocumentSelectorStore.
-+ * Do not ref or unref it, it will be destroyed at the end of the application.
-+ */
-+GeditOpenDocumentSelectorStore *
-+gedit_open_document_selector_store_get_default (void)
-+{
-+ static GeditOpenDocumentSelectorStore *instance;
-+
-+ if (instance == NULL)
-+ {
-+ instance = g_object_new (GEDIT_TYPE_OPEN_DOCUMENT_SELECTOR_STORE, NULL);
-+ g_object_add_weak_pointer (G_OBJECT (instance), (gpointer) &instance);
-+ }
-+
-+ return instance;
-+}
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-open-document-selector-store.h b/gedit/gedit-open-document-selector-store.h
-new file mode 100644
-index 000000000..d1e17a908
---- /dev/null
-+++ b/gedit/gedit-open-document-selector-store.h
-@@ -0,0 +1,68 @@
-+/*
-+ * gedit-open-document-selector-store.h
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2015 - Sébastien Lafargue
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+#ifndef GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_H
-+#define GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_H
-+
-+#include "gedit-open-document-selector-helper.h"
-+#include "gedit-open-document-selector.h"
-+
-+#include
-+#include
-+
-+G_BEGIN_DECLS
-+
-+#define GEDIT_TYPE_OPEN_DOCUMENT_SELECTOR_STORE (gedit_open_document_selector_store_get_type ())
-+
-+G_DECLARE_FINAL_TYPE (GeditOpenDocumentSelectorStore, gedit_open_document_selector_store, GEDIT, OPEN_DOCUMENT_SELECTOR_STORE, GObject)
-+
-+#define GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_ERROR gedit_open_document_selector_store_error_quark ()
-+
-+typedef enum
-+{
-+ TYPE_OUT_OF_RANGE
-+} GeditOpenDocumentSelectorStoreError;
-+
-+GQuark gedit_open_document_selector_store_error_quark (void);
-+
-+gint gedit_open_document_selector_store_get_recent_limit (GeditOpenDocumentSelectorStore *store);
-+
-+void gedit_open_document_selector_store_set_filter (GeditOpenDocumentSelectorStore *store,
-+ const gchar *filter);
-+
-+gchar *gedit_open_document_selector_store_get_filter (GeditOpenDocumentSelectorStore *store);
-+
-+GList *gedit_open_document_selector_store_update_list_finish (GeditOpenDocumentSelectorStore *open_document_selector_store,
-+ GAsyncResult *res,
-+ GError **error);
-+
-+void gedit_open_document_selector_store_update_list_async (GeditOpenDocumentSelectorStore *open_document_selector_store,
-+ GeditOpenDocumentSelector *open_document_selector,
-+ GCancellable *cancellable,
-+ GAsyncReadyCallback callback,
-+ ListType type,
-+ gpointer user_data);
-+
-+GeditOpenDocumentSelectorStore *gedit_open_document_selector_store_get_default (void);
-+
-+G_END_DECLS
-+
-+#endif /* GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_H */
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-open-document-selector.c b/gedit/gedit-open-document-selector.c
-new file mode 100644
-index 000000000..f67a6ba6d
---- /dev/null
-+++ b/gedit/gedit-open-document-selector.c
-@@ -0,0 +1,1304 @@
-+/*
-+ * gedit-open-document-selector.c
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2014 - Sébastien Lafargue
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+#include "gedit-open-document-selector.h"
-+#include "gedit-open-document-selector-store.h"
-+#include "gedit-open-document-selector-helper.h"
-+
-+#include
-+
-+#include
-+#include
-+#include
-+
-+#include
-+#include
-+
-+#include "gedit-recent.h"
-+#include "gedit-utils.h"
-+#include "gedit-window.h"
-+#include "gedit-debug.h"
-+
-+struct _GeditOpenDocumentSelector
-+{
-+ GtkBox parent_instance;
-+
-+ GeditWindow *window;
-+ GtkWidget *search_entry;
-+
-+ GtkWidget *open_button;
-+ GtkWidget *treeview;
-+ GtkListStore *liststore;
-+ GtkCellRenderer *name_renderer;
-+ GtkCellRenderer *path_renderer;
-+ GtkWidget *placeholder_box;
-+ GtkWidget *scrolled_window;
-+
-+ guint populate_listbox_id;
-+
-+ GdkRGBA name_label_color;
-+ PangoFontDescription *name_font;
-+ GdkRGBA path_label_color;
-+ PangoFontDescription *path_font;
-+ gchar *match_markup_color;
-+
-+ GeditOpenDocumentSelectorStore *selector_store;
-+ GList *recent_items;
-+ GList *home_dir_items;
-+ GList *desktop_dir_items;
-+ GList *local_bookmarks_dir_items;
-+ GList *file_browser_root_items;
-+ GList *active_doc_dir_items;
-+ GList *current_docs_items;
-+ GList *all_items;
-+};
-+
-+typedef enum
-+{
-+ SELECTOR_TAG_NONE,
-+ SELECTOR_TAG_MATCH
-+} SelectorTag;
-+
-+enum
-+{
-+ NAME_COLUMN,
-+ PATH_COLUMN,
-+ URI_COLUMN,
-+ N_COLUMNS
-+};
-+
-+enum
-+{
-+ PROP_0,
-+ PROP_WINDOW,
-+ LAST_PROP
-+};
-+
-+static GParamSpec *properties[LAST_PROP];
-+
-+enum
-+{
-+ SELECTOR_FILE_ACTIVATED,
-+ LAST_SIGNAL
-+};
-+
-+static guint signals[LAST_SIGNAL];
-+
-+/* Value 0xFF is reserved to mark the end of the array */
-+#define BYTE_ARRAY_END 0xFF
-+
-+#define OPEN_DOCUMENT_SELECTOR_WIDTH 400
-+#define OPEN_DOCUMENT_SELECTOR_MAX_VISIBLE_ROWS 10
-+
-+G_DEFINE_TYPE (GeditOpenDocumentSelector, gedit_open_document_selector, GTK_TYPE_BOX)
-+
-+static inline const guint8 *
-+get_byte_run (const guint8 *byte_array,
-+ gsize *count,
-+ SelectorTag *tag)
-+{
-+ guint8 tag_found;
-+ gsize c = 1;
-+
-+ tag_found = *byte_array++;
-+
-+ while ( *byte_array != BYTE_ARRAY_END && *byte_array == tag_found)
-+ {
-+ c++;
-+ byte_array++;
-+ }
-+
-+ *count = c;
-+ *tag = tag_found;
-+
-+ return ( *byte_array != BYTE_ARRAY_END) ? byte_array : NULL;
-+}
-+
-+static gchar*
-+get_markup_from_tagged_byte_array (GeditOpenDocumentSelector *selector,
-+ const gchar *str,
-+ const guint8 *byte_array)
-+{
-+ gchar *txt;
-+ GString *string;
-+ gchar *result_str;
-+ SelectorTag tag;
-+ gsize count;
-+
-+ string = g_string_sized_new (255);
-+
-+ while (TRUE)
-+ {
-+ byte_array = get_byte_run (byte_array, &count, &tag);
-+ txt = g_markup_escape_text (str, count);
-+ if (tag == SELECTOR_TAG_MATCH)
-+ {
-+ g_string_append (string, selector->match_markup_color);
-+ g_string_append (string, txt);
-+ g_string_append (string, "");
-+ }
-+ else
-+ {
-+ g_string_append (string, txt);
-+ }
-+
-+ g_free (txt);
-+
-+ if (!byte_array)
-+ {
-+ break;
-+ }
-+
-+ str = (const gchar *)((gsize)str + count);
-+ }
-+
-+ result_str = g_string_free (string, FALSE);
-+ return result_str;
-+}
-+
-+static guint8 *
-+get_tagged_byte_array (const gchar *uri,
-+ GRegex *filter_regex)
-+{
-+ guint8 *byte_array;
-+ gsize uri_len;
-+ GMatchInfo *match_info;
-+ gboolean no_match = TRUE;
-+
-+ g_return_val_if_fail (uri != NULL, NULL);
-+
-+ uri_len = strlen (uri);
-+ byte_array = g_malloc0 (uri_len + 1);
-+ byte_array[uri_len] = BYTE_ARRAY_END;
-+
-+ if (g_regex_match (filter_regex, uri, 0, &match_info) == TRUE)
-+ {
-+ while (g_match_info_matches (match_info) == TRUE)
-+ {
-+ guint8 *p;
-+ gint match_len;
-+ gint start_pos;
-+ gint end_pos;
-+
-+ if (g_match_info_fetch_pos (match_info, 0, &start_pos, &end_pos) == TRUE)
-+ {
-+ match_len = end_pos - start_pos;
-+ no_match = FALSE;
-+
-+ p = (guint8 *)((gsize)byte_array + start_pos);
-+ memset (p, SELECTOR_TAG_MATCH, match_len);
-+ }
-+
-+ g_match_info_next (match_info, NULL);
-+ }
-+ }
-+
-+ g_match_info_free (match_info);
-+
-+ if (no_match)
-+ {
-+ g_free (byte_array);
-+ return NULL;
-+ }
-+
-+ return byte_array;
-+}
-+
-+static void
-+get_markup_for_path_and_name (GeditOpenDocumentSelector *selector,
-+ GRegex *filter_regex,
-+ const gchar *src_path,
-+ const gchar *src_name,
-+ gchar **dst_path,
-+ gchar **dst_name)
-+{
-+ gchar *filename;
-+ gsize path_len;
-+ gsize name_len;
-+ gsize path_separator_len;
-+ guint8 *byte_array;
-+ guint8 *path_byte_array;
-+ guint8 *name_byte_array;
-+
-+ filename = g_build_filename (src_path, src_name, NULL);
-+
-+ path_len = g_utf8_strlen (src_path, -1);
-+ name_len = g_utf8_strlen (src_name, -1);
-+ path_separator_len = g_utf8_strlen (filename, -1) - ( path_len + name_len);
-+
-+ byte_array = get_tagged_byte_array (filename, filter_regex);
-+ if (byte_array)
-+ {
-+ path_byte_array = g_memdup (byte_array, path_len + 1);
-+ path_byte_array[path_len] = BYTE_ARRAY_END;
-+
-+ /* name_byte_array is part of byte_array, so released with it */
-+ name_byte_array = (guint8 *)((gsize)byte_array + path_len + path_separator_len);
-+
-+ *dst_path = get_markup_from_tagged_byte_array (selector, src_path, path_byte_array);
-+ *dst_name = get_markup_from_tagged_byte_array (selector, src_name, name_byte_array);
-+
-+ g_free (byte_array);
-+ g_free (path_byte_array);
-+ }
-+ else
-+ {
-+ *dst_path = g_strdup (src_path);
-+ *dst_name = g_strdup (src_name);
-+ }
-+
-+ g_free (filename);
-+}
-+
-+static void
-+create_row (GeditOpenDocumentSelector *selector,
-+ const FileItem *item,
-+ GRegex *filter_regex)
-+{
-+ GtkTreeIter iter;
-+ gchar *uri;
-+ gchar *dst_path;
-+ gchar *dst_name;
-+
-+ uri =item->uri;
-+
-+ if (filter_regex)
-+ {
-+ get_markup_for_path_and_name (selector,
-+ filter_regex,
-+ (const gchar *)item->path,
-+ (const gchar *)item->name,
-+ &dst_path,
-+ &dst_name);
-+ }
-+ else
-+ {
-+ dst_path = g_markup_escape_text (item->path, -1);
-+ dst_name = g_markup_escape_text (item->name, -1);
-+ }
-+
-+ gtk_list_store_append (selector->liststore, &iter);
-+ gtk_list_store_set (selector->liststore, &iter,
-+ URI_COLUMN, uri,
-+ NAME_COLUMN, dst_name,
-+ PATH_COLUMN, dst_path,
-+ -1);
-+
-+ g_free (dst_path);
-+ g_free (dst_name);
-+}
-+
-+static gint
-+sort_items_by_mru (FileItem *a,
-+ FileItem *b,
-+ gpointer unused G_GNUC_UNUSED)
-+{
-+ glong diff;
-+
-+ g_assert (a != NULL && b != NULL);
-+ diff = b->access_time.tv_sec - a->access_time.tv_sec;
-+
-+ if (diff == 0)
-+ {
-+ return (b->access_time.tv_usec - a->access_time.tv_usec);
-+ }
-+ else
-+ {
-+ return diff;
-+ }
-+}
-+
-+static GList *
-+compute_all_items_list (GeditOpenDocumentSelector *selector)
-+{
-+ GList *recent_items;
-+ GList *home_dir_items;
-+ GList *desktop_dir_items;
-+ GList *local_bookmarks_dir_items;
-+ GList *file_browser_root_items;
-+ GList *active_doc_dir_items;
-+ GList *current_docs_items;
-+ GList *all_items = NULL;
-+
-+ /* Copy/concat the whole list */
-+ recent_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->recent_items);
-+ home_dir_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->home_dir_items);
-+ desktop_dir_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->desktop_dir_items);
-+ local_bookmarks_dir_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->local_bookmarks_dir_items);
-+ file_browser_root_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->file_browser_root_items);
-+ active_doc_dir_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->active_doc_dir_items);
-+ current_docs_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->current_docs_items);
-+
-+ if (selector->all_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector->all_items);
-+ selector->all_items = NULL;
-+ }
-+
-+ all_items = g_list_concat (all_items, recent_items);
-+ all_items = g_list_concat (all_items, home_dir_items);
-+ all_items = g_list_concat (all_items, desktop_dir_items);
-+ all_items = g_list_concat (all_items, local_bookmarks_dir_items);
-+ all_items = g_list_concat (all_items, file_browser_root_items);
-+ all_items = g_list_concat (all_items, active_doc_dir_items);
-+ all_items = g_list_concat (all_items, current_docs_items);
-+
-+ return all_items;
-+}
-+
-+static GList *
-+clamp_recent_items_list (GList *recent_items,
-+ gint limit)
-+{
-+ GList *recent_items_capped = NULL;
-+ GList *l;
-+ FileItem *item;
-+
-+ l = recent_items;
-+ while (limit > 0 && l != NULL)
-+ {
-+ item = gedit_open_document_selector_copy_fileitem_item (l->data);
-+ recent_items_capped = g_list_prepend (recent_items_capped, item);
-+ l = l->next;
-+ limit -= 1;
-+ }
-+
-+ recent_items_capped = g_list_reverse (recent_items_capped);
-+ return recent_items_capped;
-+}
-+
-+/* Setup the fileitem, depending uri's scheme
-+ * Return a string to search in.
-+ */
-+static gchar *
-+fileitem_setup (FileItem *item)
-+{
-+ gchar *scheme;
-+ gchar *filename;
-+ gchar *normalized_filename = NULL;
-+ gchar *candidate = NULL;
-+ gchar *path;
-+ gchar *name;
-+
-+ scheme = g_uri_parse_scheme (item->uri);
-+ if (g_strcmp0 (scheme, "file") == 0)
-+ {
-+ filename = g_filename_from_uri ((const gchar *)item->uri, NULL, NULL);
-+ if (filename)
-+ {
-+ path = g_path_get_dirname (filename);
-+ item->path = g_filename_to_utf8 (path, -1, NULL, NULL, NULL);
-+ g_free (path);
-+
-+ name = g_path_get_basename (filename);
-+ item->name = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
-+ g_free (name);
-+
-+ normalized_filename = g_utf8_normalize (filename, -1, G_NORMALIZE_ALL);
-+ g_free (filename);
-+ }
-+ }
-+ else
-+ {
-+ GFile *file;
-+ gchar *parse_name;
-+
-+ file = g_file_new_for_uri (item->uri);
-+ item->path = gedit_utils_location_get_dirname_for_display (file);
-+ item->name = gedit_utils_basename_for_display (file);
-+ parse_name = g_file_get_parse_name (file);
-+ g_object_unref (file);
-+
-+ normalized_filename = g_utf8_normalize (parse_name, -1, G_NORMALIZE_ALL);
-+ g_free (parse_name);
-+ }
-+
-+ if (normalized_filename)
-+ {
-+ candidate = g_utf8_casefold (normalized_filename, -1);
-+ g_free (normalized_filename);
-+ }
-+
-+ g_free (scheme);
-+
-+ return candidate;
-+}
-+
-+static inline gboolean
-+is_filter_in_candidate (const gchar *candidate,
-+ const gchar *filter)
-+{
-+ gchar *candidate_fold;
-+ gboolean ret;
-+
-+ g_assert (candidate != NULL);
-+ g_assert (filter != NULL);
-+
-+ candidate_fold = g_utf8_casefold (candidate, -1);
-+ ret = (strstr (candidate_fold, filter) != NULL);
-+
-+ g_free (candidate_fold);
-+ return ret;
-+}
-+
-+/* If filter == NULL then items are
-+ * not checked against the filter.
-+ */
-+static GList *
-+fileitem_list_filter (GList *items,
-+ const gchar *filter)
-+{
-+ GList *new_items = NULL;
-+ GList *l;
-+ gchar *filter_fold = NULL;
-+
-+ if (filter != NULL)
-+ filter_fold = g_utf8_casefold (filter, -1);
-+
-+ for (l = items; l != NULL; l = l->next)
-+ {
-+ FileItem *item;
-+ gchar *candidate;
-+
-+ item = l->data;
-+ candidate = fileitem_setup (item);
-+ if (candidate != NULL)
-+ {
-+ if (filter == NULL || is_filter_in_candidate (candidate, filter_fold))
-+ {
-+ new_items = g_list_prepend (new_items,
-+ gedit_open_document_selector_copy_fileitem_item (item));
-+ }
-+
-+ g_free (candidate);
-+ }
-+ }
-+
-+ g_free (filter_fold);
-+ new_items = g_list_reverse (new_items);
-+ return new_items;
-+}
-+
-+/* Remove duplicated, the HEAD of the list never change,
-+ * the list passed in is modified.
-+ */
-+static void
-+fileitem_list_remove_duplicates (GList *items)
-+{
-+ GList *l;
-+ G_GNUC_UNUSED GList *dummy_ptr;
-+
-+ l = items;
-+ while (l != NULL)
-+ {
-+ gchar *l_uri, *l1_uri;
-+ GList *l1;
-+
-+ if ((l1 = l->next) == NULL)
-+ {
-+ break;
-+ }
-+
-+ l_uri = ((FileItem *)l->data)->uri;
-+ l1_uri = ((FileItem *)l1->data)->uri;
-+ if (g_strcmp0 (l_uri, l1_uri) == 0)
-+ {
-+ gedit_open_document_selector_free_fileitem_item ((FileItem *)l1->data);
-+ dummy_ptr = g_list_delete_link (items, l1);
-+ }
-+ else
-+ {
-+ l = l->next;
-+ }
-+ }
-+}
-+
-+static gboolean
-+real_populate_liststore (gpointer data)
-+{
-+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (data);
-+ GeditOpenDocumentSelectorStore *selector_store;
-+ GList *l;
-+ GList *filter_items = NULL;
-+ gchar *filter;
-+ GRegex *filter_regex = NULL;
-+
-+ DEBUG_SELECTOR_TIMER_DECL
-+ DEBUG_SELECTOR_TIMER_NEW
-+
-+ gtk_list_store_clear (selector->liststore);
-+
-+ selector_store = selector->selector_store;
-+ filter = gedit_open_document_selector_store_get_filter (selector_store);
-+ if (filter && *filter != '\0')
-+ {
-+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: all lists\n", selector););
-+
-+ filter_items = fileitem_list_filter (selector->all_items, (const gchar *)filter);
-+ filter_items = g_list_sort_with_data (filter_items, (GCompareDataFunc)sort_items_by_mru, NULL);
-+ fileitem_list_remove_duplicates (filter_items);
-+
-+ filter_regex = g_regex_new (filter, G_REGEX_CASELESS, 0, NULL);
-+ }
-+ else
-+ {
-+ gint recent_limit;
-+ GList *recent_items;
-+
-+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: recent files list\n", selector););
-+
-+ recent_limit = gedit_open_document_selector_store_get_recent_limit (selector_store);
-+
-+ if (recent_limit > 0 )
-+ {
-+ recent_items = fileitem_list_filter (selector->recent_items, NULL);
-+ filter_items = clamp_recent_items_list (recent_items, recent_limit);
-+ gedit_open_document_selector_free_file_items_list (recent_items);
-+ }
-+ else
-+ {
-+ filter_items = fileitem_list_filter (selector->recent_items, NULL);
-+ }
-+ }
-+
-+ g_free (filter);
-+
-+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: length:%i\n",
-+ selector, g_list_length (filter_items)););
-+
-+ /* Show the placeholder if no results, show the treeview otherwise */
-+ gtk_widget_set_visible (selector->scrolled_window, (filter_items != NULL));
-+ gtk_widget_set_visible (selector->placeholder_box, (filter_items == NULL));
-+
-+ for (l = filter_items; l != NULL; l = l->next)
-+ {
-+ FileItem *item;
-+
-+ item = l->data;
-+ create_row (selector, (const FileItem *)item, filter_regex);
-+ }
-+
-+ if (filter_regex)
-+ {
-+ g_regex_unref (filter_regex);
-+ }
-+
-+ gedit_open_document_selector_free_file_items_list (filter_items);
-+
-+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: time:%lf\n\n",
-+ selector, DEBUG_SELECTOR_TIMER_GET););
-+ DEBUG_SELECTOR_TIMER_DESTROY
-+
-+ selector->populate_listbox_id = 0;
-+ return G_SOURCE_REMOVE;
-+}
-+
-+static void
-+populate_liststore (GeditOpenDocumentSelector *selector)
-+{
-+ /* Populate requests are compressed */
-+ if (selector->populate_listbox_id != 0)
-+ {
-+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: idle\n", selector););
-+ return;
-+ }
-+
-+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: scheduled\n", selector););
-+ selector->populate_listbox_id = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 30,
-+ real_populate_liststore,
-+ selector,
-+ NULL);
-+}
-+
-+static gboolean
-+on_treeview_key_press (GtkTreeView *treeview,
-+ GdkEventKey *event,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ guint keyval;
-+ gboolean is_control_pressed;
-+ GtkTreeSelection *tree_selection;
-+ GtkTreePath *root_path;
-+ GdkModifierType modifiers;
-+
-+ if (gdk_event_get_keyval ((GdkEvent *)event, &keyval) == TRUE)
-+ {
-+ tree_selection = gtk_tree_view_get_selection (treeview);
-+ root_path = gtk_tree_path_new_from_string ("0");
-+
-+ modifiers = gtk_accelerator_get_default_mod_mask ();
-+ is_control_pressed = (event->state & modifiers) == GDK_CONTROL_MASK;
-+
-+ if ((keyval == GDK_KEY_Up || keyval == GDK_KEY_KP_Up) &&
-+ !is_control_pressed)
-+ {
-+ if (gtk_tree_selection_path_is_selected (tree_selection, root_path))
-+ {
-+ gtk_tree_selection_unselect_all (tree_selection);
-+ gtk_widget_grab_focus (selector->search_entry);
-+
-+ return GDK_EVENT_STOP;
-+ }
-+ }
-+ }
-+
-+ return GDK_EVENT_PROPAGATE;
-+}
-+
-+static void
-+on_entry_changed (GtkEntry *entry,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ const gchar *entry_text;
-+
-+ entry_text = gtk_entry_get_text (entry);
-+ gedit_open_document_selector_store_set_filter (selector->selector_store,
-+ entry_text);
-+
-+ if (gtk_widget_get_mapped ( GTK_WIDGET (selector)))
-+ {
-+ populate_liststore (selector);
-+ }
-+}
-+
-+static void
-+on_entry_activated (GtkEntry *entry,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ const gchar *entry_text;
-+ GtkTreeSelection *selection;
-+ gchar *uri;
-+ GFile *file;
-+ gchar *scheme;
-+
-+ entry_text = gtk_entry_get_text (entry);
-+ scheme = g_uri_parse_scheme (entry_text);
-+ if (!scheme)
-+ {
-+ const gchar *home_dir = g_get_home_dir ();
-+
-+ if ( home_dir != NULL && g_str_has_prefix (entry_text, "~/"))
-+ {
-+ uri = g_strconcat ("file://", home_dir, "/", entry_text + 2, NULL);
-+ }
-+ else
-+ {
-+ uri = g_strconcat ("file://", entry_text, NULL);
-+ }
-+ }
-+ else
-+ {
-+ g_free (scheme);
-+ uri = g_strdup (entry_text);
-+ }
-+
-+ file = g_file_new_for_uri (uri);
-+ if (g_file_query_exists (file, NULL))
-+ {
-+ DEBUG_SELECTOR (g_print ("Selector(%p): search entry activated : loading '%s'\n",
-+ selector, uri););
-+
-+ gtk_entry_set_text (entry, "");
-+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (selector->treeview));
-+ gtk_tree_selection_unselect_all (selection);
-+
-+ g_signal_emit (G_OBJECT (selector), signals[SELECTOR_FILE_ACTIVATED], 0, uri);
-+ }
-+
-+ g_object_unref (file);
-+}
-+
-+static void
-+gedit_open_document_selector_dispose (GObject *object)
-+{
-+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (object);
-+
-+ if (selector->populate_listbox_id != 0)
-+ {
-+ g_source_remove (selector->populate_listbox_id);
-+ selector->populate_listbox_id = 0;
-+ }
-+
-+ g_clear_pointer (&selector->name_font, pango_font_description_free);
-+ g_clear_pointer (&selector->path_font, pango_font_description_free);
-+ g_clear_pointer (&selector->match_markup_color, g_free);
-+
-+ if (selector->recent_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector->recent_items);
-+ selector->recent_items = NULL;
-+ }
-+
-+ if (selector->home_dir_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector->home_dir_items);
-+ selector->home_dir_items = NULL;
-+ }
-+
-+ if (selector->desktop_dir_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector->desktop_dir_items);
-+ selector->desktop_dir_items = NULL;
-+ }
-+
-+ if (selector->local_bookmarks_dir_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector->local_bookmarks_dir_items);
-+ selector->local_bookmarks_dir_items = NULL;
-+ }
-+
-+ if (selector->file_browser_root_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector->file_browser_root_items);
-+ selector->file_browser_root_items = NULL;
-+ }
-+
-+ if (selector->active_doc_dir_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector->active_doc_dir_items);
-+ selector->active_doc_dir_items = NULL;
-+ }
-+
-+ if (selector->current_docs_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector->current_docs_items);
-+ selector->current_docs_items = NULL;
-+ }
-+
-+ if (selector->all_items)
-+ {
-+ gedit_open_document_selector_free_file_items_list (selector->all_items);
-+ selector->all_items = NULL;
-+ }
-+
-+ G_OBJECT_CLASS (gedit_open_document_selector_parent_class)->dispose (object);
-+}
-+
-+static void
-+on_row_activated (GtkTreeView *treeview,
-+ GtkTreePath *path,
-+ GtkTreeViewColumn *column G_GNUC_UNUSED,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ GtkTreeModel *liststore = GTK_TREE_MODEL (selector->liststore);
-+ GtkTreeSelection *selection;
-+ GtkTreeIter iter;
-+ gchar *uri;
-+
-+ g_return_if_fail (gtk_tree_model_get_iter (liststore, &iter, path));
-+ gtk_tree_model_get (liststore, &iter,
-+ URI_COLUMN, &uri,
-+ -1);
-+
-+ selection = gtk_tree_view_get_selection (treeview);
-+ gtk_tree_selection_unselect_all (selection);
-+
-+ /* Leak of uri */
-+ g_signal_emit (G_OBJECT (selector), signals[SELECTOR_FILE_ACTIVATED], 0, uri);
-+}
-+
-+static void
-+update_list_cb (GeditOpenDocumentSelectorStore *selector_store,
-+ GAsyncResult *res,
-+ gpointer user_data G_GNUC_UNUSED)
-+{
-+ GList *list;
-+ GError *error;
-+ PushMessage *message;
-+ ListType type;
-+ GeditOpenDocumentSelector *selector;
-+
-+ list = gedit_open_document_selector_store_update_list_finish (selector_store, res, &error);
-+ message = g_task_get_task_data (G_TASK (res));
-+ selector = message->selector;
-+ type = message->type;
-+
-+ DEBUG_SELECTOR (g_print ("Selector(%p): update_list_cb - type:%s, length:%i\n",
-+ selector, list_type_string[type], g_list_length (list)););
-+
-+ switch (type)
-+ {
-+ case GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST:
-+ gedit_open_document_selector_free_file_items_list (selector->recent_items);
-+ selector->recent_items = list;
-+ break;
-+
-+ case GEDIT_OPEN_DOCUMENT_SELECTOR_HOME_DIR_LIST:
-+ gedit_open_document_selector_free_file_items_list (selector->home_dir_items);
-+ selector->home_dir_items = list;
-+ break;
-+
-+ case GEDIT_OPEN_DOCUMENT_SELECTOR_DESKTOP_DIR_LIST:
-+ gedit_open_document_selector_free_file_items_list (selector->desktop_dir_items);
-+ selector->desktop_dir_items = list;
-+ break;
-+
-+ case GEDIT_OPEN_DOCUMENT_SELECTOR_LOCAL_BOOKMARKS_DIR_LIST:
-+ gedit_open_document_selector_free_file_items_list (selector->local_bookmarks_dir_items);
-+ selector->local_bookmarks_dir_items = list;
-+ break;
-+
-+ case GEDIT_OPEN_DOCUMENT_SELECTOR_FILE_BROWSER_ROOT_DIR_LIST:
-+ gedit_open_document_selector_free_file_items_list (selector->file_browser_root_items);
-+ selector->file_browser_root_items = list;
-+ break;
-+
-+ case GEDIT_OPEN_DOCUMENT_SELECTOR_ACTIVE_DOC_DIR_LIST:
-+ gedit_open_document_selector_free_file_items_list (selector->active_doc_dir_items);
-+ selector->active_doc_dir_items = list;
-+ break;
-+
-+ case GEDIT_OPEN_DOCUMENT_SELECTOR_CURRENT_DOCS_LIST:
-+ gedit_open_document_selector_free_file_items_list (selector->current_docs_items);
-+ selector->current_docs_items = list;
-+ break;
-+
-+ default:
-+ g_return_if_reached ();
-+ }
-+
-+ selector->all_items = compute_all_items_list (selector);
-+ populate_liststore (selector);
-+}
-+
-+static void
-+gedit_open_document_selector_constructed (GObject *object)
-+{
-+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (object);
-+
-+ G_OBJECT_CLASS (gedit_open_document_selector_parent_class)->constructed (object);
-+
-+ DEBUG_SELECTOR (g_print ("Selector(%p): constructed - ask recent file list\n", selector););
-+
-+ gedit_open_document_selector_store_update_list_async (selector->selector_store,
-+ selector,
-+ NULL,
-+ (GAsyncReadyCallback)update_list_cb,
-+ GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST,
-+ selector);
-+}
-+
-+static void
-+gedit_open_document_selector_mapped (GtkWidget *widget)
-+{
-+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (widget);
-+ ListType list_number;
-+
-+ /* We update all the lists */
-+ DEBUG_SELECTOR (g_print ("Selector(%p): mapped - ask all lists\n", selector););
-+
-+ for (list_number = 0; list_number < GEDIT_OPEN_DOCUMENT_SELECTOR_LIST_TYPE_NUM_OF_LISTS; list_number++)
-+ {
-+ gedit_open_document_selector_store_update_list_async (selector->selector_store,
-+ selector,
-+ NULL,
-+ (GAsyncReadyCallback)update_list_cb,
-+ list_number,
-+ selector);
-+ }
-+
-+ GTK_WIDGET_CLASS (gedit_open_document_selector_parent_class)->map (widget);
-+}
-+
-+static GtkSizeRequestMode
-+gedit_open_document_selector_get_request_mode (GtkWidget *widget G_GNUC_UNUSED)
-+{
-+ return GTK_SIZE_REQUEST_CONSTANT_SIZE;
-+}
-+
-+static void
-+gedit_open_document_selector_get_preferred_width (GtkWidget *widget G_GNUC_UNUSED,
-+ gint *minimum_width,
-+ gint *natural_width)
-+{
-+ *minimum_width = *natural_width = OPEN_DOCUMENT_SELECTOR_WIDTH;
-+}
-+
-+static void
-+gedit_open_document_selector_set_property (GObject *object,
-+ guint prop_id,
-+ const GValue *value,
-+ GParamSpec *pspec)
-+{
-+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_WINDOW:
-+ selector->window = g_value_get_object (value);
-+ break;
-+
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ break;
-+ }
-+}
-+
-+static void
-+gedit_open_document_selector_get_property (GObject *object,
-+ guint prop_id,
-+ GValue *value,
-+ GParamSpec *pspec)
-+{
-+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_WINDOW:
-+ g_value_set_object (value, selector->window);
-+ break;
-+
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ break;
-+ }
-+}
-+
-+static void
-+gedit_open_document_selector_file_activated (GeditOpenDocumentSelector *selector G_GNUC_UNUSED,
-+ const gchar *uri G_GNUC_UNUSED)
-+{
-+ /* Do nothing in the default handler */
-+}
-+
-+static void
-+gedit_open_document_selector_class_init (GeditOpenDocumentSelectorClass *klass)
-+{
-+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
-+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-+
-+ object_class->constructed = gedit_open_document_selector_constructed;
-+ object_class->dispose = gedit_open_document_selector_dispose;
-+
-+ object_class->get_property = gedit_open_document_selector_get_property;
-+ object_class->set_property = gedit_open_document_selector_set_property;
-+
-+ widget_class->get_request_mode = gedit_open_document_selector_get_request_mode;
-+ widget_class->get_preferred_width = gedit_open_document_selector_get_preferred_width;
-+ widget_class->map = gedit_open_document_selector_mapped;
-+
-+ properties[PROP_WINDOW] =
-+ g_param_spec_object ("window",
-+ "Window",
-+ "The GeditWindow this GeditOpenDocumentSelector is associated with",
-+ GEDIT_TYPE_WINDOW,
-+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-+
-+ g_object_class_install_properties (object_class, LAST_PROP, properties);
-+
-+ signals[SELECTOR_FILE_ACTIVATED] =
-+ g_signal_new_class_handler ("file-activated",
-+ G_TYPE_FROM_CLASS (klass),
-+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-+ G_CALLBACK (gedit_open_document_selector_file_activated),
-+ NULL, NULL, NULL,
-+ G_TYPE_NONE,
-+ 1,
-+ G_TYPE_STRING);
-+
-+ gtk_widget_class_set_template_from_resource (widget_class,
-+ "/org/gnome/gedit/ui/gedit-open-document-selector.ui");
-+
-+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, open_button);
-+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, treeview);
-+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, placeholder_box);
-+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, scrolled_window);
-+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, search_entry);
-+}
-+
-+static void
-+on_treeview_allocate (GtkWidget *widget G_GNUC_UNUSED,
-+ GdkRectangle *allocation G_GNUC_UNUSED,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ GeditOpenDocumentSelectorStore *selector_store;
-+ GtkStyleContext *context;
-+ gint name_renderer_natural_size;
-+ gint path_renderer_natural_size;
-+ GtkBorder padding;
-+ gint ypad;
-+ gint limit_capped;
-+ gint treeview_height;
-+ gint grid_line_width;
-+ gint row_height;
-+ gint recent_limit;
-+
-+ selector_store = selector->selector_store;
-+
-+ context = gtk_widget_get_style_context (selector->treeview);
-+ gtk_style_context_get_padding (context,
-+ gtk_style_context_get_state (context),
-+ &padding);
-+
-+ /* Treeview height computation */
-+ gtk_cell_renderer_get_preferred_height (selector->name_renderer,
-+ selector->treeview,
-+ NULL,
-+ &name_renderer_natural_size);
-+
-+ gtk_cell_renderer_get_preferred_height (selector->path_renderer,
-+ selector->treeview,
-+ NULL,
-+ &path_renderer_natural_size);
-+
-+ gtk_cell_renderer_get_padding (selector->name_renderer, NULL, &ypad);
-+ gtk_widget_style_get (selector->treeview, "grid-line-width", &grid_line_width, NULL);
-+
-+ recent_limit = gedit_open_document_selector_store_get_recent_limit (selector_store);
-+
-+ limit_capped = (recent_limit > 0 ) ? MIN (recent_limit, OPEN_DOCUMENT_SELECTOR_MAX_VISIBLE_ROWS) :
-+ OPEN_DOCUMENT_SELECTOR_MAX_VISIBLE_ROWS;
-+
-+ row_height = name_renderer_natural_size +
-+ path_renderer_natural_size +
-+ 2 * (padding.top + padding.bottom) +
-+ ypad +
-+ grid_line_width;
-+
-+ treeview_height = row_height * limit_capped;
-+ gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (selector->scrolled_window),
-+ treeview_height);
-+ gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (selector->scrolled_window),
-+ treeview_height);
-+
-+ gtk_widget_set_size_request (selector->placeholder_box, -1, treeview_height);
-+}
-+
-+static inline gchar *
-+rgba_to_hex8 (GdkRGBA *rgba)
-+{
-+ guint red = (guint)(0.5 + CLAMP (rgba->red, 0.0, 1.0) * 255.0);
-+ guint green = (guint)(0.5 + CLAMP (rgba->green, 0.0, 1.0) * 255.0);
-+ guint blue = (guint)(0.5 + CLAMP (rgba->blue, 0.0, 1.0) * 255.0);
-+ guint alpha = (guint)(0.5 + CLAMP (rgba->alpha, 0.0, 1.0) * 255.0);
-+ gchar *str = g_strdup_printf ("#%02X%02X%02X%02X", red, green, blue, alpha);
-+
-+ return str;
-+}
-+
-+static void
-+on_treeview_style_updated (GtkWidget *widget,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ GtkStyleContext *context;
-+ GdkRGBA match_foreground_rgba = {0.0, 0.0, 0.0, 0.0};
-+ GdkRGBA match_background_rgba = {0.0, 0.0, 0.0, 0.0};
-+ gchar *match_foreground_hex8;
-+ gchar *match_background_hex8;
-+
-+ context = gtk_widget_get_style_context (widget);
-+
-+ /* Name label foreground and font size styling */
-+ gtk_style_context_save (context);
-+ gtk_style_context_add_class (context, "open-document-selector-name-label");
-+
-+ gtk_style_context_get_color (context,
-+ gtk_style_context_get_state (context),
-+ &selector->name_label_color);
-+
-+ g_clear_pointer (&selector->name_font, pango_font_description_free);
-+ gtk_style_context_get (context,
-+ gtk_style_context_get_state (context),
-+ "font", &selector->name_font,
-+ NULL);
-+
-+ gtk_style_context_restore (context);
-+
-+ /* Path label foreground and font size styling */
-+ gtk_style_context_save (context);
-+ gtk_style_context_add_class (context, "open-document-selector-path-label");
-+
-+ gtk_style_context_get_color (context,
-+ gtk_style_context_get_state (context),
-+ &selector->path_label_color);
-+
-+ g_clear_pointer (&selector->path_font, pango_font_description_free);
-+ gtk_style_context_get (context,
-+ gtk_style_context_get_state (context),
-+ "font", &selector->path_font,
-+ NULL);
-+
-+ gtk_style_context_restore (context);
-+
-+ /* Match styling */
-+ gtk_style_context_save (context);
-+ gtk_style_context_add_class (context, "open-document-selector-match");
-+
-+ gtk_style_context_get_color (context,
-+ gtk_style_context_get_state (context),
-+ &match_foreground_rgba);
-+
-+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-+ gtk_style_context_get_background_color (context,
-+ gtk_style_context_get_state (context),
-+ &match_background_rgba);
-+ G_GNUC_END_IGNORE_DEPRECATIONS;
-+
-+ gtk_style_context_restore (context);
-+ g_free (selector->match_markup_color);
-+
-+ match_foreground_hex8 = rgba_to_hex8 (&match_foreground_rgba);
-+ match_background_hex8 = rgba_to_hex8 (&match_background_rgba);
-+
-+ selector->match_markup_color = g_strdup_printf ("",
-+ match_foreground_hex8,
-+ match_background_hex8);
-+
-+ g_free (match_foreground_hex8);
-+ g_free (match_background_hex8);
-+}
-+
-+static void
-+name_renderer_datafunc (GtkTreeViewColumn *column G_GNUC_UNUSED,
-+ GtkCellRenderer *name_renderer G_GNUC_UNUSED,
-+ GtkTreeModel *liststore G_GNUC_UNUSED,
-+ GtkTreeIter *iter G_GNUC_UNUSED,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ g_object_set (selector->name_renderer, "foreground-rgba", &selector->name_label_color, NULL);
-+ g_object_set (selector->name_renderer, "font-desc", selector->name_font, NULL);
-+}
-+
-+static void
-+path_renderer_datafunc (GtkTreeViewColumn *column G_GNUC_UNUSED,
-+ GtkCellRenderer *path_renderer G_GNUC_UNUSED,
-+ GtkTreeModel *liststore G_GNUC_UNUSED,
-+ GtkTreeIter *iter G_GNUC_UNUSED,
-+ GeditOpenDocumentSelector *selector)
-+{
-+ g_object_set (selector->path_renderer, "foreground-rgba", &selector->path_label_color, NULL);
-+ g_object_set (selector->path_renderer, "font-desc", selector->path_font, NULL);
-+}
-+
-+static void
-+setup_treeview (GeditOpenDocumentSelector *selector)
-+{
-+ GtkTreeViewColumn *column;
-+ GtkCellArea *cell_area;
-+ GtkStyleContext *context;
-+
-+ gtk_tree_view_set_model (GTK_TREE_VIEW (selector->treeview), GTK_TREE_MODEL (selector->liststore));
-+ g_object_unref(GTK_TREE_MODEL (selector->liststore));
-+
-+ selector->name_renderer = gtk_cell_renderer_text_new ();
-+ selector->path_renderer = gtk_cell_renderer_text_new ();
-+
-+ g_object_set (selector->name_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-+ g_object_set (selector->path_renderer, "ellipsize", PANGO_ELLIPSIZE_START, NULL);
-+
-+ column = gtk_tree_view_column_new ();
-+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
-+
-+ gtk_tree_view_column_pack_start (column, selector->name_renderer, TRUE);
-+ gtk_tree_view_column_pack_start (column, selector->path_renderer, TRUE);
-+
-+ gtk_tree_view_column_set_attributes (column, selector->name_renderer, "markup", NAME_COLUMN, NULL);
-+ gtk_tree_view_column_set_attributes (column, selector->path_renderer, "markup", PATH_COLUMN, NULL);
-+
-+ gtk_tree_view_append_column (GTK_TREE_VIEW (selector->treeview), column);
-+ cell_area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
-+ gtk_orientable_set_orientation (GTK_ORIENTABLE (cell_area), GTK_ORIENTATION_VERTICAL);
-+
-+ context = gtk_widget_get_style_context (selector->treeview);
-+ gtk_style_context_add_class (context, "open-document-selector-treeview");
-+
-+ gtk_tree_view_column_set_cell_data_func (column,
-+ selector->name_renderer,
-+ (GtkTreeCellDataFunc)name_renderer_datafunc,
-+ selector,
-+ NULL);
-+
-+ gtk_tree_view_column_set_cell_data_func (column,
-+ selector->path_renderer,
-+ (GtkTreeCellDataFunc)path_renderer_datafunc,
-+ selector,
-+ NULL);
-+}
-+
-+static void
-+gedit_open_document_selector_init (GeditOpenDocumentSelector *selector)
-+{
-+ gedit_debug (DEBUG_WINDOW);
-+
-+ gtk_widget_init_template (GTK_WIDGET (selector));
-+
-+ selector->selector_store = gedit_open_document_selector_store_get_default ();
-+
-+ selector->liststore = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
-+ setup_treeview (selector);
-+
-+ g_signal_connect (selector->search_entry,
-+ "changed",
-+ G_CALLBACK (on_entry_changed),
-+ selector);
-+
-+ g_signal_connect (selector->search_entry,
-+ "activate",
-+ G_CALLBACK (on_entry_activated),
-+ selector);
-+
-+ g_signal_connect (selector->treeview,
-+ "row-activated",
-+ G_CALLBACK (on_row_activated),
-+ selector);
-+
-+ g_signal_connect (selector->treeview,
-+ "size-allocate",
-+ G_CALLBACK (on_treeview_allocate),
-+ selector);
-+
-+ g_signal_connect (selector->treeview,
-+ "key-press-event",
-+ G_CALLBACK (on_treeview_key_press),
-+ selector);
-+
-+ g_signal_connect (selector->treeview,
-+ "style-updated",
-+ G_CALLBACK (on_treeview_style_updated),
-+ selector);
-+}
-+
-+GeditOpenDocumentSelector *
-+gedit_open_document_selector_new (GeditWindow *window)
-+{
-+ g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
-+
-+ return g_object_new (GEDIT_TYPE_OPEN_DOCUMENT_SELECTOR,
-+ "window", window,
-+ NULL);
-+}
-+
-+GeditWindow *
-+gedit_open_document_selector_get_window (GeditOpenDocumentSelector *selector)
-+{
-+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR (selector), NULL);
-+
-+ return selector->window;
-+}
-+
-+GtkWidget *
-+gedit_open_document_selector_get_search_entry (GeditOpenDocumentSelector *selector)
-+{
-+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR (selector), NULL);
-+
-+ return selector->search_entry;
-+}
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-open-document-selector.h b/gedit/gedit-open-document-selector.h
-new file mode 100644
-index 000000000..b4d50cefd
---- /dev/null
-+++ b/gedit/gedit-open-document-selector.h
-@@ -0,0 +1,44 @@
-+/*
-+ * gedit-open-document-selector.h
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2014 - Sébastien Lafargue
-+ *
-+ * gedit 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.
-+ *
-+ * gedit 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 gedit. If not, see .
-+ */
-+
-+#ifndef GEDIT_OPEN_DOCUMENT_SELECTOR_H
-+#define GEDIT_OPEN_DOCUMENT_SELECTOR_H
-+
-+#include
-+#include "gedit-window.h"
-+
-+#include
-+
-+G_BEGIN_DECLS
-+
-+#define GEDIT_TYPE_OPEN_DOCUMENT_SELECTOR (gedit_open_document_selector_get_type ())
-+
-+G_DECLARE_FINAL_TYPE (GeditOpenDocumentSelector, gedit_open_document_selector, GEDIT, OPEN_DOCUMENT_SELECTOR, GtkBox)
-+
-+GeditOpenDocumentSelector *gedit_open_document_selector_new (GeditWindow *window);
-+
-+GeditWindow *gedit_open_document_selector_get_window (GeditOpenDocumentSelector *selector);
-+
-+GtkWidget *gedit_open_document_selector_get_search_entry (GeditOpenDocumentSelector *selector);
-+
-+G_END_DECLS
-+
-+#endif /* GEDIT_OPEN_DOCUMENT_SELECTOR_H */
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-pango.c b/gedit/gedit-pango.c
-new file mode 100644
-index 000000000..0488bbcd2
---- /dev/null
-+++ b/gedit/gedit-pango.c
-@@ -0,0 +1,230 @@
-+/* gedit-pango.c
-+ *
-+ * This file is a copy of pango_font_description_to_css from gtk gtkfontbutton.c
-+ *
-+ * Copyright (C) 2016 Matthias Clasen
-+ *
-+ * 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 .
-+ */
-+
-+#define G_LOG_DOMAIN "gedit-pango"
-+
-+#include "config.h"
-+
-+#include "gedit-pango.h"
-+
-+#if PANGO_VERSION_CHECK (1, 44, 0)
-+static void
-+add_css_variations (GString *s,
-+ const char *variations)
-+{
-+ const char *p;
-+ const char *sep = "";
-+
-+ if (variations == NULL || variations[0] == '\0')
-+ {
-+ g_string_append (s, "normal");
-+ return;
-+ }
-+
-+ p = variations;
-+ while (p && *p)
-+ {
-+ const char *start;
-+ const char *end, *end2;
-+ double value;
-+ char name[5];
-+
-+ while (g_ascii_isspace (*p)) p++;
-+
-+ start = p;
-+ end = strchr (p, ',');
-+ if (end && (end - p < 6))
-+ goto skip;
-+
-+ name[0] = p[0];
-+ name[1] = p[1];
-+ name[2] = p[2];
-+ name[3] = p[3];
-+ name[4] = '\0';
-+
-+ p += 4;
-+ while (g_ascii_isspace (*p)) p++;
-+ if (*p == '=') p++;
-+
-+ if (p - start < 5)
-+ goto skip;
-+
-+ value = g_ascii_strtod (p, (char **) &end2);
-+
-+ while (end2 && g_ascii_isspace (*end2)) end2++;
-+
-+ if (end2 && (*end2 != ',' && *end2 != '\0'))
-+ goto skip;
-+
-+ g_string_append_printf (s, "%s\"%s\" %g", sep, name, value);
-+ sep = ", ";
-+
-+skip:
-+ p = end ? end + 1 : NULL;
-+ }
-+}
-+#endif
-+
-+/**
-+ * gedit_pango_font_description_to_css:
-+ *
-+ * This function will generate CSS suitable for Gtk's CSS engine
-+ * based on the properties of the #PangoFontDescription.
-+ *
-+ * Returns: (transfer full): A newly allocated string containing the
-+ * CSS describing the font description.
-+ */
-+gchar *
-+gedit_pango_font_description_to_css (const PangoFontDescription *desc)
-+{
-+ GString *s;
-+ PangoFontMask set;
-+
-+ s = g_string_new ("");
-+
-+ set = pango_font_description_get_set_fields (desc);
-+ if (set & PANGO_FONT_MASK_FAMILY)
-+ {
-+ g_string_append (s, "font-family: ");
-+ g_string_append (s, pango_font_description_get_family (desc));
-+ g_string_append (s, "; ");
-+ }
-+ if (set & PANGO_FONT_MASK_STYLE)
-+ {
-+ switch (pango_font_description_get_style (desc))
-+ {
-+ case PANGO_STYLE_NORMAL:
-+ g_string_append (s, "font-style: normal; ");
-+ break;
-+ case PANGO_STYLE_OBLIQUE:
-+ g_string_append (s, "font-style: oblique; ");
-+ break;
-+ case PANGO_STYLE_ITALIC:
-+ g_string_append (s, "font-style: italic; ");
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ if (set & PANGO_FONT_MASK_VARIANT)
-+ {
-+ switch (pango_font_description_get_variant (desc))
-+ {
-+ case PANGO_VARIANT_NORMAL:
-+ g_string_append (s, "font-variant: normal; ");
-+ break;
-+ case PANGO_VARIANT_SMALL_CAPS:
-+ g_string_append (s, "font-variant: small-caps; ");
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ if (set & PANGO_FONT_MASK_WEIGHT)
-+ {
-+ switch (pango_font_description_get_weight (desc))
-+ {
-+ case PANGO_WEIGHT_THIN:
-+ g_string_append (s, "font-weight: 100; ");
-+ break;
-+ case PANGO_WEIGHT_ULTRALIGHT:
-+ g_string_append (s, "font-weight: 200; ");
-+ break;
-+ case PANGO_WEIGHT_LIGHT:
-+ case PANGO_WEIGHT_SEMILIGHT:
-+ g_string_append (s, "font-weight: 300; ");
-+ break;
-+ case PANGO_WEIGHT_BOOK:
-+ case PANGO_WEIGHT_NORMAL:
-+ g_string_append (s, "font-weight: 400; ");
-+ break;
-+ case PANGO_WEIGHT_MEDIUM:
-+ g_string_append (s, "font-weight: 500; ");
-+ break;
-+ case PANGO_WEIGHT_SEMIBOLD:
-+ g_string_append (s, "font-weight: 600; ");
-+ break;
-+ case PANGO_WEIGHT_BOLD:
-+ g_string_append (s, "font-weight: 700; ");
-+ break;
-+ case PANGO_WEIGHT_ULTRABOLD:
-+ g_string_append (s, "font-weight: 800; ");
-+ break;
-+ case PANGO_WEIGHT_HEAVY:
-+ case PANGO_WEIGHT_ULTRAHEAVY:
-+ g_string_append (s, "font-weight: 900; ");
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ if (set & PANGO_FONT_MASK_STRETCH)
-+ {
-+ switch (pango_font_description_get_stretch (desc))
-+ {
-+ case PANGO_STRETCH_ULTRA_CONDENSED:
-+ g_string_append (s, "font-stretch: ultra-condensed; ");
-+ break;
-+ case PANGO_STRETCH_EXTRA_CONDENSED:
-+ g_string_append (s, "font-stretch: extra-condensed; ");
-+ break;
-+ case PANGO_STRETCH_CONDENSED:
-+ g_string_append (s, "font-stretch: condensed; ");
-+ break;
-+ case PANGO_STRETCH_SEMI_CONDENSED:
-+ g_string_append (s, "font-stretch: semi-condensed; ");
-+ break;
-+ case PANGO_STRETCH_NORMAL:
-+ g_string_append (s, "font-stretch: normal; ");
-+ break;
-+ case PANGO_STRETCH_SEMI_EXPANDED:
-+ g_string_append (s, "font-stretch: semi-expanded; ");
-+ break;
-+ case PANGO_STRETCH_EXPANDED:
-+ g_string_append (s, "font-stretch: expanded; ");
-+ break;
-+ case PANGO_STRETCH_EXTRA_EXPANDED:
-+ break;
-+ case PANGO_STRETCH_ULTRA_EXPANDED:
-+ g_string_append (s, "font-stretch: ultra-expanded; ");
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ if (set & PANGO_FONT_MASK_SIZE)
-+ {
-+ g_string_append_printf (s, "font-size: %dpt; ", pango_font_description_get_size (desc) / PANGO_SCALE);
-+ }
-+
-+#if PANGO_VERSION_CHECK (1, 44, 0)
-+ if (set & PANGO_FONT_MASK_VARIATIONS)
-+ {
-+ const char *variations;
-+
-+ g_string_append (s, "font-variation-settings: ");
-+ variations = pango_font_description_get_variations (desc);
-+ add_css_variations (s, variations);
-+ g_string_append (s, "; ");
-+ }
-+#endif
-+
-+ return g_string_free (s, FALSE);
-+}
-diff --git a/gedit/gedit-pango.h b/gedit/gedit-pango.h
-new file mode 100644
-index 000000000..8c800d502
---- /dev/null
-+++ b/gedit/gedit-pango.h
-@@ -0,0 +1,28 @@
-+/* gedit-pango.h
-+ *
-+ * 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 GEDIT_PANGO_H
-+#define GEDIT_PANGO_H
-+
-+#include
-+
-+G_BEGIN_DECLS
-+
-+gchar *gedit_pango_font_description_to_css (const PangoFontDescription *font_desc);
-+
-+G_END_DECLS
-+
-+#endif /* GEDIT_PANGO_H */
-diff --git a/gedit/gedit-preferences-dialog.c b/gedit/gedit-preferences-dialog.c
-index 016baf189..ec3f53a3d 100644
---- a/gedit/gedit-preferences-dialog.c
-+++ b/gedit/gedit-preferences-dialog.c
-@@ -23,14 +23,22 @@
-
- #include "gedit-preferences-dialog.h"
-
-+#include
-+#include
-+#include
-+
- #include
- #include
--#include
-+#include
- #include
-
-+#include "gedit-utils.h"
- #include "gedit-debug.h"
-+#include "gedit-document.h"
- #include "gedit-dirs.h"
- #include "gedit-settings.h"
-+#include "gedit-utils.h"
-+#include "gedit-file-chooser-dialog.h"
-
- /*
- * gedit-preferences dialog is a singleton since we don't
-@@ -83,9 +91,11 @@ struct _GeditPreferencesDialog
- GtkWidget *schemes_list;
- GtkWidget *install_scheme_button;
- GtkWidget *uninstall_scheme_button;
-+ GtkWidget *schemes_scrolled_window;
- GtkWidget *schemes_toolbar;
-- GtkFileChooserNative *
-- install_scheme_file_chooser;
-+
-+ GeditFileChooserDialog *
-+ install_scheme_file_schooser;
-
- /* Tabs */
- GtkWidget *tabs_width_spinbutton;
-@@ -105,6 +115,7 @@ struct _GeditPreferencesDialog
-
- GtkWidget *display_line_numbers_checkbutton;
- GtkWidget *display_statusbar_checkbutton;
-+ GtkWidget *display_overview_map_checkbutton;
- GtkWidget *display_grid_checkbutton;
-
- /* Right margin */
-@@ -170,6 +181,7 @@ gedit_preferences_dialog_class_init (GeditPreferencesDialogClass *klass)
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_line_numbers_checkbutton);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_statusbar_checkbutton);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_grid_checkbutton);
-+ gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_overview_map_checkbutton);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, right_margin_checkbutton);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, right_margin_position_grid);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, right_margin_position_spinbutton);
-@@ -187,6 +199,7 @@ gedit_preferences_dialog_class_init (GeditPreferencesDialogClass *klass)
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, font_button);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, font_grid);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, schemes_list);
-+ gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, schemes_scrolled_window);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, install_scheme_button);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, uninstall_scheme_button);
- gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, schemes_toolbar);
-@@ -386,6 +399,11 @@ setup_view_page (GeditPreferencesDialog *dlg)
- dlg->display_statusbar_checkbutton,
- "active",
- G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
-+ g_settings_bind (dlg->editor,
-+ GEDIT_SETTINGS_DISPLAY_OVERVIEW_MAP,
-+ dlg->display_overview_map_checkbutton,
-+ "active",
-+ G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
- g_settings_bind (dlg->editor,
- GEDIT_SETTINGS_DISPLAY_RIGHT_MARGIN,
- dlg->right_margin_checkbutton,
-@@ -434,7 +452,7 @@ setup_font_colors_page_font_section (GeditPreferencesDialog *dlg)
-
- /* Get values */
- settings = _gedit_settings_get_singleton ();
-- system_font = _gedit_settings_get_system_font (settings);
-+ system_font = gedit_settings_get_system_font (settings);
-
- label = g_strdup_printf(_("_Use the system fixed width font (%s)"),
- system_font);
-@@ -462,172 +480,255 @@ setup_font_colors_page_font_section (GeditPreferencesDialog *dlg)
- }
-
- static void
--update_style_scheme_buttons_sensisitivity (GeditPreferencesDialog *dlg)
-+set_buttons_sensisitivity_according_to_scheme (GeditPreferencesDialog *dlg,
-+ GtkSourceStyleScheme *scheme)
- {
-- GtkSourceStyleScheme *selected_style_scheme;
- gboolean editable = FALSE;
-
-- selected_style_scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
--
-- if (selected_style_scheme != NULL)
-+ if (scheme != NULL)
- {
- const gchar *filename;
-
-- filename = gtk_source_style_scheme_get_filename (selected_style_scheme);
-+ filename = gtk_source_style_scheme_get_filename (scheme);
- if (filename != NULL)
- {
- editable = g_str_has_prefix (filename, gedit_dirs_get_user_styles_dir ());
- }
- }
-
-- gtk_widget_set_sensitive (dlg->uninstall_scheme_button, editable);
-+ gtk_widget_set_sensitive (dlg->uninstall_scheme_button,
-+ editable);
- }
-
- static void
--style_scheme_notify_cb (GtkSourceStyleSchemeChooser *chooser,
-- GParamSpec *pspec,
-- GeditPreferencesDialog *dlg)
-+style_scheme_changed (GtkSourceStyleSchemeChooser *chooser,
-+ GParamSpec *pspec,
-+ GeditPreferencesDialog *dlg)
- {
-- update_style_scheme_buttons_sensisitivity (dlg);
-+ GtkSourceStyleScheme *scheme;
-+ const gchar *id;
-+
-+ scheme = gtk_source_style_scheme_chooser_get_style_scheme (chooser);
-+ id = gtk_source_style_scheme_get_id (scheme);
-+
-+ g_settings_set_string (dlg->editor, GEDIT_SETTINGS_SCHEME, id);
-+ set_buttons_sensisitivity_according_to_scheme (dlg, scheme);
- }
-
--static GFile *
--get_user_style_scheme_destination_file (GFile *src_file)
-+static GtkSourceStyleScheme *
-+get_default_color_scheme (GeditPreferencesDialog *dlg)
- {
-- gchar *basename;
-- const gchar *styles_dir;
-- GFile *dest_file;
-+ GtkSourceStyleSchemeManager *manager;
-+ GtkSourceStyleScheme *scheme = NULL;
-+ gchar *pref_id;
-
-- basename = g_file_get_basename (src_file);
-- g_return_val_if_fail (basename != NULL, NULL);
-+ manager = gtk_source_style_scheme_manager_get_default ();
-
-- styles_dir = gedit_dirs_get_user_styles_dir ();
-- dest_file = g_file_new_build_filename (styles_dir, basename, NULL);
-+ pref_id = g_settings_get_string (dlg->editor,
-+ GEDIT_SETTINGS_SCHEME);
-
-- g_free (basename);
-- return dest_file;
-+ scheme = gtk_source_style_scheme_manager_get_scheme (manager,
-+ pref_id);
-+ g_free (pref_id);
-+
-+ if (scheme == NULL)
-+ {
-+ /* Fall-back to classic style scheme */
-+ scheme = gtk_source_style_scheme_manager_get_scheme (manager,
-+ "classic");
-+ }
-+
-+ return scheme;
- }
-
--/* Returns: whether @src_file has been correctly copied to @dest_file. */
-+/*
-+ * file_copy:
-+ * @name: a pointer to a %NULL-terminated string, that names
-+ * the file to be copied, in the GLib file name encoding
-+ * @dest_name: a pointer to a %NULL-terminated string, that is the
-+ * name for the destination file, in the GLib file name encoding
-+ * @error: return location for a #GError, or %NULL
-+ *
-+ * Copies file @name to @dest_name.
-+ *
-+ * If the call was successful, it returns %TRUE. If the call was not
-+ * successful, it returns %FALSE and sets @error. The error domain
-+ * is #G_FILE_ERROR. Possible error
-+ * codes are those in the #GFileError enumeration.
-+ *
-+ * Return value: %TRUE on success, %FALSE otherwise.
-+ */
- static gboolean
--copy_file (GFile *src_file,
-- GFile *dest_file,
-- GError **error)
-+file_copy (const gchar *name,
-+ const gchar *dest_name,
-+ GError **error)
- {
-- if (g_file_equal (src_file, dest_file))
-+ gchar *contents;
-+ gsize length;
-+ gchar *dest_dir;
-+
-+ /* FIXME - Paolo (Aug. 13, 2007):
-+ * Since the style scheme files are relatively small, we can implement
-+ * file copy getting all the content of the source file in a buffer and
-+ * then write the content to the destination file. In this way we
-+ * can use the g_file_get_contents and g_file_set_contents and avoid to
-+ * write custom code to copy the file (with sane error management).
-+ * If needed we can improve this code later. */
-+
-+ g_return_val_if_fail (name != NULL, FALSE);
-+ g_return_val_if_fail (dest_name != NULL, FALSE);
-+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-+
-+ /* Note: we allow to copy a file to itself since this is not a problem
-+ * in our use case */
-+
-+ /* Ensure the destination directory exists */
-+ dest_dir = g_path_get_dirname (dest_name);
-+
-+ errno = 0;
-+ if (g_mkdir_with_parents (dest_dir, 0755) != 0)
- {
-+ gint save_errno = errno;
-+ gchar *display_filename = g_filename_display_name (dest_dir);
-+
-+ g_set_error (error,
-+ G_FILE_ERROR,
-+ g_file_error_from_errno (save_errno),
-+ _("Directory “%s” could not be created: g_mkdir_with_parents() failed: %s"),
-+ display_filename,
-+ g_strerror (save_errno));
-+
-+ g_free (dest_dir);
-+ g_free (display_filename);
-+
- return FALSE;
- }
-
-- if (!tepl_utils_create_parent_directories (dest_file, NULL, error))
-+ g_free (dest_dir);
-+
-+ if (!g_file_get_contents (name, &contents, &length, error))
-+ return FALSE;
-+
-+ if (!g_file_set_contents (dest_name, contents, length, error))
- {
-+ g_free (contents);
- return FALSE;
- }
-
-- return g_file_copy (src_file,
-- dest_file,
-- G_FILE_COPY_OVERWRITE | G_FILE_COPY_TARGET_DEFAULT_PERMS,
-- NULL, /* cancellable */
-- NULL, NULL, /* progress callback */
-- error);
-+ g_free (contents);
-+
-+ return TRUE;
- }
-
--/* Get the style scheme ID of @user_style_scheme_file if it has been correctly
-- * installed and @user_style_scheme_file is a valid style scheme file.
-+/*
-+ * install_style_scheme:
-+ * @manager: a #GtkSourceStyleSchemeManager
-+ * @fname: the file name of the style scheme to be installed
-+ *
-+ * Install a new user scheme.
-+ * This function copies @fname in #GEDIT_STYLES_DIR and ask the style manager to
-+ * recompute the list of available style schemes. It then checks if a style
-+ * scheme with the right file name exists.
-+ *
-+ * If the call was succesful, it returns the id of the installed scheme
-+ * otherwise %NULL.
-+ *
-+ * Return value: the id of the installed scheme, %NULL otherwise.
- */
--static const gchar *
--get_style_scheme_id_after_installing_user_style_scheme (GFile *user_style_scheme_file)
-+static GtkSourceStyleScheme *
-+install_style_scheme (const gchar *fname)
- {
- GtkSourceStyleSchemeManager *manager;
-- const gchar * const *scheme_ids;
-- gint i;
-+ gchar *new_file_name = NULL;
-+ gchar *dirname;
-+ const gchar *styles_dir;
-+ GError *error = NULL;
-+ gboolean copied = FALSE;
-+ const gchar * const *ids;
-+
-+ g_return_val_if_fail (fname != NULL, NULL);
-
- manager = gtk_source_style_scheme_manager_get_default ();
-- gtk_source_style_scheme_manager_force_rescan (manager);
-
-- scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
-+ dirname = g_path_get_dirname (fname);
-+ styles_dir = gedit_dirs_get_user_styles_dir ();
-
-- for (i = 0; scheme_ids != NULL && scheme_ids[i] != NULL; i++)
-+ if (strcmp (dirname, styles_dir) != 0)
- {
-- const gchar *cur_scheme_id = scheme_ids[i];
-- GtkSourceStyleScheme *scheme;
-- const gchar *filename;
-- GFile *scheme_file;
-+ gchar *basename;
-
-- scheme = gtk_source_style_scheme_manager_get_scheme (manager, cur_scheme_id);
-- filename = gtk_source_style_scheme_get_filename (scheme);
-- if (filename == NULL)
-- {
-- continue;
-- }
-+ basename = g_path_get_basename (fname);
-+ new_file_name = g_build_filename (styles_dir, basename, NULL);
-+ g_free (basename);
-
-- scheme_file = g_file_new_for_path (filename);
-- if (g_file_equal (scheme_file, user_style_scheme_file))
-+ /* Copy the style scheme file into GEDIT_STYLES_DIR */
-+ if (!file_copy (fname, new_file_name, &error))
- {
-- g_object_unref (scheme_file);
-- return cur_scheme_id;
-+ g_free (new_file_name);
-+ g_free (dirname);
-+
-+ g_message ("Cannot install style scheme:\n%s",
-+ error->message);
-+
-+ g_error_free (error);
-+
-+ return NULL;
- }
-
-- g_object_unref (scheme_file);
-+ copied = TRUE;
-+ }
-+ else
-+ {
-+ new_file_name = g_strdup (fname);
- }
-
-- return NULL;
--}
--
--/* Returns: (nullable): the installed style scheme ID, or %NULL on failure. */
--static const gchar *
--install_style_scheme (GFile *src_file,
-- GError **error)
--{
-- GFile *dest_file;
-- gboolean copied;
-- const gchar *installed_style_scheme_id = NULL;
-- GError *my_error = NULL;
-+ g_free (dirname);
-
-- g_return_val_if_fail (G_IS_FILE (src_file), NULL);
-- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
-+ /* Reload the available style schemes */
-+ gtk_source_style_scheme_manager_force_rescan (manager);
-
-- dest_file = get_user_style_scheme_destination_file (src_file);
-- g_return_val_if_fail (dest_file != NULL, NULL);
-+ /* Check the new style scheme has been actually installed */
-+ ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
-
-- copied = copy_file (src_file, dest_file, &my_error);
-- if (my_error != NULL)
-+ while (*ids != NULL)
- {
-- g_propagate_error (error, my_error);
-- g_object_unref (dest_file);
-- return NULL;
-- }
-+ GtkSourceStyleScheme *scheme;
-+ const gchar *filename;
-
-- installed_style_scheme_id = get_style_scheme_id_after_installing_user_style_scheme (dest_file);
-+ scheme = gtk_source_style_scheme_manager_get_scheme (manager, *ids);
-
-- if (installed_style_scheme_id == NULL && copied)
-- {
-- /* The style scheme has not been correctly installed. */
-- g_file_delete (dest_file, NULL, &my_error);
-- if (my_error != NULL)
-- {
-- gchar *dest_file_parse_name = g_file_get_parse_name (dest_file);
-+ filename = gtk_source_style_scheme_get_filename (scheme);
-
-- g_warning ("Failed to delete the file “%s”: %s",
-- dest_file_parse_name,
-- my_error->message);
-+ if (filename && (strcmp (filename, new_file_name) == 0))
-+ {
-+ /* The style scheme has been correctly installed */
-+ g_free (new_file_name);
-
-- g_free (dest_file_parse_name);
-- g_clear_error (&my_error);
-+ return scheme;
- }
-+ ++ids;
- }
-
-- g_object_unref (dest_file);
-- return installed_style_scheme_id;
-+ /* The style scheme has not been correctly installed */
-+ if (copied)
-+ g_unlink (new_file_name);
-+
-+ g_free (new_file_name);
-+
-+ return NULL;
- }
-
--/*
-+/**
- * uninstall_style_scheme:
-+ * @manager: a #GtkSourceStyleSchemeManager
- * @scheme: a #GtkSourceStyleScheme
- *
- * Uninstall a user scheme.
- *
-- * Returns: %TRUE on success, %FALSE otherwise.
-+ * If the call was succesful, it returns %TRUE
-+ * otherwise %FALSE.
-+ *
-+ * Return value: %TRUE on success, %FALSE otherwise.
- */
- static gboolean
- uninstall_style_scheme (GtkSourceStyleScheme *scheme)
-@@ -653,94 +754,92 @@ uninstall_style_scheme (GtkSourceStyleScheme *scheme)
- }
-
- static void
--add_scheme_chooser_response_cb (GtkFileChooserNative *chooser,
-- gint response_id,
-- GeditPreferencesDialog *dialog)
-+add_scheme_chooser_response_cb (GeditFileChooserDialog *chooser,
-+ gint res_id,
-+ GeditPreferencesDialog *dlg)
- {
- GFile *file;
-- const gchar *scheme_id;
-- GeditSettings *settings;
-- GSettings *editor_settings;
-- GError *error = NULL;
-+ gchar *filename;
-+ GtkSourceStyleScheme *scheme;
-
-- if (response_id != GTK_RESPONSE_ACCEPT)
-+ if (res_id != GTK_RESPONSE_ACCEPT)
- {
-+ gedit_file_chooser_dialog_hide (chooser);
- return;
- }
-
-- file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (chooser));
-+ file = gedit_file_chooser_dialog_get_file (chooser);
-+
- if (file == NULL)
- {
- return;
- }
-
-- scheme_id = install_style_scheme (file, &error);
-+ filename = g_file_get_path (file);
- g_object_unref (file);
-
-- if (scheme_id == NULL)
-+ if (filename == NULL)
- {
-- if (error != NULL)
-- {
-- tepl_utils_show_warning_dialog (GTK_WINDOW (dialog),
-- _("The selected color scheme cannot be installed: %s"),
-- error->message);
-- }
-- else
-- {
-- tepl_utils_show_warning_dialog (GTK_WINDOW (dialog),
-- _("The selected color scheme cannot be installed."));
-- }
-+ return;
-+ }
-+
-+ gedit_file_chooser_dialog_hide (chooser);
-+
-+ scheme = install_style_scheme (filename);
-+ g_free (filename);
-+
-+ if (scheme == NULL)
-+ {
-+ gedit_warning (GTK_WINDOW (dlg),
-+ _("The selected color scheme cannot be installed."));
-
-- g_clear_error (&error);
- return;
- }
-
-- settings = _gedit_settings_get_singleton ();
-- editor_settings = _gedit_settings_peek_editor_settings (settings);
-- g_settings_set_string (editor_settings, GEDIT_SETTINGS_SCHEME, scheme_id);
-+ g_settings_set_string (dlg->editor, GEDIT_SETTINGS_SCHEME,
-+ gtk_source_style_scheme_get_id (scheme));
-+
-+ set_buttons_sensisitivity_according_to_scheme (dlg, scheme);
- }
-
- static void
- install_scheme_clicked (GtkButton *button,
-- GeditPreferencesDialog *dialog)
-+ GeditPreferencesDialog *dlg)
- {
-- GtkFileChooserNative *chooser;
-- GtkFileFilter *scheme_filter;
-- GtkFileFilter *all_filter;
-+ GeditFileChooserDialog *chooser;
-
-- if (dialog->install_scheme_file_chooser != NULL)
-+ if (dlg->install_scheme_file_schooser != NULL)
- {
-- gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog->install_scheme_file_chooser));
-+ gedit_file_chooser_dialog_show (dlg->install_scheme_file_schooser);
- return;
- }
-
-- chooser = gtk_file_chooser_native_new (_("Add Color Scheme"),
-- GTK_WINDOW (dialog),
-- GTK_FILE_CHOOSER_ACTION_OPEN,
-- _("_Add Scheme"),
-- _("_Cancel"));
-+ chooser = gedit_file_chooser_dialog_create (_("Add Scheme"),
-+ GTK_WINDOW (dlg),
-+ GEDIT_FILE_CHOOSER_FLAG_OPEN,
-+ _("_Cancel"),
-+ _("A_dd Scheme"));
-
- /* Filters */
-- scheme_filter = gtk_file_filter_new ();
-- gtk_file_filter_set_name (scheme_filter, _("Color Scheme Files"));
-- gtk_file_filter_add_pattern (scheme_filter, "*.xml");
-- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), scheme_filter);
--
-- all_filter = gtk_file_filter_new ();
-- gtk_file_filter_set_name (all_filter, _("All Files"));
-- gtk_file_filter_add_pattern (all_filter, "*");
-- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), all_filter);
-+ gedit_file_chooser_dialog_add_pattern_filter (chooser,
-+ _("Color Scheme Files"),
-+ "*.xml");
-
-- gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), scheme_filter);
-+ gedit_file_chooser_dialog_add_pattern_filter (chooser,
-+ _("All Files"),
-+ "*");
-
- g_signal_connect (chooser,
- "response",
- G_CALLBACK (add_scheme_chooser_response_cb),
-- dialog);
-+ dlg);
-
-- g_set_weak_pointer (&dialog->install_scheme_file_chooser, chooser);
-+ dlg->install_scheme_file_schooser = chooser;
-
-- gtk_native_dialog_show (GTK_NATIVE_DIALOG (chooser));
-+ g_object_add_weak_pointer (G_OBJECT (chooser),
-+ (gpointer) &dlg->install_scheme_file_schooser);
-+
-+ gedit_file_chooser_dialog_show (chooser);
- }
-
- static void
-@@ -748,33 +847,14 @@ uninstall_scheme_clicked (GtkButton *button,
- GeditPreferencesDialog *dlg)
- {
- GtkSourceStyleScheme *scheme;
-- GtkSourceStyleScheme *new_selected_scheme;
-
- scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
-
-- if (scheme == NULL)
-- {
-- return;
-- }
--
- if (!uninstall_style_scheme (scheme))
- {
-- tepl_utils_show_warning_dialog (GTK_WINDOW (dlg),
-- _("Could not remove color scheme “%s”."),
-- gtk_source_style_scheme_get_name (scheme));
-- return;
-- }
--
-- new_selected_scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
-- if (new_selected_scheme == NULL)
-- {
-- GeditSettings *settings;
-- GSettings *editor_settings;
--
-- settings = _gedit_settings_get_singleton ();
-- editor_settings = _gedit_settings_peek_editor_settings (settings);
--
-- g_settings_reset (editor_settings, GEDIT_SETTINGS_SCHEME);
-+ gedit_warning (GTK_WINDOW (dlg),
-+ _("Could not remove color scheme “%s”."),
-+ gtk_source_style_scheme_get_name (scheme));
- }
- }
-
-@@ -782,13 +862,14 @@ static void
- setup_font_colors_page_style_scheme_section (GeditPreferencesDialog *dlg)
- {
- GtkStyleContext *context;
-- GeditSettings *settings;
-- GSettings *editor_settings;
-+ GtkSourceStyleScheme *scheme;
-
- gedit_debug (DEBUG_PREFS);
-
-- /* junction between the schemes list and the toolbar */
-- context = gtk_widget_get_style_context (dlg->schemes_list);
-+ scheme = get_default_color_scheme (dlg);
-+
-+ /* junction between the scrolled window and the toolbar */
-+ context = gtk_widget_get_style_context (dlg->schemes_scrolled_window);
- gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
- context = gtk_widget_get_style_context (dlg->schemes_toolbar);
- gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
-@@ -796,7 +877,7 @@ setup_font_colors_page_style_scheme_section (GeditPreferencesDialog *dlg)
- /* Connect signals */
- g_signal_connect (dlg->schemes_list,
- "notify::style-scheme",
-- G_CALLBACK (style_scheme_notify_cb),
-+ G_CALLBACK (style_scheme_changed),
- dlg);
- g_signal_connect (dlg->install_scheme_button,
- "clicked",
-@@ -807,13 +888,11 @@ setup_font_colors_page_style_scheme_section (GeditPreferencesDialog *dlg)
- G_CALLBACK (uninstall_scheme_clicked),
- dlg);
-
-- settings = _gedit_settings_get_singleton ();
-- editor_settings = _gedit_settings_peek_editor_settings (settings);
-- g_settings_bind (editor_settings, GEDIT_SETTINGS_SCHEME,
-- dlg->schemes_list, "tepl-style-scheme-id",
-- G_SETTINGS_BIND_DEFAULT);
-+ gtk_source_style_scheme_chooser_set_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list),
-+ scheme);
-
-- update_style_scheme_buttons_sensisitivity (dlg);
-+ /* Set initial widget sensitivity */
-+ set_buttons_sensisitivity_according_to_scheme (dlg, scheme);
- }
-
- static void
-diff --git a/gedit/gedit-print-job.c b/gedit/gedit-print-job.c
-index 6083669f9..e6c1dcdcb 100644
---- a/gedit/gedit-print-job.c
-+++ b/gedit/gedit-print-job.c
-@@ -23,7 +23,7 @@
- #include "gedit-print-job.h"
-
- #include
--#include
-+#include
-
- #include "gedit-debug.h"
- #include "gedit-document-private.h"
-@@ -535,7 +535,7 @@ create_compositor (GeditPrintJob *job)
- gchar *left;
-
- doc_name = _gedit_document_get_uri_for_display (GEDIT_DOCUMENT (buf));
-- name_to_display = tepl_utils_str_middle_truncate (doc_name, 60);
-+ name_to_display = gedit_utils_str_middle_truncate (doc_name, 60);
-
- left = g_strdup_printf (_("File: %s"), name_to_display);
-
-diff --git a/gedit/gedit-progress-info-bar.c b/gedit/gedit-progress-info-bar.c
-new file mode 100644
-index 000000000..d547189fb
---- /dev/null
-+++ b/gedit/gedit-progress-info-bar.c
-@@ -0,0 +1,177 @@
-+/*
-+ * gedit-progress-info-bar.c
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2005 - Paolo Maggi
-+ *
-+ * 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 "gedit-progress-info-bar.h"
-+#include
-+
-+enum {
-+ PROP_0,
-+ PROP_HAS_CANCEL_BUTTON,
-+ LAST_PROP
-+};
-+
-+static GParamSpec *properties[LAST_PROP];
-+
-+struct _GeditProgressInfoBar
-+{
-+ GtkInfoBar parent_instance;
-+
-+ GtkWidget *image;
-+ GtkWidget *label;
-+ GtkWidget *progress;
-+};
-+
-+G_DEFINE_TYPE (GeditProgressInfoBar, gedit_progress_info_bar, GTK_TYPE_INFO_BAR)
-+
-+static void
-+gedit_progress_info_bar_set_has_cancel_button (GeditProgressInfoBar *bar,
-+ gboolean has_button)
-+{
-+ if (has_button)
-+ {
-+ gtk_info_bar_add_button (GTK_INFO_BAR (bar), _("_Cancel"), GTK_RESPONSE_CANCEL);
-+ }
-+}
-+
-+static void
-+gedit_progress_info_bar_set_property (GObject *object,
-+ guint prop_id,
-+ const GValue *value,
-+ GParamSpec *pspec)
-+{
-+ GeditProgressInfoBar *bar;
-+
-+ bar = GEDIT_PROGRESS_INFO_BAR (object);
-+
-+ switch (prop_id)
-+ {
-+ case PROP_HAS_CANCEL_BUTTON:
-+ gedit_progress_info_bar_set_has_cancel_button (bar,
-+ g_value_get_boolean (value));
-+ break;
-+ default:
-+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-+ break;
-+ }
-+}
-+
-+static void
-+gedit_progress_info_bar_class_init (GeditProgressInfoBarClass *klass)
-+{
-+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-+
-+ gobject_class->set_property = gedit_progress_info_bar_set_property;
-+
-+ properties[PROP_HAS_CANCEL_BUTTON] =
-+ g_param_spec_boolean ("has-cancel-button",
-+ "Has Cancel Button",
-+ "If the message bar has a cancel button",
-+ TRUE,
-+ G_PARAM_WRITABLE |
-+ G_PARAM_CONSTRUCT_ONLY |
-+ G_PARAM_STATIC_STRINGS);
-+
-+ g_object_class_install_properties (gobject_class, LAST_PROP, properties);
-+
-+ /* Bind class to template */
-+ gtk_widget_class_set_template_from_resource (widget_class,
-+ "/org/gnome/gedit/ui/gedit-progress-info-bar.ui");
-+ gtk_widget_class_bind_template_child (widget_class, GeditProgressInfoBar, image);
-+ gtk_widget_class_bind_template_child (widget_class, GeditProgressInfoBar, label);
-+ gtk_widget_class_bind_template_child (widget_class, GeditProgressInfoBar, progress);
-+}
-+
-+static void
-+gedit_progress_info_bar_init (GeditProgressInfoBar *bar)
-+{
-+ gtk_widget_init_template (GTK_WIDGET (bar));
-+}
-+
-+GtkWidget *
-+gedit_progress_info_bar_new (const gchar *icon_name,
-+ const gchar *markup,
-+ gboolean has_cancel)
-+{
-+ GeditProgressInfoBar *bar;
-+
-+ g_return_val_if_fail (icon_name != NULL, NULL);
-+ g_return_val_if_fail (markup != NULL, NULL);
-+
-+ bar = GEDIT_PROGRESS_INFO_BAR (g_object_new (GEDIT_TYPE_PROGRESS_INFO_BAR,
-+ "has-cancel-button", has_cancel,
-+ NULL));
-+
-+ gedit_progress_info_bar_set_icon_name (bar, icon_name);
-+ gedit_progress_info_bar_set_markup (bar, markup);
-+
-+ return GTK_WIDGET (bar);
-+}
-+
-+void
-+gedit_progress_info_bar_set_icon_name (GeditProgressInfoBar *bar,
-+ const gchar *icon_name)
-+{
-+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
-+ g_return_if_fail (icon_name != NULL);
-+
-+ gtk_image_set_from_icon_name (GTK_IMAGE (bar->image),
-+ icon_name,
-+ GTK_ICON_SIZE_SMALL_TOOLBAR);
-+}
-+
-+void
-+gedit_progress_info_bar_set_markup (GeditProgressInfoBar *bar,
-+ const gchar *markup)
-+{
-+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
-+ g_return_if_fail (markup != NULL);
-+
-+ gtk_label_set_markup (GTK_LABEL (bar->label), markup);
-+}
-+
-+void
-+gedit_progress_info_bar_set_text (GeditProgressInfoBar *bar,
-+ const gchar *text)
-+{
-+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
-+ g_return_if_fail (text != NULL);
-+
-+ gtk_label_set_text (GTK_LABEL (bar->label), text);
-+}
-+
-+void
-+gedit_progress_info_bar_set_fraction (GeditProgressInfoBar *bar,
-+ gdouble fraction)
-+{
-+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
-+
-+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar->progress), fraction);
-+}
-+
-+void
-+gedit_progress_info_bar_pulse (GeditProgressInfoBar *bar)
-+{
-+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
-+
-+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (bar->progress));
-+}
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-progress-info-bar.h b/gedit/gedit-progress-info-bar.h
-new file mode 100644
-index 000000000..0d820d8e4
---- /dev/null
-+++ b/gedit/gedit-progress-info-bar.h
-@@ -0,0 +1,53 @@
-+/*
-+ * gedit-progress-info-bar.h
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2005 - Paolo Maggi
-+ *
-+ * 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 GEDIT_PROGRESS_INFO_BAR_H
-+#define GEDIT_PROGRESS_INFO_BAR_H
-+
-+#include
-+
-+G_BEGIN_DECLS
-+
-+#define GEDIT_TYPE_PROGRESS_INFO_BAR (gedit_progress_info_bar_get_type ())
-+G_DECLARE_FINAL_TYPE (GeditProgressInfoBar, gedit_progress_info_bar, GEDIT, PROGRESS_INFO_BAR, GtkInfoBar)
-+
-+GtkWidget *gedit_progress_info_bar_new (const gchar *icon_name,
-+ const gchar *markup,
-+ gboolean has_cancel);
-+
-+void gedit_progress_info_bar_set_icon_name (GeditProgressInfoBar *bar,
-+ const gchar *icon_name);
-+
-+void gedit_progress_info_bar_set_markup (GeditProgressInfoBar *bar,
-+ const gchar *markup);
-+
-+void gedit_progress_info_bar_set_text (GeditProgressInfoBar *bar,
-+ const gchar *text);
-+
-+void gedit_progress_info_bar_set_fraction (GeditProgressInfoBar *bar,
-+ gdouble fraction);
-+
-+void gedit_progress_info_bar_pulse (GeditProgressInfoBar *bar);
-+
-+G_END_DECLS
-+
-+#endif /* GEDIT_PROGRESS_INFO_BAR_H */
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-recent-osx.c b/gedit/gedit-recent-osx.c
-deleted file mode 100644
-index 6f8c8cd6e..000000000
---- a/gedit/gedit-recent-osx.c
-+++ /dev/null
-@@ -1,249 +0,0 @@
--/*
-- * This file is part of gedit
-- *
-- * Copyright (C) 2005 - Paolo Maggi
-- * Copyright (C) 2014 - Paolo Borelli
-- * Copyright (C) 2014 - 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 "gedit-recent-osx.h"
--
--static gint
--sort_recent_items_mru (GtkRecentInfo *a,
-- GtkRecentInfo *b,
-- gpointer unused)
--{
-- g_assert (a != NULL && b != NULL);
-- return gtk_recent_info_get_modified (b) - gtk_recent_info_get_modified (a);
--}
--
--static void
--populate_filter_info (GtkRecentInfo *info,
-- GtkRecentFilterInfo *filter_info,
-- GtkRecentFilterFlags needed)
--{
-- filter_info->uri = gtk_recent_info_get_uri (info);
-- filter_info->mime_type = gtk_recent_info_get_mime_type (info);
--
-- filter_info->contains = GTK_RECENT_FILTER_URI | GTK_RECENT_FILTER_MIME_TYPE;
--
-- if (needed & GTK_RECENT_FILTER_DISPLAY_NAME)
-- {
-- filter_info->display_name = gtk_recent_info_get_display_name (info);
-- filter_info->contains |= GTK_RECENT_FILTER_DISPLAY_NAME;
-- }
-- else
-- {
-- filter_info->uri = NULL;
-- }
--
-- if (needed & GTK_RECENT_FILTER_APPLICATION)
-- {
-- filter_info->applications = (const gchar **) gtk_recent_info_get_applications (info, NULL);
-- filter_info->contains |= GTK_RECENT_FILTER_APPLICATION;
-- }
-- else
-- {
-- filter_info->applications = NULL;
-- }
--
-- if (needed & GTK_RECENT_FILTER_GROUP)
-- {
-- filter_info->groups = (const gchar **) gtk_recent_info_get_groups (info, NULL);
-- filter_info->contains |= GTK_RECENT_FILTER_GROUP;
-- }
-- else
-- {
-- filter_info->groups = NULL;
-- }
--
-- if (needed & GTK_RECENT_FILTER_AGE)
-- {
-- filter_info->age = gtk_recent_info_get_age (info);
-- filter_info->contains |= GTK_RECENT_FILTER_AGE;
-- }
-- else
-- {
-- filter_info->age = -1;
-- }
--}
--
--/* The GeditRecentConfiguration struct is allocated and owned by the caller */
--void
--gedit_recent_configuration_init_default (GeditRecentConfiguration *config)
--{
-- config->manager = gtk_recent_manager_get_default ();
--
-- if (config->filter != NULL)
-- {
-- g_object_unref (config->filter);
-- }
--
-- config->filter = gtk_recent_filter_new ();
-- gtk_recent_filter_add_application (config->filter, g_get_application_name ());
-- gtk_recent_filter_add_mime_type (config->filter, "text/plain");
-- g_object_ref_sink (config->filter);
--
-- config->limit = 5;
-- config->show_not_found = TRUE;
-- config->show_private = FALSE;
-- config->local_only = FALSE;
--
-- config->substring_filter = NULL;
--}
--
--/* The GeditRecentConfiguration struct is owned and destroyed by the caller */
--void
--gedit_recent_configuration_destroy (GeditRecentConfiguration *config)
--{
-- g_clear_object (&config->filter);
-- config->manager = NULL;
--
-- g_clear_pointer (&config->substring_filter, (GDestroyNotify)g_free);
--}
--
--GList *
--gedit_recent_get_items (GeditRecentConfiguration *config)
--{
-- GtkRecentFilterFlags needed;
-- GList *items;
-- GList *retitems = NULL;
-- gint length;
-- char *substring_filter = NULL;
--
-- if (config->limit == 0)
-- {
-- return NULL;
-- }
--
-- items = gtk_recent_manager_get_items (config->manager);
--
-- if (!items)
-- {
-- return NULL;
-- }
--
-- needed = gtk_recent_filter_get_needed (config->filter);
-- if (config->substring_filter && *config->substring_filter != '\0')
-- {
-- gchar *filter_normalized;
--
-- filter_normalized = g_utf8_normalize (config->substring_filter, -1, G_NORMALIZE_ALL);
-- substring_filter = g_utf8_casefold (filter_normalized, -1);
-- g_free (filter_normalized);
-- }
--
-- while (items)
-- {
-- GtkRecentInfo *info;
-- GtkRecentFilterInfo filter_info;
-- gboolean is_filtered;
--
-- info = items->data;
-- is_filtered = FALSE;
--
-- if (config->local_only && !gtk_recent_info_is_local (info))
-- {
-- is_filtered = TRUE;
-- }
-- else if (!config->show_private && gtk_recent_info_get_private_hint (info))
-- {
-- is_filtered = TRUE;
-- }
-- else if (!config->show_not_found && !gtk_recent_info_exists (info))
-- {
-- is_filtered = TRUE;
-- }
-- else
-- {
-- if (substring_filter)
-- {
-- gchar *uri_normalized;
-- gchar *uri_casefolded;
--
-- uri_normalized = g_utf8_normalize (gtk_recent_info_get_uri_display (info), -1, G_NORMALIZE_ALL);
-- uri_casefolded = g_utf8_casefold (uri_normalized, -1);
-- g_free (uri_normalized);
--
-- if (strstr (uri_casefolded, substring_filter) == NULL)
-- {
-- is_filtered = TRUE;
-- }
--
-- g_free (uri_casefolded);
-- }
--
-- if (!is_filtered)
-- {
-- populate_filter_info (info, &filter_info, needed);
-- is_filtered = !gtk_recent_filter_filter (config->filter, &filter_info);
--
-- /* these we own */
-- if (filter_info.applications)
-- {
-- g_strfreev ((gchar **) filter_info.applications);
-- }
--
-- if (filter_info.groups)
-- {
-- g_strfreev ((gchar **) filter_info.groups);
-- }
-- }
-- }
--
-- if (!is_filtered)
-- {
-- retitems = g_list_prepend (retitems, info);
-- }
-- else
-- {
-- gtk_recent_info_unref (info);
-- }
--
-- items = g_list_delete_link (items, items);
-- }
--
-- g_free (substring_filter);
--
-- if (!retitems)
-- {
-- return NULL;
-- }
--
-- retitems = g_list_sort_with_data (retitems, (GCompareDataFunc) sort_recent_items_mru, NULL);
-- length = g_list_length (retitems);
--
-- if ((config->limit != -1) && (length > config->limit))
-- {
-- GList *clamp, *l;
--
-- clamp = g_list_nth (retitems, config->limit - 1);
--
-- if (!clamp)
-- {
-- return retitems;
-- }
--
-- l = clamp->next;
-- clamp->next = NULL;
--
-- g_list_free_full (l, (GDestroyNotify) gtk_recent_info_unref);
-- }
--
-- return retitems;
--}
--
--/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-recent-osx.h b/gedit/gedit-recent-osx.h
-deleted file mode 100644
-index df77ca724..000000000
---- a/gedit/gedit-recent-osx.h
-+++ /dev/null
-@@ -1,54 +0,0 @@
--/*
-- * This file is part of gedit
-- *
-- * Copyright (C) 2005 - Paolo Maggi
-- * Copyright (C) 2014 - Paolo Borelli
-- * Copyright (C) 2014 - 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
-- * MERCHANWINDOWILITY 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 GEDIT_RECENT_OSX_H
--#define GEDIT_RECENT_OSX_H
--
--#include
--
--G_BEGIN_DECLS
--
--/* TODO: this code can be simplified, the struct can be made private, the dead
-- * code can be removed, etc.
-- */
--
--typedef struct
--{
-- GtkRecentManager *manager;
-- GtkRecentFilter *filter;
--
-- gint limit;
-- gchar *substring_filter;
--
-- guint show_private : 1;
-- guint show_not_found : 1;
-- guint local_only : 1;
--} GeditRecentConfiguration;
--
--void gedit_recent_configuration_init_default (GeditRecentConfiguration *config);
--void gedit_recent_configuration_destroy (GeditRecentConfiguration *config);
--GList *gedit_recent_get_items (GeditRecentConfiguration *config);
--
--G_END_DECLS
--
--#endif /* GEDIT_RECENT_OSX_H */
--
--/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-recent.c b/gedit/gedit-recent.c
-index b1535d057..2a0063306 100644
---- a/gedit/gedit-recent.c
-+++ b/gedit/gedit-recent.c
-@@ -24,7 +24,7 @@
- void
- gedit_recent_add_document (GeditDocument *document)
- {
-- TeplFile *file;
-+ GtkSourceFile *file;
- GFile *location;
- GtkRecentManager *recent_manager;
- GtkRecentData recent_data;
-@@ -33,8 +33,8 @@ gedit_recent_add_document (GeditDocument *document)
-
- g_return_if_fail (GEDIT_IS_DOCUMENT (document));
-
-- file = tepl_buffer_get_file (TEPL_BUFFER (document));
-- location = tepl_file_get_location (file);
-+ file = gedit_document_get_file (document);
-+ location = gtk_source_file_get_location (file);
-
- if (location == NULL)
- {
-@@ -89,4 +89,229 @@ gedit_recent_remove_if_local (GFile *location)
- }
- }
-
-+static gint
-+sort_recent_items_mru (GtkRecentInfo *a,
-+ GtkRecentInfo *b,
-+ gpointer unused)
-+{
-+ g_assert (a != NULL && b != NULL);
-+ return gtk_recent_info_get_modified (b) - gtk_recent_info_get_modified (a);
-+}
-+
-+static void
-+populate_filter_info (GtkRecentInfo *info,
-+ GtkRecentFilterInfo *filter_info,
-+ GtkRecentFilterFlags needed)
-+{
-+ filter_info->uri = gtk_recent_info_get_uri (info);
-+ filter_info->mime_type = gtk_recent_info_get_mime_type (info);
-+
-+ filter_info->contains = GTK_RECENT_FILTER_URI | GTK_RECENT_FILTER_MIME_TYPE;
-+
-+ if (needed & GTK_RECENT_FILTER_DISPLAY_NAME)
-+ {
-+ filter_info->display_name = gtk_recent_info_get_display_name (info);
-+ filter_info->contains |= GTK_RECENT_FILTER_DISPLAY_NAME;
-+ }
-+ else
-+ {
-+ filter_info->uri = NULL;
-+ }
-+
-+ if (needed & GTK_RECENT_FILTER_APPLICATION)
-+ {
-+ filter_info->applications = (const gchar **) gtk_recent_info_get_applications (info, NULL);
-+ filter_info->contains |= GTK_RECENT_FILTER_APPLICATION;
-+ }
-+ else
-+ {
-+ filter_info->applications = NULL;
-+ }
-+
-+ if (needed & GTK_RECENT_FILTER_GROUP)
-+ {
-+ filter_info->groups = (const gchar **) gtk_recent_info_get_groups (info, NULL);
-+ filter_info->contains |= GTK_RECENT_FILTER_GROUP;
-+ }
-+ else
-+ {
-+ filter_info->groups = NULL;
-+ }
-+
-+ if (needed & GTK_RECENT_FILTER_AGE)
-+ {
-+ filter_info->age = gtk_recent_info_get_age (info);
-+ filter_info->contains |= GTK_RECENT_FILTER_AGE;
-+ }
-+ else
-+ {
-+ filter_info->age = -1;
-+ }
-+}
-+
-+/* The GeditRecentConfiguration struct is allocated and owned by the caller */
-+void
-+gedit_recent_configuration_init_default (GeditRecentConfiguration *config)
-+{
-+ config->manager = gtk_recent_manager_get_default ();
-+
-+ if (config->filter != NULL)
-+ {
-+ g_object_unref (config->filter);
-+ }
-+
-+ config->filter = gtk_recent_filter_new ();
-+ gtk_recent_filter_add_application (config->filter, g_get_application_name ());
-+ gtk_recent_filter_add_mime_type (config->filter, "text/plain");
-+ g_object_ref_sink (config->filter);
-+
-+ config->limit = 5;
-+ config->show_not_found = TRUE;
-+ config->show_private = FALSE;
-+ config->local_only = FALSE;
-+
-+ config->substring_filter = NULL;
-+}
-+
-+/* The GeditRecentConfiguration struct is owned and destroyed by the caller */
-+void
-+gedit_recent_configuration_destroy (GeditRecentConfiguration *config)
-+{
-+ g_clear_object (&config->filter);
-+ config->manager = NULL;
-+
-+ g_clear_pointer (&config->substring_filter, (GDestroyNotify)g_free);
-+}
-+
-+GList *
-+gedit_recent_get_items (GeditRecentConfiguration *config)
-+{
-+ GtkRecentFilterFlags needed;
-+ GList *items;
-+ GList *retitems = NULL;
-+ gint length;
-+ char *substring_filter = NULL;
-+
-+ if (config->limit == 0)
-+ {
-+ return NULL;
-+ }
-+
-+ items = gtk_recent_manager_get_items (config->manager);
-+
-+ if (!items)
-+ {
-+ return NULL;
-+ }
-+
-+ needed = gtk_recent_filter_get_needed (config->filter);
-+ if (config->substring_filter && *config->substring_filter != '\0')
-+ {
-+ gchar *filter_normalized;
-+
-+ filter_normalized = g_utf8_normalize (config->substring_filter, -1, G_NORMALIZE_ALL);
-+ substring_filter = g_utf8_casefold (filter_normalized, -1);
-+ g_free (filter_normalized);
-+ }
-+
-+ while (items)
-+ {
-+ GtkRecentInfo *info;
-+ GtkRecentFilterInfo filter_info;
-+ gboolean is_filtered;
-+
-+ info = items->data;
-+ is_filtered = FALSE;
-+
-+ if (config->local_only && !gtk_recent_info_is_local (info))
-+ {
-+ is_filtered = TRUE;
-+ }
-+ else if (!config->show_private && gtk_recent_info_get_private_hint (info))
-+ {
-+ is_filtered = TRUE;
-+ }
-+ else if (!config->show_not_found && !gtk_recent_info_exists (info))
-+ {
-+ is_filtered = TRUE;
-+ }
-+ else
-+ {
-+ if (substring_filter)
-+ {
-+ gchar *uri_normalized;
-+ gchar *uri_casefolded;
-+
-+ uri_normalized = g_utf8_normalize (gtk_recent_info_get_uri_display (info), -1, G_NORMALIZE_ALL);
-+ uri_casefolded = g_utf8_casefold (uri_normalized, -1);
-+ g_free (uri_normalized);
-+
-+ if (strstr (uri_casefolded, substring_filter) == NULL)
-+ {
-+ is_filtered = TRUE;
-+ }
-+
-+ g_free (uri_casefolded);
-+ }
-+
-+ if (!is_filtered)
-+ {
-+ populate_filter_info (info, &filter_info, needed);
-+ is_filtered = !gtk_recent_filter_filter (config->filter, &filter_info);
-+
-+ /* these we own */
-+ if (filter_info.applications)
-+ {
-+ g_strfreev ((gchar **) filter_info.applications);
-+ }
-+
-+ if (filter_info.groups)
-+ {
-+ g_strfreev ((gchar **) filter_info.groups);
-+ }
-+ }
-+ }
-+
-+ if (!is_filtered)
-+ {
-+ retitems = g_list_prepend (retitems, info);
-+ }
-+ else
-+ {
-+ gtk_recent_info_unref (info);
-+ }
-+
-+ items = g_list_delete_link (items, items);
-+ }
-+
-+ g_free (substring_filter);
-+
-+ if (!retitems)
-+ {
-+ return NULL;
-+ }
-+
-+ retitems = g_list_sort_with_data (retitems, (GCompareDataFunc) sort_recent_items_mru, NULL);
-+ length = g_list_length (retitems);
-+
-+ if ((config->limit != -1) && (length > config->limit))
-+ {
-+ GList *clamp, *l;
-+
-+ clamp = g_list_nth (retitems, config->limit - 1);
-+
-+ if (!clamp)
-+ {
-+ return retitems;
-+ }
-+
-+ l = clamp->next;
-+ clamp->next = NULL;
-+
-+ g_list_free_full (l, (GDestroyNotify) gtk_recent_info_unref);
-+ }
-+
-+ return retitems;
-+}
-+
- /* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-recent.h b/gedit/gedit-recent.h
-index 068d89c72..5c72837ed 100644
---- a/gedit/gedit-recent.h
-+++ b/gedit/gedit-recent.h
-@@ -27,12 +27,29 @@
-
- G_BEGIN_DECLS
-
--void gedit_recent_add_document (GeditDocument *document);
-+typedef struct
-+{
-+ GtkRecentManager *manager;
-+ GtkRecentFilter *filter;
-
--void gedit_recent_remove_if_local (GFile *location);
-+ gint limit;
-+ gchar *substring_filter;
-+
-+ guint show_private : 1;
-+ guint show_not_found : 1;
-+ guint local_only : 1;
-+} GeditRecentConfiguration;
-+
-+void gedit_recent_add_document (GeditDocument *document);
-+
-+void gedit_recent_remove_if_local (GFile *location);
-+
-+void gedit_recent_configuration_init_default (GeditRecentConfiguration *config);
-+void gedit_recent_configuration_destroy (GeditRecentConfiguration *config);
-+GList *gedit_recent_get_items (GeditRecentConfiguration *config);
-
- G_END_DECLS
-
--#endif /* GEDIT_RECENT_H */
-+#endif /* GEDIT_RECENT_H */
-
- /* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-settings.c b/gedit/gedit-settings.c
-index a762a1dc2..6fa300f29 100644
---- a/gedit/gedit-settings.c
-+++ b/gedit/gedit-settings.c
-@@ -37,13 +37,7 @@ struct _GeditSettings
- GSettings *settings_file_chooser_state;
- };
-
--enum
--{
-- SIGNAL_FONTS_CHANGED,
-- N_SIGNALS
--};
--
--static guint signals[N_SIGNALS];
-+/* GeditSettings is a singleton. */
- static GeditSettings *singleton = NULL;
-
- G_DEFINE_TYPE (GeditSettings, gedit_settings, G_TYPE_OBJECT)
-@@ -81,46 +75,92 @@ gedit_settings_class_init (GeditSettingsClass *klass)
-
- object_class->dispose = gedit_settings_dispose;
- object_class->finalize = gedit_settings_finalize;
-+}
-
-- /* This signal is emitted when the return value of
-- * _gedit_settings_get_selected_font() has potentially changed.
-- */
-- signals[SIGNAL_FONTS_CHANGED] =
-- g_signal_new ("fonts-changed",
-- G_TYPE_FROM_CLASS (klass),
-- G_SIGNAL_RUN_FIRST,
-- 0,
-- NULL, NULL, NULL,
-- G_TYPE_NONE, 0);
-+static void
-+set_font (GeditSettings *self,
-+ const gchar *font)
-+{
-+ guint tabs_size;
-+ GList *views;
-+ GList *l;
-+
-+ tabs_size = g_settings_get_uint (self->settings_editor, GEDIT_SETTINGS_TABS_SIZE);
-+
-+ views = gedit_app_get_views (GEDIT_APP (g_application_get_default ()));
-+
-+ for (l = views; l != NULL; l = l->next)
-+ {
-+ /* Note: we use def=FALSE to avoid GeditView to query dconf. */
-+ gedit_view_set_font (GEDIT_VIEW (l->data), FALSE, font);
-+
-+ /* FIXME: setting the tab width seems unrelated to set_font(). */
-+ gtk_source_view_set_tab_width (GTK_SOURCE_VIEW (l->data), tabs_size);
-+ }
-+
-+ g_list_free (views);
- }
-
- static void
--system_font_changed_cb (GSettings *settings,
-+on_system_font_changed (GSettings *settings,
- const gchar *key,
- GeditSettings *self)
- {
-- if (g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT))
-+
-+ gboolean use_default_font;
-+
-+ use_default_font = g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT);
-+
-+ if (use_default_font)
- {
-- g_signal_emit (self, signals[SIGNAL_FONTS_CHANGED], 0);
-+ gchar *font;
-+
-+ font = g_settings_get_string (settings, key);
-+ set_font (self, font);
-+ g_free (font);
- }
- }
-
- static void
--use_default_font_changed_cb (GSettings *settings,
-+on_use_default_font_changed (GSettings *settings,
- const gchar *key,
- GeditSettings *self)
- {
-- g_signal_emit (self, signals[SIGNAL_FONTS_CHANGED], 0);
-+ gboolean use_default_font;
-+ gchar *font;
-+
-+ use_default_font = g_settings_get_boolean (settings, key);
-+
-+ if (use_default_font)
-+ {
-+ font = g_settings_get_string (self->settings_interface, GEDIT_SETTINGS_SYSTEM_FONT);
-+ }
-+ else
-+ {
-+ font = g_settings_get_string (self->settings_editor, GEDIT_SETTINGS_EDITOR_FONT);
-+ }
-+
-+ set_font (self, font);
-+
-+ g_free (font);
- }
-
- static void
--editor_font_changed_cb (GSettings *settings,
-+on_editor_font_changed (GSettings *settings,
- const gchar *key,
- GeditSettings *self)
- {
-- if (!g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT))
-+ gboolean use_default_font;
-+
-+ use_default_font = g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT);
-+
-+ if (!use_default_font)
- {
-- g_signal_emit (self, signals[SIGNAL_FONTS_CHANGED], 0);
-+ gchar *font;
-+
-+ font = g_settings_get_string (settings, key);
-+ set_font (self, font);
-+ g_free (font);
- }
- }
-
-@@ -207,47 +247,43 @@ on_syntax_highlighting_changed (GSettings *settings,
- static void
- gedit_settings_init (GeditSettings *self)
- {
-- self->settings_interface = g_settings_new ("org.gnome.desktop.interface");
--
- self->settings_editor = g_settings_new ("org.gnome.gedit.preferences.editor");
- self->settings_ui = g_settings_new ("org.gnome.gedit.preferences.ui");
- self->settings_file_chooser_state = g_settings_new ("org.gnome.gedit.state.file-chooser");
-
-- g_signal_connect_object (self->settings_interface,
-- "changed::" GEDIT_SETTINGS_SYSTEM_FONT,
-- G_CALLBACK (system_font_changed_cb),
-- self,
-- 0);
--
-- g_signal_connect_object (self->settings_editor,
-- "changed::" GEDIT_SETTINGS_USE_DEFAULT_FONT,
-- G_CALLBACK (use_default_font_changed_cb),
-- self,
-- 0);
--
-- g_signal_connect_object (self->settings_editor,
-- "changed::" GEDIT_SETTINGS_EDITOR_FONT,
-- G_CALLBACK (editor_font_changed_cb),
-- self,
-- 0);
--
-- g_signal_connect_object (self->settings_editor,
-- "changed::auto-save",
-- G_CALLBACK (on_auto_save_changed),
-- self,
-- 0);
--
-- g_signal_connect_object (self->settings_editor,
-- "changed::auto-save-interval",
-- G_CALLBACK (on_auto_save_interval_changed),
-- self,
-- 0);
--
-- g_signal_connect_object (self->settings_editor,
-- "changed::syntax-highlighting",
-- G_CALLBACK (on_syntax_highlighting_changed),
-- self,
-- 0);
-+ self->settings_interface = g_settings_new ("org.gnome.desktop.interface");
-+
-+ g_signal_connect (self->settings_interface,
-+ "changed::monospace-font-name",
-+ G_CALLBACK (on_system_font_changed),
-+ self);
-+
-+ /* editor changes */
-+
-+ g_signal_connect (self->settings_editor,
-+ "changed::use-default-font",
-+ G_CALLBACK (on_use_default_font_changed),
-+ self);
-+
-+ g_signal_connect (self->settings_editor,
-+ "changed::editor-font",
-+ G_CALLBACK (on_editor_font_changed),
-+ self);
-+
-+ g_signal_connect (self->settings_editor,
-+ "changed::auto-save",
-+ G_CALLBACK (on_auto_save_changed),
-+ self);
-+
-+ g_signal_connect (self->settings_editor,
-+ "changed::auto-save-interval",
-+ G_CALLBACK (on_auto_save_interval_changed),
-+ self);
-+
-+ g_signal_connect (self->settings_editor,
-+ "changed::syntax-highlighting",
-+ G_CALLBACK (on_syntax_highlighting_changed),
-+ self);
- }
-
- GeditSettings *
-@@ -292,24 +328,11 @@ _gedit_settings_peek_file_chooser_state_settings (GeditSettings *self)
- }
-
- gchar *
--_gedit_settings_get_system_font (GeditSettings *self)
-+gedit_settings_get_system_font (GeditSettings *self)
- {
- g_return_val_if_fail (GEDIT_IS_SETTINGS (self), NULL);
-
-- return g_settings_get_string (self->settings_interface, GEDIT_SETTINGS_SYSTEM_FONT);
--}
--
--gchar *
--_gedit_settings_get_selected_font (GeditSettings *self)
--{
-- g_return_val_if_fail (GEDIT_IS_SETTINGS (self), NULL);
--
-- if (g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT))
-- {
-- return _gedit_settings_get_system_font (self);
-- }
--
-- return g_settings_get_string (self->settings_editor, GEDIT_SETTINGS_EDITOR_FONT);
-+ return g_settings_get_string (self->settings_interface, "monospace-font-name");
- }
-
- static gboolean
-diff --git a/gedit/gedit-settings.h b/gedit/gedit-settings.h
-index a7993d5d1..a2fe9e47b 100644
---- a/gedit/gedit-settings.h
-+++ b/gedit/gedit-settings.h
-@@ -43,11 +43,7 @@ GSettings * _gedit_settings_peek_editor_settings (GeditSettings *self);
- G_GNUC_INTERNAL
- GSettings * _gedit_settings_peek_file_chooser_state_settings (GeditSettings *self);
-
--G_GNUC_INTERNAL
--gchar * _gedit_settings_get_system_font (GeditSettings *self);
--
--G_GNUC_INTERNAL
--gchar * _gedit_settings_get_selected_font (GeditSettings *self);
-+gchar * gedit_settings_get_system_font (GeditSettings *self);
-
- GSList * gedit_settings_get_candidate_encodings (gboolean *default_candidates);
-
-@@ -73,6 +69,7 @@ GSList * gedit_settings_get_candidate_encodings (gboolean *default_candidates)
- #define GEDIT_SETTINGS_RESTORE_CURSOR_POSITION "restore-cursor-position"
- #define GEDIT_SETTINGS_SYNTAX_HIGHLIGHTING "syntax-highlighting"
- #define GEDIT_SETTINGS_SEARCH_HIGHLIGHTING "search-highlighting"
-+#define GEDIT_SETTINGS_DISPLAY_OVERVIEW_MAP "display-overview-map"
- #define GEDIT_SETTINGS_BACKGROUND_PATTERN "background-pattern"
- #define GEDIT_SETTINGS_STATUSBAR_VISIBLE "statusbar-visible"
- #define GEDIT_SETTINGS_SIDE_PANEL_VISIBLE "side-panel-visible"
-diff --git a/gedit/gedit-tab.c b/gedit/gedit-tab.c
-index 8bff54690..45e80c828 100644
---- a/gedit/gedit-tab.c
-+++ b/gedit/gedit-tab.c
-@@ -24,7 +24,6 @@
-
- #include
- #include
--#include
-
- #include "gedit-app.h"
- #include "gedit-app-private.h"
-@@ -33,6 +32,7 @@
- #include "gedit-io-error-info-bar.h"
- #include "gedit-print-job.h"
- #include "gedit-print-preview.h"
-+#include "gedit-progress-info-bar.h"
- #include "gedit-debug.h"
- #include "gedit-document.h"
- #include "gedit-document-private.h"
-@@ -577,9 +577,9 @@ document_location_notify_handler (GtkSourceFile *file,
- }
-
- static void
--document_shortname_notify_handler (TeplFile *file,
-- GParamSpec *pspec,
-- GeditTab *tab)
-+document_shortname_notify_handler (GeditDocument *document,
-+ GParamSpec *pspec,
-+ GeditTab *tab)
- {
- gedit_debug (DEBUG_TAB);
-
-@@ -737,7 +737,7 @@ load_cancelled (GtkWidget *bar,
- {
- LoaderData *data = g_task_get_task_data (loading_task);
-
-- g_return_if_fail (TEPL_IS_PROGRESS_INFO_BAR (data->tab->info_bar));
-+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (data->tab->info_bar));
-
- g_cancellable_cancel (g_task_get_cancellable (loading_task));
- remove_tab (data->tab);
-@@ -768,7 +768,7 @@ static void
- show_loading_info_bar (GTask *loading_task)
- {
- LoaderData *data = g_task_get_task_data (loading_task);
-- TeplProgressInfoBar *bar;
-+ GtkWidget *bar;
- GeditDocument *doc;
- gchar *name;
- gchar *dirname = NULL;
-@@ -796,7 +796,7 @@ show_loading_info_bar (GTask *loading_task)
- {
- gchar *str;
-
-- str = tepl_utils_str_middle_truncate (name, MAX_MSG_LENGTH);
-+ str = gedit_utils_str_middle_truncate (name, MAX_MSG_LENGTH);
- g_free (name);
- name = str;
- }
-@@ -815,8 +815,8 @@ show_loading_info_bar (GTask *loading_task)
- * we have a title long 99 + 20, but I think it's a rare enough
- * case to be acceptable. It's justa darn title afterall :)
- */
-- dirname = tepl_utils_str_middle_truncate (str,
-- MAX (20, MAX_MSG_LENGTH - len));
-+ dirname = gedit_utils_str_middle_truncate (str,
-+ MAX (20, MAX_MSG_LENGTH - len));
- g_free (str);
- }
- }
-@@ -841,7 +841,7 @@ show_loading_info_bar (GTask *loading_task)
- msg = g_strdup_printf (_("Reverting %s"), name_markup);
- }
-
-- bar = tepl_progress_info_bar_new ("document-revert", msg, TRUE);
-+ bar = gedit_progress_info_bar_new ("document-revert", msg, TRUE);
- }
- else
- {
-@@ -861,7 +861,7 @@ show_loading_info_bar (GTask *loading_task)
- msg = g_strdup_printf (_("Loading %s"), name_markup);
- }
-
-- bar = tepl_progress_info_bar_new ("document-open", msg, TRUE);
-+ bar = gedit_progress_info_bar_new ("document-open", msg, TRUE);
- }
-
- g_signal_connect_object (bar,
-@@ -870,7 +870,7 @@ show_loading_info_bar (GTask *loading_task)
- loading_task,
- 0);
-
-- set_info_bar (data->tab, GTK_WIDGET (bar), GTK_RESPONSE_NONE);
-+ set_info_bar (data->tab, bar, GTK_RESPONSE_NONE);
-
- g_free (msg);
- g_free (name);
-@@ -882,7 +882,7 @@ static void
- show_saving_info_bar (GTask *saving_task)
- {
- GeditTab *tab = g_task_get_source_object (saving_task);
-- TeplProgressInfoBar *bar;
-+ GtkWidget *bar;
- GeditDocument *doc;
- gchar *short_name;
- gchar *from;
-@@ -910,7 +910,7 @@ show_saving_info_bar (GTask *saving_task)
- */
- if (len > MAX_MSG_LENGTH)
- {
-- from = tepl_utils_str_middle_truncate (short_name, MAX_MSG_LENGTH);
-+ from = gedit_utils_str_middle_truncate (short_name, MAX_MSG_LENGTH);
- g_free (short_name);
- }
- else
-@@ -924,7 +924,7 @@ show_saving_info_bar (GTask *saving_task)
-
- from = short_name;
- to = g_file_get_parse_name (location);
-- str = tepl_utils_str_middle_truncate (to, MAX (20, MAX_MSG_LENGTH - len));
-+ str = gedit_utils_str_middle_truncate (to, MAX (20, MAX_MSG_LENGTH - len));
- g_free (to);
-
- to = str;
-@@ -946,9 +946,9 @@ show_saving_info_bar (GTask *saving_task)
- msg = g_strdup_printf (_("Saving %s"), from_markup);
- }
-
-- bar = tepl_progress_info_bar_new ("document-save", msg, FALSE);
-+ bar = gedit_progress_info_bar_new ("document-save", msg, FALSE);
-
-- set_info_bar (tab, GTK_WIDGET (bar), GTK_RESPONSE_NONE);
-+ set_info_bar (tab, bar, GTK_RESPONSE_NONE);
-
- g_free (msg);
- g_free (to);
-@@ -961,7 +961,7 @@ info_bar_set_progress (GeditTab *tab,
- goffset size,
- goffset total_size)
- {
-- TeplProgressInfoBar *progress_info_bar;
-+ GeditProgressInfoBar *progress_info_bar;
-
- if (tab->info_bar == NULL)
- {
-@@ -970,23 +970,23 @@ info_bar_set_progress (GeditTab *tab,
-
- gedit_debug_message (DEBUG_TAB, "%" G_GOFFSET_FORMAT "/%" G_GOFFSET_FORMAT, size, total_size);
-
-- g_return_if_fail (TEPL_IS_PROGRESS_INFO_BAR (tab->info_bar));
-+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (tab->info_bar));
-
-- progress_info_bar = TEPL_PROGRESS_INFO_BAR (tab->info_bar);
-+ progress_info_bar = GEDIT_PROGRESS_INFO_BAR (tab->info_bar);
-
- if (total_size != 0)
- {
- gdouble frac = (gdouble)size / (gdouble)total_size;
-
-- tepl_progress_info_bar_set_fraction (progress_info_bar, frac);
-+ gedit_progress_info_bar_set_fraction (progress_info_bar, frac);
- }
- else if (size != 0)
- {
-- tepl_progress_info_bar_pulse (progress_info_bar);
-+ gedit_progress_info_bar_pulse (progress_info_bar);
- }
- else
- {
-- tepl_progress_info_bar_set_fraction (progress_info_bar, 0);
-+ gedit_progress_info_bar_set_fraction (progress_info_bar, 0);
- }
- }
-
-@@ -1045,7 +1045,7 @@ scroll_to_cursor (GeditTab *tab)
- GeditView *view;
-
- view = gedit_tab_get_view (tab);
-- tepl_view_scroll_to_cursor (TEPL_VIEW (view));
-+ gedit_view_scroll_to_cursor (view);
-
- tab->idle_scroll = 0;
- return G_SOURCE_REMOVE;
-@@ -1129,9 +1129,9 @@ invalid_character_info_bar_response (GtkWidget *info_bar,
- }
-
- static void
--cant_create_backup_error_info_bar_response (GtkWidget *info_bar,
-- gint response_id,
-- GTask *saving_task)
-+no_backup_error_info_bar_response (GtkWidget *info_bar,
-+ gint response_id,
-+ GTask *saving_task)
- {
- if (response_id == GTK_RESPONSE_YES)
- {
-@@ -1237,7 +1237,7 @@ externally_modified_notification_info_bar_response (GtkWidget *info_bar,
- static void
- display_externally_modified_notification (GeditTab *tab)
- {
-- TeplInfoBar *info_bar;
-+ GtkWidget *info_bar;
- GeditDocument *doc;
- GtkSourceFile *file;
- GFile *location;
-@@ -1251,9 +1251,9 @@ display_externally_modified_notification (GeditTab *tab)
- g_return_if_fail (location != NULL);
-
- document_modified = gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc));
-- info_bar = tepl_io_error_info_bar_externally_modified (location, document_modified);
-+ info_bar = gedit_externally_modified_info_bar_new (location, document_modified);
-
-- set_info_bar (tab, GTK_WIDGET (info_bar), GTK_RESPONSE_OK);
-+ set_info_bar (tab, info_bar, GTK_RESPONSE_OK);
-
- g_signal_connect (info_bar,
- "response",
-@@ -1318,7 +1318,6 @@ gedit_tab_init (GeditTab *tab)
- GeditDocument *doc;
- GeditView *view;
- GtkSourceFile *file;
-- TeplFile *tepl_file;
-
- tab->state = GEDIT_TAB_STATE_NORMAL;
-
-@@ -1349,7 +1348,6 @@ gedit_tab_init (GeditTab *tab)
- g_object_set_data (G_OBJECT (doc), GEDIT_TAB_KEY, tab);
-
- file = gedit_document_get_file (doc);
-- tepl_file = tepl_buffer_get_file (TEPL_BUFFER (doc));
-
- g_signal_connect_object (file,
- "notify::location",
-@@ -1357,11 +1355,10 @@ gedit_tab_init (GeditTab *tab)
- tab,
- 0);
-
-- g_signal_connect_object (tepl_file,
-- "notify::short-name",
-- G_CALLBACK (document_shortname_notify_handler),
-- tab,
-- 0);
-+ g_signal_connect (doc,
-+ "notify::shortname",
-+ G_CALLBACK (document_shortname_notify_handler),
-+ tab);
-
- g_signal_connect (doc,
- "modified_changed",
-@@ -1445,7 +1442,7 @@ _gedit_tab_get_name (GeditTab *tab)
- name = gedit_document_get_short_name_for_display (doc);
-
- /* Truncate the name so it doesn't get insanely wide. */
-- docname = tepl_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
-+ docname = gedit_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
-
- if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
- {
-@@ -1478,7 +1475,7 @@ _gedit_tab_get_tooltip (GeditTab *tab)
- uri = _gedit_document_get_uri_for_display (doc);
- g_return_val_if_fail (uri != NULL, NULL);
-
-- ruri = tepl_utils_replace_home_dir_with_tilde (uri);
-+ ruri = gedit_utils_replace_home_dir_with_tilde (uri);
- g_free (uri);
-
- ruri_markup = g_markup_printf_escaped ("%s", ruri);
-@@ -1644,11 +1641,9 @@ goto_line (GTask *loading_task)
- /* Move the cursor at the requested line if any. */
- if (data->line_pos > 0)
- {
-- TeplView *view = TEPL_VIEW (gedit_tab_get_view (data->tab));
--
-- tepl_view_goto_line_offset (view,
-- data->line_pos - 1,
-- MAX (0, data->column_pos - 1));
-+ gedit_document_goto_line_offset (doc,
-+ data->line_pos - 1,
-+ MAX (0, data->column_pos - 1));
- return;
- }
-
-@@ -1764,18 +1759,18 @@ successful_load (GTask *loading_task)
- if (!gtk_source_file_is_readonly (file) &&
- file_already_opened (doc, location))
- {
-- TeplInfoBar *info_bar;
-+ GtkWidget *info_bar;
-
- set_editable (data->tab, FALSE);
-
-- info_bar = tepl_io_error_info_bar_file_already_open (location);
-+ info_bar = gedit_file_already_open_warning_info_bar_new (location);
-
- g_signal_connect (info_bar,
- "response",
- G_CALLBACK (file_already_open_warning_info_bar_response),
- data->tab);
-
-- set_info_bar (data->tab, GTK_WIDGET (info_bar), GTK_RESPONSE_CANCEL);
-+ set_info_bar (data->tab, info_bar, GTK_RESPONSE_CANCEL);
- }
-
- /* When loading from stdin, the contents may not be saved, so set the
-@@ -2406,12 +2401,12 @@ save_cb (GtkSourceFileSaver *saver,
- error->code == G_IO_ERROR_CANT_CREATE_BACKUP)
- {
- /* This error is recoverable */
-- info_bar = GTK_WIDGET (tepl_io_error_info_bar_cant_create_backup (location, error));
-+ info_bar = gedit_no_backup_saving_error_info_bar_new (location, error);
- g_return_if_fail (info_bar != NULL);
-
- g_signal_connect (info_bar,
- "response",
-- G_CALLBACK (cant_create_backup_error_info_bar_response),
-+ G_CALLBACK (no_backup_error_info_bar_response),
- saving_task);
- }
- else if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR &&
-@@ -2420,7 +2415,7 @@ save_cb (GtkSourceFileSaver *saver,
- /* If we have any invalid char in the document we must warn the user
- * as it can make the document useless if it is saved.
- */
-- info_bar = GTK_WIDGET (tepl_io_error_info_bar_invalid_characters (location));
-+ info_bar = gedit_invalid_character_info_bar_new (location);
- g_return_if_fail (info_bar != NULL);
-
- g_signal_connect (info_bar,
-@@ -2802,15 +2797,15 @@ printing_cb (GeditPrintJob *job,
- GeditPrintJobStatus status,
- GeditTab *tab)
- {
-- g_return_if_fail (TEPL_IS_PROGRESS_INFO_BAR (tab->info_bar));
-+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (tab->info_bar));
-
- gtk_widget_show (tab->info_bar);
-
-- tepl_progress_info_bar_set_text (TEPL_PROGRESS_INFO_BAR (tab->info_bar),
-- gedit_print_job_get_status_string (job));
-+ gedit_progress_info_bar_set_text (GEDIT_PROGRESS_INFO_BAR (tab->info_bar),
-+ gedit_print_job_get_status_string (job));
-
-- tepl_progress_info_bar_set_fraction (TEPL_PROGRESS_INFO_BAR (tab->info_bar),
-- gedit_print_job_get_progress (job));
-+ gedit_progress_info_bar_set_fraction (GEDIT_PROGRESS_INFO_BAR (tab->info_bar),
-+ gedit_print_job_get_progress (job));
- }
-
- static void
-@@ -2920,19 +2915,21 @@ print_cancelled (GtkWidget *bar,
- static void
- add_printing_info_bar (GeditTab *tab)
- {
-- TeplProgressInfoBar *bar;
-+ GtkWidget *bar;
-
-- bar = tepl_progress_info_bar_new ("document-print", NULL, TRUE);
-+ bar = gedit_progress_info_bar_new ("document-print",
-+ "",
-+ TRUE);
-
- g_signal_connect (bar,
- "response",
- G_CALLBACK (print_cancelled),
- tab);
-
-- set_info_bar (tab, GTK_WIDGET (bar), GTK_RESPONSE_NONE);
-+ set_info_bar (tab, bar, GTK_RESPONSE_NONE);
-
- /* hide until we start printing */
-- gtk_widget_hide (GTK_WIDGET (bar));
-+ gtk_widget_hide (bar);
- }
-
- void
-diff --git a/gedit/gedit-utils.c b/gedit/gedit-utils.c
-index 9fc9e4fb0..ae7e92156 100644
---- a/gedit/gedit-utils.c
-+++ b/gedit/gedit-utils.c
-@@ -23,7 +23,6 @@
- #include "gedit-utils.h"
- #include
- #include
--#include
- #include "gedit-debug.h"
-
- gboolean
-@@ -87,6 +86,122 @@ gedit_utils_set_atk_name_description (GtkWidget *widget,
- atk_object_set_description (aobj, description);
- }
-
-+void
-+gedit_warning (GtkWindow *parent, const gchar *format, ...)
-+{
-+ va_list args;
-+ gchar *str;
-+ GtkWidget *dialog;
-+ GtkWindowGroup *wg = NULL;
-+
-+ g_return_if_fail (format != NULL);
-+
-+ if (parent != NULL)
-+ wg = gtk_window_get_group (parent);
-+
-+ va_start (args, format);
-+ str = g_strdup_vprintf (format, args);
-+ va_end (args);
-+
-+ dialog = gtk_message_dialog_new_with_markup (
-+ parent,
-+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-+ GTK_MESSAGE_ERROR,
-+ GTK_BUTTONS_OK,
-+ "%s", str);
-+
-+ g_free (str);
-+
-+ if (wg != NULL)
-+ gtk_window_group_add_window (wg, GTK_WINDOW (dialog));
-+
-+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-+
-+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
-+
-+ g_signal_connect (G_OBJECT (dialog),
-+ "response",
-+ G_CALLBACK (gtk_widget_destroy),
-+ NULL);
-+
-+ gtk_widget_show (dialog);
-+}
-+
-+/* the following functions are taken from eel */
-+
-+static gchar *
-+gedit_utils_str_truncate (const gchar *string,
-+ guint truncate_length,
-+ gboolean middle)
-+{
-+ GString *truncated;
-+ guint length;
-+ guint n_chars;
-+ guint num_left_chars;
-+ guint right_offset;
-+ guint delimiter_length;
-+ const gchar *delimiter = "\342\200\246";
-+
-+ g_return_val_if_fail (string != NULL, NULL);
-+
-+ length = strlen (string);
-+
-+ g_return_val_if_fail (g_utf8_validate (string, length, NULL), NULL);
-+
-+ /* It doesnt make sense to truncate strings to less than
-+ * the size of the delimiter plus 2 characters (one on each
-+ * side)
-+ */
-+ delimiter_length = g_utf8_strlen (delimiter, -1);
-+ if (truncate_length < (delimiter_length + 2))
-+ {
-+ return g_strdup (string);
-+ }
-+
-+ n_chars = g_utf8_strlen (string, length);
-+
-+ /* Make sure the string is not already small enough. */
-+ if (n_chars <= truncate_length)
-+ {
-+ return g_strdup (string);
-+ }
-+
-+ /* Find the 'middle' where the truncation will occur. */
-+ if (middle)
-+ {
-+ num_left_chars = (truncate_length - delimiter_length) / 2;
-+ right_offset = n_chars - truncate_length + num_left_chars + delimiter_length;
-+
-+ truncated = g_string_new_len (string,
-+ g_utf8_offset_to_pointer (string, num_left_chars) - string);
-+ g_string_append (truncated, delimiter);
-+ g_string_append (truncated, g_utf8_offset_to_pointer (string, right_offset));
-+ }
-+ else
-+ {
-+ num_left_chars = truncate_length - delimiter_length;
-+ truncated = g_string_new_len (string,
-+ g_utf8_offset_to_pointer (string, num_left_chars) - string);
-+ g_string_append (truncated, delimiter);
-+ }
-+
-+ return g_string_free (truncated, FALSE);
-+}
-+
-+gchar *
-+gedit_utils_str_middle_truncate (const gchar *string,
-+ guint truncate_length)
-+{
-+ return gedit_utils_str_truncate (string, truncate_length, TRUE);
-+}
-+
-+gchar *
-+gedit_utils_str_end_truncate (const gchar *string,
-+ guint truncate_length)
-+{
-+ return gedit_utils_str_truncate (string, truncate_length, FALSE);
-+}
-+
- static gchar *
- uri_get_dirname (const gchar *uri)
- {
-@@ -106,7 +221,7 @@ uri_get_dirname (const gchar *uri)
- return NULL;
- }
-
-- res = tepl_utils_replace_home_dir_with_tilde (str);
-+ res = gedit_utils_replace_home_dir_with_tilde (str);
-
- g_free (str);
-
-@@ -149,10 +264,10 @@ gedit_utils_location_get_dirname_for_display (GFile *location)
- g_object_unref (mount);
-
- /* obtain the "path" part of the uri */
-- tepl_utils_decode_uri (uri,
-- NULL, NULL,
-- NULL, NULL,
-- &path);
-+ gedit_utils_decode_uri (uri,
-+ NULL, NULL,
-+ NULL, NULL,
-+ &path);
-
- if (path == NULL)
- {
-@@ -187,6 +302,51 @@ gedit_utils_location_get_dirname_for_display (GFile *location)
- return res;
- }
-
-+gchar *
-+gedit_utils_replace_home_dir_with_tilde (const gchar *uri)
-+{
-+ gchar *tmp;
-+ gchar *home;
-+
-+ g_return_val_if_fail (uri != NULL, NULL);
-+
-+ /* Note that g_get_home_dir returns a const string */
-+ tmp = (gchar *)g_get_home_dir ();
-+
-+ if (tmp == NULL)
-+ return g_strdup (uri);
-+
-+ home = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL);
-+ if (home == NULL)
-+ return g_strdup (uri);
-+
-+ if (strcmp (uri, home) == 0)
-+ {
-+ g_free (home);
-+
-+ return g_strdup ("~/");
-+ }
-+
-+ tmp = home;
-+ home = g_strdup_printf ("%s/", tmp);
-+ g_free (tmp);
-+
-+ if (g_str_has_prefix (uri, home))
-+ {
-+ gchar *res;
-+
-+ res = g_strdup_printf ("~/%s", uri + strlen (home));
-+
-+ g_free (home);
-+
-+ return res;
-+ }
-+
-+ g_free (home);
-+
-+ return g_strdup (uri);
-+}
-+
- static gboolean
- is_valid_scheme_character (gchar c)
- {
-@@ -353,7 +513,7 @@ gedit_utils_basename_for_display (GFile *location)
- }
- }
- else if (g_file_has_parent (location, NULL) ||
-- !tepl_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL))
-+ !gedit_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL))
- {
- /* For remote files with a parent (so not just http://foo.com)
- or remote file for which the decoding of the host name fails,
-@@ -438,6 +598,165 @@ gedit_utils_drop_get_uris (GtkSelectionData *selection_data)
- return uri_list;
- }
-
-+static void
-+null_ptr (gchar **ptr)
-+{
-+ if (ptr)
-+ *ptr = NULL;
-+}
-+
-+/**
-+ * gedit_utils_decode_uri:
-+ * @uri: the uri to decode
-+ * @scheme: (out) (allow-none): return value pointer for the uri's
-+ * scheme (e.g. http, sftp, ...), or %NULL
-+ * @user: (out) (allow-none): return value pointer for the uri user info, or %NULL
-+ * @port: (out) (allow-none): return value pointer for the uri port, or %NULL
-+ * @host: (out) (allow-none): return value pointer for the uri host, or %NULL
-+ * @path: (out) (allow-none): return value pointer for the uri path, or %NULL
-+ *
-+ * Parse and break an uri apart in its individual components like the uri
-+ * scheme, user info, port, host and path. The return value pointer can be
-+ * %NULL to ignore certain parts of the uri. If the function returns %TRUE, then
-+ * all return value pointers should be freed using g_free
-+ *
-+ * Return value: %TRUE if the uri could be properly decoded, %FALSE otherwise.
-+ */
-+gboolean
-+gedit_utils_decode_uri (const gchar *uri,
-+ gchar **scheme,
-+ gchar **user,
-+ gchar **host,
-+ gchar **port,
-+ gchar **path)
-+{
-+ /* Largely copied from glib/gio/gdummyfile.c:_g_decode_uri. This
-+ * functionality should be in glib/gio, but for now we implement it
-+ * ourselves (see bug #546182) */
-+
-+ const char *p, *in, *hier_part_start, *hier_part_end;
-+ char *out;
-+ char c;
-+
-+ /* From RFC 3986 Decodes:
-+ * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
-+ */
-+
-+ p = uri;
-+
-+ null_ptr (scheme);
-+ null_ptr (user);
-+ null_ptr (port);
-+ null_ptr (host);
-+ null_ptr (path);
-+
-+ /* Decode scheme:
-+ * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-+ */
-+
-+ if (!g_ascii_isalpha (*p))
-+ return FALSE;
-+
-+ while (1)
-+ {
-+ c = *p++;
-+
-+ if (c == ':')
-+ break;
-+
-+ if (!(g_ascii_isalnum(c) ||
-+ c == '+' ||
-+ c == '-' ||
-+ c == '.'))
-+ {
-+ return FALSE;
-+ }
-+ }
-+
-+ if (scheme)
-+ {
-+ *scheme = g_malloc (p - uri);
-+ out = *scheme;
-+
-+ for (in = uri; in < p - 1; in++)
-+ {
-+ *out++ = g_ascii_tolower (*in);
-+ }
-+
-+ *out = '\0';
-+ }
-+
-+ hier_part_start = p;
-+ hier_part_end = p + strlen (p);
-+
-+ if (hier_part_start[0] == '/' && hier_part_start[1] == '/')
-+ {
-+ const char *authority_start, *authority_end;
-+ const char *userinfo_start, *userinfo_end;
-+ const char *host_start, *host_end;
-+ const char *port_start;
-+
-+ authority_start = hier_part_start + 2;
-+ /* authority is always followed by / or nothing */
-+ authority_end = memchr (authority_start, '/', hier_part_end - authority_start);
-+
-+ if (authority_end == NULL)
-+ authority_end = hier_part_end;
-+
-+ /* 3.2:
-+ * authority = [ userinfo "@" ] host [ ":" port ]
-+ */
-+
-+ userinfo_end = memchr (authority_start, '@', authority_end - authority_start);
-+
-+ if (userinfo_end)
-+ {
-+ userinfo_start = authority_start;
-+
-+ if (user)
-+ *user = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL);
-+
-+ if (user && *user == NULL)
-+ {
-+ if (scheme)
-+ g_free (*scheme);
-+
-+ return FALSE;
-+ }
-+
-+ host_start = userinfo_end + 1;
-+ }
-+ else
-+ {
-+ host_start = authority_start;
-+ }
-+
-+ port_start = memchr (host_start, ':', authority_end - host_start);
-+
-+ if (port_start)
-+ {
-+ host_end = port_start++;
-+
-+ if (port)
-+ *port = g_strndup (port_start, authority_end - port_start);
-+ }
-+ else
-+ {
-+ host_end = authority_end;
-+ }
-+
-+ if (host)
-+ *host = g_strndup (host_start, host_end - host_start);
-+
-+ hier_part_start = authority_end;
-+ }
-+
-+ if (path)
-+ *path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/");
-+
-+ return TRUE;
-+}
-+
- GtkSourceCompressionType
- gedit_utils_get_compression_type_from_content_type (const gchar *content_type)
- {
-diff --git a/gedit/gedit-utils.h b/gedit/gedit-utils.h
-index a6b423db0..64af070d2 100644
---- a/gedit/gedit-utils.h
-+++ b/gedit/gedit-utils.h
-@@ -27,19 +27,38 @@
-
- G_BEGIN_DECLS
-
-+/* useful macro */
-+#define GBOOLEAN_TO_POINTER(i) (GINT_TO_POINTER ((i) ? 2 : 1))
-+#define GPOINTER_TO_BOOLEAN(i) ((gboolean) ((GPOINTER_TO_INT(i) == 2) ? TRUE : FALSE))
-+
- gboolean gedit_utils_menu_position_under_tree_view (GtkTreeView *tree_view,
- GdkRectangle *rect);
-
-+gchar *gedit_utils_str_middle_truncate (const gchar *string,
-+ guint truncate_length);
-+gchar *gedit_utils_str_end_truncate (const gchar *string,
-+ guint truncate_length);
- void gedit_utils_set_atk_name_description (GtkWidget *widget,
- const gchar *name,
- const gchar *description);
-+void gedit_warning (GtkWindow *parent,
-+ const gchar *format,
-+ ...) G_GNUC_PRINTF(2, 3);
-
--gchar *gedit_utils_location_get_dirname_for_display (GFile *location);
-+gchar *gedit_utils_location_get_dirname_for_display (GFile *location);
-+gchar *gedit_utils_replace_home_dir_with_tilde (const gchar *uri);
-
- gboolean gedit_utils_is_valid_location (GFile *location);
-
- gchar *gedit_utils_basename_for_display (GFile *location);
-
-+gboolean gedit_utils_decode_uri (const gchar *uri,
-+ gchar **scheme,
-+ gchar **user,
-+ gchar **host,
-+ gchar **port,
-+ gchar **path);
-+
- /* Turns data from a drop into a list of well formatted uris */
- gchar **gedit_utils_drop_get_uris (GtkSelectionData *selection_data);
-
-diff --git a/gedit/gedit-view-centering.c b/gedit/gedit-view-centering.c
-new file mode 100644
-index 000000000..f9c742076
---- /dev/null
-+++ b/gedit/gedit-view-centering.c
-@@ -0,0 +1,495 @@
-+/*
-+ * gedit-view-centering.c
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2014 - Sébastien Lafargue
-+ *
-+ * Gedit is free software; you can redistribute this file 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.
-+ *
-+ * Gedit 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, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ *
-+ * Based on Christian Hergert's prototype.
-+ */
-+
-+#include "gedit-view-centering.h"
-+
-+#include
-+
-+#include "gedit-view.h"
-+#include "gedit-debug.h"
-+
-+struct _GeditViewCenteringPrivate
-+{
-+ GtkWidget *box;
-+ GtkWidget *scrolled_window;
-+ GtkWidget *sourceview;
-+ GtkWidget *spacer;
-+
-+ GtkStyleContext *view_context;
-+ GdkRGBA view_background;
-+ GdkRGBA view_line_margin_fg;
-+ GdkRGBA view_margin_background;
-+ guint view_text_width;
-+
-+ guint centered : 1;
-+ guint view_background_set : 1;
-+ guint view_line_margin_fg_set : 1;
-+ guint view_margin_background_set : 1;
-+};
-+
-+G_DEFINE_TYPE_WITH_PRIVATE (GeditViewCentering, gedit_view_centering, GTK_TYPE_BIN)
-+
-+#define STYLE_TEXT "text"
-+#define STYLE_RIGHT_MARGIN "right-margin"
-+
-+#define RIGHT_MARGIN_LINE_ALPHA 40
-+#define RIGHT_MARGIN_OVERLAY_ALPHA 15
-+
-+static gboolean
-+get_style (GtkSourceStyleScheme *scheme,
-+ const gchar *style_id,
-+ const gchar *attribute,
-+ GdkRGBA *color)
-+{
-+ GtkSourceStyle *style;
-+ gchar *style_string;
-+
-+ style = gtk_source_style_scheme_get_style (scheme, style_id);
-+ if (!style)
-+ {
-+ return FALSE;
-+ }
-+
-+ g_object_get (style, attribute, &style_string, NULL);
-+ if (style_string)
-+ {
-+ gdk_rgba_parse (color, style_string);
-+ g_free (style_string);
-+
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
-+static void
-+get_spacer_colors (GeditViewCentering *container,
-+ GtkSourceStyleScheme *scheme)
-+{
-+ GeditViewCenteringPrivate *priv = container->priv;
-+
-+ if (scheme)
-+ {
-+ priv->view_background_set = get_style (scheme,
-+ STYLE_TEXT, "background",
-+ &priv->view_background);
-+
-+ priv->view_line_margin_fg_set = get_style (scheme,
-+ STYLE_RIGHT_MARGIN, "foreground",
-+ &priv->view_line_margin_fg);
-+ priv->view_line_margin_fg.alpha = RIGHT_MARGIN_LINE_ALPHA / 255.0;
-+
-+ priv->view_margin_background_set = get_style (scheme,
-+ STYLE_RIGHT_MARGIN, "background",
-+ &priv->view_margin_background);
-+ priv->view_margin_background.alpha = RIGHT_MARGIN_OVERLAY_ALPHA / 255.0;
-+ }
-+}
-+
-+/* FIXME: when GeditViewCentering will be transfered to GtkSourceView,
-+ * this method will be replaced by a call to a new method called
-+ * gtk_source_view_get_right_margin_pixel_position ()
-+ */
-+static guint
-+_gedit_view_centering_get_right_margin_pixel_position (GeditViewCentering *container)
-+{
-+ GeditViewCenteringPrivate *priv;
-+ gchar *str;
-+ PangoFontDescription *font_desc;
-+ PangoLayout *layout;
-+ guint right_margin_position;
-+ gint width = 0;
-+
-+ g_return_val_if_fail (GEDIT_IS_VIEW_CENTERING (container), 0);
-+
-+ priv = container->priv;
-+
-+ right_margin_position = gtk_source_view_get_right_margin_position (GTK_SOURCE_VIEW (priv->sourceview));
-+
-+ gtk_style_context_save (priv->view_context);
-+ gtk_style_context_set_state (priv->view_context, GTK_STATE_FLAG_NORMAL);
-+ gtk_style_context_get (priv->view_context,
-+ gtk_style_context_get_state (priv->view_context),
-+ GTK_STYLE_PROPERTY_FONT, &font_desc,
-+ NULL);
-+ gtk_style_context_restore (priv->view_context);
-+
-+ str = g_strnfill (right_margin_position, '_');
-+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (priv->sourceview), str);
-+ g_free (str);
-+
-+ pango_layout_set_font_description (layout, font_desc);
-+ pango_font_description_free (font_desc);
-+ pango_layout_get_pixel_size (layout, &width, NULL);
-+
-+ g_object_unref (G_OBJECT (layout));
-+
-+ return width;
-+}
-+
-+static void
-+on_view_right_margin_visibility_changed (GeditView *view,
-+ GParamSpec *pspec,
-+ GeditViewCentering *container)
-+{
-+ GeditViewCenteringPrivate *priv = container->priv;
-+ gboolean visibility;
-+
-+ visibility = gtk_source_view_get_show_right_margin (GTK_SOURCE_VIEW (priv->sourceview));
-+
-+ gtk_widget_set_visible (GTK_WIDGET (container->priv->spacer), visibility && priv->centered);
-+}
-+
-+static void
-+on_view_right_margin_position_changed (GeditView *view,
-+ GParamSpec *pspec,
-+ GeditViewCentering *container)
-+{
-+ GeditViewCenteringPrivate *priv = container->priv;
-+ gboolean visibility;
-+
-+ priv->view_text_width = _gedit_view_centering_get_right_margin_pixel_position (container);
-+
-+ visibility = gtk_source_view_get_show_right_margin (GTK_SOURCE_VIEW (priv->sourceview));
-+
-+ if (visibility)
-+ {
-+ gtk_widget_queue_resize (priv->spacer);
-+ }
-+}
-+
-+static void
-+on_view_context_changed (GtkStyleContext *stylecontext,
-+ GeditViewCentering *container)
-+{
-+ GeditViewCenteringPrivate *priv = container->priv;
-+ GtkTextBuffer *buffer;
-+ GtkSourceStyleScheme *scheme;
-+ gboolean visibility;
-+
-+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->sourceview));
-+ scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
-+ get_spacer_colors (container, scheme);
-+
-+ priv->view_text_width = _gedit_view_centering_get_right_margin_pixel_position (container);
-+
-+ visibility = gtk_source_view_get_show_right_margin (GTK_SOURCE_VIEW (priv->sourceview));
-+
-+ if (visibility)
-+ {
-+ gtk_widget_queue_resize (priv->spacer);
-+ }
-+}
-+
-+static gboolean
-+on_spacer_draw (GeditViewCentering *container,
-+ cairo_t *cr,
-+ GtkDrawingArea *spacer)
-+{
-+ GeditViewCenteringPrivate *priv = container->priv;
-+ GtkStyleContext *context;
-+ guint width, height;
-+
-+ if (!container->priv->sourceview)
-+ {
-+ return FALSE;
-+ }
-+
-+ width = gtk_widget_get_allocated_width (GTK_WIDGET (spacer));
-+ height = gtk_widget_get_allocated_height (GTK_WIDGET (spacer));
-+
-+ context = gtk_widget_get_style_context (GTK_WIDGET (spacer));
-+ gtk_style_context_save (context);
-+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
-+ gtk_render_background (context, cr, 0, 0, width, height);
-+ gtk_style_context_restore (context);
-+
-+ cairo_set_line_width (cr, 1.0);
-+
-+ if (priv->view_background_set)
-+ {
-+ gdk_cairo_set_source_rgba (cr, &container->priv->view_background);
-+ cairo_rectangle (cr, 0, 0, width, height);
-+ cairo_fill (cr);
-+ }
-+
-+ if (priv->view_margin_background_set)
-+ {
-+ gdk_cairo_set_source_rgba (cr, &container->priv->view_margin_background);
-+ cairo_rectangle (cr, 0, 0, width, height);
-+ cairo_fill (cr);
-+ }
-+
-+ if (priv->view_line_margin_fg_set)
-+ {
-+ gdk_cairo_set_source_rgba (cr, &container->priv->view_line_margin_fg);
-+ cairo_move_to (cr, width - 0.5, 0);
-+ cairo_line_to (cr, width - 0.5, height);
-+ cairo_stroke (cr);
-+ }
-+
-+ return FALSE;
-+}
-+
-+static void
-+gedit_view_centering_remove (GtkContainer *container,
-+ GtkWidget *child)
-+{
-+ GeditViewCenteringPrivate *priv;
-+
-+ g_assert (GEDIT_IS_VIEW_CENTERING (container));
-+
-+ priv = GEDIT_VIEW_CENTERING (container)->priv;
-+
-+ if (priv->sourceview == child)
-+ {
-+ gtk_container_remove (GTK_CONTAINER (priv->scrolled_window), priv->sourceview);
-+ g_object_remove_weak_pointer (G_OBJECT (priv->sourceview), (gpointer *)&priv->sourceview);
-+ priv->sourceview = NULL;
-+ priv->view_context = NULL;
-+ }
-+ else
-+ {
-+ GTK_CONTAINER_CLASS (gedit_view_centering_parent_class)->remove (container, child);
-+ }
-+}
-+
-+static void
-+gedit_view_centering_add (GtkContainer *container,
-+ GtkWidget *child)
-+{
-+ GeditViewCenteringPrivate *priv;
-+ GtkTextBuffer *buffer;
-+ GtkSourceStyleScheme *scheme;
-+
-+ g_assert (GEDIT_IS_VIEW_CENTERING (container));
-+
-+ priv = GEDIT_VIEW_CENTERING (container)->priv;
-+
-+ if (GEDIT_IS_VIEW (child))
-+ {
-+ if (priv->sourceview)
-+ {
-+ gedit_view_centering_remove (container, priv->sourceview);
-+ }
-+
-+ priv->sourceview = child;
-+ g_object_add_weak_pointer (G_OBJECT (child), (gpointer *)&priv->sourceview);
-+ gtk_container_add (GTK_CONTAINER (priv->scrolled_window), child);
-+
-+ priv->view_context = gtk_widget_get_style_context (child);
-+
-+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->sourceview));
-+ scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
-+ get_spacer_colors (GEDIT_VIEW_CENTERING (container), scheme);
-+
-+ g_signal_connect (priv->sourceview,
-+ "notify::right-margin-position",
-+ G_CALLBACK (on_view_right_margin_position_changed),
-+ container);
-+
-+ g_signal_connect (priv->sourceview,
-+ "notify::show-right-margin",
-+ G_CALLBACK (on_view_right_margin_visibility_changed),
-+ container);
-+
-+ g_signal_connect (priv->view_context,
-+ "changed",
-+ G_CALLBACK (on_view_context_changed),
-+ container);
-+
-+ gtk_widget_queue_resize (GTK_WIDGET (container));
-+ }
-+ else
-+ {
-+ GTK_CONTAINER_CLASS (gedit_view_centering_parent_class)->add (container, child);
-+ }
-+}
-+
-+static gboolean
-+on_spacer_scroll_event (GtkWidget *widget,
-+ GdkEvent *event,
-+ GeditViewCentering *container)
-+{
-+ GdkEventScroll *new_scroll_event;
-+
-+ new_scroll_event = (GdkEventScroll *)gdk_event_copy (event);
-+ g_object_unref (new_scroll_event->window);
-+
-+ new_scroll_event->window = g_object_ref (gtk_widget_get_window (container->priv->sourceview));
-+ new_scroll_event->send_event = TRUE;
-+
-+ new_scroll_event->x = 0;
-+ new_scroll_event->y = 0;
-+ new_scroll_event->x_root = 0;
-+ new_scroll_event->y_root = 0;
-+
-+ gtk_main_do_event ((GdkEvent *)new_scroll_event);
-+ gdk_event_free ((GdkEvent *)new_scroll_event);
-+
-+ return TRUE;
-+}
-+
-+static void
-+gedit_view_centering_size_allocate (GtkWidget *widget,
-+ GtkAllocation *alloc)
-+{
-+ GeditViewCenteringPrivate *priv;
-+ GtkTextView *view;
-+ gint container_width;
-+ gint gutter_width;
-+ gint text_width;
-+ gint spacer_width;
-+ gint current_spacer_width;
-+ GdkWindow *gutter_window;
-+
-+ g_assert (GEDIT_IS_VIEW_CENTERING (widget));
-+
-+ priv = GEDIT_VIEW_CENTERING (widget)->priv;
-+
-+ view = GTK_TEXT_VIEW (priv->sourceview);
-+
-+ if (view)
-+ {
-+ container_width = alloc->width;
-+
-+ gutter_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_LEFT);
-+ gutter_width = (gutter_window) ? gdk_window_get_width (gutter_window) : 0;
-+
-+ text_width = priv->view_text_width;
-+ spacer_width = MAX (0, container_width - text_width - gutter_width) / 2;
-+
-+ g_object_get(priv->spacer, "width-request", ¤t_spacer_width, NULL);
-+
-+ if (current_spacer_width != spacer_width)
-+ {
-+ g_object_set(priv->spacer, "width-request", spacer_width, NULL);
-+ }
-+ }
-+
-+ GTK_WIDGET_CLASS (gedit_view_centering_parent_class)->size_allocate (widget, alloc);
-+}
-+
-+static void
-+gedit_view_centering_finalize (GObject *object)
-+{
-+ GeditViewCentering *container = GEDIT_VIEW_CENTERING (object);
-+ GeditViewCenteringPrivate *priv = container->priv;
-+
-+ if (priv->sourceview)
-+ {
-+ gedit_view_centering_remove (GTK_CONTAINER (container), priv->sourceview);
-+ }
-+
-+ G_OBJECT_CLASS (gedit_view_centering_parent_class)->finalize (object);
-+}
-+
-+static void
-+gedit_view_centering_class_init (GeditViewCenteringClass *klass)
-+{
-+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
-+
-+ gobject_class->finalize = gedit_view_centering_finalize;
-+
-+ widget_class->size_allocate = gedit_view_centering_size_allocate;
-+
-+ container_class->add = gedit_view_centering_add;
-+ container_class->remove = gedit_view_centering_remove;
-+}
-+
-+static void
-+gedit_view_centering_init (GeditViewCentering *container)
-+{
-+ GeditViewCenteringPrivate *priv;
-+
-+ container->priv = gedit_view_centering_get_instance_private (container);
-+ priv = container->priv;
-+ priv->view_text_width = 0;
-+
-+ priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-+ priv->spacer = gtk_drawing_area_new ();
-+ priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
-+
-+ gtk_container_add (GTK_CONTAINER (container), priv->box);
-+ gtk_box_pack_start (GTK_BOX (priv->box), priv->spacer, FALSE, FALSE, 0);
-+ gtk_box_pack_start (GTK_BOX (priv->box), priv->scrolled_window, TRUE, TRUE, 0);
-+
-+ gtk_widget_set_no_show_all (GTK_WIDGET (priv->spacer), TRUE);
-+ gtk_widget_show_all (GTK_WIDGET (priv->box));
-+
-+ g_signal_connect_swapped (priv->spacer, "draw",
-+ G_CALLBACK (on_spacer_draw),
-+ container);
-+
-+ gtk_widget_add_events(GTK_WIDGET(priv->spacer), GDK_SCROLL_MASK);
-+ g_signal_connect (priv->spacer, "scroll-event",
-+ G_CALLBACK (on_spacer_scroll_event),
-+ container);
-+}
-+
-+/**
-+ * gedit_view_centering_set_centered:
-+ * @container: a #GeditViewCentering.
-+ * @centered: whether to center the sourceview child or not.
-+ *
-+ * If @centered is %TRUE, the sourceview child is centered
-+ * horizontally on the #GeditViewCentering container.
-+ **/
-+void
-+gedit_view_centering_set_centered (GeditViewCentering *container,
-+ gboolean centered)
-+{
-+ g_return_if_fail (GEDIT_IS_VIEW_CENTERING (container));
-+
-+ container->priv->centered = centered != FALSE;
-+
-+ on_view_right_margin_visibility_changed (GEDIT_VIEW (container->priv->sourceview), NULL, container);
-+}
-+
-+/**
-+ * gedit_view_centering_get_centered:
-+ * @container: a #GeditViewCentering.
-+ *
-+ * Return whether the #GtkSourceView child is centered or not.
-+ *
-+ * Return value: %TRUE if the #GtkSourceView child is centered
-+ * horizontally on the #GeditViewCentering container.
-+ **/
-+gboolean
-+gedit_view_centering_get_centered (GeditViewCentering *container)
-+{
-+ g_return_val_if_fail (GEDIT_IS_VIEW_CENTERING (container), FALSE);
-+
-+ return container->priv->centered;
-+}
-+
-+GeditViewCentering *
-+gedit_view_centering_new (void)
-+{
-+ return g_object_new (GEDIT_TYPE_VIEW_CENTERING,
-+ NULL);
-+}
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-view-centering.h b/gedit/gedit-view-centering.h
-new file mode 100644
-index 000000000..1d7218969
---- /dev/null
-+++ b/gedit/gedit-view-centering.h
-@@ -0,0 +1,67 @@
-+/*
-+ * gedit-view-centering.h
-+ * This file is part of gedit
-+ *
-+ * Copyright (C) 2014 - Sébastien Lafargue
-+ * Copyright (C) 2015 - Sébastien Wilmet
-+ *
-+ * Gedit is free software; you can redistribute this file 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.
-+ *
-+ * Gedit 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, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ */
-+
-+#ifndef GEDIT_VIEW_CENTERING_H
-+#define GEDIT_VIEW_CENTERING_H
-+
-+#include
-+
-+G_BEGIN_DECLS
-+
-+#define GEDIT_TYPE_VIEW_CENTERING (gedit_view_centering_get_type())
-+#define GEDIT_VIEW_CENTERING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_VIEW_CENTERING, GeditViewCentering))
-+#define GEDIT_VIEW_CENTERING_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_VIEW_CENTERING, GeditViewCentering const))
-+#define GEDIT_VIEW_CENTERING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_VIEW_CENTERING, GeditViewCenteringClass))
-+#define GEDIT_IS_VIEW_CENTERING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_VIEW_CENTERING))
-+#define GEDIT_IS_VIEW_CENTERING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_VIEW_CENTERING))
-+#define GEDIT_VIEW_CENTERING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_VIEW_CENTERING, GeditViewCenteringClass))
-+
-+typedef struct _GeditViewCentering GeditViewCentering;
-+typedef struct _GeditViewCenteringClass GeditViewCenteringClass;
-+typedef struct _GeditViewCenteringPrivate GeditViewCenteringPrivate;
-+
-+struct _GeditViewCentering
-+{
-+ GtkBin parent;
-+
-+ GeditViewCenteringPrivate *priv;
-+};
-+
-+struct _GeditViewCenteringClass
-+{
-+ GtkBinClass parent_class;
-+};
-+
-+GType gedit_view_centering_get_type (void) G_GNUC_CONST;
-+
-+GeditViewCentering * gedit_view_centering_new (void);
-+
-+void gedit_view_centering_set_centered (GeditViewCentering *container,
-+ gboolean centered);
-+
-+gboolean gedit_view_centering_get_centered (GeditViewCentering *container);
-+
-+G_END_DECLS
-+
-+#endif /* GEDIT_VIEW_CENTERING_H */
-+
-+/* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-view-frame.c b/gedit/gedit-view-frame.c
-index f41734c47..67c067a41 100644
---- a/gedit/gedit-view-frame.c
-+++ b/gedit/gedit-view-frame.c
-@@ -3,7 +3,7 @@
- * This file is part of gedit
- *
- * Copyright (C) 2010 - Ignacio Casal Quinteiro
-- * Copyright (C) 2013, 2019 - Sébastien Wilmet
-+ * Copyright (C) 2013 - Sébastien Wilmet
- *
- * gedit is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
-@@ -28,6 +28,7 @@
- #include
- #include
-
-+#include "gedit-view-centering.h"
- #include "gedit-debug.h"
- #include "gedit-utils.h"
- #include "gedit-settings.h"
-@@ -53,7 +54,11 @@ struct _GeditViewFrame
- {
- GtkOverlay parent_instance;
-
-+ GSettings *editor_settings;
-+
- GeditView *view;
-+ GeditViewCentering *view_centering;
-+ GtkFrame *map_frame;
-
- SearchMode search_mode;
-
-@@ -159,6 +164,7 @@ gedit_view_frame_dispose (GObject *object)
- gtk_source_file_set_mount_operation_factory (file, NULL, NULL, NULL);
- }
-
-+ g_clear_object (&frame->editor_settings);
- g_clear_object (&frame->entry_tag);
- g_clear_object (&frame->search_settings);
- g_clear_object (&frame->old_search_settings);
-@@ -213,7 +219,7 @@ hide_search_widget (GeditViewFrame *frame,
- frame->start_mark);
- gtk_text_buffer_place_cursor (buffer, &iter);
-
-- tepl_view_scroll_to_cursor (TEPL_VIEW (frame->view));
-+ gedit_view_scroll_to_cursor (frame->view);
- }
-
- if (frame->start_mark != NULL)
-@@ -297,7 +303,7 @@ finish_search (GeditViewFrame *frame,
-
- if (found || (entry_text[0] == '\0'))
- {
-- tepl_view_scroll_to_cursor (TEPL_VIEW (frame->view));
-+ gedit_view_scroll_to_cursor (frame->view);
-
- set_search_state (frame, SEARCH_STATE_NORMAL);
- }
-@@ -1061,6 +1067,7 @@ update_goto_line (GeditViewFrame *frame)
- gchar **split_text = NULL;
- const gchar *text;
- GtkTextIter iter;
-+ GeditDocument *doc;
-
- entry_text = gtk_entry_get_text (GTK_ENTRY (frame->search_entry));
-
-@@ -1116,8 +1123,11 @@ update_goto_line (GeditViewFrame *frame)
-
- g_strfreev (split_text);
-
-- moved = tepl_view_goto_line (TEPL_VIEW (frame->view), line);
-- moved_offset = tepl_view_goto_line_offset (TEPL_VIEW (frame->view), line, line_offset);
-+ doc = get_document (frame);
-+ moved = gedit_document_goto_line (doc, line);
-+ moved_offset = gedit_document_goto_line_offset (doc, line, line_offset);
-+
-+ gedit_view_scroll_to_cursor (frame->view);
-
- if (!moved || !moved_offset)
- {
-@@ -1428,6 +1438,8 @@ gedit_view_frame_class_init (GeditViewFrameClass *klass)
- gtk_widget_class_set_template_from_resource (widget_class,
- "/org/gnome/gedit/ui/gedit-view-frame.ui");
- gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, view);
-+ gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, view_centering);
-+ gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, map_frame);
- gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, revealer);
- gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, search_entry);
- gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, go_up_button);
-@@ -1454,6 +1466,13 @@ gedit_view_frame_init (GeditViewFrame *frame)
-
- gtk_widget_init_template (GTK_WIDGET (frame));
-
-+ frame->editor_settings = g_settings_new ("org.gnome.gedit.preferences.editor");
-+ g_settings_bind (frame->editor_settings,
-+ GEDIT_SETTINGS_DISPLAY_OVERVIEW_MAP,
-+ frame->map_frame,
-+ "visible",
-+ G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
-+
- doc = get_document (frame);
- file = gedit_document_get_file (doc);
-
-@@ -1551,6 +1570,14 @@ gedit_view_frame_new (void)
- return g_object_new (GEDIT_TYPE_VIEW_FRAME, NULL);
- }
-
-+GeditViewCentering *
-+gedit_view_frame_get_view_centering (GeditViewFrame *frame)
-+{
-+ g_return_val_if_fail (GEDIT_IS_VIEW_FRAME (frame), NULL);
-+
-+ return frame->view_centering;
-+}
-+
- GeditView *
- gedit_view_frame_get_view (GeditViewFrame *frame)
- {
-diff --git a/gedit/gedit-view-frame.h b/gedit/gedit-view-frame.h
-index 78ac469d1..d2e550840 100644
---- a/gedit/gedit-view-frame.h
-+++ b/gedit/gedit-view-frame.h
-@@ -24,6 +24,7 @@
- #include
- #include "gedit-document.h"
- #include "gedit-view.h"
-+#include "gedit-view-centering.h"
-
- G_BEGIN_DECLS
-
-@@ -32,6 +33,9 @@ G_DECLARE_FINAL_TYPE (GeditViewFrame, gedit_view_frame, GEDIT, VIEW_FRAME, GtkOv
-
- GeditViewFrame *gedit_view_frame_new (void);
-
-+GeditViewCentering
-+ *gedit_view_frame_get_view_centering (GeditViewFrame *frame);
-+
- GeditView *gedit_view_frame_get_view (GeditViewFrame *frame);
-
- void gedit_view_frame_popup_search (GeditViewFrame *frame);
-diff --git a/gedit/gedit-view.c b/gedit/gedit-view.c
-index 0c730c989..035e599ab 100644
---- a/gedit/gedit-view.c
-+++ b/gedit/gedit-view.c
-@@ -24,16 +24,21 @@
- #include "gedit-view-activatable.h"
- #include "gedit-plugins-engine.h"
- #include "gedit-debug.h"
-+#include "gedit-pango.h"
- #include "gedit-utils.h"
- #include "gedit-settings.h"
-
-+#define GEDIT_VIEW_SCROLL_MARGIN 0.02
-+
- struct _GeditViewPrivate
- {
-+ GeditDocument *current_document;
- PeasExtensionSet *extensions;
-
- gchar *direct_save_uri;
-
-- TeplSignalGroup *file_signal_group;
-+ GtkCssProvider *css_provider;
-+ PangoFontDescription *font_desc;
- };
-
- enum
-@@ -50,7 +55,7 @@ enum
-
- static guint signals[N_SIGNALS];
-
--G_DEFINE_TYPE_WITH_PRIVATE (GeditView, gedit_view, TEPL_TYPE_VIEW)
-+G_DEFINE_TYPE_WITH_PRIVATE (GeditView, gedit_view, GTK_SOURCE_TYPE_VIEW)
-
- static void
- update_editable (GeditView *view)
-@@ -73,23 +78,46 @@ file_read_only_notify_cb (GtkSourceFile *file,
- update_editable (view);
- }
-
-+static void
-+current_document_removed (GeditView *view)
-+{
-+ if (view->priv->current_document != NULL)
-+ {
-+ GtkSourceFile *file;
-+
-+ file = gedit_document_get_file (view->priv->current_document);
-+
-+ g_signal_handlers_disconnect_by_func (file,
-+ file_read_only_notify_cb,
-+ view);
-+
-+ g_object_unref (view->priv->current_document);
-+ view->priv->current_document = NULL;
-+ }
-+}
-+
- static void
- buffer_changed (GeditView *view)
- {
-- GeditDocument *doc;
- GtkSourceFile *file;
-+ GtkTextBuffer *buffer;
-
-- doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
-- file = gedit_document_get_file (doc);
-+ current_document_removed (view);
-+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-+
-+ if (!GEDIT_IS_DOCUMENT (buffer))
-+ {
-+ return;
-+ }
-
-- tepl_signal_group_clear (&view->priv->file_signal_group);
-- view->priv->file_signal_group = tepl_signal_group_new (G_OBJECT (file));
-+ view->priv->current_document = g_object_ref (GEDIT_DOCUMENT (buffer));
-
-- tepl_signal_group_add (view->priv->file_signal_group,
-- g_signal_connect (file,
-- "notify::read-only",
-- G_CALLBACK (file_read_only_notify_cb),
-- view));
-+ file = gedit_document_get_file (view->priv->current_document);
-+ g_signal_connect_object (file,
-+ "notify::read-only",
-+ G_CALLBACK (file_read_only_notify_cb),
-+ view,
-+ 0);
-
- update_editable (view);
- }
-@@ -106,7 +134,7 @@ static void
- gedit_view_init (GeditView *view)
- {
- GtkTargetList *target_list;
-- GtkStyleContext *style_context;
-+ GtkStyleContext *context;
-
- gedit_debug (DEBUG_VIEW);
-
-@@ -140,8 +168,13 @@ gedit_view_init (GeditView *view)
- NULL);
-
- /* CSS stuff */
-- style_context = gtk_widget_get_style_context (GTK_WIDGET (view));
-- gtk_style_context_add_class (style_context, "gedit-view");
-+ context = gtk_widget_get_style_context (GTK_WIDGET (view));
-+ gtk_style_context_add_class (context, "gedit-view");
-+
-+ view->priv->css_provider = gtk_css_provider_new ();
-+ gtk_style_context_add_provider (context,
-+ GTK_STYLE_PROVIDER (view->priv->css_provider),
-+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- }
-
- static void
-@@ -150,7 +183,8 @@ gedit_view_dispose (GObject *object)
- GeditView *view = GEDIT_VIEW (object);
-
- g_clear_object (&view->priv->extensions);
-- tepl_signal_group_clear (&view->priv->file_signal_group);
-+
-+ current_document_removed (view);
-
- /* Disconnect notify buffer because the destroy of the textview will set
- * the buffer to NULL, and we call get_buffer in the notify which would
-@@ -160,26 +194,10 @@ gedit_view_dispose (GObject *object)
- */
- g_signal_handlers_disconnect_by_func (view, buffer_notify_cb, NULL);
-
-- G_OBJECT_CLASS (gedit_view_parent_class)->dispose (object);
--}
--
--static void
--update_font (GeditView *view)
--{
-- GeditSettings *settings;
-- gchar *selected_font;
--
-- settings = _gedit_settings_get_singleton ();
-- selected_font = _gedit_settings_get_selected_font (settings);
-- tepl_utils_override_font (GTK_WIDGET (view), selected_font);
-- g_free (selected_font);
--}
-+ g_clear_object (&view->priv->css_provider);
-+ g_clear_pointer (&view->priv->font_desc, pango_font_description_free);
-
--static void
--fonts_changed_cb (GeditSettings *settings,
-- GeditView *view)
--{
-- update_font (view);
-+ G_OBJECT_CLASS (gedit_view_parent_class)->dispose (object);
- }
-
- static void
-@@ -188,18 +206,27 @@ gedit_view_constructed (GObject *object)
- GeditView *view = GEDIT_VIEW (object);
- GeditSettings *settings;
- GSettings *editor_settings;
-+ gboolean use_default_font;
-
- G_OBJECT_CLASS (gedit_view_parent_class)->constructed (object);
-
- settings = _gedit_settings_get_singleton ();
- editor_settings = _gedit_settings_peek_editor_settings (settings);
-
-- update_font (view);
-- g_signal_connect_object (settings,
-- "fonts-changed",
-- G_CALLBACK (fonts_changed_cb),
-- view,
-- 0);
-+ use_default_font = g_settings_get_boolean (editor_settings, GEDIT_SETTINGS_USE_DEFAULT_FONT);
-+
-+ if (use_default_font)
-+ {
-+ gedit_view_set_font (view, TRUE, NULL);
-+ }
-+ else
-+ {
-+ gchar *editor_font;
-+
-+ editor_font = g_settings_get_string (editor_settings, GEDIT_SETTINGS_EDITOR_FONT);
-+ gedit_view_set_font (view, FALSE, editor_font);
-+ g_free (editor_font);
-+ }
-
- g_settings_bind (editor_settings, GEDIT_SETTINGS_DISPLAY_LINE_NUMBERS,
- view, "show-line-numbers",
-@@ -720,4 +747,217 @@ gedit_view_new (GeditDocument *doc)
- NULL);
- }
-
-+void
-+gedit_view_cut_clipboard (GeditView *view)
-+{
-+ GtkTextBuffer *buffer;
-+ GtkClipboard *clipboard;
-+
-+ gedit_debug (DEBUG_VIEW);
-+
-+ g_return_if_fail (GEDIT_IS_VIEW (view));
-+
-+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-+
-+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
-+ GDK_SELECTION_CLIPBOARD);
-+
-+ gtk_text_buffer_cut_clipboard (buffer,
-+ clipboard,
-+ gtk_text_view_get_editable (GTK_TEXT_VIEW (view)));
-+
-+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
-+ gtk_text_buffer_get_insert (buffer),
-+ GEDIT_VIEW_SCROLL_MARGIN,
-+ FALSE,
-+ 0.0,
-+ 0.0);
-+}
-+
-+void
-+gedit_view_copy_clipboard (GeditView *view)
-+{
-+ GtkTextBuffer *buffer;
-+ GtkClipboard *clipboard;
-+
-+ gedit_debug (DEBUG_VIEW);
-+
-+ g_return_if_fail (GEDIT_IS_VIEW (view));
-+
-+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-+
-+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
-+ GDK_SELECTION_CLIPBOARD);
-+
-+ gtk_text_buffer_copy_clipboard (buffer, clipboard);
-+
-+ /* on copy do not scroll, we are already on screen */
-+}
-+
-+void
-+gedit_view_paste_clipboard (GeditView *view)
-+{
-+ GtkTextBuffer *buffer;
-+ GtkClipboard *clipboard;
-+
-+ gedit_debug (DEBUG_VIEW);
-+
-+ g_return_if_fail (GEDIT_IS_VIEW (view));
-+
-+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-+
-+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
-+ GDK_SELECTION_CLIPBOARD);
-+
-+ gtk_text_buffer_paste_clipboard (buffer,
-+ clipboard,
-+ NULL,
-+ gtk_text_view_get_editable (GTK_TEXT_VIEW (view)));
-+
-+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
-+ gtk_text_buffer_get_insert (buffer),
-+ GEDIT_VIEW_SCROLL_MARGIN,
-+ FALSE,
-+ 0.0,
-+ 0.0);
-+}
-+
-+/**
-+ * gedit_view_delete_selection:
-+ * @view: a #GeditView
-+ *
-+ * Deletes the text currently selected in the #GtkTextBuffer associated
-+ * to the view and scroll to the cursor position.
-+ */
-+void
-+gedit_view_delete_selection (GeditView *view)
-+{
-+ GtkTextBuffer *buffer;
-+
-+ gedit_debug (DEBUG_VIEW);
-+
-+ g_return_if_fail (GEDIT_IS_VIEW (view));
-+
-+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-+
-+ gtk_text_buffer_delete_selection (buffer,
-+ TRUE,
-+ gtk_text_view_get_editable (GTK_TEXT_VIEW (view)));
-+
-+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
-+ gtk_text_buffer_get_insert (buffer),
-+ GEDIT_VIEW_SCROLL_MARGIN,
-+ FALSE,
-+ 0.0,
-+ 0.0);
-+}
-+
-+/**
-+ * gedit_view_select_all:
-+ * @view: a #GeditView
-+ *
-+ * Selects all the text.
-+ */
-+void
-+gedit_view_select_all (GeditView *view)
-+{
-+ GtkTextBuffer *buffer;
-+ GtkTextIter start;
-+ GtkTextIter end;
-+
-+ gedit_debug (DEBUG_VIEW);
-+
-+ g_return_if_fail (GEDIT_IS_VIEW (view));
-+
-+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-+
-+ gtk_text_buffer_get_bounds (buffer, &start, &end);
-+ gtk_text_buffer_select_range (buffer, &start, &end);
-+}
-+
-+/**
-+ * gedit_view_scroll_to_cursor:
-+ * @view: a #GeditView
-+ *
-+ * Scrolls the @view to the cursor position.
-+ */
-+void
-+gedit_view_scroll_to_cursor (GeditView *view)
-+{
-+ GtkTextBuffer *buffer;
-+
-+ gedit_debug (DEBUG_VIEW);
-+
-+ g_return_if_fail (GEDIT_IS_VIEW (view));
-+
-+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
-+
-+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
-+ gtk_text_buffer_get_insert (buffer),
-+ 0.25,
-+ FALSE,
-+ 0.0,
-+ 0.0);
-+}
-+
-+static void
-+update_css_provider (GeditView *view)
-+{
-+ gchar *str;
-+ gchar *css;
-+
-+ g_assert (GEDIT_IS_VIEW (view));
-+ g_assert (view->priv->font_desc != NULL);
-+
-+ str = gedit_pango_font_description_to_css (view->priv->font_desc);
-+ css = g_strdup_printf ("textview { %s }", str ? str : "");
-+ gtk_css_provider_load_from_data (view->priv->css_provider, css, -1, NULL);
-+
-+ g_free (css);
-+ g_free (str);
-+}
-+
-+/**
-+ * gedit_view_set_font:
-+ * @view: a #GeditView
-+ * @default_font: whether to reset to the default font
-+ * @font_name: the name of the font to use
-+ *
-+ * If @default_font is #TRUE, resets the font of the @view to the default font.
-+ * Otherwise sets it to @font_name.
-+ */
-+void
-+gedit_view_set_font (GeditView *view,
-+ gboolean default_font,
-+ const gchar *font_name)
-+{
-+ gedit_debug (DEBUG_VIEW);
-+
-+ g_return_if_fail (GEDIT_IS_VIEW (view));
-+
-+ g_clear_pointer (&view->priv->font_desc, pango_font_description_free);
-+
-+ if (default_font)
-+ {
-+ GeditSettings *settings;
-+ gchar *font;
-+
-+ settings = _gedit_settings_get_singleton ();
-+ font = gedit_settings_get_system_font (settings);
-+
-+ view->priv->font_desc = pango_font_description_from_string (font);
-+ g_free (font);
-+ }
-+ else
-+ {
-+ g_return_if_fail (font_name != NULL);
-+
-+ view->priv->font_desc = pango_font_description_from_string (font_name);
-+ }
-+
-+ g_return_if_fail (view->priv->font_desc != NULL);
-+
-+ update_css_provider (view);
-+}
-+
- /* ex:set ts=8 noet: */
-diff --git a/gedit/gedit-view.h b/gedit/gedit-view.h
-index c05d68553..7f2ae3ae2 100644
---- a/gedit/gedit-view.h
-+++ b/gedit/gedit-view.h
-@@ -22,8 +22,10 @@
- #ifndef GEDIT_VIEW_H
- #define GEDIT_VIEW_H
-
-+#include
-+
- #include
--#include
-+#include
-
- G_BEGIN_DECLS
-
-@@ -40,7 +42,7 @@ typedef struct _GeditViewPrivate GeditViewPrivate;
-
- struct _GeditView
- {
-- TeplView view;
-+ GtkSourceView view;
-
- /*< private >*/
- GeditViewPrivate *priv;
-@@ -48,7 +50,7 @@ struct _GeditView
-
- struct _GeditViewClass
- {
-- TeplViewClass parent_class;
-+ GtkSourceViewClass parent_class;
-
- void (*drop_uris) (GeditView *view,
- gchar **uri_list);
-@@ -60,6 +62,22 @@ GType gedit_view_get_type (void);
-
- GtkWidget * gedit_view_new (GeditDocument *doc);
-
-+void gedit_view_cut_clipboard (GeditView *view);
-+
-+void gedit_view_copy_clipboard (GeditView *view);
-+
-+void gedit_view_paste_clipboard (GeditView *view);
-+
-+void gedit_view_delete_selection (GeditView *view);
-+
-+void gedit_view_select_all (GeditView *view);
-+
-+void gedit_view_scroll_to_cursor (GeditView *view);
-+
-+void gedit_view_set_font (GeditView *view,
-+ gboolean default_font,
-+ const gchar *font_name);
-+
- G_END_DECLS
-
- #endif /* GEDIT_VIEW_H */
-diff --git a/gedit/gedit-window-private.h b/gedit/gedit-window-private.h
-index 60f8ba706..380f6bdc5 100644
---- a/gedit/gedit-window-private.h
-+++ b/gedit/gedit-window-private.h
-@@ -27,6 +27,7 @@
- #include "gedit-message-bus.h"
- #include "gedit-settings.h"
- #include "gedit-multi-notebook.h"
-+#include "gedit-open-document-selector.h"
-
- G_BEGIN_DECLS
-
-@@ -53,12 +54,15 @@ struct _GeditWindowPrivate
- PeasExtensionSet *extensions;
-
- /* Widgets for fullscreen mode */
-+ GtkWidget *fullscreen_controls;
- GtkWidget *fullscreen_eventbox;
-- GtkRevealer *fullscreen_revealer;
- GtkWidget *fullscreen_headerbar;
-- GtkWidget *fullscreen_new_button;
- GtkMenuButton *fullscreen_gear_button;
-- GtkMenuButton *fullscreen_open_recent_button;
-+
-+ GtkWidget *fullscreen_new_button;
-+ GtkWidget *fullscreen_open_button;
-+ GtkWidget *fullscreen_open_document_popover;
-+ GeditOpenDocumentSelector *fullscreen_open_document_selector;
-
- /* statusbar and context ids for statusbar messages */
- GtkWidget *statusbar;
-@@ -79,7 +83,10 @@ struct _GeditWindowPrivate
- GtkWidget *side_headerbar;
- GtkWidget *headerbar;
-
-- GtkWidget *new_button;
-+ GtkWidget *open_document_popover;
-+ GtkWidget *new_button;
-+ GtkWidget *open_button;
-+ GeditOpenDocumentSelector *open_document_selector;
-
- GtkMenuButton *gear_button;
-
-diff --git a/gedit/gedit-window.c b/gedit/gedit-window.c
-index 2f9a2076f..b08a1dbcc 100644
---- a/gedit/gedit-window.c
-+++ b/gedit/gedit-window.c
-@@ -28,11 +28,11 @@
-
- #include
- #include
--#include
-
- #include "gedit-window-private.h"
- #include "gedit-app.h"
- #include "gedit-app-private.h"
-+#include "gedit-recent.h"
- #include "gedit-notebook.h"
- #include "gedit-notebook-popup-menu.h"
- #include "gedit-multi-notebook.h"
-@@ -40,6 +40,7 @@
- #include "gedit-tab.h"
- #include "gedit-tab-private.h"
- #include "gedit-view-frame.h"
-+#include "gedit-view-centering.h"
- #include "gedit-utils.h"
- #include "gedit-commands.h"
- #include "gedit-commands-private.h"
-@@ -54,6 +55,11 @@
- #include "gedit-status-menu-button.h"
- #include "gedit-settings.h"
- #include "gedit-menu-stack-switcher.h"
-+#include "gedit-highlight-mode-selector.h"
-+#include "gedit-open-document-selector.h"
-+
-+#define TAB_WIDTH_DATA "GeditWindowTabWidthData"
-+#define FULLSCREEN_ANIMATION_SPEED 500
-
- enum
- {
-@@ -158,9 +164,9 @@ save_window_state (GtkWidget *widget)
- GeditWindow *window = GEDIT_WINDOW (widget);
-
- if ((window->priv->window_state &
-- (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
-+ (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
- {
-- gtk_window_get_size (GTK_WINDOW (widget), &window->priv->width, &window->priv->height);
-+ gtk_window_get_size (GTK_WINDOW (widget), &window->priv->width, &window->priv->height);
-
- g_settings_set (window->priv->window_settings, GEDIT_SETTINGS_WINDOW_SIZE,
- "(ii)", window->priv->width, window->priv->height);
-@@ -231,8 +237,6 @@ gedit_window_dispose (GObject *object)
- */
- remove_actions (window);
-
-- window->priv->fullscreen_open_recent_button = NULL;
--
- G_OBJECT_CLASS (gedit_window_parent_class)->dispose (object);
- }
-
-@@ -247,6 +251,22 @@ gedit_window_finalize (GObject *object)
- G_OBJECT_CLASS (gedit_window_parent_class)->finalize (object);
- }
-
-+/* Center the view when the window is in fullscreen mode. */
-+static void
-+update_view_centering (GeditTab *tab,
-+ gpointer user_data)
-+{
-+ GeditViewFrame *view_frame;
-+ GeditViewCentering *view_centering;
-+ gboolean is_fullscreen;
-+
-+ view_frame = _gedit_tab_get_view_frame (tab);
-+ view_centering = gedit_view_frame_get_view_centering (view_frame);
-+
-+ is_fullscreen = GPOINTER_TO_BOOLEAN (user_data);
-+ gedit_view_centering_set_centered (view_centering, is_fullscreen);
-+}
-+
- static void
- update_fullscreen (GeditWindow *window,
- gboolean is_fullscreen)
-@@ -267,6 +287,10 @@ update_fullscreen (GeditWindow *window,
- }
- }
-
-+ gedit_multi_notebook_foreach_tab (window->priv->multi_notebook,
-+ (GtkCallback)update_view_centering,
-+ GBOOLEAN_TO_POINTER (is_fullscreen));
-+
- #ifndef OS_OSX
- if (is_fullscreen)
- {
-@@ -312,7 +336,7 @@ gedit_window_configure_event (GtkWidget *widget,
-
- if (gtk_widget_get_realized (widget) &&
- (window->priv->window_state &
-- (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
-+ (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
- {
- save_window_state (widget);
- }
-@@ -454,6 +478,7 @@ gedit_window_class_init (GeditWindowClass *klass)
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, side_headerbar);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, headerbar);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, new_button);
-+ gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, open_button);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, gear_button);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, hpaned);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, side_panel);
-@@ -466,10 +491,11 @@ gedit_window_class_init (GeditWindowClass *klass)
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, language_button);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, tab_width_button);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, line_col_button);
-+ gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_controls);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_eventbox);
-- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_revealer);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_headerbar);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_new_button);
-+ gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_open_button);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_gear_button);
- }
-
-@@ -765,8 +791,48 @@ update_actions_sensitivity (GeditWindow *window)
- }
-
- static void
--language_chooser_show_cb (TeplLanguageChooser *language_chooser,
-- GeditWindow *window)
-+on_recent_chooser_item_activated (GeditOpenDocumentSelector *open_document_selector,
-+ gchar *uri,
-+ GeditWindow *window)
-+{
-+ GFile *location;
-+ GeditView *active_view;
-+
-+ g_return_if_fail (GEDIT_WINDOW (window));
-+ g_return_if_fail (GEDIT_OPEN_DOCUMENT_SELECTOR (open_document_selector));
-+
-+ /* TODO: get_current_file when exists */
-+ location = g_file_new_for_uri (uri);
-+
-+ if (location)
-+ {
-+ GSList *locations = NULL;
-+ GSList *loaded = NULL;
-+
-+ locations = g_slist_prepend (locations, (gpointer) location);
-+ loaded = gedit_commands_load_locations (window, locations, NULL, 0, 0);
-+
-+ /* if it doesn't contain just 1 element */
-+ if (!loaded || loaded->next)
-+ {
-+ gedit_recent_remove_if_local (location);
-+ }
-+
-+ g_slist_free (locations);
-+ g_slist_free (loaded);
-+
-+ g_object_unref (location);
-+ }
-+
-+ /* Needed to close the popover when activating the same
-+ * document as the current one */
-+ active_view = gedit_window_get_active_view (window);
-+ gtk_widget_grab_focus (GTK_WIDGET (active_view));
-+}
-+
-+static void
-+language_selector_show_cb (GeditHighlightModeSelector *selector,
-+ GeditWindow *window)
- {
- GeditDocument *active_document;
-
-@@ -776,14 +842,14 @@ language_chooser_show_cb (TeplLanguageChooser *language_chooser,
- GtkSourceLanguage *language;
-
- language = gedit_document_get_language (active_document);
-- tepl_language_chooser_select_language (language_chooser, language);
-+ gedit_highlight_mode_selector_select_language (selector, language);
- }
- }
-
- static void
--language_activated_cb (TeplLanguageChooser *language_chooser,
-- GtkSourceLanguage *language,
-- GeditWindow *window)
-+language_selected_cb (GeditHighlightModeSelector *selector,
-+ GtkSourceLanguage *language,
-+ GeditWindow *window)
- {
- GeditDocument *active_document;
-
-@@ -793,13 +859,13 @@ language_activated_cb (TeplLanguageChooser *language_chooser,
- gedit_document_set_language (active_document, language);
- }
-
-- gtk_widget_hide (window->priv->language_popover);
-+ gtk_widget_hide (GTK_WIDGET (window->priv->language_popover));
- }
-
- static void
- setup_statusbar (GeditWindow *window)
- {
-- TeplLanguageChooserWidget *language_chooser;
-+ GeditHighlightModeSelector *selector;
-
- gedit_debug (DEBUG_WINDOW);
-
-@@ -829,20 +895,20 @@ setup_statusbar (GeditWindow *window)
- gtk_menu_button_set_popover (GTK_MENU_BUTTON (window->priv->language_button),
- window->priv->language_popover);
-
-- language_chooser = tepl_language_chooser_widget_new ();
-+ selector = gedit_highlight_mode_selector_new ();
-
-- g_signal_connect (language_chooser,
-+ g_signal_connect (selector,
- "show",
-- G_CALLBACK (language_chooser_show_cb),
-+ G_CALLBACK (language_selector_show_cb),
- window);
-
-- g_signal_connect (language_chooser,
-- "language-activated",
-- G_CALLBACK (language_activated_cb),
-+ g_signal_connect (selector,
-+ "language-selected",
-+ G_CALLBACK (language_selected_cb),
- window);
-
-- gtk_container_add (GTK_CONTAINER (window->priv->language_popover), GTK_WIDGET (language_chooser));
-- gtk_widget_show (GTK_WIDGET (language_chooser));
-+ gtk_container_add (GTK_CONTAINER (window->priv->language_popover), GTK_WIDGET (selector));
-+ gtk_widget_show (GTK_WIDGET (selector));
- }
-
- static GeditWindow *
-@@ -1044,8 +1110,8 @@ set_title (GeditWindow *window)
- {
- gchar *tmp;
-
-- tmp = tepl_utils_str_middle_truncate (name,
-- MAX_TITLE_LENGTH);
-+ tmp = gedit_utils_str_middle_truncate (name,
-+ MAX_TITLE_LENGTH);
- g_free (name);
- name = tmp;
- }
-@@ -1063,8 +1129,8 @@ set_title (GeditWindow *window)
- * we have a title long 99 + 20, but I think it's a rare enough
- * case to be acceptable. It's justa darn title afterall :)
- */
-- dirname = tepl_utils_str_middle_truncate (str,
-- MAX (20, MAX_TITLE_LENGTH - len));
-+ dirname = gedit_utils_str_middle_truncate (str,
-+ MAX (20, MAX_TITLE_LENGTH - len));
- g_free (str);
- }
- }
-@@ -1690,88 +1756,84 @@ drop_uris_cb (GtkWidget *widget,
- load_uris_from_drop (window, uri_list);
- }
-
--static void
--update_fullscreen_revealer_state (GeditWindow *window)
-+static gboolean
-+on_fullscreen_controls_enter_notify_event (GtkWidget *widget,
-+ GdkEventCrossing *event,
-+ GeditWindow *window)
- {
-- gboolean open_recent_menu_is_active;
-- gboolean hamburger_menu_is_active;
-+ window->priv->in_fullscreen_eventbox = TRUE;
-
-- open_recent_menu_is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window->priv->fullscreen_open_recent_button));
-- hamburger_menu_is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window->priv->fullscreen_gear_button));
-+ gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls), TRUE);
-
-- gtk_revealer_set_reveal_child (window->priv->fullscreen_revealer,
-- (window->priv->in_fullscreen_eventbox ||
-- open_recent_menu_is_active ||
-- hamburger_menu_is_active));
-+ return FALSE;
- }
-
- static gboolean
--on_fullscreen_eventbox_enter_notify_event (GtkWidget *fullscreen_eventbox,
-- GdkEventCrossing *event,
-- GeditWindow *window)
-+real_fullscreen_controls_leave_notify_event (gpointer data)
- {
-- window->priv->in_fullscreen_eventbox = TRUE;
-- update_fullscreen_revealer_state (window);
-+ GeditWindow *window = GEDIT_WINDOW (data);
-+ gboolean hamburger_menu_state;
-+ gboolean fullscreen_open_button_state;
-
-- return GDK_EVENT_PROPAGATE;
--}
-+ hamburger_menu_state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window->priv->fullscreen_gear_button));
-+ fullscreen_open_button_state =
-+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window->priv->fullscreen_open_button));
-
--static gboolean
--on_fullscreen_eventbox_leave_notify_event (GtkWidget *fullscreen_eventbox,
-- GdkEventCrossing *event,
-- GeditWindow *window)
--{
-- if (-1.0 <= event->y && event->y <= 0.0)
-- {
-- /* Ignore the event.
-- *
-- * Leave notify events are received with -1 <= y <= 0
-- * coordinates, although the GeditWindow is in fullscreen mode
-- * and when there are no screens above (it's maybe a bug in an
-- * underlying library).
-- * If we hide the headerbar when those events happen, then it
-- * makes the headerbar to be shown/hidden a lot of time in a
-- * short period of time, i.e. a "stuttering". In other words
-- * lots of leave/enter events are received when moving the mouse
-- * upwards on the screen when the mouse is already at the top.
-- * The expected leave event has a positive event->y value being
-- * >= to the height of the headerbar (approximately
-- * 40 <= y <= 50). So clearly when we receive a leave event with
-- * event->y <= 0, it means that the mouse has left the eventbox
-- * on the wrong side.
-- * The -1.0 <= event->y is there (instead of just <= 0.0) in the
-- * case that there is another screen *above*, even if this
-- * heuristic/workaround is not perfect in that case. But that
-- * case is quite rare, so it's probably a good enough solution.
-- *
-- * Note that apparently the "stuttering" occurs only on an Xorg
-- * session, not on Wayland (tested with GNOME).
-- *
-- * If you see a better solution...
-- */
-- return GDK_EVENT_PROPAGATE;
-+ window->priv->in_fullscreen_eventbox = FALSE;
-+
-+ if (!hamburger_menu_state && !fullscreen_open_button_state)
-+ {
-+ gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls), FALSE);
- }
-
-- window->priv->in_fullscreen_eventbox = FALSE;
-- update_fullscreen_revealer_state (window);
-+ return G_SOURCE_REMOVE;
-+}
-+
-+/* this idle is needed because the toggled signal from gear button is received
-+ * after the leave event from the event box ( which is automatically triggered when user
-+ * bring up the gear menu */
-+static gboolean
-+on_fullscreen_controls_leave_notify_event (GtkWidget *widget,
-+ GdkEventCrossing *event,
-+ GeditWindow *window)
-+{
-+ g_idle_add (real_fullscreen_controls_leave_notify_event, window);
-
- return GDK_EVENT_PROPAGATE;
- }
-
- static void
--setup_fullscreen_eventbox (GeditWindow *window)
-+fullscreen_controls_setup (GeditWindow *window)
- {
-- gtk_widget_set_size_request (window->priv->fullscreen_eventbox, -1, 1);
-- gtk_widget_hide (window->priv->fullscreen_eventbox);
-+ GeditWindowPrivate *priv = window->priv;
-
-- g_signal_connect (window->priv->fullscreen_eventbox,
-+ g_signal_connect (priv->fullscreen_eventbox,
- "enter-notify-event",
-- G_CALLBACK (on_fullscreen_eventbox_enter_notify_event),
-+ G_CALLBACK (on_fullscreen_controls_enter_notify_event),
- window);
-
-- g_signal_connect (window->priv->fullscreen_eventbox,
-+ g_signal_connect (priv->fullscreen_eventbox,
- "leave-notify-event",
-- G_CALLBACK (on_fullscreen_eventbox_leave_notify_event),
-+ G_CALLBACK (on_fullscreen_controls_leave_notify_event),
-+ window);
-+
-+ gtk_widget_set_size_request (GTK_WIDGET (window->priv->fullscreen_eventbox), -1, 1);
-+ gtk_widget_hide (window->priv->fullscreen_eventbox);
-+
-+ priv->fullscreen_open_document_popover = gtk_popover_new (priv->fullscreen_open_button);
-+ gtk_menu_button_set_popover (GTK_MENU_BUTTON (priv->fullscreen_open_button),
-+ priv->fullscreen_open_document_popover);
-+
-+ window->priv->fullscreen_open_document_selector = gedit_open_document_selector_new (window);
-+
-+ gtk_container_add (GTK_CONTAINER (priv->fullscreen_open_document_popover),
-+ GTK_WIDGET (priv->fullscreen_open_document_selector));
-+
-+ gtk_widget_show_all (GTK_WIDGET (priv->fullscreen_open_document_selector));
-+
-+ g_signal_connect (window->priv->fullscreen_open_document_selector,
-+ "file-activated",
-+ G_CALLBACK (on_recent_chooser_item_activated),
- window);
- }
-
-@@ -1885,7 +1947,7 @@ on_tab_added (GeditMultiNotebook *multi,
- G_CALLBACK (bracket_matched_cb),
- window);
- g_signal_connect (doc,
-- "tepl-cursor-moved",
-+ "cursor-moved",
- G_CALLBACK (update_cursor_position_statusbar),
- window);
- g_signal_connect (doc,
-@@ -2144,10 +2206,23 @@ on_notebook_removed (GeditMultiNotebook *mnb,
- }
-
- static void
--on_fullscreen_toggle_button_toggled (GtkToggleButton *fullscreen_toggle_button,
-- GeditWindow *window)
-+on_fullscreen_gear_button_toggled (GtkToggleButton *fullscreen_gear_button,
-+ GeditWindow *window)
- {
-- update_fullscreen_revealer_state (window);
-+ gboolean button_active = gtk_toggle_button_get_active (fullscreen_gear_button);
-+
-+ gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls),
-+ button_active || window->priv->in_fullscreen_eventbox);
-+}
-+
-+static void
-+on_fullscreen_file_menu_button_toggled (GtkMenuButton *fullscreen_open_button,
-+ GeditWindow *window)
-+{
-+ gboolean button_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fullscreen_open_button));
-+
-+ gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls),
-+ button_active || window->priv->in_fullscreen_eventbox);
- }
-
- static void
-@@ -2537,6 +2612,18 @@ window_unrealized (GtkWidget *window,
- window);
- }
-
-+static void
-+check_window_is_active (GeditWindow *window,
-+ GParamSpec *property,
-+ gpointer useless)
-+{
-+ if (window->priv->window_state & GDK_WINDOW_STATE_FULLSCREEN)
-+ {
-+ gtk_widget_set_visible (window->priv->fullscreen_eventbox,
-+ gtk_window_is_active (GTK_WINDOW (window)));
-+ }
-+}
-+
- static void
- extension_added (PeasExtensionSet *extensions,
- PeasPluginInfo *info,
-@@ -2608,76 +2695,6 @@ sync_fullscreen_actions (GeditWindow *window,
- g_object_unref (action);
- }
-
--static void
--init_amtk_application_window (GeditWindow *gedit_window)
--{
-- AmtkApplicationWindow *amtk_window;
--
-- amtk_window = amtk_application_window_get_from_gtk_application_window (GTK_APPLICATION_WINDOW (gedit_window));
-- amtk_application_window_set_statusbar (amtk_window, GTK_STATUSBAR (gedit_window->priv->statusbar));
--}
--
--static GtkWidget *
--create_open_buttons (GeditWindow *window,
-- GtkMenuButton **open_recent_button)
--{
-- GtkWidget *hbox;
-- GtkStyleContext *style_context;
-- GtkWidget *open_dialog_button;
-- GtkWidget *my_open_recent_button;
-- AmtkApplicationWindow *amtk_window;
-- GtkWidget *recent_menu;
--
-- /* It currently needs to be a GtkBox, not a GtkGrid, because GtkGrid and
-- * GTK_STYLE_CLASS_LINKED doesn't work as expected in a RTL locale.
-- * Probably a GtkGrid bug.
-- */
-- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-- style_context = gtk_widget_get_style_context (hbox);
-- gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_LINKED);
--
-- open_dialog_button = gtk_button_new_with_mnemonic (_("_Open"));
-- gtk_widget_set_tooltip_text (open_dialog_button, _("Open a file"));
-- gtk_actionable_set_action_name (GTK_ACTIONABLE (open_dialog_button), "win.open");
--
-- my_open_recent_button = gtk_menu_button_new ();
-- gtk_widget_set_tooltip_text (my_open_recent_button, _("Open a recently used file"));
--
-- amtk_window = amtk_application_window_get_from_gtk_application_window (GTK_APPLICATION_WINDOW (window));
-- recent_menu = amtk_application_window_create_open_recent_menu (amtk_window);
-- gtk_menu_button_set_popup (GTK_MENU_BUTTON (my_open_recent_button), recent_menu);
--
-- gtk_container_add (GTK_CONTAINER (hbox), open_dialog_button);
-- gtk_container_add (GTK_CONTAINER (hbox), my_open_recent_button);
-- gtk_widget_show_all (hbox);
--
-- if (open_recent_button != NULL)
-- {
-- *open_recent_button = GTK_MENU_BUTTON (my_open_recent_button);
-- }
--
-- return hbox;
--}
--
--static void
--init_open_buttons (GeditWindow *window)
--{
-- gtk_container_add_with_properties (GTK_CONTAINER (window->priv->headerbar),
-- create_open_buttons (window, NULL),
-- "position", 0, /* The first on the left. */
-- NULL);
--
-- gtk_container_add_with_properties (GTK_CONTAINER (window->priv->fullscreen_headerbar),
-- create_open_buttons (window, &(window->priv->fullscreen_open_recent_button)),
-- "position", 0, /* The first on the left. */
-- NULL);
--
-- g_signal_connect (GTK_TOGGLE_BUTTON (window->priv->fullscreen_open_recent_button),
-- "toggled",
-- G_CALLBACK (on_fullscreen_toggle_button_toggled),
-- window);
--}
--
- static void
- gedit_window_init (GeditWindow *window)
- {
-@@ -2692,6 +2709,7 @@ gedit_window_init (GeditWindow *window)
- window->priv->state = GEDIT_WINDOW_STATE_NORMAL;
- window->priv->inhibition_cookie = 0;
- window->priv->dispose_has_run = FALSE;
-+ window->priv->fullscreen_controls = NULL;
- window->priv->direct_save_uri = NULL;
- window->priv->closed_docs_stack = NULL;
- window->priv->editor_settings = g_settings_new ("org.gnome.gedit.preferences.editor");
-@@ -2705,8 +2723,6 @@ gedit_window_init (GeditWindow *window)
- window->priv->message_bus = gedit_message_bus_new ();
-
- gtk_widget_init_template (GTK_WIDGET (window));
-- init_amtk_application_window (window);
-- init_open_buttons (window);
-
- g_action_map_add_action_entries (G_ACTION_MAP (window),
- win_entries,
-@@ -2716,9 +2732,32 @@ gedit_window_init (GeditWindow *window)
- window->priv->window_group = gtk_window_group_new ();
- gtk_window_group_add_window (window->priv->window_group, GTK_WINDOW (window));
-
-- setup_fullscreen_eventbox (window);
-+ /* Setup file popover and file dialog */
-+ window->priv->open_document_popover = gtk_popover_new (window->priv->open_button);
-+ gtk_menu_button_set_popover (GTK_MENU_BUTTON (window->priv->open_button),
-+ window->priv->open_document_popover);
-+
-+ window->priv->open_document_selector = gedit_open_document_selector_new (window);
-+
-+ gtk_container_add (GTK_CONTAINER (window->priv->open_document_popover),
-+ GTK_WIDGET (window->priv->open_document_selector));
-+
-+ gtk_widget_show_all (GTK_WIDGET (window->priv->open_document_selector));
-+
-+ g_signal_connect (window->priv->open_document_selector,
-+ "file-activated",
-+ G_CALLBACK (on_recent_chooser_item_activated),
-+ window);
-+
-+ fullscreen_controls_setup (window);
- sync_fullscreen_actions (window, FALSE);
-
-+ g_object_bind_property (gedit_open_document_selector_get_search_entry (window->priv->open_document_selector),
-+ "text",
-+ gedit_open_document_selector_get_search_entry (window->priv->fullscreen_open_document_selector),
-+ "text",
-+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-+
- hamburger_menu = _gedit_app_get_hamburger_menu (GEDIT_APP (g_application_get_default ()));
- if (hamburger_menu)
- {
-@@ -2733,9 +2772,14 @@ gedit_window_init (GeditWindow *window)
- gtk_widget_set_no_show_all (GTK_WIDGET (window->priv->fullscreen_gear_button), TRUE);
- }
-
-+ g_signal_connect (GTK_TOGGLE_BUTTON (window->priv->fullscreen_open_button),
-+ "toggled",
-+ G_CALLBACK (on_fullscreen_file_menu_button_toggled),
-+ window);
-+
- g_signal_connect (GTK_TOGGLE_BUTTON (window->priv->fullscreen_gear_button),
- "toggled",
-- G_CALLBACK (on_fullscreen_toggle_button_toggled),
-+ G_CALLBACK (on_fullscreen_gear_button_toggled),
- window);
-
- /* Setup status bar */
-@@ -2849,6 +2893,12 @@ gedit_window_init (GeditWindow *window)
- G_CALLBACK (window_unrealized),
- NULL);
-
-+ /* Check if the window is active for fullscreen */
-+ g_signal_connect (window,
-+ "notify::is-active",
-+ G_CALLBACK (check_window_is_active),
-+ NULL);
-+
- gedit_debug_message (DEBUG_WINDOW, "Update plugins ui");
-
- window->priv->extensions = peas_extension_set_new (PEAS_ENGINE (gedit_plugins_engine_get_default ()),
-diff --git a/gedit/gedit.c b/gedit/gedit.c
-index fcffdaca6..ee3769537 100644
---- a/gedit/gedit.c
-+++ b/gedit/gedit.c
-@@ -28,13 +28,12 @@
- # include "gedit-app-win32.h"
- #endif
-
-+#include
- #include
- #include
--#include
-
- #include "gedit-dirs.h"
- #include "gedit-debug.h"
--#include "gedit-factory.h"
- #include "gedit-settings.h"
-
- #ifdef G_OS_WIN32
-@@ -117,7 +116,6 @@ int
- main (int argc, char *argv[])
- {
- GType type;
-- GeditFactory *factory;
- GeditApp *app;
- gint status;
-
-@@ -140,9 +138,6 @@ main (int argc, char *argv[])
- gedit_dirs_init ();
-
- setup_i18n ();
-- tepl_init ();
-- factory = gedit_factory_new ();
-- tepl_abstract_factory_set_singleton (TEPL_ABSTRACT_FACTORY (factory));
-
- app = g_object_new (type,
- "application-id", "org.gnome.gedit",
-@@ -167,7 +162,6 @@ main (int argc, char *argv[])
- G_OBJECT (app)->ref_count);
- }
-
-- tepl_finalize ();
- gedit_dirs_shutdown ();
-
- #ifdef G_OS_WIN32
-diff --git a/gedit/meson.build b/gedit/meson.build
-index 9fc81468e..844b6bac8 100644
---- a/gedit/meson.build
-+++ b/gedit/meson.build
-@@ -8,6 +8,7 @@ libgedit_public_headers = [
- 'gedit-menu-extension.h',
- 'gedit-message-bus.h',
- 'gedit-message.h',
-+ 'gedit-progress-info-bar.h',
- 'gedit-statusbar.h',
- 'gedit-tab.h',
- 'gedit-utils.h',
-@@ -27,11 +28,13 @@ libgedit_public_sources = [
- 'gedit-menu-extension.c',
- 'gedit-message-bus.c',
- 'gedit-message.c',
-+ 'gedit-progress-info-bar.c',
- 'gedit-statusbar.c',
- 'gedit-tab.c',
- 'gedit-utils.c',
- 'gedit-view-activatable.c',
- 'gedit-view.c',
-+ 'gedit-view-centering.c',
- 'gedit-window-activatable.c',
- 'gedit-window.c',
- ]
-@@ -45,30 +48,37 @@ libgedit_private_headers = [
- 'gedit-documents-panel.h',
- 'gedit-encoding-items.h',
- 'gedit-encodings-dialog.h',
-- 'gedit-factory.h',
- 'gedit-file-chooser-dialog-gtk.h',
- 'gedit-file-chooser-dialog.h',
- 'gedit-file-chooser.h',
- 'gedit-file-chooser-open-dialog.h',
- 'gedit-file-chooser-open.h',
- 'gedit-file-chooser-open-native.h',
-+ 'gedit-highlight-mode-dialog.h',
-+ 'gedit-highlight-mode-selector.h',
- 'gedit-history-entry.h',
- 'gedit-io-error-info-bar.h',
- 'gedit-menu-stack-switcher.h',
-+ 'gedit-metadata-manager.h',
- 'gedit-multi-notebook.h',
- 'gedit-notebook.h',
- 'gedit-notebook-popup-menu.h',
- 'gedit-notebook-stack-switcher.h',
-+ 'gedit-open-document-selector.h',
-+ 'gedit-open-document-selector-helper.h',
-+ 'gedit-open-document-selector-store.h',
-+ 'gedit-pango.h',
- 'gedit-plugins-engine.h',
- 'gedit-preferences-dialog.h',
- 'gedit-print-job.h',
- 'gedit-print-preview.h',
- 'gedit-recent.h',
-- 'gedit-recent-osx.h',
- 'gedit-replace-dialog.h',
- 'gedit-settings.h',
- 'gedit-status-menu-button.h',
- 'gedit-tab-label.h',
-+ 'gedit-tab-private.h',
-+ 'gedit-view-centering.h',
- 'gedit-view-frame.h',
- 'gedit-window-private.h',
- ]
-@@ -85,20 +95,26 @@ libgedit_private_sources = [
- 'gedit-documents-panel.c',
- 'gedit-encoding-items.c',
- 'gedit-encodings-dialog.c',
-- 'gedit-factory.c',
- 'gedit-file-chooser.c',
- 'gedit-file-chooser-dialog.c',
- 'gedit-file-chooser-dialog-gtk.c',
- 'gedit-file-chooser-open.c',
- 'gedit-file-chooser-open-dialog.c',
- 'gedit-file-chooser-open-native.c',
-+ 'gedit-highlight-mode-dialog.c',
-+ 'gedit-highlight-mode-selector.c',
- 'gedit-history-entry.c',
- 'gedit-io-error-info-bar.c',
- 'gedit-menu-stack-switcher.c',
-+ 'gedit-metadata-manager.c',
- 'gedit-multi-notebook.c',
- 'gedit-notebook.c',
- 'gedit-notebook-popup-menu.c',
- 'gedit-notebook-stack-switcher.c',
-+ 'gedit-open-document-selector.c',
-+ 'gedit-open-document-selector-helper.c',
-+ 'gedit-open-document-selector-store.c',
-+ 'gedit-pango.c',
- 'gedit-plugins-engine.c',
- 'gedit-preferences-dialog.c',
- 'gedit-print-job.c',
-@@ -117,6 +133,7 @@ libgedit_link_args = []
- libgedit_deps = [
- deps_basic_list,
- libgd_dep,
-+ libxml_dep,
- ]
-
- if host_machine.system() == 'darwin'
-diff --git a/gedit/resources/css/gedit-style.css b/gedit/resources/css/gedit-style.css
-index eb43a8233..7036567c4 100644
---- a/gedit/resources/css/gedit-style.css
-+++ b/gedit/resources/css/gedit-style.css
-@@ -14,6 +14,18 @@
- padding: 12px;
- }
-
-+.gedit-map-frame:dir(ltr) border {
-+ border-width: 0 0 0 1px;
-+}
-+
-+.gedit-map-frame:dir(rtl) border {
-+ border-width: 0 1px 0 0;
-+}
-+
-+.open-document-selector-treeview {
-+ padding: 3px 6px 3px 6px;
-+}
-+
- statusbar frame {
- border: none;
- padding-left: 6px;
-diff --git a/gedit/resources/css/gedit.adwaita.css b/gedit/resources/css/gedit.adwaita.css
-index 784e72aa2..8377c62a9 100644
---- a/gedit/resources/css/gedit.adwaita.css
-+++ b/gedit/resources/css/gedit.adwaita.css
-@@ -1,3 +1,28 @@
-+.open-document-selector-treeview:hover {
-+ background-color: alpha(@theme_fg_color, 0.05);
-+}
-+
-+.open-document-selector-treeview:selected:hover {
-+ background-color: @theme_selected_bg_color;
-+}
-+
-+/* Only normal state is handle */
-+.open-document-selector-name-label {
-+ color: @theme_fg_color;
-+}
-+
-+/* Only normal state is handle */
-+.open-document-selector-path-label {
-+ color: @theme_unfocused_fg_color;
-+ font-size: smaller;
-+}
-+
-+/* Only normal state is handle */
-+.open-document-selector-match {
-+ color: shade (@theme_fg_color, 0.6);
-+ background-color: alpha(@warning_color, 0.4);
-+}
-+
- .gedit-document-panel {
- background-color: @sidebar_bg;
- }
-diff --git a/gedit/resources/gedit.gresource.xml.in b/gedit/resources/gedit.gresource.xml.in
-index a5905110e..b0a70c185 100644
---- a/gedit/resources/gedit.gresource.xml.in
-+++ b/gedit/resources/gedit.gresource.xml.in
-@@ -8,10 +8,14 @@
- ui/gedit-replace-dialog.ui
- ui/gedit-print-preview.ui
- ui/gedit-print-preferences.ui
-+ ui/gedit-progress-info-bar.ui
- ui/gedit-status-menu-button.ui
- ui/gedit-tab-label.ui
- ui/gedit-view-frame.ui
-+ ui/gedit-highlight-mode-dialog.ui
-+ ui/gedit-highlight-mode-selector.ui
- ui/gedit-window.ui
-+ ui/gedit-open-document-selector.ui
- ui/gedit-shortcuts.ui
- ui/gedit-statusbar.ui
- css/gedit-style.css
-diff --git a/gedit/resources/ui/gedit-highlight-mode-dialog.ui b/gedit/resources/ui/gedit-highlight-mode-dialog.ui
-new file mode 100644
-index 000000000..31b8690bd
---- /dev/null
-+++ b/gedit/resources/ui/gedit-highlight-mode-dialog.ui
-@@ -0,0 +1,87 @@
-+
-+
-+
-+
-+ 300
-+ 400
-+ False
-+ False
-+ False
-+ 5
-+ Highlight Mode
-+ dialog
-+ True
-+
-+
-+
-+
-+ cancel_button
-+ ok_button
-+
-+
-+
-diff --git a/gedit/resources/ui/gedit-highlight-mode-selector.ui b/gedit/resources/ui/gedit-highlight-mode-selector.ui
-new file mode 100644
-index 000000000..1aa5c950e
---- /dev/null
-+++ b/gedit/resources/ui/gedit-highlight-mode-selector.ui
-@@ -0,0 +1,83 @@
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+ liststore
-+
-+
-+ 300
-+ 400
-+ True
-+ False
-+ False
-+ False
-+ 3
-+ 6
-+
-+
-+ True
-+ True
-+ True
-+ False
-+ True
-+ Search highlight mode…
-+
-+
-+ 0
-+ 0
-+ 1
-+ 1
-+
-+
-+
-+
-+ True
-+ True
-+ False
-+ False
-+ True
-+ True
-+ in
-+
-+
-+ True
-+ True
-+ False
-+ False
-+ treemodelfilter
-+ False
-+ False
-+ False
-+
-+
-+
-+
-+
-+
-+
-+
-+ 0
-+
-+
-+
-+
-+
-+
-+
-+
-+ 0
-+ 1
-+ 1
-+ 1
-+
-+
-+
-+
-diff --git a/gedit/resources/ui/gedit-open-document-selector.ui b/gedit/resources/ui/gedit-open-document-selector.ui
-new file mode 100644
-index 000000000..9393ac46c
---- /dev/null
-+++ b/gedit/resources/ui/gedit-open-document-selector.ui
-@@ -0,0 +1,115 @@
-+
-+
-+
-+
-+ True
-+ False
-+ 9
-+ vertical
-+ 6
-+
-+
-+ True
-+ True
-+ edit-find-symbolic
-+ False
-+ False
-+
-+
-+ False
-+ False
-+ 0
-+
-+
-+
-+
-+ False
-+ False
-+ True
-+ True
-+ in
-+
-+
-+ True
-+ vertical
-+ center
-+ center
-+
-+
-+ True
-+ edit-find-symbolic
-+ 64
-+ False
-+
-+
-+
-+
-+
-+ True
-+ False
-+ False
-+ No results
-+
-+
-+
-+
-+
-+
-+
-+ True
-+ True
-+ 1
-+
-+
-+
-+
-+ True
-+ True
-+ True
-+ never
-+ in
-+
-+
-+ True
-+ True
-+ True
-+ True
-+ False
-+ True
-+ horizontal
-+ False
-+ True
-+
-+
-+
-+
-+ True
-+ True
-+ 2
-+
-+
-+
-+
-+ Other _Documents…
-+ True
-+ True
-+ True
-+ Open another file
-+ 6
-+ win.open
-+
-+
-+
-+ False
-+ True
-+ 3
-+
-+
-+
-+
-diff --git a/gedit/resources/ui/gedit-preferences-dialog.ui b/gedit/resources/ui/gedit-preferences-dialog.ui
-index f1eeed45c..1ce0755da 100644
---- a/gedit/resources/ui/gedit-preferences-dialog.ui
-+++ b/gedit/resources/ui/gedit-preferences-dialog.ui
-@@ -105,6 +105,21 @@
- 2
-
-
-+
-+
-+ Display _overview map
-+ True
-+ True
-+ False
-+ True
-+ True
-+
-+
-+ 0
-+ 3
-+ 2
-+
-+
-
-
- Display _grid pattern
-@@ -116,7 +131,7 @@
-
-
- 0
-- 3
-+ 4
- 2
-
-
-@@ -630,8 +645,19 @@
- True
- True
-
--
-+
- True
-+ True
-+ True
-+ True
-+ etched-in
-+ 200
-+
-+
-+ True
-+ True
-+
-+
-
-
- 0
-diff --git a/gedit/resources/ui/gedit-progress-info-bar.ui b/gedit/resources/ui/gedit-progress-info-bar.ui
-new file mode 100644
-index 000000000..3f733e4b6
---- /dev/null
-+++ b/gedit/resources/ui/gedit-progress-info-bar.ui
-@@ -0,0 +1,88 @@
-+
-+
-+
-+
-+ True
-+ False
-+ other
-+
-+
-+ False
-+ vertical
-+ 6
-+
-+
-+ True
-+ False
-+ 4
-+
-+
-+ True
-+ False
-+ 2
-+ image-missing
-+
-+
-+ False
-+ True
-+ 4
-+ 0
-+
-+
-+
-+
-+ True
-+ False
-+ start
-+ label
-+ True
-+ end
-+
-+
-+ False
-+ True
-+ 1
-+
-+
-+
-+
-+ False
-+ True
-+ 0
-+
-+
-+
-+
-+ 15
-+ True
-+ False
-+ True
-+
-+
-+ False
-+ True
-+ 1
-+
-+
-+
-+
-+ True
-+ True
-+ 0
-+
-+
-+
-+
-+ False
-+
-+
-+
-+
-+
-+ False
-+ True
-+ 1
-+
-+
-+
-+
-diff --git a/gedit/resources/ui/gedit-view-frame.ui b/gedit/resources/ui/gedit-view-frame.ui
-index ebf70b013..b61d82c3a 100644
---- a/gedit/resources/ui/gedit-view-frame.ui
-+++ b/gedit/resources/ui/gedit-view-frame.ui
-@@ -7,15 +7,33 @@
- False
- False
-
--
-+
- True
-- True
-- True
-- False
-
--
-+
- True
-- True
-+ True
-+ True
-+
-+
-+ True
-+ True
-+
-+
-+
-+
-+
-+
-+ True
-+
-+
-+
-+ True
-+ view
-+
-+
-
-
-
-diff --git a/gedit/resources/ui/gedit-window.ui b/gedit/resources/ui/gedit-window.ui
-index 0d131ad69..b6283dcf4 100644
---- a/gedit/resources/ui/gedit-window.ui
-+++ b/gedit/resources/ui/gedit-window.ui
-@@ -27,6 +27,50 @@
-
- True
- True
-+
-+
-+ True
-+ Open a file
-+ center
-+ True
-+
-+
-+
-+ True
-+ False
-+ False
-+ False
-+
-+
-+ _Open
-+ True
-+ True
-+ baseline
-+
-+
-+
-+
-+ True
-+ baseline
-+ pan-down-symbolic
-+
-+
-+
-+
-+
-+
-+ Open
-+ Open a file
-+
-+
-+
-+
-+ start
-+
-+
-
-
- True
-@@ -310,7 +354,7 @@
- False
- start
-
--
-+
- True
- False
- False
-@@ -318,6 +362,47 @@
-
-
- True
-+
-+
-+ True
-+ Open a file dialog
-+ center
-+ True
-+
-+
-+
-+ True
-+ False
-+ False
-+ False
-+
-+
-+ Open
-+ True
-+
-+
-+
-+
-+ True
-+ pan-down-symbolic
-+
-+
-+
-+
-+
-+
-+ Open
-+ Open a file
-+
-+
-+
-+
-+ start
-+
-+
-
-
- True
-diff --git a/help/C/gedit-tab-groups.page b/help/C/gedit-tab-groups.page
-index a25fcb6e0..d7ed84e8b 100644
---- a/help/C/gedit-tab-groups.page
-+++ b/help/C/gedit-tab-groups.page
-@@ -24,8 +24,8 @@
-
If you are working with multiple tabs in gedit you can group
- them, making it easier to keep your opened files organized. Adding a new tab
- group will divide the gedit window in two panes, open a new
-- “Untitled File” in the new pane, and make it active. You can open files into
-- that tab group and move tabs from one tab group to another.
-+ “Untitled Document” in the new pane, and make it active. You can open files
-+ into that tab group and move tabs from one tab group to another.
-
-
- Open a new tab group in the gedit window
-diff --git a/meson.build b/meson.build
-index be77a885f..ef77bc8a8 100644
---- a/meson.build
-+++ b/meson.build
-@@ -40,13 +40,25 @@ libgd_subproject = subproject(
- libgd_dep = libgd_subproject.get_variable('libgd_dep')
-
- # Dependencies
--gio_dep = dependency('gio-2.0', version: '>= 2.64')
-+glib_req = '>= 2.64'
-+gtk_req = '>= 2.22'
-+gtksourceview_req = '>= 4.0'
-+libpeas_req = '>= 1.14.1'
-+libxml_req = '>= 2.5.0'
-+gspell_req = '>= 1.0'
-+pygobject_req = '>= 3.0.0'
-+
-+gio_dep = dependency('gio-2.0', version: glib_req)
-+libxml_dep = dependency('libxml-2.0', version: libxml_req)
-+gspell_dep = dependency('gspell-1', version: gspell_req)
-+
-+python3 = python.find_installation('python3')
-
- libgedit_public_deps = [
- gio_dep,
-- dependency('gtk+-3.0', version: '>= 3.22'),
-- dependency('tepl-6', version: '>= 5.99.0'),
-- dependency('libpeas-gtk-1.0'),
-+ dependency('gtk+-3.0', version: gtk_req),
-+ dependency('gtksourceview-4', version: gtksourceview_req),
-+ dependency('libpeas-gtk-1.0', version: libpeas_req),
- ]
-
- deps_basic_list = [
-@@ -54,9 +66,6 @@ deps_basic_list = [
- dependency('gobject-introspection-1.0'),
- ]
-
--gspell_dep = dependency('gspell-1', version: '>= 1.0')
--python3 = python.find_installation('python3')
--
- # Configurations
- config_h = configuration_data()
- config_h.set_quoted('PACKAGE_STRING', 'gedit-@0@'.format(api_version))
-@@ -65,6 +74,17 @@ config_h.set_quoted('LIBDIR', join_paths(get_option('prefix'), get_option('libdi
- config_h.set_quoted('DATADIR', join_paths(get_option('prefix'), get_option('datadir')))
- config_h.set_quoted('VERSION', meson.project_version())
-
-+enable_gvfs_metadata = get_option('enable-gvfs-metadata')
-+if enable_gvfs_metadata == 'yes' or (enable_gvfs_metadata == 'auto' and host_machine.system() == 'linux')
-+ enable_gvfs_metadata = true
-+else
-+ enable_gvfs_metadata = false
-+endif
-+
-+if enable_gvfs_metadata
-+ config_h.set('ENABLE_GVFS_METADATA', 1)
-+endif
-+
- configure_file(
- output: 'config.h',
- configuration: config_h
-diff --git a/meson_options.txt b/meson_options.txt
-index 4e842d1ea..33d03cb14 100644
---- a/meson_options.txt
-+++ b/meson_options.txt
-@@ -21,4 +21,11 @@ option(
- description: 'Build user documentation'
- )
-
-+option(
-+ 'enable-gvfs-metadata',
-+ type: 'combo',
-+ choices: ['yes', 'no', 'auto'], value: 'auto',
-+ description: 'Enable using gvfs to store metadata'
-+)
-+
- option('plugin_externaltools', type: 'boolean', value: true)
-diff --git a/plugins/snippets/snippets/document.py b/plugins/snippets/snippets/document.py
-index 003237d17..23df28091 100644
---- a/plugins/snippets/snippets/document.py
-+++ b/plugins/snippets/snippets/document.py
-@@ -162,13 +162,13 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
- buf = self.view.get_buffer()
-
- self.connect_signal(buf, 'changed', self.on_buffer_changed)
-- self.connect_signal(buf, 'tepl-cursor-moved', self.on_buffer_cursor_moved)
-+ self.connect_signal(buf, 'cursor-moved', self.on_buffer_cursor_moved)
- self.connect_signal_after(buf, 'insert-text', self.on_buffer_insert_text)
-
- def last_snippet_removed(self):
- buf = self.view.get_buffer()
- self.disconnect_signal(buf, 'changed')
-- self.disconnect_signal(buf, 'tepl-cursor-moved')
-+ self.disconnect_signal(buf, 'cursor-moved')
- self.disconnect_signal(buf, 'insert-text')
-
- def current_placeholder(self):
-@@ -559,7 +559,7 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
- self.goto_placeholder(current, None)
-
- if len(self.active_snippets) > 0:
-- self.block_signal(buf, 'tepl-cursor-moved')
-+ self.block_signal(buf, 'cursor-moved')
-
- buf.begin_user_action()
-
-@@ -569,7 +569,7 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
- # Insert the snippet
- if len(self.active_snippets) == 0:
- self.first_snippet_inserted()
-- self.block_signal(buf, 'tepl-cursor-moved')
-+ self.block_signal(buf, 'cursor-moved')
-
- sn = s.insert_into(self, start)
- self.active_snippets.append(sn)
-@@ -585,7 +585,7 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
- else:
- self.goto_placeholder(self.active_placeholder, sn.placeholders[keys[0]])
-
-- self.unblock_signal(buf, 'tepl-cursor-moved')
-+ self.unblock_signal(buf, 'cursor-moved')
-
- if sn in self.active_snippets:
- # Check if we can get end_iter in view without moving the
-diff --git a/plugins/spell/gedit-spell-plugin.c b/plugins/spell/gedit-spell-plugin.c
-index 611677826..47d449433 100644
---- a/plugins/spell/gedit-spell-plugin.c
-+++ b/plugins/spell/gedit-spell-plugin.c
-@@ -30,8 +30,13 @@
-
- #include "gedit-spell-app-activatable.h"
-
--#define GEDIT_METADATA_ATTRIBUTE_SPELL_LANGUAGE "gedit-spell-language"
--#define GEDIT_METADATA_ATTRIBUTE_SPELL_ENABLED "gedit-spell-enabled"
-+#ifdef G_OS_WIN32
-+#define GEDIT_METADATA_ATTRIBUTE_SPELL_LANGUAGE "spell-language"
-+#define GEDIT_METADATA_ATTRIBUTE_SPELL_ENABLED "spell-enabled"
-+#else
-+#define GEDIT_METADATA_ATTRIBUTE_SPELL_LANGUAGE "metadata::gedit-spell-language"
-+#define GEDIT_METADATA_ATTRIBUTE_SPELL_ENABLED "metadata::gedit-spell-enabled"
-+#endif
-
- #define SPELL_ENABLED_STR "1"
- #define SPELL_BASE_SETTINGS "org.gnome.gedit.plugins.spell"
-diff --git a/po/POTFILES.in b/po/POTFILES.in
-index be8af499a..25ff2db1a 100644
---- a/po/POTFILES.in
-+++ b/po/POTFILES.in
-@@ -16,19 +16,22 @@ gedit/gedit-documents-panel.c
- gedit/gedit-encodings-combo-box.c
- gedit/gedit-encoding-items.c
- gedit/gedit-encodings-dialog.c
--gedit/gedit-factory.c
- gedit/gedit-file-chooser.c
- gedit/gedit-file-chooser-dialog-gtk.c
- gedit/gedit-file-chooser-open.c
- gedit/gedit-file-chooser-open-dialog.c
- gedit/gedit-file-chooser-open-native.c
-+gedit/gedit-highlight-mode-dialog.c
-+gedit/gedit-highlight-mode-selector.c
- gedit/gedit-io-error-info-bar.c
- gedit/gedit-notebook.c
- gedit/gedit-notebook-popup-menu.c
-+gedit/gedit-open-document-selector.c
- gedit/gedit-plugins-engine.c
- gedit/gedit-preferences-dialog.c
- gedit/gedit-print-job.c
- gedit/gedit-print-preview.c
-+gedit/gedit-progress-info-bar.c
- gedit/gedit-replace-dialog.c
- gedit/gedit-statusbar.c
- gedit/gedit-tab.c
-@@ -41,6 +44,9 @@ gedit/resources/gtk/menus-common.ui
- gedit/resources/gtk/menus.ui
- gedit/resources/gtk/menus-traditional.ui
- gedit/resources/ui/gedit-encodings-dialog.ui
-+gedit/resources/ui/gedit-highlight-mode-dialog.ui
-+gedit/resources/ui/gedit-highlight-mode-selector.ui
-+gedit/resources/ui/gedit-open-document-selector.ui
- gedit/resources/ui/gedit-preferences-dialog.ui
- gedit/resources/ui/gedit-print-preferences.ui
- gedit/resources/ui/gedit-print-preview.ui
---
-GitLab
-
diff -Nru gedit-40.1/docs/gedit-development-getting-started.md gedit-41.0/docs/gedit-development-getting-started.md
--- gedit-40.1/docs/gedit-development-getting-started.md 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/docs/gedit-development-getting-started.md 2022-02-14 13:58:26.000000000 +0000
@@ -31,11 +31,9 @@
mostly valid). But GtkTextView is not enough for source code edition. gedit
actually uses the
[GtkSourceView](https://wiki.gnome.org/Projects/GtkSourceView) library, which
-contains a subclass of GtkTextView with many features useful for a text editor
-or an IDE. But GtkSourceView is not enough to have a full-blown text editor,
-gedit is actually in the process of using more features from the
-[Tepl](https://wiki.gnome.org/Projects/Tepl) library, and to further develop
-Tepl alongside gedit.
+contains a subclass of GtkTextView with syntax highlighting, a completion
+framework, the search and replace, and many other features useful for a text
+editor or an IDE.
For its plugin system, gedit uses the
[libpeas](https://wiki.gnome.org/Projects/Libpeas) library.
diff -Nru gedit-40.1/docs/reference/api-breaks.xml gedit-41.0/docs/reference/api-breaks.xml
--- gedit-40.1/docs/reference/api-breaks.xml 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/docs/reference/api-breaks.xml 2022-02-14 13:58:26.000000000 +0000
@@ -22,6 +22,56 @@
+ 40 -> 41
+
+
+
+ The GeditProgressInfoBar class has been restored
+
+
+
+
+ GeditDocument is no longer a subclass
+ of TeplBuffer.
+
+
+
+
+ The GeditDocument::cursor-moved signal has been restored.
+
+
+
+
+ The GeditDocument:shortname property has been restored.
+
+
+
+
+ The gedit_document_is_untouched() function has been
+ restored.
+
+
+
+
+ The gedit_view_set_font() function has been restored.
+
+
+
+
+ DEBUG_METADATA has been restored.
+
+
+
+
+ The GBOOLEAN_TO_POINTER() and
+ GPOINTER_TO_BOOLEAN() macros have been restored to
+ gedit-utils.h.
+
+
+
+
+
+ 3.38 -> 40
diff -Nru gedit-40.1/docs/reference/gedit-docs.xml gedit-41.0/docs/reference/gedit-docs.xml
--- gedit-40.1/docs/reference/gedit-docs.xml 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/docs/reference/gedit-docs.xml 2022-02-14 13:58:26.000000000 +0000
@@ -16,6 +16,7 @@
+
diff -Nru gedit-40.1/docs/reference/gedit-sections.txt gedit-41.0/docs/reference/gedit-sections.txt
--- gedit-40.1/docs/reference/gedit-sections.txt 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/docs/reference/gedit-sections.txt 2022-02-14 13:58:26.000000000 +0000
@@ -54,7 +54,10 @@
gedit_document_get_file
gedit_document_get_short_name_for_display
gedit_document_get_mime_type
+gedit_document_is_untouched
gedit_document_is_untitled
+gedit_document_goto_line
+gedit_document_goto_line_offset
gedit_document_set_language
gedit_document_get_content_type
gedit_document_get_metadata
@@ -149,6 +152,26 @@
+gedit-progress-info-bar
+GeditProgressInfoBar
+GeditProgressInfoBar
+gedit_progress_info_bar_new
+gedit_progress_info_bar_set_icon_name
+gedit_progress_info_bar_set_markup
+gedit_progress_info_bar_set_text
+gedit_progress_info_bar_set_fraction
+gedit_progress_info_bar_pulse
+
+GEDIT_PROGRESS_INFO_BAR
+GEDIT_IS_PROGRESS_INFO_BAR
+GEDIT_TYPE_PROGRESS_INFO_BAR
+gedit_progress_info_bar_get_type
+GEDIT_PROGRESS_INFO_BAR_CLASS
+GEDIT_IS_PROGRESS_INFO_BAR_CLASS
+GEDIT_PROGRESS_INFO_BAR_GET_CLASS
+
+
+gedit-statusbarGeditStatusbar
GeditStatusbar
@@ -199,6 +222,13 @@
GeditView
GeditView
gedit_view_new
+gedit_view_cut_clipboard
+gedit_view_copy_clipboard
+gedit_view_paste_clipboard
+gedit_view_delete_selection
+gedit_view_select_all
+gedit_view_scroll_to_cursor
+gedit_view_set_font
GEDIT_VIEW
GEDIT_IS_VIEW
@@ -291,6 +321,7 @@
DEBUG_COMMANDS
DEBUG_APP
DEBUG_UTILS
+DEBUG_METADATA
gedit_debug_init
gedit_debug
gedit_debug_message
@@ -321,9 +352,14 @@
gedit-utils
+GBOOLEAN_TO_POINTER
+GPOINTER_TO_BOOLEAN
gedit_utils_menu_position_under_tree_view
gedit_utils_set_atk_name_description
+gedit_warning
+gedit_utils_replace_home_dir_with_tilde
gedit_utils_basename_for_display
+gedit_utils_decode_uri
gedit_utils_drop_get_uris
gedit_utils_get_compression_type_from_content_type
gedit_utils_is_valid_location
diff -Nru gedit-40.1/docs/reference/meson.build gedit-41.0/docs/reference/meson.build
--- gedit-40.1/docs/reference/meson.build 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/docs/reference/meson.build 2022-02-14 13:58:26.000000000 +0000
@@ -6,14 +6,12 @@
gdk_docpath = dependency('gdk-3.0').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/gdk3'
gtk_docpath = dependency('gtk+-3.0').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/gtk3'
gsv_docpath = dependency('gtksourceview-4').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/gtksourceview-4.0'
-amtk_docpath = dependency('amtk-5').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/amtk-5'
-tepl_docpath = dependency('tepl-6').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/tepl-6'
libpeas_docpath = dependency('libpeas-1.0').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/libpeas'
gedit_doc_dep = declare_dependency(
link_with: libgedit_shared_lib,
include_directories: root_include_dir,
- dependencies: deps_basic_list,
+ dependencies: deps_basic_list + [libxml_dep],
)
gnome.gtkdoc(
@@ -30,8 +28,6 @@
'--extra-dir=@0@'.format(gdk_docpath),
'--extra-dir=@0@'.format(gtk_docpath),
'--extra-dir=@0@'.format(gsv_docpath),
- '--extra-dir=@0@'.format(amtk_docpath),
- '--extra-dir=@0@'.format(tepl_docpath),
'--extra-dir=@0@'.format(libpeas_docpath),
],
content_files: [
diff -Nru gedit-40.1/docs/roadmap-done.md gedit-41.0/docs/roadmap-done.md
--- gedit-40.1/docs/roadmap-done.md 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/docs/roadmap-done.md 1970-01-01 00:00:00.000000000 +0000
@@ -1,56 +0,0 @@
-gedit roadmap - done tasks
-==========================
-
-Tepl-ification of the gedit core
---------------------------------
-
-- gedit 3.36:
- - Start to use the Tepl library.
- - Use some Tepl utility functions.
- - Use TeplFileMetadata, remove GeditMetadataManager.
-- gedit 3.38:
- - Move some utility functions to the Tepl library.
- - Refactor and move some I/O error infobars to Tepl.
- - GeditView now inherits from TeplView.
- - Port to the new Tepl metadata API.
- - Use TeplStyleSchemeChooserWidget in the preferences dialog.
- - Create GeditFactory class, subclass of TeplAbstractFactory.
-- gedit 40:
- - Use `tepl_pango_font_description_to_css()`.
- - Use TeplLanguageChooser's, for choosing a language for the syntax
- highlighting. Remove GeditHighlightModeSelector and
- GeditHighlightModeDialog.
- - Use TeplProgressInfoBar. Remove GeditProgressInfoBar.
- - GeditDocument now inherits from TeplBuffer, start to use the
- TeplBuffer and TeplFile APIs.
-
-Links:
-- https://wiki.gnome.org/Projects/Tepl
-
-Tepl-ification of the gedit plugins
------------------------------------
-
-- gedit 40:
- - Draw Spaces plugin: new implementation based on TeplSpaceDrawerPrefs.
-
-Other done tasks in gedit plugins
----------------------------------
-
-- gedit 40:
- - Smart Spaces plugin: new implementation based on a GtkSourceView
- feature.
-
-New version of gedit on Windows
--------------------------------
-
-[gedit is now available on the Microsoft Store](https://www.microsoft.com/store/apps/9PL1J21XF0PT).
-It was done during the GNOME 3.38 development cycle. The integration with
-Windows is not perfect, but it works. It is planned to improve gedit for
-Windows over time.
-
-Documentation for contributors
-------------------------------
-
-Write a guide to get started with gedit development.
-
-Done during the GNOME 3.34 development cycle.
diff -Nru gedit-40.1/docs/roadmap.md gedit-41.0/docs/roadmap.md
--- gedit-40.1/docs/roadmap.md 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/docs/roadmap.md 2022-02-14 13:58:26.000000000 +0000
@@ -4,27 +4,10 @@
This page contains the plans for major code changes we hope to get done in the
future.
-See the [roadmap-done.md](roadmap-done.md) file for done tasks.
+See also the [GtkSourceView](https://wiki.gnome.org/Projects/GtkSourceView/RoadMap).
See the [NEWS file](../NEWS) for a detailed history.
-See also the
-[Tepl roadmap](https://gitlab.gnome.org/GNOME/tepl/blob/master/docs/roadmap.md).
-
-Continue to make the gedit source code more re-usable
------------------------------------------------------
-
-Status: **in progress** (this is an ongoing effort)
-
-Next steps:
-- Use more features from the Tepl library, and develop Tepl alongside gedit.
- The goal is to reduce the amount of code in gedit, by having re-usable code
- in Tepl instead.
-
-Links:
-- https://wiki.gnome.org/Apps/Gedit/ReusableCode
-- https://wiki.gnome.org/Projects/Tepl
-
Improve gedit on Windows
------------------------
diff -Nru gedit-40.1/gedit/Gedit-3.0.metadata gedit-41.0/gedit/Gedit-3.0.metadata
--- gedit-40.1/gedit/Gedit-3.0.metadata 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/gedit/Gedit-3.0.metadata 2022-02-14 13:58:26.000000000 +0000
@@ -6,6 +6,7 @@
MenuExtension cheader_filename="gedit/gedit-menu-extension.h"
Message cheader_filename="gedit/gedit-message.h"
MessageBus cheader_filename="gedit/gedit-message-bus.h"
+ProgressInfoBar cheader_filename="gedit/gedit-progress-info-bar.h"
Statusbar cheader_filename="gedit/gedit-statusbar.h"
Tab cheader_filename="gedit/gedit-tab.h"
TabState cheader_filename="gedit/gedit-tab.h"
diff -Nru gedit-40.1/gedit/gedit-app.c gedit-41.0/gedit/gedit-app.c
--- gedit-40.1/gedit/gedit-app.c 2021-04-17 05:45:35.452544200 +0000
+++ gedit-41.0/gedit/gedit-app.c 2022-02-14 13:58:26.000000000 +0000
@@ -28,8 +28,9 @@
#include
#include
+#include
#include
-#include
+#include
#include "gedit-commands-private.h"
#include "gedit-notebook.h"
@@ -44,6 +45,10 @@
#include "gedit-preferences-dialog.h"
#include "gedit-tab.h"
+#ifndef ENABLE_GVFS_METADATA
+#include "gedit-metadata-manager.h"
+#endif
+
#define GEDIT_PAGE_SETUP_FILE "gedit-page-setup"
#define GEDIT_PRINT_SETTINGS_FILE "gedit-print-settings"
@@ -51,6 +56,10 @@
{
GeditPluginsEngine *engine;
+#ifndef ENABLE_GVFS_METADATA
+ GeditMetadataManager *metadata_manager;
+#endif
+
GtkCssProvider *theme_provider;
GtkPageSetup *page_setup;
@@ -145,6 +154,10 @@
priv = gedit_app_get_instance_private (GEDIT_APP (object));
+#ifndef ENABLE_GVFS_METADATA
+ g_clear_object (&priv->metadata_manager);
+#endif
+
g_clear_object (&priv->ui_settings);
g_clear_object (&priv->window_settings);
@@ -643,6 +656,10 @@
GeditAppPrivate *priv;
GtkCssProvider *css_provider;
GtkSourceStyleSchemeManager *manager;
+#ifndef ENABLE_GVFS_METADATA
+ const gchar *cache_dir;
+ gchar *metadata_filename;
+#endif
priv = gedit_app_get_instance_private (GEDIT_APP (application));
@@ -654,6 +671,13 @@
setup_theme_extensions (GEDIT_APP (application));
+#ifndef ENABLE_GVFS_METADATA
+ cache_dir = gedit_dirs_get_user_cache_dir ();
+ metadata_filename = g_build_filename (cache_dir, "gedit-metadata.xml", NULL);
+ priv->metadata_manager = gedit_metadata_manager_new (metadata_filename);
+ g_free (metadata_filename);
+#endif
+
/* Load/init settings */
_gedit_settings_get_singleton ();
priv->ui_settings = g_settings_new ("org.gnome.gedit.preferences.ui");
@@ -1114,6 +1138,10 @@
save_page_setup (GEDIT_APP (app));
save_print_settings (GEDIT_APP (app));
+ /* GTK+ can still hold references to some gedit objects, for example
+ * GeditDocument for the clipboard. So the metadata-manager should be
+ * shutdown after.
+ */
G_APPLICATION_CLASS (gedit_app_parent_class)->shutdown (app);
}
@@ -1253,15 +1281,10 @@
static void
gedit_app_init (GeditApp *app)
{
- TeplApplication *tepl_app;
-
g_set_application_name ("gedit");
gtk_window_set_default_icon_name ("org.gnome.gedit");
g_application_add_main_option_entries (G_APPLICATION (app), options);
-
- tepl_app = tepl_application_get_from_gtk_application (GTK_APPLICATION (app));
- tepl_application_handle_metadata (tepl_app);
}
/**
@@ -1571,6 +1594,25 @@
priv->print_settings = g_object_ref (settings);
}
+
+GeditMetadataManager *
+_gedit_app_get_metadata_manager (GeditApp *app)
+{
+#ifndef ENABLE_GVFS_METADATA
+ GeditAppPrivate *priv;
+
+ g_return_val_if_fail (GEDIT_IS_APP (app), NULL);
+
+ priv = gedit_app_get_instance_private (app);
+
+ return priv->metadata_manager;
+#else
+ g_assert_not_reached ();
+ return NULL;
+#endif
+}
+
+
GMenuModel *
_gedit_app_get_hamburger_menu (GeditApp *app)
{
diff -Nru gedit-40.1/gedit/gedit-app-osx.m gedit-41.0/gedit/gedit-app-osx.m
--- gedit-40.1/gedit/gedit-app-osx.m 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/gedit/gedit-app-osx.m 2022-02-14 13:58:26.000000000 +0000
@@ -31,7 +31,7 @@
#include "gedit-debug.h"
#include "gedit-commands.h"
#include "gedit-commands-private.h"
-#include "gedit-recent-osx.h"
+#include "gedit-recent.h"
#import
NSWindow *gdk_quartz_window_get_nswindow(GdkWindow *window);
@@ -286,7 +286,7 @@
g_free (uri);
}
- ismodified = !tepl_buffer_is_untouched (TEPL_BUFFER (document));
+ ismodified = !gedit_document_is_untouched (document);
[native setDocumentEdited:ismodified];
}
else
diff -Nru gedit-40.1/gedit/gedit-app-private.h gedit-41.0/gedit/gedit-app-private.h
--- gedit-40.1/gedit/gedit-app-private.h 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/gedit/gedit-app-private.h 2022-02-14 13:58:26.000000000 +0000
@@ -22,6 +22,7 @@
#define GEDIT_APP_PRIVATE_H
#include "gedit-app.h"
+#include "gedit-metadata-manager.h"
#include "gedit-menu-extension.h"
G_BEGIN_DECLS
@@ -34,6 +35,8 @@
void _gedit_app_set_default_print_settings (GeditApp *app,
GtkPrintSettings *settings);
+GeditMetadataManager *_gedit_app_get_metadata_manager (GeditApp *app);
+
GMenuModel *_gedit_app_get_hamburger_menu (GeditApp *app);
GMenuModel *_gedit_app_get_notebook_menu (GeditApp *app);
diff -Nru gedit-40.1/gedit/gedit.c gedit-41.0/gedit/gedit.c
--- gedit-40.1/gedit/gedit.c 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/gedit.c 2022-02-14 13:58:26.000000000 +0000
@@ -28,13 +28,12 @@
# include "gedit-app-win32.h"
#endif
+#include
#include
#include
-#include
#include "gedit-dirs.h"
#include "gedit-debug.h"
-#include "gedit-factory.h"
#include "gedit-settings.h"
#ifdef G_OS_WIN32
@@ -117,7 +116,6 @@
main (int argc, char *argv[])
{
GType type;
- GeditFactory *factory;
GeditApp *app;
gint status;
@@ -140,9 +138,6 @@
gedit_dirs_init ();
setup_i18n ();
- tepl_init ();
- factory = gedit_factory_new ();
- tepl_abstract_factory_set_singleton (TEPL_ABSTRACT_FACTORY (factory));
app = g_object_new (type,
"application-id", "org.gnome.gedit",
@@ -167,7 +162,6 @@
G_OBJECT (app)->ref_count);
}
- tepl_finalize ();
gedit_dirs_shutdown ();
#ifdef G_OS_WIN32
diff -Nru gedit-40.1/gedit/gedit-commands-edit.c gedit-41.0/gedit/gedit-commands-edit.c
--- gedit-40.1/gedit/gedit-commands-edit.c 2021-04-17 05:45:35.664548600 +0000
+++ gedit-41.0/gedit/gedit-commands-edit.c 2022-02-14 13:58:26.000000000 +0000
@@ -44,13 +44,13 @@
gedit_debug (DEBUG_COMMANDS);
active_view = gedit_window_get_active_view (window);
- g_return_if_fail (active_view != NULL);
+ g_return_if_fail (active_view);
active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
gtk_source_buffer_undo (active_document);
- tepl_view_scroll_to_cursor (TEPL_VIEW (active_view));
+ gedit_view_scroll_to_cursor (active_view);
gtk_widget_grab_focus (GTK_WIDGET (active_view));
}
@@ -67,13 +67,13 @@
gedit_debug (DEBUG_COMMANDS);
active_view = gedit_window_get_active_view (window);
- g_return_if_fail (active_view != NULL);
+ g_return_if_fail (active_view);
active_document = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (active_view)));
gtk_source_buffer_redo (active_document);
- tepl_view_scroll_to_cursor (TEPL_VIEW (active_view));
+ gedit_view_scroll_to_cursor (active_view);
gtk_widget_grab_focus (GTK_WIDGET (active_view));
}
@@ -89,9 +89,9 @@
gedit_debug (DEBUG_COMMANDS);
active_view = gedit_window_get_active_view (window);
- g_return_if_fail (active_view != NULL);
+ g_return_if_fail (active_view);
- tepl_view_cut_clipboard (TEPL_VIEW (active_view));
+ gedit_view_cut_clipboard (active_view);
gtk_widget_grab_focus (GTK_WIDGET (active_view));
}
@@ -107,9 +107,9 @@
gedit_debug (DEBUG_COMMANDS);
active_view = gedit_window_get_active_view (window);
- g_return_if_fail (active_view != NULL);
+ g_return_if_fail (active_view);
- tepl_view_copy_clipboard (TEPL_VIEW (active_view));
+ gedit_view_copy_clipboard (active_view);
gtk_widget_grab_focus (GTK_WIDGET (active_view));
}
@@ -125,9 +125,9 @@
gedit_debug (DEBUG_COMMANDS);
active_view = gedit_window_get_active_view (window);
- g_return_if_fail (active_view != NULL);
+ g_return_if_fail (active_view);
- tepl_view_paste_clipboard (TEPL_VIEW (active_view));
+ gedit_view_paste_clipboard (active_view);
gtk_widget_grab_focus (GTK_WIDGET (active_view));
}
@@ -143,9 +143,9 @@
gedit_debug (DEBUG_COMMANDS);
active_view = gedit_window_get_active_view (window);
- g_return_if_fail (active_view != NULL);
+ g_return_if_fail (active_view);
- tepl_view_delete_selection (TEPL_VIEW (active_view));
+ gedit_view_delete_selection (active_view);
gtk_widget_grab_focus (GTK_WIDGET (active_view));
}
@@ -161,9 +161,9 @@
gedit_debug (DEBUG_COMMANDS);
active_view = gedit_window_get_active_view (window);
- g_return_if_fail (active_view != NULL);
+ g_return_if_fail (active_view);
- tepl_view_select_all (TEPL_VIEW (active_view));
+ gedit_view_select_all (active_view);
gtk_widget_grab_focus (GTK_WIDGET (active_view));
}
diff -Nru gedit-40.1/gedit/gedit-commands-file.c gedit-41.0/gedit/gedit-commands-file.c
--- gedit-40.1/gedit/gedit-commands-file.c 2021-04-17 05:45:35.664548600 +0000
+++ gedit-41.0/gedit/gedit-commands-file.c 2022-02-14 13:58:26.000000000 +0000
@@ -27,7 +27,6 @@
#include "gedit-commands-private.h"
#include
-#include
#include "gedit-app.h"
#include "gedit-debug.h"
@@ -44,10 +43,6 @@
#include "gedit-file-chooser-open.h"
#include "gedit-close-confirmation-dialog.h"
-/* useful macro */
-#define GBOOLEAN_TO_POINTER(i) (GINT_TO_POINTER ((i) ? 2 : 1))
-#define GPOINTER_TO_BOOLEAN(i) ((gboolean) ((GPOINTER_TO_INT(i) == 2) ? TRUE : FALSE))
-
#define GEDIT_IS_CLOSING_ALL "gedit-is-closing-all"
#define GEDIT_NOTEBOOK_TO_CLOSE "gedit-notebook-to-close"
#define GEDIT_IS_QUITTING "gedit-is-quitting"
@@ -150,24 +145,26 @@
{
if (l == files)
{
- TeplView *view;
+ GeditDocument *doc;
gedit_window_set_active_tab (window, tab);
jump_to = FALSE;
- view = TEPL_VIEW (gedit_tab_get_view (tab));
+ doc = gedit_tab_get_document (tab);
if (line_pos > 0)
{
if (column_pos > 0)
{
- tepl_view_goto_line_offset (view,
- line_pos - 1,
- column_pos - 1);
+ gedit_document_goto_line_offset (doc,
+ line_pos - 1,
+ column_pos - 1);
}
else
{
- tepl_view_goto_line (view, line_pos - 1);
+ gedit_document_goto_line (doc, line_pos - 1);
}
+
+ gedit_view_scroll_to_cursor (gedit_tab_get_view (tab));
}
}
@@ -194,7 +191,7 @@
doc = gedit_tab_get_document (tab);
- if (tepl_buffer_is_untouched (TEPL_BUFFER (doc)) &&
+ if (gedit_document_is_untouched (doc) &&
gedit_tab_get_state (tab) == GEDIT_TAB_STATE_NORMAL)
{
_gedit_tab_load (tab,
@@ -513,7 +510,7 @@
* though the dialog uses wrapped text, if the name doesn't contain
* white space then the text-wrapping code is too stupid to wrap it.
*/
- name_for_display = tepl_utils_str_middle_truncate (parse_name, 50);
+ name_for_display = gedit_utils_str_middle_truncate (parse_name, 50);
g_free (parse_name);
dialog = gtk_message_dialog_new (parent,
@@ -565,7 +562,7 @@
* though the dialog uses wrapped text, if the name doesn't contain
* white space then the text-wrapping code is too stupid to wrap it.
*/
- name_for_display = tepl_utils_str_middle_truncate (parse_name, 50);
+ name_for_display = gedit_utils_str_middle_truncate (parse_name, 50);
g_free (parse_name);
if (compressed)
@@ -827,6 +824,7 @@
/* Translators: "Save As" is the title of the file chooser window. */
save_dialog = gedit_file_chooser_dialog_create (C_("window title", "Save As"),
GTK_WINDOW (window),
+ GEDIT_FILE_CHOOSER_FLAG_SAVE,
_("_Save"),
_("_Cancel"));
diff -Nru gedit-40.1/gedit/gedit-commands-search.c gedit-41.0/gedit/gedit-commands-search.c
--- gedit-40.1/gedit/gedit-commands-search.c 2021-04-17 05:45:35.724550000 +0000
+++ gedit-41.0/gedit/gedit-commands-search.c 2022-02-14 13:58:26.000000000 +0000
@@ -29,7 +29,6 @@
#include
#include
#include
-#include
#include "gedit-debug.h"
#include "gedit-statusbar.h"
@@ -132,7 +131,7 @@
gchar *truncated_text;
search_text = gedit_replace_dialog_get_search_text (replace_dialog);
- truncated_text = tepl_utils_str_end_truncate (search_text, MAX_MSG_LENGTH);
+ truncated_text = gedit_utils_str_end_truncate (search_text, MAX_MSG_LENGTH);
gedit_statusbar_flash_message (GEDIT_STATUSBAR (window->priv->statusbar),
window->priv->generic_message_cid,
@@ -188,7 +187,7 @@
&match_start,
&match_end);
- tepl_view_scroll_to_cursor (TEPL_VIEW (view));
+ gedit_view_scroll_to_cursor (view);
}
else
{
@@ -294,7 +293,7 @@
&match_start,
&match_end);
- tepl_view_scroll_to_cursor (TEPL_VIEW (view));
+ gedit_view_scroll_to_cursor (view);
}
else
{
diff -Nru gedit-40.1/gedit/gedit-commands-view.c gedit-41.0/gedit/gedit-commands-view.c
--- gedit-40.1/gedit/gedit-commands-view.c 2021-04-17 05:45:35.728550000 +0000
+++ gedit-41.0/gedit/gedit-commands-view.c 2022-02-14 13:58:26.000000000 +0000
@@ -21,11 +21,16 @@
*/
#include "config.h"
+
#include "gedit-commands.h"
#include "gedit-commands-private.h"
-#include
+
+#include
+
#include "gedit-debug.h"
#include "gedit-window.h"
+#include "gedit-highlight-mode-dialog.h"
+#include "gedit-highlight-mode-selector.h"
void
_gedit_cmd_view_focus_active (GSimpleAction *action,
@@ -121,9 +126,9 @@
}
static void
-language_activated_cb (TeplLanguageChooserDialog *dialog,
- GtkSourceLanguage *language,
- GeditWindow *window)
+language_selected_cb (GeditHighlightModeSelector *selector,
+ GtkSourceLanguage *language,
+ GeditWindow *window)
{
GeditDocument *active_document;
@@ -132,16 +137,6 @@
{
gedit_document_set_language (active_document, language);
}
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
-}
-
-static void
-language_chooser_dialog_response_after_cb (TeplLanguageChooserDialog *dialog,
- gint response_id,
- gpointer user_data)
-{
- gtk_widget_destroy (GTK_WIDGET (dialog));
}
void
@@ -150,10 +145,12 @@
gpointer user_data)
{
GeditWindow *window = GEDIT_WINDOW (user_data);
- TeplLanguageChooserDialog *dialog;
+ GeditHighlightModeDialog *dialog;
+ GeditHighlightModeSelector *selector;
GeditDocument *active_document;
- dialog = tepl_language_chooser_dialog_new (GTK_WINDOW (window));
+ dialog = GEDIT_HIGHLIGHT_MODE_DIALOG (gedit_highlight_mode_dialog_new (GTK_WINDOW (window)));
+ selector = gedit_highlight_mode_dialog_get_selector (dialog);
active_document = gedit_window_get_active_document (window);
if (active_document != NULL)
@@ -161,20 +158,15 @@
GtkSourceLanguage *language;
language = gedit_document_get_language (active_document);
- tepl_language_chooser_select_language (TEPL_LANGUAGE_CHOOSER (dialog), language);
+ gedit_highlight_mode_selector_select_language (selector, language);
}
- g_signal_connect_object (dialog,
- "language-activated",
- G_CALLBACK (language_activated_cb),
+ g_signal_connect_object (selector,
+ "language-selected",
+ G_CALLBACK (language_selected_cb),
window,
0);
- g_signal_connect_after (dialog,
- "response",
- G_CALLBACK (language_chooser_dialog_response_after_cb),
- NULL);
-
gtk_widget_show (GTK_WIDGET (dialog));
}
diff -Nru gedit-40.1/gedit/gedit-debug.c gedit-41.0/gedit/gedit-debug.c
--- gedit-40.1/gedit/gedit-debug.c 2021-04-17 05:45:35.728550000 +0000
+++ gedit-41.0/gedit/gedit-debug.c 2022-02-14 13:58:26.000000000 +0000
@@ -100,6 +100,10 @@
{
enabled_sections |= GEDIT_DEBUG_UTILS;
}
+ if (g_getenv ("GEDIT_DEBUG_METADATA") != NULL)
+ {
+ enabled_sections |= GEDIT_DEBUG_METADATA;
+ }
out:
diff -Nru gedit-40.1/gedit/gedit-debug.h gedit-41.0/gedit/gedit-debug.h
--- gedit-40.1/gedit/gedit-debug.h 2021-04-17 05:45:35.728550000 +0000
+++ gedit-41.0/gedit/gedit-debug.h 2022-02-14 13:58:26.000000000 +0000
@@ -48,6 +48,7 @@
GEDIT_DEBUG_COMMANDS = 1 << 7,
GEDIT_DEBUG_APP = 1 << 8,
GEDIT_DEBUG_UTILS = 1 << 9,
+ GEDIT_DEBUG_METADATA = 1 << 10,
} GeditDebugSection;
#define DEBUG_VIEW GEDIT_DEBUG_VIEW, __FILE__, __LINE__, G_STRFUNC
@@ -60,6 +61,7 @@
#define DEBUG_COMMANDS GEDIT_DEBUG_COMMANDS,__FILE__, __LINE__, G_STRFUNC
#define DEBUG_APP GEDIT_DEBUG_APP, __FILE__, __LINE__, G_STRFUNC
#define DEBUG_UTILS GEDIT_DEBUG_UTILS, __FILE__, __LINE__, G_STRFUNC
+#define DEBUG_METADATA GEDIT_DEBUG_METADATA,__FILE__, __LINE__, G_STRFUNC
void gedit_debug_init (void);
diff -Nru gedit-40.1/gedit/gedit-document.c gedit-41.0/gedit/gedit-document.c
--- gedit-40.1/gedit/gedit-document.c 2021-04-17 05:45:35.860552800 +0000
+++ gedit-41.0/gedit/gedit-document.c 2022-02-14 13:58:26.000000000 +0000
@@ -5,7 +5,7 @@
* Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
* Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
* Copyright (C) 2002-2005 Paolo Maggi
- * Copyright (C) 2014-2020 Sébastien Wilmet
+ * Copyright (C) 2014-2015 Sébastien Wilmet
*
* 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
@@ -22,13 +22,21 @@
*/
#include "config.h"
+
#include "gedit-document.h"
#include "gedit-document-private.h"
+
#include
#include
+
+#include "gedit-app.h"
+#include "gedit-app-private.h"
#include "gedit-settings.h"
#include "gedit-debug.h"
#include "gedit-utils.h"
+#include "gedit-metadata-manager.h"
+
+#define METADATA_QUERY "metadata::*"
#define NO_LANGUAGE_NAME "_NORMAL_"
@@ -43,7 +51,11 @@
{
GtkSourceFile *file;
- TeplMetadata *metadata;
+ GSettings *editor_settings;
+
+ gint untitled_number;
+
+ GFileInfo *metadata_info;
gchar *content_type;
@@ -54,7 +66,12 @@
*/
GtkSourceSearchContext *search_context;
+ GeditMetadataManager *metadata_manager;
+
+ guint user_action;
+
guint language_set_by_user : 1;
+ guint use_gvfs_metadata : 1;
/* The search is empty if there is no search context, or if the
* search text is empty. It is used for the sensitivity of some menu
@@ -71,9 +88,11 @@
enum
{
PROP_0,
+ PROP_SHORTNAME,
PROP_CONTENT_TYPE,
PROP_MIME_TYPE,
PROP_EMPTY_SEARCH,
+ PROP_USE_GVFS_METADATA,
LAST_PROP
};
@@ -81,6 +100,7 @@
enum
{
+ CURSOR_MOVED,
LOAD,
LOADED,
SAVE,
@@ -90,40 +110,41 @@
static guint document_signals[LAST_SIGNAL];
-G_DEFINE_TYPE_WITH_PRIVATE (GeditDocument, gedit_document, TEPL_TYPE_BUFFER)
+static GHashTable *allocated_untitled_numbers = NULL;
-static void
-load_metadata_from_metadata_manager (GeditDocument *doc)
+G_DEFINE_TYPE_WITH_PRIVATE (GeditDocument, gedit_document, GTK_SOURCE_TYPE_BUFFER)
+
+static gint
+get_untitled_number (void)
{
- GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
- GFile *location;
+ gint i = 1;
- location = gtk_source_file_get_location (priv->file);
+ if (allocated_untitled_numbers == NULL)
+ allocated_untitled_numbers = g_hash_table_new (NULL, NULL);
- if (location != NULL)
+ g_return_val_if_fail (allocated_untitled_numbers != NULL, -1);
+
+ while (TRUE)
{
- TeplMetadataManager *manager;
+ if (g_hash_table_lookup (allocated_untitled_numbers, GINT_TO_POINTER (i)) == NULL)
+ {
+ g_hash_table_insert (allocated_untitled_numbers,
+ GINT_TO_POINTER (i),
+ GINT_TO_POINTER (i));
- manager = tepl_metadata_manager_get_singleton ();
- tepl_metadata_manager_copy_from (manager, location, priv->metadata);
+ return i;
+ }
+
+ ++i;
}
}
static void
-save_metadata_into_metadata_manager (GeditDocument *doc)
+release_untitled_number (gint n)
{
- GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
- GFile *location;
-
- location = gtk_source_file_get_location (priv->file);
-
- if (location != NULL)
- {
- TeplMetadataManager *manager;
+ g_return_if_fail (allocated_untitled_numbers != NULL);
- manager = tepl_metadata_manager_get_singleton ();
- tepl_metadata_manager_merge_into (manager, location, priv->metadata);
- }
+ g_hash_table_remove (allocated_untitled_numbers, GINT_TO_POINTER (n));
}
static void
@@ -195,16 +216,17 @@
/* Metadata must be saved here and not in finalize because the language
* is gone by the time finalize runs.
*/
- if (priv->metadata != NULL)
+ if (priv->file != NULL)
{
save_metadata (doc);
- g_object_unref (priv->metadata);
- priv->metadata = NULL;
+ g_object_unref (priv->file);
+ priv->file = NULL;
}
- g_clear_object (&priv->file);
+ g_clear_object (&priv->metadata_info);
g_clear_object (&priv->search_context);
+ g_clear_object (&priv->metadata_manager);
G_OBJECT_CLASS (gedit_document_parent_class)->dispose (object);
}
@@ -212,10 +234,17 @@
static void
gedit_document_finalize (GObject *object)
{
- GeditDocumentPrivate *priv = gedit_document_get_instance_private (GEDIT_DOCUMENT (object));
+ GeditDocumentPrivate *priv;
gedit_debug (DEBUG_DOCUMENT);
+ priv = gedit_document_get_instance_private (GEDIT_DOCUMENT (object));
+
+ if (priv->untitled_number > 0)
+ {
+ release_untitled_number (priv->untitled_number);
+ }
+
g_free (priv->content_type);
if (priv->time_of_last_save_or_load != NULL)
@@ -239,6 +268,10 @@
switch (prop_id)
{
+ case PROP_SHORTNAME:
+ g_value_take_string (value, gedit_document_get_short_name_for_display (doc));
+ break;
+
case PROP_CONTENT_TYPE:
g_value_take_string (value, gedit_document_get_content_type (doc));
break;
@@ -251,6 +284,10 @@
g_value_set_boolean (value, priv->empty_search);
break;
+ case PROP_USE_GVFS_METADATA:
+ g_value_set_boolean (value, priv->use_gvfs_metadata);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -264,6 +301,7 @@
GParamSpec *pspec)
{
GeditDocument *doc = GEDIT_DOCUMENT (object);
+ GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
switch (prop_id)
{
@@ -271,6 +309,10 @@
set_content_type (doc, g_value_get_string (value));
break;
+ case PROP_USE_GVFS_METADATA:
+ priv->use_gvfs_metadata = g_value_get_boolean (value);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -278,15 +320,86 @@
}
static void
+gedit_document_begin_user_action (GtkTextBuffer *buffer)
+{
+ GeditDocumentPrivate *priv;
+
+ priv = gedit_document_get_instance_private (GEDIT_DOCUMENT (buffer));
+
+ ++priv->user_action;
+
+ if (GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->begin_user_action != NULL)
+ {
+ GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->begin_user_action (buffer);
+ }
+}
+
+static void
+gedit_document_end_user_action (GtkTextBuffer *buffer)
+{
+ GeditDocumentPrivate *priv;
+
+ priv = gedit_document_get_instance_private (GEDIT_DOCUMENT (buffer));
+
+ --priv->user_action;
+
+ if (GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->end_user_action != NULL)
+ {
+ GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->end_user_action (buffer);
+ }
+}
+
+static void
+gedit_document_mark_set (GtkTextBuffer *buffer,
+ const GtkTextIter *iter,
+ GtkTextMark *mark)
+{
+ GeditDocument *doc = GEDIT_DOCUMENT (buffer);
+ GeditDocumentPrivate *priv;
+
+ priv = gedit_document_get_instance_private (doc);
+
+ if (GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->mark_set != NULL)
+ {
+ GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->mark_set (buffer, iter, mark);
+ }
+
+ if (mark == gtk_text_buffer_get_insert (buffer) && (priv->user_action == 0))
+ {
+ g_signal_emit (doc, document_signals[CURSOR_MOVED], 0);
+ }
+}
+
+static void
+gedit_document_changed (GtkTextBuffer *buffer)
+{
+ g_signal_emit (GEDIT_DOCUMENT (buffer), document_signals[CURSOR_MOVED], 0);
+
+ GTK_TEXT_BUFFER_CLASS (gedit_document_parent_class)->changed (buffer);
+}
+
+static void
gedit_document_constructed (GObject *object)
{
GeditDocument *doc = GEDIT_DOCUMENT (object);
+ GeditDocumentPrivate *priv;
GeditSettings *settings;
GSettings *editor_settings;
+ priv = gedit_document_get_instance_private (doc);
+
settings = _gedit_settings_get_singleton ();
editor_settings = _gedit_settings_peek_editor_settings (settings);
+ if (!priv->use_gvfs_metadata)
+ {
+ GeditMetadataManager *metadata_manager;
+
+ metadata_manager = _gedit_app_get_metadata_manager (GEDIT_APP (g_application_get_default ()));
+ g_assert (GEDIT_IS_METADATA_MANAGER (metadata_manager));
+ priv->metadata_manager = g_object_ref (metadata_manager);
+ }
+
/* Bind construct properties. */
g_settings_bind (editor_settings, GEDIT_SETTINGS_ENSURE_TRAILING_NEWLINE,
doc, "implicit-trailing-newline",
@@ -299,6 +412,7 @@
gedit_document_class_init (GeditDocumentClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkTextBufferClass *buf_class = GTK_TEXT_BUFFER_CLASS (klass);
object_class->dispose = gedit_document_dispose;
object_class->finalize = gedit_document_finalize;
@@ -306,10 +420,27 @@
object_class->set_property = gedit_document_set_property;
object_class->constructed = gedit_document_constructed;
+ buf_class->begin_user_action = gedit_document_begin_user_action;
+ buf_class->end_user_action = gedit_document_end_user_action;
+ buf_class->mark_set = gedit_document_mark_set;
+ buf_class->changed = gedit_document_changed;
+
klass->loaded = gedit_document_loaded_real;
klass->saved = gedit_document_saved_real;
/**
+ * GeditDocument:shortname:
+ *
+ * The document's short name.
+ */
+ properties[PROP_SHORTNAME] =
+ g_param_spec_string ("shortname",
+ "Short Name",
+ "The document's short name",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
* GeditDocument:content-type:
*
* The document's content type.
@@ -348,8 +479,44 @@
TRUE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ /**
+ * GeditDocument:use-gvfs-metadata:
+ *
+ * Whether to use GVFS metadata. If %FALSE, use the gedit metadata
+ * manager that stores the metadata in an XML file in the user cache
+ * directory.
+ *
+ *
+ * The property is used internally by gedit. It must not be used in a
+ * gedit plugin. The property can be modified or removed at any time.
+ *
+ */
+ properties[PROP_USE_GVFS_METADATA] =
+ g_param_spec_boolean ("use-gvfs-metadata",
+ "Use GVFS metadata",
+ "",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, LAST_PROP, properties);
+ /* This signal is used to update the cursor position in the statusbar,
+ * it's emitted either when the insert mark is moved explicitely or
+ * when the buffer changes (insert/delete).
+ * FIXME When the replace_all was implemented in gedit, this signal was
+ * not emitted during the replace_all to improve performance. Now the
+ * replace_all is implemented in GtkSourceView, so the signal is
+ * emitted.
+ */
+ document_signals[CURSOR_MOVED] =
+ g_signal_new ("cursor-moved",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GeditDocumentClass, cursor_moved),
+ NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 0);
+
/**
* GeditDocument::load:
* @document: the #GeditDocument.
@@ -632,20 +799,79 @@
GParamSpec *pspec,
GeditDocument *doc)
{
+ GeditDocumentPrivate *priv;
+ GFile *location;
+
gedit_debug (DEBUG_DOCUMENT);
- load_metadata_from_metadata_manager (doc);
+
+ priv = gedit_document_get_instance_private (doc);
+
+ location = gtk_source_file_get_location (file);
+
+ if (location != NULL && priv->untitled_number > 0)
+ {
+ release_untitled_number (priv->untitled_number);
+ priv->untitled_number = 0;
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_SHORTNAME]);
+
+ /* Load metadata for this location: we load sync since metadata is
+ * always local so it should be fast and we need the information
+ * right after the location was set.
+ * TODO: do async I/O for the metadata.
+ */
+ if (priv->use_gvfs_metadata && location != NULL)
+ {
+ GError *error = NULL;
+
+ if (priv->metadata_info != NULL)
+ {
+ g_object_unref (priv->metadata_info);
+ }
+
+ priv->metadata_info = g_file_query_info (location,
+ METADATA_QUERY,
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ &error);
+
+ if (error != NULL)
+ {
+ /* Do not complain about metadata if we are opening a
+ * non existing file.
+ */
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_ISDIR) &&
+ !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOTDIR) &&
+ !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_warning ("%s", error->message);
+ }
+
+ g_error_free (error);
+ }
+
+ if (priv->metadata_info == NULL)
+ {
+ priv->metadata_info = g_file_info_new ();
+ }
+ }
}
static void
gedit_document_init (GeditDocument *doc)
{
GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
- TeplFile *tepl_file;
GeditSettings *settings;
GSettings *editor_settings;
gedit_debug (DEBUG_DOCUMENT);
+ settings = _gedit_settings_get_singleton ();
+ editor_settings = _gedit_settings_peek_editor_settings (settings);
+
+ priv->untitled_number = get_untitled_number ();
priv->content_type = get_default_content_type ();
priv->language_set_by_user = FALSE;
priv->empty_search = TRUE;
@@ -653,13 +879,7 @@
update_time_of_last_save_or_load (doc);
priv->file = gtk_source_file_new ();
- tepl_file = tepl_buffer_get_file (TEPL_BUFFER (doc));
-
- g_object_bind_property (priv->file, "location",
- tepl_file, "location",
- G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
-
- priv->metadata = tepl_metadata_new ();
+ priv->metadata_info = g_file_info_new ();
g_signal_connect_object (priv->file,
"notify::location",
@@ -667,9 +887,6 @@
doc,
0);
- settings = _gedit_settings_get_singleton ();
- editor_settings = _gedit_settings_peek_editor_settings (settings);
-
g_settings_bind (editor_settings, GEDIT_SETTINGS_MAX_UNDO_ACTIONS,
doc, "max-undo-levels",
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
@@ -699,7 +916,17 @@
GeditDocument *
gedit_document_new (void)
{
- return g_object_new (GEDIT_TYPE_DOCUMENT, NULL);
+ gboolean use_gvfs_metadata;
+
+#ifdef ENABLE_GVFS_METADATA
+ use_gvfs_metadata = TRUE;
+#else
+ use_gvfs_metadata = FALSE;
+#endif
+
+ return g_object_new (GEDIT_TYPE_DOCUMENT,
+ "use-gvfs-metadata", use_gvfs_metadata,
+ NULL);
}
static gchar *
@@ -814,17 +1041,19 @@
gchar *
_gedit_document_get_uri_for_display (GeditDocument *doc)
{
- TeplFile *file;
+ GeditDocumentPrivate *priv;
GFile *location;
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), g_strdup (""));
- file = tepl_buffer_get_file (TEPL_BUFFER (doc));
- location = tepl_file_get_location (file);
+ priv = gedit_document_get_instance_private (doc);
+
+ location = gtk_source_file_get_location (priv->file);
if (location == NULL)
{
- return tepl_file_get_short_name (file);
+ return g_strdup_printf (_("Untitled Document %d"),
+ priv->untitled_number);
}
else
{
@@ -841,12 +1070,24 @@
gchar *
gedit_document_get_short_name_for_display (GeditDocument *doc)
{
- TeplFile *file;
+ GeditDocumentPrivate *priv;
+ GFile *location;
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), g_strdup (""));
- file = tepl_buffer_get_file (TEPL_BUFFER (doc));
- return tepl_file_get_short_name (file);
+ priv = gedit_document_get_instance_private (doc);
+
+ location = gtk_source_file_get_location (priv->file);
+
+ if (location == NULL)
+ {
+ return g_strdup_printf (_("Untitled Document %d"),
+ priv->untitled_number);
+ }
+ else
+ {
+ return gedit_utils_basename_for_display (location);
+ }
}
gchar *
@@ -1033,14 +1274,30 @@
}
gboolean
+gedit_document_is_untouched (GeditDocument *doc)
+{
+ GeditDocumentPrivate *priv;
+ GFile *location;
+
+ g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), TRUE);
+
+ priv = gedit_document_get_instance_private (doc);
+
+ location = gtk_source_file_get_location (priv->file);
+
+ return location == NULL && !gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc));
+}
+
+gboolean
gedit_document_is_untitled (GeditDocument *doc)
{
- TeplFile *file;
+ GeditDocumentPrivate *priv;
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), TRUE);
- file = tepl_buffer_get_file (TEPL_BUFFER (doc));
- return tepl_file_get_location (file) == NULL;
+ priv = gedit_document_get_instance_private (doc);
+
+ return gtk_source_file_get_location (priv->file) == NULL;
}
/*
@@ -1072,6 +1329,51 @@
return (externally_modified || deleted) && !priv->create;
}
+/* If @line is bigger than the lines of the document, the cursor is moved
+ * to the last line and FALSE is returned.
+ */
+gboolean
+gedit_document_goto_line (GeditDocument *doc,
+ gint line)
+{
+ GtkTextIter iter;
+
+ gedit_debug (DEBUG_DOCUMENT);
+
+ g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
+ g_return_val_if_fail (line >= -1, FALSE);
+
+ gtk_text_buffer_get_iter_at_line (GTK_TEXT_BUFFER (doc),
+ &iter,
+ line);
+
+ gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
+
+ return gtk_text_iter_get_line (&iter) == line;
+}
+
+gboolean
+gedit_document_goto_line_offset (GeditDocument *doc,
+ gint line,
+ gint line_offset)
+{
+ GtkTextIter iter;
+
+ g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
+ g_return_val_if_fail (line >= -1, FALSE);
+ g_return_val_if_fail (line_offset >= -1, FALSE);
+
+ gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER (doc),
+ &iter,
+ line,
+ line_offset);
+
+ gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), &iter);
+
+ return (gtk_text_iter_get_line (&iter) == line &&
+ gtk_text_iter_get_line_offset (&iter) == line_offset);
+}
+
/**
* gedit_document_set_language:
* @doc:
@@ -1130,6 +1432,64 @@
return n_microseconds / (1000 * 1000);
}
+static gchar *
+get_metadata_from_metadata_manager (GeditDocument *doc,
+ const gchar *key)
+{
+ GeditDocumentPrivate *priv;
+ GFile *location;
+
+ priv = gedit_document_get_instance_private (doc);
+
+ location = gtk_source_file_get_location (priv->file);
+
+ if (location != NULL)
+ {
+ return gedit_metadata_manager_get (priv->metadata_manager, location, key);
+ }
+
+ return NULL;
+}
+
+static gchar *
+get_metadata_from_gvfs (GeditDocument *doc,
+ const gchar *key)
+{
+ GeditDocumentPrivate *priv;
+
+ priv = gedit_document_get_instance_private (doc);
+
+ if (priv->metadata_info != NULL &&
+ g_file_info_has_attribute (priv->metadata_info, key) &&
+ g_file_info_get_attribute_type (priv->metadata_info, key) == G_FILE_ATTRIBUTE_TYPE_STRING)
+ {
+ return g_strdup (g_file_info_get_attribute_string (priv->metadata_info, key));
+ }
+
+ return NULL;
+}
+
+static void
+set_gvfs_metadata (GFileInfo *info,
+ const gchar *key,
+ const gchar *value)
+{
+ g_return_if_fail (G_IS_FILE_INFO (info));
+
+ if (value != NULL)
+ {
+ g_file_info_set_attribute_string (info, key, value);
+ }
+ else
+ {
+ /* Unset the key */
+ g_file_info_set_attribute (info,
+ key,
+ G_FILE_ATTRIBUTE_TYPE_INVALID,
+ NULL);
+ }
+}
+
/**
* gedit_document_get_metadata:
* @doc: a #GeditDocument
@@ -1150,12 +1510,12 @@
priv = gedit_document_get_instance_private (doc);
- if (priv->metadata == NULL)
+ if (priv->use_gvfs_metadata)
{
- return NULL;
+ return get_metadata_from_gvfs (doc, key);
}
- return tepl_metadata_get (priv->metadata, key);
+ return get_metadata_from_metadata_manager (doc, key);
}
/**
@@ -1173,30 +1533,84 @@
...)
{
GeditDocumentPrivate *priv;
- va_list var_args;
+ GFile *location;
const gchar *key;
+ va_list var_args;
+ GFileInfo *info = NULL;
g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
g_return_if_fail (first_key != NULL);
priv = gedit_document_get_instance_private (doc);
- if (priv->metadata == NULL)
+ location = gtk_source_file_get_location (priv->file);
+
+ /* With the metadata manager, can't set metadata for untitled documents.
+ * With GVFS metadata, if the location is NULL the metadata is stored in
+ * priv->metadata_info, so that it can be saved later if the document is
+ * saved.
+ */
+ if (!priv->use_gvfs_metadata && location == NULL)
{
return;
}
+ if (priv->use_gvfs_metadata)
+ {
+ info = g_file_info_new ();
+ }
+
va_start (var_args, first_key);
- for (key = first_key; key != NULL; key = va_arg (var_args, const gchar *))
+ for (key = first_key; key; key = va_arg (var_args, const gchar *))
{
const gchar *value = va_arg (var_args, const gchar *);
- tepl_metadata_set (priv->metadata, key, value);
+
+ if (priv->use_gvfs_metadata)
+ {
+ set_gvfs_metadata (info, key, value);
+ set_gvfs_metadata (priv->metadata_info, key, value);
+ }
+ else
+ {
+ gedit_metadata_manager_set (priv->metadata_manager, location, key, value);
+ }
}
va_end (var_args);
- save_metadata_into_metadata_manager (doc);
+ if (priv->use_gvfs_metadata && location != NULL)
+ {
+ GError *error = NULL;
+
+ /* We save synchronously since metadata is always local so it
+ * should be fast. Moreover this function can be called on
+ * application shutdown, when the main loop has already exited,
+ * so an async operation would not terminate.
+ * https://bugzilla.gnome.org/show_bug.cgi?id=736591
+ */
+ g_file_set_attributes_from_info (location,
+ info,
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ &error);
+
+ if (error != NULL)
+ {
+ /* Do not complain about metadata if we are closing a
+ * document for a non existing file.
+ */
+ if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_warning ("Set document metadata failed: %s", error->message);
+ }
+
+ g_error_free (error);
+ }
+ }
+
+ g_clear_object (&info);
}
static void
diff -Nru gedit-40.1/gedit/gedit-document.h gedit-41.0/gedit/gedit-document.h
--- gedit-40.1/gedit/gedit-document.h 2021-04-17 05:45:35.860552800 +0000
+++ gedit-41.0/gedit/gedit-document.h 2022-02-14 13:58:26.000000000 +0000
@@ -5,7 +5,7 @@
* Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
* Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
* Copyright (C) 2002-2005 Paolo Maggi
- * Copyright (C) 2014-2020 Sébastien Wilmet
+ * Copyright (C) 2014 Sébastien Wilmet
*
* 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
@@ -24,19 +24,20 @@
#ifndef GEDIT_DOCUMENT_H
#define GEDIT_DOCUMENT_H
-#include
+#include
G_BEGIN_DECLS
#define GEDIT_TYPE_DOCUMENT (gedit_document_get_type())
-G_DECLARE_DERIVABLE_TYPE (GeditDocument, gedit_document, GEDIT, DOCUMENT, TeplBuffer)
+G_DECLARE_DERIVABLE_TYPE (GeditDocument, gedit_document, GEDIT, DOCUMENT, GtkSourceBuffer)
struct _GeditDocumentClass
{
- TeplBufferClass parent_class;
+ GtkSourceBufferClass parent_class;
/* Signals */
+ void (* cursor_moved) (GeditDocument *document);
void (* load) (GeditDocument *document);
@@ -57,8 +58,17 @@
gchar *gedit_document_get_mime_type (GeditDocument *doc);
+gboolean gedit_document_is_untouched (GeditDocument *doc);
+
gboolean gedit_document_is_untitled (GeditDocument *doc);
+gboolean gedit_document_goto_line (GeditDocument *doc,
+ gint line);
+
+gboolean gedit_document_goto_line_offset (GeditDocument *doc,
+ gint line,
+ gint line_offset);
+
void gedit_document_set_language (GeditDocument *doc,
GtkSourceLanguage *lang);
GtkSourceLanguage
diff -Nru gedit-40.1/gedit/gedit-document-private.h gedit-41.0/gedit/gedit-document-private.h
--- gedit-40.1/gedit/gedit-document-private.h 2021-04-17 05:45:35.728550000 +0000
+++ gedit-41.0/gedit/gedit-document-private.h 2022-02-14 13:58:26.000000000 +0000
@@ -28,9 +28,15 @@
G_BEGIN_DECLS
-#define GEDIT_METADATA_ATTRIBUTE_POSITION "gedit-position"
-#define GEDIT_METADATA_ATTRIBUTE_ENCODING "gedit-encoding"
-#define GEDIT_METADATA_ATTRIBUTE_LANGUAGE "gedit-language"
+#ifdef G_OS_WIN32
+#define GEDIT_METADATA_ATTRIBUTE_POSITION "position"
+#define GEDIT_METADATA_ATTRIBUTE_ENCODING "encoding"
+#define GEDIT_METADATA_ATTRIBUTE_LANGUAGE "language"
+#else
+#define GEDIT_METADATA_ATTRIBUTE_POSITION "metadata::gedit-position"
+#define GEDIT_METADATA_ATTRIBUTE_ENCODING "metadata::gedit-encoding"
+#define GEDIT_METADATA_ATTRIBUTE_LANGUAGE "metadata::gedit-language"
+#endif
G_GNUC_INTERNAL
glong _gedit_document_get_seconds_since_last_save_or_load (GeditDocument *doc);
diff -Nru gedit-40.1/gedit/gedit-documents-panel.c gedit-41.0/gedit/gedit-documents-panel.c
--- gedit-40.1/gedit/gedit-documents-panel.c 2021-04-17 05:45:35.892553600 +0000
+++ gedit-41.0/gedit/gedit-documents-panel.c 2022-02-14 13:58:26.000000000 +0000
@@ -23,7 +23,6 @@
#include "gedit-documents-panel.h"
#include
-#include
#include "gedit-debug.h"
#include "gedit-document.h"
@@ -447,7 +446,7 @@
name = gedit_document_get_short_name_for_display (doc);
/* Truncate the name so it doesn't get insanely wide. */
- docname = tepl_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
+ docname = gedit_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
g_free (name);
diff -Nru gedit-40.1/gedit/gedit-factory.c gedit-41.0/gedit/gedit-factory.c
--- gedit-40.1/gedit/gedit-factory.c 2021-04-17 05:45:35.892553600 +0000
+++ gedit-41.0/gedit/gedit-factory.c 1970-01-01 00:00:00.000000000 +0000
@@ -1,50 +0,0 @@
-/*
- * This file is part of gedit
- *
- * Copyright (C) 2020 Sébastien Wilmet
- *
- * 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 "gedit-factory.h"
-#include "gedit-dirs.h"
-
-G_DEFINE_TYPE (GeditFactory, gedit_factory, TEPL_TYPE_ABSTRACT_FACTORY)
-
-static GFile *
-gedit_factory_create_metadata_manager_file (TeplAbstractFactory *factory)
-{
- return g_file_new_build_filename (gedit_dirs_get_user_data_dir (),
- "gedit-metadata.xml",
- NULL);
-}
-
-static void
-gedit_factory_class_init (GeditFactoryClass *klass)
-{
- TeplAbstractFactoryClass *factory_class = TEPL_ABSTRACT_FACTORY_CLASS (klass);
-
- factory_class->create_metadata_manager_file = gedit_factory_create_metadata_manager_file;
-}
-
-static void
-gedit_factory_init (GeditFactory *factory)
-{
-}
-
-GeditFactory *
-gedit_factory_new (void)
-{
- return g_object_new (GEDIT_TYPE_FACTORY, NULL);
-}
diff -Nru gedit-40.1/gedit/gedit-factory.h gedit-41.0/gedit/gedit-factory.h
--- gedit-40.1/gedit/gedit-factory.h 2021-04-17 05:45:35.892553600 +0000
+++ gedit-41.0/gedit/gedit-factory.h 1970-01-01 00:00:00.000000000 +0000
@@ -1,53 +0,0 @@
-/*
- * This file is part of gedit
- *
- * Copyright (C) 2020 Sébastien Wilmet
- *
- * 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 GEDIT_FACTORY_H
-#define GEDIT_FACTORY_H
-
-#include
-
-G_BEGIN_DECLS
-
-#define GEDIT_TYPE_FACTORY (gedit_factory_get_type ())
-#define GEDIT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_FACTORY, GeditFactory))
-#define GEDIT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_FACTORY, GeditFactoryClass))
-#define GEDIT_IS_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_FACTORY))
-#define GEDIT_IS_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_FACTORY))
-#define GEDIT_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_FACTORY, GeditFactoryClass))
-
-typedef struct _GeditFactory GeditFactory;
-typedef struct _GeditFactoryClass GeditFactoryClass;
-
-struct _GeditFactory
-{
- TeplAbstractFactory parent;
-};
-
-struct _GeditFactoryClass
-{
- TeplAbstractFactoryClass parent_class;
-};
-
-GType gedit_factory_get_type (void);
-
-GeditFactory * gedit_factory_new (void);
-
-G_END_DECLS
-
-#endif /* GEDIT_FACTORY_H */
diff -Nru gedit-40.1/gedit/gedit-file-chooser-dialog.c gedit-41.0/gedit/gedit-file-chooser-dialog.c
--- gedit-40.1/gedit/gedit-file-chooser-dialog.c 2021-04-17 05:45:36.012556000 +0000
+++ gedit-41.0/gedit/gedit-file-chooser-dialog.c 2022-02-14 13:58:26.000000000 +0000
@@ -62,13 +62,15 @@
}
GeditFileChooserDialog *
-gedit_file_chooser_dialog_create (const gchar *title,
- GtkWindow *parent,
- const gchar *accept_label,
- const gchar *cancel_label)
+gedit_file_chooser_dialog_create (const gchar *title,
+ GtkWindow *parent,
+ GeditFileChooserFlags flags,
+ const gchar *accept_label,
+ const gchar *cancel_label)
{
return gedit_file_chooser_dialog_gtk_create (title,
parent,
+ flags,
accept_label,
cancel_label);
}
@@ -212,6 +214,19 @@
}
void
+gedit_file_chooser_dialog_hide (GeditFileChooserDialog *dialog)
+{
+ GeditFileChooserDialogInterface *iface;
+
+ g_return_if_fail (GEDIT_IS_FILE_CHOOSER_DIALOG (dialog));
+
+ iface = GEDIT_FILE_CHOOSER_DIALOG_GET_IFACE (dialog);
+ g_return_if_fail (iface->hide != NULL);
+
+ iface->hide (dialog);
+}
+
+void
gedit_file_chooser_dialog_destroy (GeditFileChooserDialog *dialog)
{
GeditFileChooserDialogInterface *iface;
@@ -255,4 +270,21 @@
return NULL;
}
+void
+gedit_file_chooser_dialog_add_pattern_filter (GeditFileChooserDialog *dialog,
+ const gchar *name,
+ const gchar *pattern)
+{
+ GeditFileChooserDialogInterface *iface;
+
+ g_return_if_fail (GEDIT_IS_FILE_CHOOSER_DIALOG (dialog));
+
+ iface = GEDIT_FILE_CHOOSER_DIALOG_GET_IFACE (dialog);
+
+ if (iface->add_pattern_filter)
+ {
+ iface->add_pattern_filter (dialog, name, pattern);
+ }
+}
+
/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-file-chooser-dialog-gtk.c gedit-41.0/gedit/gedit-file-chooser-dialog-gtk.c
--- gedit-40.1/gedit/gedit-file-chooser-dialog-gtk.c 2021-04-17 05:45:35.892553600 +0000
+++ gedit-41.0/gedit/gedit-file-chooser-dialog-gtk.c 2022-02-14 13:58:26.000000000 +0000
@@ -193,6 +193,12 @@
}
static void
+chooser_hide (GeditFileChooserDialog *dialog)
+{
+ gtk_widget_hide (GTK_WIDGET (dialog));
+}
+
+static void
chooser_destroy (GeditFileChooserDialog *dialog)
{
gtk_widget_destroy (GTK_WIDGET (dialog));
@@ -212,6 +218,26 @@
}
static void
+chooser_add_pattern_filter (GeditFileChooserDialog *dialog,
+ const gchar *name,
+ const gchar *pattern)
+{
+ GtkFileFilter *filter;
+
+ filter = gtk_file_filter_new ();
+
+ gtk_file_filter_set_name (filter, name);
+ gtk_file_filter_add_pattern (filter, pattern);
+
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ if (gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (dialog)) == NULL)
+ {
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filter);
+ }
+}
+
+static void
gedit_file_chooser_dialog_gtk_chooser_init (gpointer g_iface,
gpointer iface_data)
{
@@ -229,9 +255,11 @@
iface->get_file = chooser_get_file;
iface->set_do_overwrite_confirmation = chooser_set_do_overwrite_confirmation;
iface->show = chooser_show;
+ iface->hide = chooser_hide;
iface->destroy = chooser_destroy;
iface->set_modal = chooser_set_modal;
iface->get_window = chooser_get_window;
+ iface->add_pattern_filter = chooser_add_pattern_filter;
}
static void
@@ -253,7 +281,8 @@
}
static void
-create_option_menu (GeditFileChooserDialogGtk *dialog)
+create_option_menu (GeditFileChooserDialogGtk *dialog,
+ GeditFileChooserFlags flags)
{
GtkWidget *label;
GtkWidget *menu;
@@ -262,7 +291,7 @@
label = gtk_label_new_with_mnemonic (_("C_haracter Encoding:"));
gtk_widget_set_halign (label, GTK_ALIGN_START);
- save_mode = TRUE;
+ save_mode = (flags & GEDIT_FILE_CHOOSER_FLAG_SAVE) != 0;
menu = gedit_encodings_combo_box_new (save_mode);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), menu);
@@ -374,13 +403,18 @@
}
static void
-create_extra_widget (GeditFileChooserDialogGtk *dialog)
+create_extra_widget (GeditFileChooserDialogGtk *dialog,
+ GeditFileChooserFlags flags)
{
dialog->extra_widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_widget_show (dialog->extra_widget);
- create_option_menu (dialog);
- create_newline_combo (dialog);
+ create_option_menu (dialog, flags);
+
+ if ((flags & GEDIT_FILE_CHOOSER_FLAG_SAVE) != 0)
+ {
+ create_newline_combo (dialog);
+ }
gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), dialog->extra_widget);
}
@@ -421,21 +455,35 @@
}
GeditFileChooserDialog *
-gedit_file_chooser_dialog_gtk_create (const gchar *title,
- GtkWindow *parent,
- const gchar *accept_label,
- const gchar *cancel_label)
+gedit_file_chooser_dialog_gtk_create (const gchar *title,
+ GtkWindow *parent,
+ GeditFileChooserFlags flags,
+ const gchar *accept_label,
+ const gchar *cancel_label)
{
GeditFileChooserDialogGtk *result;
+ GtkFileChooserAction action;
+ gboolean select_multiple;
+
+ if ((flags & GEDIT_FILE_CHOOSER_FLAG_SAVE) != 0)
+ {
+ action = GTK_FILE_CHOOSER_ACTION_SAVE;
+ select_multiple = FALSE;
+ }
+ else
+ {
+ action = GTK_FILE_CHOOSER_ACTION_OPEN;
+ select_multiple = TRUE;
+ }
result = g_object_new (GEDIT_TYPE_FILE_CHOOSER_DIALOG_GTK,
"title", title,
"local-only", FALSE,
- "action", GTK_FILE_CHOOSER_ACTION_SAVE,
- "select-multiple", FALSE,
+ "action", action,
+ "select-multiple", select_multiple,
NULL);
- create_extra_widget (result);
+ create_extra_widget (result, flags);
g_signal_connect (result,
"notify::action",
diff -Nru gedit-40.1/gedit/gedit-file-chooser-dialog-gtk.h gedit-41.0/gedit/gedit-file-chooser-dialog-gtk.h
--- gedit-40.1/gedit/gedit-file-chooser-dialog-gtk.h 2021-04-17 05:45:35.892553600 +0000
+++ gedit-41.0/gedit/gedit-file-chooser-dialog-gtk.h 2022-02-14 13:58:26.000000000 +0000
@@ -33,10 +33,11 @@
GEDIT, FILE_CHOOSER_DIALOG_GTK,
GtkFileChooserDialog)
-GeditFileChooserDialog * gedit_file_chooser_dialog_gtk_create (const gchar *title,
- GtkWindow *parent,
- const gchar *accept_label,
- const gchar *cancel_label);
+GeditFileChooserDialog * gedit_file_chooser_dialog_gtk_create (const gchar *title,
+ GtkWindow *parent,
+ GeditFileChooserFlags flags,
+ const gchar *accept_label,
+ const gchar *cancel_label);
G_END_DECLS
diff -Nru gedit-40.1/gedit/gedit-file-chooser-dialog.h gedit-41.0/gedit/gedit-file-chooser-dialog.h
--- gedit-40.1/gedit/gedit-file-chooser-dialog.h 2021-04-17 05:45:36.012556000 +0000
+++ gedit-41.0/gedit/gedit-file-chooser-dialog.h 2022-02-14 13:58:26.000000000 +0000
@@ -64,6 +64,7 @@
gboolean overwrite_confirmation);
void (*show) (GeditFileChooserDialog *dialog);
+ void (*hide) (GeditFileChooserDialog *dialog);
void (*destroy) (GeditFileChooserDialog *dialog);
@@ -72,11 +73,22 @@
GtkWindow *
(*get_window) (GeditFileChooserDialog *dialog);
+
+ void (*add_pattern_filter) (GeditFileChooserDialog *dilaog,
+ const gchar *name,
+ const gchar *pattern);
};
+typedef enum
+{
+ GEDIT_FILE_CHOOSER_FLAG_SAVE = 1 << 0,
+ GEDIT_FILE_CHOOSER_FLAG_OPEN = 1 << 1
+} GeditFileChooserFlags;
+
GeditFileChooserDialog *
gedit_file_chooser_dialog_create (const gchar *title,
GtkWindow *parent,
+ GeditFileChooserFlags flags,
const gchar *accept_label,
const gchar *cancel_label);
@@ -110,12 +122,17 @@
gboolean overwrite_confirmation);
void gedit_file_chooser_dialog_show (GeditFileChooserDialog *dialog);
+void gedit_file_chooser_dialog_hide (GeditFileChooserDialog *dialog);
void gedit_file_chooser_dialog_set_modal (GeditFileChooserDialog *dialog,
gboolean is_modal);
GtkWindow *gedit_file_chooser_dialog_get_window (GeditFileChooserDialog *dialog);
+void gedit_file_chooser_dialog_add_pattern_filter (GeditFileChooserDialog *dialog,
+ const gchar *name,
+ const gchar *pattern);
+
G_END_DECLS
#endif /* GEDIT_FILE_CHOOSER_DIALOG_H */
diff -Nru gedit-40.1/gedit/gedit-highlight-mode-dialog.c gedit-41.0/gedit/gedit-highlight-mode-dialog.c
--- gedit-40.1/gedit/gedit-highlight-mode-dialog.c 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-highlight-mode-dialog.c 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,102 @@
+/*
+ * gedit-highlight-mode-dialog.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+#include "gedit-highlight-mode-dialog.h"
+
+struct _GeditHighlightModeDialog
+{
+ GtkDialog parent_instance;
+
+ GeditHighlightModeSelector *selector;
+ gulong on_language_selected_id;
+};
+
+G_DEFINE_TYPE (GeditHighlightModeDialog, gedit_highlight_mode_dialog, GTK_TYPE_DIALOG)
+
+static void
+gedit_highlight_mode_dialog_response (GtkDialog *dialog,
+ gint response_id)
+{
+ GeditHighlightModeDialog *dlg = GEDIT_HIGHLIGHT_MODE_DIALOG (dialog);
+
+ if (response_id == GTK_RESPONSE_OK)
+ {
+ g_signal_handler_block (dlg->selector, dlg->on_language_selected_id);
+ gedit_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 (GeditHighlightModeSelector *sel,
+ GtkSourceLanguage *language,
+ GeditHighlightModeDialog *dlg)
+{
+ g_signal_handler_block (dlg->selector, dlg->on_language_selected_id);
+ gedit_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
+gedit_highlight_mode_dialog_class_init (GeditHighlightModeDialogClass *klass)
+{
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkDialogClass *dialog_class = GTK_DIALOG_CLASS (klass);
+
+ dialog_class->response = gedit_highlight_mode_dialog_response;
+
+ /* Bind class to template */
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/gedit/ui/gedit-highlight-mode-dialog.ui");
+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeDialog, selector);
+}
+
+static void
+gedit_highlight_mode_dialog_init (GeditHighlightModeDialog *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 *
+gedit_highlight_mode_dialog_new (GtkWindow *parent)
+{
+ return GTK_WIDGET (g_object_new (GEDIT_TYPE_HIGHLIGHT_MODE_DIALOG,
+ "transient-for", parent,
+ "use-header-bar", TRUE,
+ NULL));
+}
+
+GeditHighlightModeSelector *
+gedit_highlight_mode_dialog_get_selector (GeditHighlightModeDialog *dlg)
+{
+ g_return_val_if_fail (GEDIT_IS_HIGHLIGHT_MODE_DIALOG (dlg), NULL);
+
+ return dlg->selector;
+}
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-highlight-mode-dialog.h gedit-41.0/gedit/gedit-highlight-mode-dialog.h
--- gedit-40.1/gedit/gedit-highlight-mode-dialog.h 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-highlight-mode-dialog.h 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,41 @@
+/*
+ * gedit-highlight-mode-dialog.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+
+#ifndef GEDIT_HIGHLIGHT_MODE_DIALOG_H
+#define GEDIT_HIGHLIGHT_MODE_DIALOG_H
+
+#include "gedit-highlight-mode-selector.h"
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_HIGHLIGHT_MODE_DIALOG (gedit_highlight_mode_dialog_get_type ())
+
+G_DECLARE_FINAL_TYPE (GeditHighlightModeDialog, gedit_highlight_mode_dialog, GEDIT, HIGHLIGHT_MODE_DIALOG, GtkDialog)
+
+GtkWidget *gedit_highlight_mode_dialog_new (GtkWindow *parent);
+
+GeditHighlightModeSelector *gedit_highlight_mode_dialog_get_selector (GeditHighlightModeDialog *dlg);
+
+G_END_DECLS
+
+#endif /* GEDIT_HIGHLIGHT_MODE_DIALOG_H */
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-highlight-mode-selector.c gedit-41.0/gedit/gedit-highlight-mode-selector.c
--- gedit-40.1/gedit/gedit-highlight-mode-selector.c 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-highlight-mode-selector.c 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,375 @@
+/*
+ * gedit-highlight-mode-selector.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+#include "gedit-highlight-mode-selector.h"
+#include
+
+enum
+{
+ COLUMN_NAME,
+ COLUMN_LANG,
+ N_COLUMNS
+};
+
+struct _GeditHighlightModeSelector
+{
+ 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 (GeditHighlightModeSelector, gedit_highlight_mode_selector, GTK_TYPE_GRID)
+
+static void
+gedit_highlight_mode_selector_language_selected (GeditHighlightModeSelector *widget,
+ GtkSourceLanguage *language)
+{
+}
+
+static void
+gedit_highlight_mode_selector_class_init (GeditHighlightModeSelectorClass *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 (gedit_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/gnome/gedit/ui/gedit-highlight-mode-selector.ui");
+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, treeview);
+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, entry);
+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, liststore);
+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, treemodelfilter);
+ gtk_widget_class_bind_template_child (widget_class, GeditHighlightModeSelector, treeview_selection);
+}
+
+static gboolean
+visible_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GeditHighlightModeSelector *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,
+ GeditHighlightModeSelector *selector)
+{
+ gedit_highlight_mode_selector_activate_selected_language (selector);
+}
+
+static void
+on_entry_changed (GtkEntry *entry,
+ GeditHighlightModeSelector *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 (GeditHighlightModeSelector *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,
+ GeditHighlightModeSelector *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,
+ GeditHighlightModeSelector *selector)
+{
+ gedit_highlight_mode_selector_activate_selected_language (selector);
+}
+
+static void
+gedit_highlight_mode_selector_init (GeditHighlightModeSelector *selector)
+{
+ GtkSourceLanguageManager *lm;
+ const gchar * const *ids;
+ gint i;
+ GtkTreeIter iter;
+
+ selector = gedit_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);
+ }
+}
+
+GeditHighlightModeSelector *
+gedit_highlight_mode_selector_new ()
+{
+ return g_object_new (GEDIT_TYPE_HIGHLIGHT_MODE_SELECTOR, NULL);
+}
+
+void
+gedit_highlight_mode_selector_select_language (GeditHighlightModeSelector *selector,
+ GtkSourceLanguage *language)
+{
+ GtkTreeIter iter;
+
+ g_return_if_fail (GEDIT_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
+gedit_highlight_mode_selector_activate_selected_language (GeditHighlightModeSelector *selector)
+{
+ GtkSourceLanguage *lang;
+ GtkTreeIter iter;
+
+ g_return_if_fail (GEDIT_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 -Nru gedit-40.1/gedit/gedit-highlight-mode-selector.h gedit-41.0/gedit/gedit-highlight-mode-selector.h
--- gedit-40.1/gedit/gedit-highlight-mode-selector.h 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-highlight-mode-selector.h 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,44 @@
+/*
+ * gedit-highlight-mode-selector.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2013 - Ignacio Casal Quinteiro
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+#ifndef GEDIT_HIGHLIGHT_MODE_SELECTOR_H
+#define GEDIT_HIGHLIGHT_MODE_SELECTOR_H
+
+#include
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_HIGHLIGHT_MODE_SELECTOR (gedit_highlight_mode_selector_get_type ())
+
+G_DECLARE_FINAL_TYPE (GeditHighlightModeSelector, gedit_highlight_mode_selector, GEDIT, HIGHLIGHT_MODE_SELECTOR, GtkGrid)
+
+GeditHighlightModeSelector *gedit_highlight_mode_selector_new (void);
+
+void gedit_highlight_mode_selector_select_language (GeditHighlightModeSelector *selector,
+ GtkSourceLanguage *language);
+
+void gedit_highlight_mode_selector_activate_selected_language
+ (GeditHighlightModeSelector *selector);
+
+G_END_DECLS
+
+#endif /* GEDIT_HIGHLIGHT_MODE_SELECTOR_H */
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-io-error-info-bar.c gedit-41.0/gedit/gedit-io-error-info-bar.c
--- gedit-40.1/gedit/gedit-io-error-info-bar.c 2021-04-17 05:45:36.016556000 +0000
+++ gedit-41.0/gedit/gedit-io-error-info-bar.c 2022-02-14 13:58:26.000000000 +0000
@@ -23,9 +23,16 @@
*/
#include "gedit-io-error-info-bar.h"
+
+#include
+#include
#include
-#include
+#include
+
#include "gedit-encodings-combo-box.h"
+#include "gedit-settings.h"
+#include "gedit-utils.h"
+#include "gedit-document.h"
#define MAX_URI_IN_DIALOG_LENGTH 50
@@ -220,7 +227,7 @@
uri = g_file_get_uri (location);
}
- if (uri && tepl_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL))
+ if (uri && gedit_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL))
{
if (hn != NULL)
{
@@ -323,8 +330,8 @@
* though the dialog uses wrapped text, if the URI doesn't contain
* white space then the text-wrapping code is too stupid to wrap it.
*/
- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
- MAX_URI_IN_DIALOG_LENGTH);
+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
+ MAX_URI_IN_DIALOG_LENGTH);
g_free (full_formatted_uri);
uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
@@ -395,6 +402,67 @@
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
}
+static void
+create_primary_and_secondary_widgets_info_bar(GtkWidget *vbox, const gchar *primary_text,
+ const gchar *secondary_text)
+{
+ gchar *primary_markup;
+ gchar *secondary_markup;
+ GtkWidget *primary_label;
+ GtkWidget *secondary_label;
+
+ primary_markup = g_strdup_printf ("%s", primary_text);
+ primary_label = gtk_label_new (primary_markup);
+ g_free (primary_markup);
+ gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
+ gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+ gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
+ gtk_widget_set_can_focus (primary_label, TRUE);
+ gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
+
+ if (secondary_text != NULL)
+ {
+ secondary_markup = g_strdup_printf ("%s",
+ secondary_text);
+ secondary_label = gtk_label_new (secondary_markup);
+ g_free (secondary_markup);
+ gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
+ gtk_widget_set_can_focus (secondary_label, TRUE);
+ gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+ gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
+ gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
+ }
+}
+
+static GtkWidget *
+create_file_too_big_error_info_bar (const gchar *primary_text,
+ const gchar *secondary_text)
+{
+ GtkWidget *info_bar;
+ GtkWidget *hbox_content;
+ GtkWidget *vbox;
+
+ info_bar = gtk_info_bar_new ();
+ gtk_info_bar_set_show_close_button (GTK_INFO_BAR (info_bar), TRUE);
+
+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ _("_Continue loading"),
+ GTK_RESPONSE_ACCEPT);
+
+ hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
+
+ create_primary_and_secondary_widgets_info_bar (vbox, primary_text, secondary_text);
+ gtk_widget_show_all (hbox_content);
+ set_contents (info_bar, hbox_content);
+
+ return info_bar;
+}
+
static GtkWidget *
create_conversion_error_info_bar (const gchar *primary_text,
const gchar *secondary_text,
@@ -403,10 +471,6 @@
GtkWidget *info_bar;
GtkWidget *hbox_content;
GtkWidget *vbox;
- gchar *primary_markup;
- gchar *secondary_markup;
- GtkWidget *primary_label;
- GtkWidget *secondary_label;
info_bar = gtk_info_bar_new ();
gtk_info_bar_set_show_close_button (GTK_INFO_BAR (info_bar), TRUE);
@@ -436,30 +500,7 @@
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
- primary_markup = g_strdup_printf ("%s", primary_text);
- primary_label = gtk_label_new (primary_markup);
- g_free (primary_markup);
- gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
- gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
- gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
- gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
- gtk_widget_set_can_focus (primary_label, TRUE);
- gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
-
- if (secondary_text != NULL)
- {
- secondary_markup = g_strdup_printf ("%s",
- secondary_text);
- secondary_label = gtk_label_new (secondary_markup);
- g_free (secondary_markup);
- gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
- gtk_widget_set_can_focus (secondary_label, TRUE);
- gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
- gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
- gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
- gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
- }
-
+ create_primary_and_secondary_widgets_info_bar (vbox, primary_text, secondary_text);
create_combo_box (info_bar, vbox);
gtk_widget_show_all (hbox_content);
set_contents (info_bar, hbox_content);
@@ -480,6 +521,7 @@
GtkWidget *info_bar;
gboolean edit_anyway = FALSE;
gboolean convert_error = FALSE;
+ gboolean file_too_big = FALSE;
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_LOADER_ERROR ||
@@ -499,8 +541,8 @@
* though the dialog uses wrapped text, if the URI doesn't contain
* white space then the text-wrapping code is too stupid to wrap it.
*/
- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
- MAX_URI_IN_DIALOG_LENGTH);
+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
+ MAX_URI_IN_DIALOG_LENGTH);
g_free (full_formatted_uri);
uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
@@ -549,6 +591,16 @@
g_free (encoding_name);
}
+ else if (error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
+ error->code == GTK_SOURCE_FILE_LOADER_ERROR_TOO_BIG)
+ {
+ error_message = g_strdup_printf (_("The file “%s” is very big."),
+ uri_for_display);
+ message_details = g_strconcat (_("Large files can make gedit slow or unresponsive. "
+ "You can continue loading this file at your own risk"),
+ NULL);
+ file_too_big = TRUE;
+ }
else
{
parse_error (error, &error_message, &message_details, location, uri_for_display);
@@ -560,7 +612,12 @@
uri_for_display);
}
- if (convert_error)
+ if (file_too_big)
+ {
+ info_bar = create_file_too_big_error_info_bar (error_message,
+ message_details);
+ }
+ else if (convert_error)
{
info_bar = create_conversion_error_info_bar (error_message,
message_details,
@@ -605,8 +662,8 @@
* though the dialog uses wrapped text, if the URI doesn't contain
* white space then the text-wrapping code is too stupid to wrap it.
*/
- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
- MAX_URI_IN_DIALOG_LENGTH);
+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
+ MAX_URI_IN_DIALOG_LENGTH);
g_free (full_formatted_uri);
uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
@@ -651,6 +708,88 @@
}
GtkWidget *
+gedit_file_already_open_warning_info_bar_new (GFile *location)
+{
+ GtkWidget *info_bar;
+ GtkWidget *hbox_content;
+ GtkWidget *vbox;
+ gchar *primary_markup;
+ gchar *secondary_markup;
+ GtkWidget *primary_label;
+ GtkWidget *secondary_label;
+ gchar *primary_text;
+ const gchar *secondary_text;
+ gchar *full_formatted_uri;
+ gchar *uri_for_display;
+ gchar *temp_uri_for_display;
+
+ g_return_val_if_fail (G_IS_FILE (location), NULL);
+
+ full_formatted_uri = g_file_get_parse_name (location);
+
+ /* Truncate the URI so it doesn't get insanely wide. Note that even
+ * though the dialog uses wrapped text, if the URI doesn't contain
+ * white space then the text-wrapping code is too stupid to wrap it.
+ */
+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
+ MAX_URI_IN_DIALOG_LENGTH);
+ g_free (full_formatted_uri);
+
+ uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
+ g_free (temp_uri_for_display);
+
+ info_bar = gtk_info_bar_new ();
+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ /* Translators: the access key chosen for this string should be
+ different from other main menu access keys (Open, Edit, View...) */
+ _("Edit Any_way"),
+ GTK_RESPONSE_YES);
+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ /* Translators: the access key chosen for this string should be
+ different from other main menu access keys (Open, Edit, View...) */
+ _("D_on’t Edit"),
+ GTK_RESPONSE_CANCEL);
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar),
+ GTK_MESSAGE_WARNING);
+
+ hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
+
+ primary_text = g_strdup_printf (_("This file “%s” is already open in another window."), uri_for_display);
+ g_free (uri_for_display);
+
+ primary_markup = g_strdup_printf ("%s", primary_text);
+ g_free (primary_text);
+ primary_label = gtk_label_new (primary_markup);
+ g_free (primary_markup);
+ gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
+ gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+ gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
+ gtk_widget_set_can_focus (primary_label, TRUE);
+ gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
+
+ secondary_text = _("Do you want to edit it anyway?");
+ secondary_markup = g_strdup_printf ("%s",
+ secondary_text);
+ secondary_label = gtk_label_new (secondary_markup);
+ g_free (secondary_markup);
+ gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
+ gtk_widget_set_can_focus (secondary_label, TRUE);
+ gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+ gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
+ gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
+
+ gtk_widget_show_all (hbox_content);
+ set_contents (info_bar, hbox_content);
+
+ return info_bar;
+}
+
+GtkWidget *
gedit_externally_modified_saving_error_info_bar_new (GFile *location,
const GError *error)
{
@@ -678,8 +817,8 @@
* though the dialog uses wrapped text, if the URI doesn't contain
* white space then the text-wrapping code is too stupid to wrap it.
*/
- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
- MAX_URI_IN_DIALOG_LENGTH);
+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
+ MAX_URI_IN_DIALOG_LENGTH);
g_free (full_formatted_uri);
uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
@@ -739,6 +878,110 @@
}
GtkWidget *
+gedit_no_backup_saving_error_info_bar_new (GFile *location,
+ const GError *error)
+{
+ GtkWidget *info_bar;
+ GtkWidget *hbox_content;
+ GtkWidget *vbox;
+ gchar *primary_markup;
+ gchar *secondary_markup;
+ GtkWidget *primary_label;
+ GtkWidget *secondary_label;
+ gchar *primary_text;
+ const gchar *secondary_text;
+ gchar *full_formatted_uri;
+ gchar *uri_for_display;
+ gchar *temp_uri_for_display;
+ gboolean create_backup_copy;
+ GSettings *editor_settings;
+
+ g_return_val_if_fail (G_IS_FILE (location), NULL);
+ g_return_val_if_fail (error != NULL, NULL);
+ g_return_val_if_fail (error->domain == G_IO_ERROR &&
+ error->code == G_IO_ERROR_CANT_CREATE_BACKUP, NULL);
+
+ full_formatted_uri = g_file_get_parse_name (location);
+
+ /* Truncate the URI so it doesn't get insanely wide. Note that even
+ * though the dialog uses wrapped text, if the URI doesn't contain
+ * white space then the text-wrapping code is too stupid to wrap it.
+ */
+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
+ MAX_URI_IN_DIALOG_LENGTH);
+ g_free (full_formatted_uri);
+
+ uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
+ g_free (temp_uri_for_display);
+
+ info_bar = gtk_info_bar_new ();
+
+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ _("S_ave Anyway"),
+ GTK_RESPONSE_YES);
+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ _("D_on’t Save"),
+ GTK_RESPONSE_CANCEL);
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar),
+ GTK_MESSAGE_WARNING);
+
+ hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
+
+ editor_settings = g_settings_new ("org.gnome.gedit.preferences.editor");
+
+ create_backup_copy = g_settings_get_boolean (editor_settings,
+ GEDIT_SETTINGS_CREATE_BACKUP_COPY);
+ g_object_unref (editor_settings);
+
+ /* FIXME: review this messages */
+ if (create_backup_copy)
+ {
+ primary_text = g_strdup_printf (_("Could not create a backup file while saving “%s”"),
+ uri_for_display);
+ }
+ else
+ {
+ primary_text = g_strdup_printf (_("Could not create a temporary backup file while saving “%s”"),
+ uri_for_display);
+ }
+
+ g_free (uri_for_display);
+
+ primary_markup = g_strdup_printf ("%s", primary_text);
+ g_free (primary_text);
+ primary_label = gtk_label_new (primary_markup);
+ g_free (primary_markup);
+ gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
+ gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+ gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
+ gtk_widget_set_can_focus (primary_label, TRUE);
+ gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
+
+ secondary_text = _("Could not back up the old copy of the file before saving the new one. "
+ "You can ignore this warning and save the file anyway, but if an error "
+ "occurs while saving, you could lose the old copy of the file. Save anyway?");
+ secondary_markup = g_strdup_printf ("%s",
+ secondary_text);
+ secondary_label = gtk_label_new (secondary_markup);
+ g_free (secondary_markup);
+ gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
+ gtk_widget_set_can_focus (secondary_label, TRUE);
+ gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+ gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
+ gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
+
+ gtk_widget_show_all (hbox_content);
+ set_contents (info_bar, hbox_content);
+
+ return info_bar;
+}
+
+GtkWidget *
gedit_unrecoverable_saving_error_info_bar_new (GFile *location,
const GError *error)
{
@@ -762,8 +1005,8 @@
* though the dialog uses wrapped text, if the URI doesn't contain
* white space then the text-wrapping code is too stupid to wrap it.
*/
- temp_uri_for_display = tepl_utils_str_middle_truncate (full_formatted_uri,
- MAX_URI_IN_DIALOG_LENGTH);
+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
+ MAX_URI_IN_DIALOG_LENGTH);
g_free (full_formatted_uri);
uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
@@ -866,5 +1109,150 @@
return info_bar;
}
+
+GtkWidget *
+gedit_externally_modified_info_bar_new (GFile *location,
+ gboolean document_modified)
+{
+ gchar *full_formatted_uri;
+ gchar *uri_for_display;
+ gchar *temp_uri_for_display;
+ gchar *primary_text;
+ GtkWidget *info_bar;
+
+ g_return_val_if_fail (G_IS_FILE (location), NULL);
+
+ full_formatted_uri = g_file_get_parse_name (location);
+
+ /* Truncate the URI so it doesn't get insanely wide. Note that even
+ * though the dialog uses wrapped text, if the URI doesn't contain
+ * white space then the text-wrapping code is too stupid to wrap it.
+ */
+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
+ MAX_URI_IN_DIALOG_LENGTH);
+ g_free (full_formatted_uri);
+
+ uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
+ g_free (temp_uri_for_display);
+
+ primary_text = g_strdup_printf (_("The file “%s” changed on disk."),
+ uri_for_display);
+ g_free (uri_for_display);
+
+ info_bar = gtk_info_bar_new ();
+
+ if (document_modified)
+ {
+ GtkWidget *box;
+ GtkWidget *button;
+ button = gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ _("Drop Changes and _Reload"),
+ GTK_RESPONSE_OK);
+ box = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
+ gtk_button_box_set_child_non_homogeneous (GTK_BUTTON_BOX (box),
+ button,
+ TRUE);
+ }
+ else
+ {
+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ _("_Reload"),
+ GTK_RESPONSE_OK);
+ }
+
+ gtk_info_bar_set_show_close_button (GTK_INFO_BAR (info_bar), TRUE);
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar),
+ GTK_MESSAGE_WARNING);
+
+ set_info_bar_text (info_bar,
+ primary_text,
+ NULL);
+
+ g_free (primary_text);
+
+ return info_bar;
+}
+
+GtkWidget *
+gedit_invalid_character_info_bar_new (GFile *location)
+{
+ GtkWidget *info_bar;
+ GtkWidget *hbox_content;
+ GtkWidget *vbox;
+ GtkWidget *primary_label;
+ GtkWidget *secondary_label;
+ gchar *primary_markup;
+ gchar *secondary_markup;
+ gchar *primary_text;
+ gchar *full_formatted_uri;
+ gchar *uri_for_display;
+ gchar *temp_uri_for_display;
+ const gchar *secondary_text;
+
+ g_return_val_if_fail (G_IS_FILE (location), NULL);
+
+ full_formatted_uri = g_file_get_parse_name (location);
+
+ /* Truncate the URI so it doesn't get insanely wide. Note that even
+ * though the dialog uses wrapped text, if the URI doesn't contain
+ * white space then the text-wrapping code is too stupid to wrap it.
+ */
+ temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri,
+ MAX_URI_IN_DIALOG_LENGTH);
+ g_free (full_formatted_uri);
+
+ uri_for_display = g_markup_escape_text (temp_uri_for_display, -1);
+ g_free (temp_uri_for_display);
+
+ info_bar = gtk_info_bar_new ();
+
+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ _("S_ave Anyway"),
+ GTK_RESPONSE_YES);
+ gtk_info_bar_add_button (GTK_INFO_BAR (info_bar),
+ _("D_on’t Save"),
+ GTK_RESPONSE_CANCEL);
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar),
+ GTK_MESSAGE_WARNING);
+
+ hbox_content = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
+
+ primary_text = g_strdup_printf (_("Some invalid chars have been detected while saving “%s”"),
+ uri_for_display);
+
+ g_free (uri_for_display);
+
+ primary_markup = g_strdup_printf ("%s", primary_text);
+ g_free (primary_text);
+ primary_label = gtk_label_new (primary_markup);
+ g_free (primary_markup);
+ gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
+ gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+ gtk_widget_set_halign (primary_label, GTK_ALIGN_START);
+ gtk_widget_set_can_focus (primary_label, TRUE);
+ gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
+
+ secondary_text = _("If you continue saving this file you can corrupt the document. "
+ " Save anyway?");
+ secondary_markup = g_strdup_printf ("%s",
+ secondary_text);
+ secondary_label = gtk_label_new (secondary_markup);
+ g_free (secondary_markup);
+ gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
+ gtk_widget_set_can_focus (secondary_label, TRUE);
+ gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+ gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
+ gtk_widget_set_halign (secondary_label, GTK_ALIGN_START);
+
+ gtk_widget_show_all (hbox_content);
+ set_contents (info_bar, hbox_content);
+
+ return info_bar;
+}
/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-io-error-info-bar.h gedit-41.0/gedit/gedit-io-error-info-bar.h
--- gedit-40.1/gedit/gedit-io-error-info-bar.h 2021-04-17 05:45:36.016556000 +0000
+++ gedit-41.0/gedit/gedit-io-error-info-bar.h 2022-02-14 13:58:26.000000000 +0000
@@ -39,12 +39,22 @@
const GtkSourceEncoding
*gedit_conversion_error_info_bar_get_encoding (GtkWidget *info_bar);
+GtkWidget *gedit_file_already_open_warning_info_bar_new (GFile *location);
+
GtkWidget *gedit_externally_modified_saving_error_info_bar_new (GFile *location,
const GError *error);
+GtkWidget *gedit_no_backup_saving_error_info_bar_new (GFile *location,
+ const GError *error);
+
GtkWidget *gedit_unrecoverable_saving_error_info_bar_new (GFile *location,
const GError *error);
+GtkWidget *gedit_externally_modified_info_bar_new (GFile *location,
+ gboolean document_modified);
+
+GtkWidget *gedit_invalid_character_info_bar_new (GFile *location);
+
G_END_DECLS
#endif /* GEDIT_IO_ERROR_INFO_BAR_H */
diff -Nru gedit-40.1/gedit/gedit-metadata-manager.c gedit-41.0/gedit/gedit-metadata-manager.c
--- gedit-40.1/gedit/gedit-metadata-manager.c 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-metadata-manager.c 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,650 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * gedit-metadata-manager.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2003-2007 Paolo Maggi
+ * Copyright (C) 2019 Canonical LTD
+ *
+ * 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 "gedit-metadata-manager.h"
+#include
+#include "gedit-debug.h"
+
+/*
+#define GEDIT_METADATA_VERBOSE_DEBUG 1
+*/
+
+#define MAX_ITEMS 50
+
+typedef struct _Item Item;
+
+struct _Item
+{
+ /* Time of last access in seconds since January 1, 1970 UTC. */
+ gint64 atime;
+
+ GHashTable *values;
+};
+
+struct _GeditMetadataManager
+{
+ GObject parent_instance;
+
+ /* It is true if the file has been read. */
+ gboolean values_loaded;
+
+ guint timeout_id;
+
+ GHashTable *items;
+
+ gchar *metadata_filename;
+};
+
+enum
+{
+ PROP_0,
+ PROP_METADATA_FILENAME,
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP];
+
+G_DEFINE_TYPE (GeditMetadataManager, gedit_metadata_manager, G_TYPE_OBJECT);
+
+static gboolean gedit_metadata_manager_save (GeditMetadataManager *self);
+
+static void
+item_free (gpointer data)
+{
+ Item *item;
+
+ g_return_if_fail (data != NULL);
+
+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
+ gedit_debug (DEBUG_METADATA);
+#endif
+
+ item = (Item *)data;
+
+ if (item->values != NULL)
+ g_hash_table_destroy (item->values);
+
+ g_free (item);
+}
+
+static void
+gedit_metadata_manager_arm_timeout (GeditMetadataManager *self)
+{
+ if (self->timeout_id == 0)
+ {
+ self->timeout_id =
+ g_timeout_add_seconds_full (G_PRIORITY_DEFAULT_IDLE,
+ 2,
+ (GSourceFunc)gedit_metadata_manager_save,
+ self,
+ NULL);
+ }
+}
+
+static void
+gedit_metadata_manager_parse_item (GeditMetadataManager *self,
+ xmlDocPtr doc,
+ xmlNodePtr cur)
+{
+ Item *item;
+
+ xmlChar *uri;
+ xmlChar *atime;
+
+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
+ gedit_debug (DEBUG_METADATA);
+#endif
+
+ if (xmlStrcmp (cur->name, (const xmlChar *)"document") != 0)
+ return;
+
+ uri = xmlGetProp (cur, (const xmlChar *)"uri");
+ if (uri == NULL)
+ return;
+
+ atime = xmlGetProp (cur, (const xmlChar *)"atime");
+ if (atime == NULL)
+ {
+ xmlFree (uri);
+ return;
+ }
+
+ item = g_new0 (Item, 1);
+
+ item->atime = g_ascii_strtoll ((char *)atime, NULL, 0);
+
+ item->values = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_free);
+
+ cur = cur->xmlChildrenNode;
+
+ while (cur != NULL)
+ {
+ if (xmlStrcmp (cur->name, (const xmlChar *)"entry") == 0)
+ {
+ xmlChar *key;
+ xmlChar *value;
+
+ key = xmlGetProp (cur, (const xmlChar *)"key");
+ value = xmlGetProp (cur, (const xmlChar *)"value");
+
+ if ((key != NULL) && (value != NULL))
+ {
+ g_hash_table_insert (item->values,
+ g_strdup ((gchar *)key),
+ g_strdup ((gchar *)value));
+ }
+
+ if (key != NULL)
+ xmlFree (key);
+ if (value != NULL)
+ xmlFree (value);
+ }
+
+ cur = cur->next;
+ }
+
+ g_hash_table_insert (self->items,
+ g_strdup ((gchar *)uri),
+ item);
+
+ xmlFree (uri);
+ xmlFree (atime);
+}
+
+/* Returns FALSE in case of error. */
+static gboolean
+gedit_metadata_manager_load_values (GeditMetadataManager *self)
+{
+ xmlDocPtr doc;
+ xmlNodePtr cur;
+
+ gedit_debug (DEBUG_METADATA);
+
+ g_return_val_if_fail (self != NULL, FALSE);
+ g_return_val_if_fail (self->values_loaded == FALSE, FALSE);
+
+ self->values_loaded = TRUE;
+
+ xmlKeepBlanksDefault (0);
+
+ if (self->metadata_filename == NULL)
+ {
+ return FALSE;
+ }
+
+ /* TODO: avoid races */
+ if (!g_file_test (self->metadata_filename, G_FILE_TEST_EXISTS))
+ {
+ return TRUE;
+ }
+
+ doc = xmlParseFile (self->metadata_filename);
+
+ if (doc == NULL)
+ {
+ return FALSE;
+ }
+
+ cur = xmlDocGetRootElement (doc);
+ if (cur == NULL)
+ {
+ g_message ("The metadata file '%s' is empty",
+ g_path_get_basename (self->metadata_filename));
+ xmlFreeDoc (doc);
+
+ return TRUE;
+ }
+
+ if (xmlStrcmp (cur->name, (const xmlChar *) "metadata"))
+ {
+ g_message ("File '%s' is of the wrong type",
+ g_path_get_basename (self->metadata_filename));
+ xmlFreeDoc (doc);
+
+ return FALSE;
+ }
+
+ cur = xmlDocGetRootElement (doc);
+ cur = cur->xmlChildrenNode;
+
+ while (cur != NULL)
+ {
+ gedit_metadata_manager_parse_item (self, doc, cur);
+
+ cur = cur->next;
+ }
+
+ xmlFreeDoc (doc);
+
+ return TRUE;
+}
+
+/**
+ * gedit_metadata_manager_get:
+ * @self: a #GeditMetadataManager.
+ * @location: a #GFile.
+ * @key: a key.
+ *
+ * Gets the value associated with the specified @key for the file @location.
+ */
+gchar *
+gedit_metadata_manager_get (GeditMetadataManager *self,
+ GFile *location,
+ const gchar *key)
+{
+ Item *item;
+ gchar *value;
+ gchar *uri;
+
+ g_return_val_if_fail (GEDIT_IS_METADATA_MANAGER (self), NULL);
+ g_return_val_if_fail (G_IS_FILE (location), NULL);
+ g_return_val_if_fail (key != NULL, NULL);
+
+ uri = g_file_get_uri (location);
+
+ gedit_debug_message (DEBUG_METADATA, "URI: %s --- key: %s", uri, key );
+
+ if (!self->values_loaded)
+ {
+ gboolean res;
+
+ res = gedit_metadata_manager_load_values (self);
+
+ if (!res)
+ {
+ g_free (uri);
+ return NULL;
+ }
+ }
+
+ item = (Item *)g_hash_table_lookup (self->items, uri);
+
+ g_free (uri);
+
+ if (item == NULL)
+ return NULL;
+
+ item->atime = g_get_real_time () / 1000;
+
+ if (item->values == NULL)
+ return NULL;
+
+ value = g_hash_table_lookup (item->values, key);
+
+ if (value == NULL)
+ return NULL;
+ else
+ return g_strdup (value);
+}
+
+/**
+ * gedit_metadata_manager_set:
+ * @self: a #GeditMetadataManager.
+ * @location: a #GFile.
+ * @key: a key.
+ * @value: the value associated with the @key.
+ *
+ * Sets the @key to contain the given @value for the file @location.
+ */
+void
+gedit_metadata_manager_set (GeditMetadataManager *self,
+ GFile *location,
+ const gchar *key,
+ const gchar *value)
+{
+ Item *item;
+ gchar *uri;
+
+ g_return_if_fail (GEDIT_IS_METADATA_MANAGER (self));
+ g_return_if_fail (G_IS_FILE (location));
+ g_return_if_fail (key != NULL);
+
+ uri = g_file_get_uri (location);
+
+ gedit_debug_message (DEBUG_METADATA, "URI: %s --- key: %s --- value: %s", uri, key, value);
+
+ if (!self->values_loaded)
+ {
+ gboolean ok;
+
+ ok = gedit_metadata_manager_load_values (self);
+
+ if (!ok)
+ {
+ g_free (uri);
+ return;
+ }
+ }
+
+ item = (Item *)g_hash_table_lookup (self->items, uri);
+
+ if (item == NULL)
+ {
+ item = g_new0 (Item, 1);
+
+ g_hash_table_insert (self->items,
+ g_strdup (uri),
+ item);
+ }
+
+ if (item->values == NULL)
+ {
+ item->values = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_free);
+ }
+
+ if (value != NULL)
+ {
+ g_hash_table_insert (item->values,
+ g_strdup (key),
+ g_strdup (value));
+ }
+ else
+ {
+ g_hash_table_remove (item->values,
+ key);
+ }
+
+ item->atime = g_get_real_time () / 1000;
+
+ g_free (uri);
+
+ gedit_metadata_manager_arm_timeout (self);
+}
+
+static void
+save_values (const gchar *key, const gchar *value, xmlNodePtr parent)
+{
+ xmlNodePtr xml_node;
+
+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
+ gedit_debug (DEBUG_METADATA);
+#endif
+
+ g_return_if_fail (key != NULL);
+
+ if (value == NULL)
+ return;
+
+ xml_node = xmlNewChild (parent,
+ NULL,
+ (const xmlChar *)"entry",
+ NULL);
+
+ xmlSetProp (xml_node,
+ (const xmlChar *)"key",
+ (const xmlChar *)key);
+ xmlSetProp (xml_node,
+ (const xmlChar *)"value",
+ (const xmlChar *)value);
+
+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
+ gedit_debug_message (DEBUG_METADATA, "entry: %s = %s", key, value);
+#endif
+}
+
+static void
+save_item (const gchar *key, const gpointer *data, xmlNodePtr parent)
+{
+ xmlNodePtr xml_node;
+ const Item *item = (const Item *)data;
+ gchar *atime;
+
+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
+ gedit_debug (DEBUG_METADATA);
+#endif
+
+ g_return_if_fail (key != NULL);
+
+ if (item == NULL)
+ return;
+
+ xml_node = xmlNewChild (parent, NULL, (const xmlChar *)"document", NULL);
+
+ xmlSetProp (xml_node, (const xmlChar *)"uri", (const xmlChar *)key);
+
+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
+ gedit_debug_message (DEBUG_METADATA, "uri: %s", key);
+#endif
+
+ atime = g_strdup_printf ("%" G_GINT64_FORMAT, item->atime);
+ xmlSetProp (xml_node, (const xmlChar *)"atime", (const xmlChar *)atime);
+
+#ifdef GEDIT_METADATA_VERBOSE_DEBUG
+ gedit_debug_message (DEBUG_METADATA, "atime: %s", atime);
+#endif
+
+ g_free (atime);
+
+ g_hash_table_foreach (item->values,
+ (GHFunc)save_values,
+ xml_node);
+}
+
+static const gchar *
+gedit_metadata_manager_get_oldest (GeditMetadataManager *self)
+{
+ GHashTableIter iter;
+ gpointer key, value, key_to_remove = NULL;
+ const Item *item_to_remove = NULL;
+
+ g_hash_table_iter_init (&iter, self->items);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ const Item *item = (const Item *) value;
+
+ if (key_to_remove == NULL)
+ {
+ key_to_remove = key;
+ item_to_remove = item;
+ }
+ else
+ {
+ g_return_val_if_fail (item_to_remove != NULL, NULL);
+
+ if (item->atime < item_to_remove->atime)
+ key_to_remove = key;
+ }
+ }
+
+ return key_to_remove;
+}
+
+static void
+gedit_metadata_manager_resize_items (GeditMetadataManager *self)
+{
+ while (g_hash_table_size (self->items) > MAX_ITEMS)
+ {
+ const gchar *key_to_remove;
+
+ key_to_remove = gedit_metadata_manager_get_oldest (self);
+ g_return_if_fail (key_to_remove != NULL);
+ g_hash_table_remove (self->items,
+ key_to_remove);
+ }
+}
+
+static gboolean
+gedit_metadata_manager_save (GeditMetadataManager *self)
+{
+ xmlDocPtr doc;
+ xmlNodePtr root;
+
+ gedit_debug (DEBUG_METADATA);
+
+ self->timeout_id = 0;
+
+ gedit_metadata_manager_resize_items (self);
+
+ xmlIndentTreeOutput = TRUE;
+
+ doc = xmlNewDoc ((const xmlChar *)"1.0");
+ if (doc == NULL)
+ return TRUE;
+
+ /* Create metadata root */
+ root = xmlNewDocNode (doc, NULL, (const xmlChar *)"metadata", NULL);
+ xmlDocSetRootElement (doc, root);
+
+ g_hash_table_foreach (self->items,
+ (GHFunc)save_item,
+ root);
+
+ /* FIXME: lock file - Paolo */
+ if (self->metadata_filename != NULL)
+ {
+ gchar *cache_dir;
+ int res;
+
+ /* make sure the cache dir exists */
+ cache_dir = g_path_get_dirname (self->metadata_filename);
+ res = g_mkdir_with_parents (cache_dir, 0755);
+ if (res != -1)
+ {
+ xmlSaveFormatFile (self->metadata_filename,
+ doc,
+ 1);
+ }
+
+ g_free (cache_dir);
+ }
+
+ xmlFreeDoc (doc);
+
+ gedit_debug_message (DEBUG_METADATA, "DONE");
+
+ return FALSE;
+}
+
+static void
+gedit_metadata_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GeditMetadataManager *self = GEDIT_METADATA_MANAGER (object);
+
+ switch (prop_id)
+ {
+ case PROP_METADATA_FILENAME:
+ g_value_set_string (value, self->metadata_filename);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+gedit_metadata_manager_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeditMetadataManager *self = GEDIT_METADATA_MANAGER (object);
+
+ switch (prop_id)
+ {
+ case PROP_METADATA_FILENAME:
+ self->metadata_filename = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gedit_metadata_manager_init (GeditMetadataManager *self)
+{
+ gedit_debug (DEBUG_METADATA);
+
+ self->values_loaded = FALSE;
+
+ self->items =
+ g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ item_free);
+}
+
+static void
+gedit_metadata_manager_dispose (GObject *object)
+{
+ GeditMetadataManager *self = GEDIT_METADATA_MANAGER (object);
+
+ gedit_debug (DEBUG_METADATA);
+
+ if (self->timeout_id)
+ {
+ g_source_remove (self->timeout_id);
+ self->timeout_id = 0;
+ gedit_metadata_manager_save (self);
+ }
+
+ if (self->items != NULL)
+ g_hash_table_destroy (self->items);
+
+ g_free (self->metadata_filename);
+}
+
+static void
+gedit_metadata_manager_class_init (GeditMetadataManagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gedit_metadata_manager_dispose;
+ object_class->get_property = gedit_metadata_manager_get_property;
+ object_class->set_property = gedit_metadata_manager_set_property;
+
+ /**
+ * GeditMetadataManager:metadata-filename:
+ *
+ * The filename where the metadata is stored.
+ */
+ properties[PROP_METADATA_FILENAME] =
+ g_param_spec_string ("metadata-filename",
+ "Metadata filename",
+ "The filename where the metadata is stored",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+}
+
+GeditMetadataManager *
+gedit_metadata_manager_new (const gchar *metadata_filename)
+{
+ gedit_debug (DEBUG_METADATA);
+
+ return g_object_new (GEDIT_TYPE_METADATA_MANAGER,
+ "metadata-filename", metadata_filename,
+ NULL);
+}
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-metadata-manager.h gedit-41.0/gedit/gedit-metadata-manager.h
--- gedit-40.1/gedit/gedit-metadata-manager.h 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-metadata-manager.h 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,49 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * gedit-metadata-manager.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2003 Paolo Maggi
+ * Copyright (C) 2019 Canonical LTD
+ *
+ * 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 GEDIT_METADATA_MANAGER_H
+#define GEDIT_METADATA_MANAGER_H
+
+#include
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_METADATA_MANAGER (gedit_metadata_manager_get_type())
+
+G_DECLARE_FINAL_TYPE (GeditMetadataManager, gedit_metadata_manager, GEDIT, METADATA_MANAGER, GObject)
+
+GeditMetadataManager *gedit_metadata_manager_new (const gchar *metadata_filename);
+
+gchar *gedit_metadata_manager_get (GeditMetadataManager *self,
+ GFile *location,
+ const gchar *key);
+
+void gedit_metadata_manager_set (GeditMetadataManager *self,
+ GFile *location,
+ const gchar *key,
+ const gchar *value);
+
+G_END_DECLS
+
+#endif /* GEDIT_METADATA_MANAGER_H */
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-open-document-selector.c gedit-41.0/gedit/gedit-open-document-selector.c
--- gedit-40.1/gedit/gedit-open-document-selector.c 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-open-document-selector.c 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,1294 @@
+/*
+ * gedit-open-document-selector.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2014 - Sébastien Lafargue
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+#include "gedit-open-document-selector.h"
+#include "gedit-open-document-selector-store.h"
+#include "gedit-open-document-selector-helper.h"
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include "gedit-recent.h"
+#include "gedit-utils.h"
+#include "gedit-window.h"
+#include "gedit-debug.h"
+
+struct _GeditOpenDocumentSelector
+{
+ GtkBox parent_instance;
+
+ GeditWindow *window;
+ GtkWidget *search_entry;
+
+ GtkWidget *open_button;
+ GtkWidget *treeview;
+ GtkListStore *liststore;
+ GtkCellRenderer *name_renderer;
+ GtkCellRenderer *path_renderer;
+ GtkWidget *placeholder_box;
+ GtkWidget *scrolled_window;
+
+ guint populate_listbox_id;
+
+ GdkRGBA name_label_color;
+ PangoFontDescription *name_font;
+ GdkRGBA path_label_color;
+ PangoFontDescription *path_font;
+ gchar *match_markup_color;
+
+ GeditOpenDocumentSelectorStore *selector_store;
+ GList *recent_items;
+ GList *home_dir_items;
+ GList *desktop_dir_items;
+ GList *local_bookmarks_dir_items;
+ GList *file_browser_root_items;
+ GList *active_doc_dir_items;
+ GList *current_docs_items;
+ GList *all_items;
+};
+
+typedef enum
+{
+ SELECTOR_TAG_NONE,
+ SELECTOR_TAG_MATCH
+} SelectorTag;
+
+enum
+{
+ NAME_COLUMN,
+ PATH_COLUMN,
+ URI_COLUMN,
+ N_COLUMNS
+};
+
+enum
+{
+ PROP_0,
+ PROP_WINDOW,
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP];
+
+enum
+{
+ SELECTOR_FILE_ACTIVATED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+/* Value 0xFF is reserved to mark the end of the array */
+#define BYTE_ARRAY_END 0xFF
+
+#define OPEN_DOCUMENT_SELECTOR_WIDTH 400
+#define OPEN_DOCUMENT_SELECTOR_MAX_VISIBLE_ROWS 10
+
+G_DEFINE_TYPE (GeditOpenDocumentSelector, gedit_open_document_selector, GTK_TYPE_BOX)
+
+static inline const guint8 *
+get_byte_run (const guint8 *byte_array,
+ gsize *count,
+ SelectorTag *tag)
+{
+ guint8 tag_found;
+ gsize c = 1;
+
+ tag_found = *byte_array++;
+
+ while ( *byte_array != BYTE_ARRAY_END && *byte_array == tag_found)
+ {
+ c++;
+ byte_array++;
+ }
+
+ *count = c;
+ *tag = tag_found;
+
+ return ( *byte_array != BYTE_ARRAY_END) ? byte_array : NULL;
+}
+
+static gchar*
+get_markup_from_tagged_byte_array (GeditOpenDocumentSelector *selector,
+ const gchar *str,
+ const guint8 *byte_array)
+{
+ gchar *txt;
+ GString *string;
+ gchar *result_str;
+ SelectorTag tag;
+ gsize count;
+
+ string = g_string_sized_new (255);
+
+ while (TRUE)
+ {
+ byte_array = get_byte_run (byte_array, &count, &tag);
+ txt = g_markup_escape_text (str, count);
+ if (tag == SELECTOR_TAG_MATCH)
+ {
+ g_string_append (string, selector->match_markup_color);
+ g_string_append (string, txt);
+ g_string_append (string, "");
+ }
+ else
+ {
+ g_string_append (string, txt);
+ }
+
+ g_free (txt);
+
+ if (!byte_array)
+ {
+ break;
+ }
+
+ str = (const gchar *)((gsize)str + count);
+ }
+
+ result_str = g_string_free (string, FALSE);
+ return result_str;
+}
+
+static guint8 *
+get_tagged_byte_array (const gchar *uri,
+ GRegex *filter_regex)
+{
+ guint8 *byte_array;
+ gsize uri_len;
+ GMatchInfo *match_info;
+ gboolean no_match = TRUE;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ uri_len = strlen (uri);
+ byte_array = g_malloc0 (uri_len + 1);
+ byte_array[uri_len] = BYTE_ARRAY_END;
+
+ if (g_regex_match (filter_regex, uri, 0, &match_info) == TRUE)
+ {
+ while (g_match_info_matches (match_info) == TRUE)
+ {
+ guint8 *p;
+ gint match_len;
+ gint start_pos;
+ gint end_pos;
+
+ if (g_match_info_fetch_pos (match_info, 0, &start_pos, &end_pos) == TRUE)
+ {
+ match_len = end_pos - start_pos;
+ no_match = FALSE;
+
+ p = (guint8 *)((gsize)byte_array + start_pos);
+ memset (p, SELECTOR_TAG_MATCH, match_len);
+ }
+
+ g_match_info_next (match_info, NULL);
+ }
+ }
+
+ g_match_info_free (match_info);
+
+ if (no_match)
+ {
+ g_free (byte_array);
+ return NULL;
+ }
+
+ return byte_array;
+}
+
+static void
+get_markup_for_path_and_name (GeditOpenDocumentSelector *selector,
+ GRegex *filter_regex,
+ const gchar *src_path,
+ const gchar *src_name,
+ gchar **dst_path,
+ gchar **dst_name)
+{
+ gchar *filename;
+ gsize path_len;
+ gsize name_len;
+ gsize path_separator_len;
+ guint8 *byte_array;
+ guint8 *path_byte_array;
+ guint8 *name_byte_array;
+
+ filename = g_build_filename (src_path, src_name, NULL);
+
+ path_len = g_utf8_strlen (src_path, -1);
+ name_len = g_utf8_strlen (src_name, -1);
+ path_separator_len = g_utf8_strlen (filename, -1) - ( path_len + name_len);
+
+ byte_array = get_tagged_byte_array (filename, filter_regex);
+ if (byte_array)
+ {
+ path_byte_array = g_memdup (byte_array, path_len + 1);
+ path_byte_array[path_len] = BYTE_ARRAY_END;
+
+ /* name_byte_array is part of byte_array, so released with it */
+ name_byte_array = (guint8 *)((gsize)byte_array + path_len + path_separator_len);
+
+ *dst_path = get_markup_from_tagged_byte_array (selector, src_path, path_byte_array);
+ *dst_name = get_markup_from_tagged_byte_array (selector, src_name, name_byte_array);
+
+ g_free (byte_array);
+ g_free (path_byte_array);
+ }
+ else
+ {
+ *dst_path = g_strdup (src_path);
+ *dst_name = g_strdup (src_name);
+ }
+
+ g_free (filename);
+}
+
+static void
+create_row (GeditOpenDocumentSelector *selector,
+ const FileItem *item,
+ GRegex *filter_regex)
+{
+ GtkTreeIter iter;
+ gchar *uri;
+ gchar *dst_path;
+ gchar *dst_name;
+
+ uri =item->uri;
+
+ if (filter_regex)
+ {
+ get_markup_for_path_and_name (selector,
+ filter_regex,
+ (const gchar *)item->path,
+ (const gchar *)item->name,
+ &dst_path,
+ &dst_name);
+ }
+ else
+ {
+ dst_path = g_markup_escape_text (item->path, -1);
+ dst_name = g_markup_escape_text (item->name, -1);
+ }
+
+ gtk_list_store_append (selector->liststore, &iter);
+ gtk_list_store_set (selector->liststore, &iter,
+ URI_COLUMN, uri,
+ NAME_COLUMN, dst_name,
+ PATH_COLUMN, dst_path,
+ -1);
+
+ g_free (dst_path);
+ g_free (dst_name);
+}
+
+static gint
+sort_items_by_mru (FileItem *a,
+ FileItem *b,
+ gpointer unused G_GNUC_UNUSED)
+{
+ g_assert (a != NULL && b != NULL);
+
+ return g_date_time_compare (b->accessed, a->accessed);
+}
+
+static GList *
+compute_all_items_list (GeditOpenDocumentSelector *selector)
+{
+ GList *recent_items;
+ GList *home_dir_items;
+ GList *desktop_dir_items;
+ GList *local_bookmarks_dir_items;
+ GList *file_browser_root_items;
+ GList *active_doc_dir_items;
+ GList *current_docs_items;
+ GList *all_items = NULL;
+
+ /* Copy/concat the whole list */
+ recent_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->recent_items);
+ home_dir_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->home_dir_items);
+ desktop_dir_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->desktop_dir_items);
+ local_bookmarks_dir_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->local_bookmarks_dir_items);
+ file_browser_root_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->file_browser_root_items);
+ active_doc_dir_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->active_doc_dir_items);
+ current_docs_items = gedit_open_document_selector_copy_file_items_list ((const GList *)selector->current_docs_items);
+
+ if (selector->all_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector->all_items);
+ selector->all_items = NULL;
+ }
+
+ all_items = g_list_concat (all_items, recent_items);
+ all_items = g_list_concat (all_items, home_dir_items);
+ all_items = g_list_concat (all_items, desktop_dir_items);
+ all_items = g_list_concat (all_items, local_bookmarks_dir_items);
+ all_items = g_list_concat (all_items, file_browser_root_items);
+ all_items = g_list_concat (all_items, active_doc_dir_items);
+ all_items = g_list_concat (all_items, current_docs_items);
+
+ return all_items;
+}
+
+static GList *
+clamp_recent_items_list (GList *recent_items,
+ gint limit)
+{
+ GList *recent_items_capped = NULL;
+ GList *l;
+ FileItem *item;
+
+ l = recent_items;
+ while (limit > 0 && l != NULL)
+ {
+ item = gedit_open_document_selector_copy_fileitem_item (l->data);
+ recent_items_capped = g_list_prepend (recent_items_capped, item);
+ l = l->next;
+ limit -= 1;
+ }
+
+ recent_items_capped = g_list_reverse (recent_items_capped);
+ return recent_items_capped;
+}
+
+/* Setup the fileitem, depending uri's scheme
+ * Return a string to search in.
+ */
+static gchar *
+fileitem_setup (FileItem *item)
+{
+ gchar *scheme;
+ gchar *filename;
+ gchar *normalized_filename = NULL;
+ gchar *candidate = NULL;
+ gchar *path;
+ gchar *name;
+
+ scheme = g_uri_parse_scheme (item->uri);
+ if (g_strcmp0 (scheme, "file") == 0)
+ {
+ filename = g_filename_from_uri ((const gchar *)item->uri, NULL, NULL);
+ if (filename)
+ {
+ path = g_path_get_dirname (filename);
+ item->path = g_filename_to_utf8 (path, -1, NULL, NULL, NULL);
+ g_free (path);
+
+ name = g_path_get_basename (filename);
+ item->name = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
+ g_free (name);
+
+ normalized_filename = g_utf8_normalize (filename, -1, G_NORMALIZE_ALL);
+ g_free (filename);
+ }
+ }
+ else
+ {
+ GFile *file;
+ gchar *parse_name;
+
+ file = g_file_new_for_uri (item->uri);
+ item->path = gedit_utils_location_get_dirname_for_display (file);
+ item->name = gedit_utils_basename_for_display (file);
+ parse_name = g_file_get_parse_name (file);
+ g_object_unref (file);
+
+ normalized_filename = g_utf8_normalize (parse_name, -1, G_NORMALIZE_ALL);
+ g_free (parse_name);
+ }
+
+ if (normalized_filename)
+ {
+ candidate = g_utf8_casefold (normalized_filename, -1);
+ g_free (normalized_filename);
+ }
+
+ g_free (scheme);
+
+ return candidate;
+}
+
+static inline gboolean
+is_filter_in_candidate (const gchar *candidate,
+ const gchar *filter)
+{
+ gchar *candidate_fold;
+ gboolean ret;
+
+ g_assert (candidate != NULL);
+ g_assert (filter != NULL);
+
+ candidate_fold = g_utf8_casefold (candidate, -1);
+ ret = (strstr (candidate_fold, filter) != NULL);
+
+ g_free (candidate_fold);
+ return ret;
+}
+
+/* If filter == NULL then items are
+ * not checked against the filter.
+ */
+static GList *
+fileitem_list_filter (GList *items,
+ const gchar *filter)
+{
+ GList *new_items = NULL;
+ GList *l;
+ gchar *filter_fold = NULL;
+
+ if (filter != NULL)
+ filter_fold = g_utf8_casefold (filter, -1);
+
+ for (l = items; l != NULL; l = l->next)
+ {
+ FileItem *item;
+ gchar *candidate;
+
+ item = l->data;
+ candidate = fileitem_setup (item);
+ if (candidate != NULL)
+ {
+ if (filter == NULL || is_filter_in_candidate (candidate, filter_fold))
+ {
+ new_items = g_list_prepend (new_items,
+ gedit_open_document_selector_copy_fileitem_item (item));
+ }
+
+ g_free (candidate);
+ }
+ }
+
+ g_free (filter_fold);
+ new_items = g_list_reverse (new_items);
+ return new_items;
+}
+
+/* Remove duplicated, the HEAD of the list never change,
+ * the list passed in is modified.
+ */
+static void
+fileitem_list_remove_duplicates (GList *items)
+{
+ GList *l;
+ G_GNUC_UNUSED GList *dummy_ptr;
+
+ l = items;
+ while (l != NULL)
+ {
+ gchar *l_uri, *l1_uri;
+ GList *l1;
+
+ if ((l1 = l->next) == NULL)
+ {
+ break;
+ }
+
+ l_uri = ((FileItem *)l->data)->uri;
+ l1_uri = ((FileItem *)l1->data)->uri;
+ if (g_strcmp0 (l_uri, l1_uri) == 0)
+ {
+ gedit_open_document_selector_free_fileitem_item ((FileItem *)l1->data);
+ dummy_ptr = g_list_delete_link (items, l1);
+ }
+ else
+ {
+ l = l->next;
+ }
+ }
+}
+
+static gboolean
+real_populate_liststore (gpointer data)
+{
+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (data);
+ GeditOpenDocumentSelectorStore *selector_store;
+ GList *l;
+ GList *filter_items = NULL;
+ gchar *filter;
+ GRegex *filter_regex = NULL;
+
+ DEBUG_SELECTOR_TIMER_DECL
+ DEBUG_SELECTOR_TIMER_NEW
+
+ gtk_list_store_clear (selector->liststore);
+
+ selector_store = selector->selector_store;
+ filter = gedit_open_document_selector_store_get_filter (selector_store);
+ if (filter && *filter != '\0')
+ {
+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: all lists\n", selector););
+
+ filter_items = fileitem_list_filter (selector->all_items, (const gchar *)filter);
+ filter_items = g_list_sort_with_data (filter_items, (GCompareDataFunc)sort_items_by_mru, NULL);
+ fileitem_list_remove_duplicates (filter_items);
+
+ filter_regex = g_regex_new (filter, G_REGEX_CASELESS, 0, NULL);
+ }
+ else
+ {
+ gint recent_limit;
+ GList *recent_items;
+
+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: recent files list\n", selector););
+
+ recent_limit = gedit_open_document_selector_store_get_recent_limit (selector_store);
+
+ if (recent_limit > 0 )
+ {
+ recent_items = fileitem_list_filter (selector->recent_items, NULL);
+ filter_items = clamp_recent_items_list (recent_items, recent_limit);
+ gedit_open_document_selector_free_file_items_list (recent_items);
+ }
+ else
+ {
+ filter_items = fileitem_list_filter (selector->recent_items, NULL);
+ }
+ }
+
+ g_free (filter);
+
+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: length:%i\n",
+ selector, g_list_length (filter_items)););
+
+ /* Show the placeholder if no results, show the treeview otherwise */
+ gtk_widget_set_visible (selector->scrolled_window, (filter_items != NULL));
+ gtk_widget_set_visible (selector->placeholder_box, (filter_items == NULL));
+
+ for (l = filter_items; l != NULL; l = l->next)
+ {
+ FileItem *item;
+
+ item = l->data;
+ create_row (selector, (const FileItem *)item, filter_regex);
+ }
+
+ if (filter_regex)
+ {
+ g_regex_unref (filter_regex);
+ }
+
+ gedit_open_document_selector_free_file_items_list (filter_items);
+
+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: time:%lf\n\n",
+ selector, DEBUG_SELECTOR_TIMER_GET););
+ DEBUG_SELECTOR_TIMER_DESTROY
+
+ selector->populate_listbox_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static void
+populate_liststore (GeditOpenDocumentSelector *selector)
+{
+ /* Populate requests are compressed */
+ if (selector->populate_listbox_id != 0)
+ {
+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: idle\n", selector););
+ return;
+ }
+
+ DEBUG_SELECTOR (g_print ("Selector(%p): populate liststore: scheduled\n", selector););
+ selector->populate_listbox_id = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 30,
+ real_populate_liststore,
+ selector,
+ NULL);
+}
+
+static gboolean
+on_treeview_key_press (GtkTreeView *treeview,
+ GdkEventKey *event,
+ GeditOpenDocumentSelector *selector)
+{
+ guint keyval;
+ gboolean is_control_pressed;
+ GtkTreeSelection *tree_selection;
+ GtkTreePath *root_path;
+ GdkModifierType modifiers;
+
+ if (gdk_event_get_keyval ((GdkEvent *)event, &keyval) == TRUE)
+ {
+ tree_selection = gtk_tree_view_get_selection (treeview);
+ root_path = gtk_tree_path_new_from_string ("0");
+
+ modifiers = gtk_accelerator_get_default_mod_mask ();
+ is_control_pressed = (event->state & modifiers) == GDK_CONTROL_MASK;
+
+ if ((keyval == GDK_KEY_Up || keyval == GDK_KEY_KP_Up) &&
+ !is_control_pressed)
+ {
+ if (gtk_tree_selection_path_is_selected (tree_selection, root_path))
+ {
+ gtk_tree_selection_unselect_all (tree_selection);
+ gtk_widget_grab_focus (selector->search_entry);
+
+ return GDK_EVENT_STOP;
+ }
+ }
+ }
+
+ return GDK_EVENT_PROPAGATE;
+}
+
+static void
+on_entry_changed (GtkEntry *entry,
+ GeditOpenDocumentSelector *selector)
+{
+ const gchar *entry_text;
+
+ entry_text = gtk_entry_get_text (entry);
+ gedit_open_document_selector_store_set_filter (selector->selector_store,
+ entry_text);
+
+ if (gtk_widget_get_mapped ( GTK_WIDGET (selector)))
+ {
+ populate_liststore (selector);
+ }
+}
+
+static void
+on_entry_activated (GtkEntry *entry,
+ GeditOpenDocumentSelector *selector)
+{
+ const gchar *entry_text;
+ GtkTreeSelection *selection;
+ gchar *uri;
+ GFile *file;
+ gchar *scheme;
+
+ entry_text = gtk_entry_get_text (entry);
+ scheme = g_uri_parse_scheme (entry_text);
+ if (!scheme)
+ {
+ const gchar *home_dir = g_get_home_dir ();
+
+ if ( home_dir != NULL && g_str_has_prefix (entry_text, "~/"))
+ {
+ uri = g_strconcat ("file://", home_dir, "/", entry_text + 2, NULL);
+ }
+ else
+ {
+ uri = g_strconcat ("file://", entry_text, NULL);
+ }
+ }
+ else
+ {
+ g_free (scheme);
+ uri = g_strdup (entry_text);
+ }
+
+ file = g_file_new_for_uri (uri);
+ if (g_file_query_exists (file, NULL))
+ {
+ DEBUG_SELECTOR (g_print ("Selector(%p): search entry activated : loading '%s'\n",
+ selector, uri););
+
+ gtk_entry_set_text (entry, "");
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (selector->treeview));
+ gtk_tree_selection_unselect_all (selection);
+
+ g_signal_emit (G_OBJECT (selector), signals[SELECTOR_FILE_ACTIVATED], 0, uri);
+ }
+
+ g_object_unref (file);
+}
+
+static void
+gedit_open_document_selector_dispose (GObject *object)
+{
+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (object);
+
+ if (selector->populate_listbox_id != 0)
+ {
+ g_source_remove (selector->populate_listbox_id);
+ selector->populate_listbox_id = 0;
+ }
+
+ g_clear_pointer (&selector->name_font, pango_font_description_free);
+ g_clear_pointer (&selector->path_font, pango_font_description_free);
+ g_clear_pointer (&selector->match_markup_color, g_free);
+
+ if (selector->recent_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector->recent_items);
+ selector->recent_items = NULL;
+ }
+
+ if (selector->home_dir_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector->home_dir_items);
+ selector->home_dir_items = NULL;
+ }
+
+ if (selector->desktop_dir_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector->desktop_dir_items);
+ selector->desktop_dir_items = NULL;
+ }
+
+ if (selector->local_bookmarks_dir_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector->local_bookmarks_dir_items);
+ selector->local_bookmarks_dir_items = NULL;
+ }
+
+ if (selector->file_browser_root_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector->file_browser_root_items);
+ selector->file_browser_root_items = NULL;
+ }
+
+ if (selector->active_doc_dir_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector->active_doc_dir_items);
+ selector->active_doc_dir_items = NULL;
+ }
+
+ if (selector->current_docs_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector->current_docs_items);
+ selector->current_docs_items = NULL;
+ }
+
+ if (selector->all_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector->all_items);
+ selector->all_items = NULL;
+ }
+
+ G_OBJECT_CLASS (gedit_open_document_selector_parent_class)->dispose (object);
+}
+
+static void
+on_row_activated (GtkTreeView *treeview,
+ GtkTreePath *path,
+ GtkTreeViewColumn *column G_GNUC_UNUSED,
+ GeditOpenDocumentSelector *selector)
+{
+ GtkTreeModel *liststore = GTK_TREE_MODEL (selector->liststore);
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ gchar *uri;
+
+ g_return_if_fail (gtk_tree_model_get_iter (liststore, &iter, path));
+ gtk_tree_model_get (liststore, &iter,
+ URI_COLUMN, &uri,
+ -1);
+
+ selection = gtk_tree_view_get_selection (treeview);
+ gtk_tree_selection_unselect_all (selection);
+
+ /* Leak of uri */
+ g_signal_emit (G_OBJECT (selector), signals[SELECTOR_FILE_ACTIVATED], 0, uri);
+}
+
+static void
+update_list_cb (GeditOpenDocumentSelectorStore *selector_store,
+ GAsyncResult *res,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ GList *list;
+ GError *error;
+ PushMessage *message;
+ ListType type;
+ GeditOpenDocumentSelector *selector;
+
+ list = gedit_open_document_selector_store_update_list_finish (selector_store, res, &error);
+ message = g_task_get_task_data (G_TASK (res));
+ selector = message->selector;
+ type = message->type;
+
+ DEBUG_SELECTOR (g_print ("Selector(%p): update_list_cb - type:%s, length:%i\n",
+ selector, list_type_string[type], g_list_length (list)););
+
+ switch (type)
+ {
+ case GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST:
+ gedit_open_document_selector_free_file_items_list (selector->recent_items);
+ selector->recent_items = list;
+ break;
+
+ case GEDIT_OPEN_DOCUMENT_SELECTOR_HOME_DIR_LIST:
+ gedit_open_document_selector_free_file_items_list (selector->home_dir_items);
+ selector->home_dir_items = list;
+ break;
+
+ case GEDIT_OPEN_DOCUMENT_SELECTOR_DESKTOP_DIR_LIST:
+ gedit_open_document_selector_free_file_items_list (selector->desktop_dir_items);
+ selector->desktop_dir_items = list;
+ break;
+
+ case GEDIT_OPEN_DOCUMENT_SELECTOR_LOCAL_BOOKMARKS_DIR_LIST:
+ gedit_open_document_selector_free_file_items_list (selector->local_bookmarks_dir_items);
+ selector->local_bookmarks_dir_items = list;
+ break;
+
+ case GEDIT_OPEN_DOCUMENT_SELECTOR_FILE_BROWSER_ROOT_DIR_LIST:
+ gedit_open_document_selector_free_file_items_list (selector->file_browser_root_items);
+ selector->file_browser_root_items = list;
+ break;
+
+ case GEDIT_OPEN_DOCUMENT_SELECTOR_ACTIVE_DOC_DIR_LIST:
+ gedit_open_document_selector_free_file_items_list (selector->active_doc_dir_items);
+ selector->active_doc_dir_items = list;
+ break;
+
+ case GEDIT_OPEN_DOCUMENT_SELECTOR_CURRENT_DOCS_LIST:
+ gedit_open_document_selector_free_file_items_list (selector->current_docs_items);
+ selector->current_docs_items = list;
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+
+ selector->all_items = compute_all_items_list (selector);
+ populate_liststore (selector);
+}
+
+static void
+gedit_open_document_selector_constructed (GObject *object)
+{
+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (object);
+
+ G_OBJECT_CLASS (gedit_open_document_selector_parent_class)->constructed (object);
+
+ DEBUG_SELECTOR (g_print ("Selector(%p): constructed - ask recent file list\n", selector););
+
+ gedit_open_document_selector_store_update_list_async (selector->selector_store,
+ selector,
+ NULL,
+ (GAsyncReadyCallback)update_list_cb,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST,
+ selector);
+}
+
+static void
+gedit_open_document_selector_mapped (GtkWidget *widget)
+{
+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (widget);
+ ListType list_number;
+
+ /* We update all the lists */
+ DEBUG_SELECTOR (g_print ("Selector(%p): mapped - ask all lists\n", selector););
+
+ for (list_number = 0; list_number < GEDIT_OPEN_DOCUMENT_SELECTOR_LIST_TYPE_NUM_OF_LISTS; list_number++)
+ {
+ gedit_open_document_selector_store_update_list_async (selector->selector_store,
+ selector,
+ NULL,
+ (GAsyncReadyCallback)update_list_cb,
+ list_number,
+ selector);
+ }
+
+ GTK_WIDGET_CLASS (gedit_open_document_selector_parent_class)->map (widget);
+}
+
+static GtkSizeRequestMode
+gedit_open_document_selector_get_request_mode (GtkWidget *widget G_GNUC_UNUSED)
+{
+ return GTK_SIZE_REQUEST_CONSTANT_SIZE;
+}
+
+static void
+gedit_open_document_selector_get_preferred_width (GtkWidget *widget G_GNUC_UNUSED,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ *minimum_width = *natural_width = OPEN_DOCUMENT_SELECTOR_WIDTH;
+}
+
+static void
+gedit_open_document_selector_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_WINDOW:
+ selector->window = g_value_get_object (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gedit_open_document_selector_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GeditOpenDocumentSelector *selector = GEDIT_OPEN_DOCUMENT_SELECTOR (object);
+
+ switch (prop_id)
+ {
+ case PROP_WINDOW:
+ g_value_set_object (value, selector->window);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gedit_open_document_selector_file_activated (GeditOpenDocumentSelector *selector G_GNUC_UNUSED,
+ const gchar *uri G_GNUC_UNUSED)
+{
+ /* Do nothing in the default handler */
+}
+
+static void
+gedit_open_document_selector_class_init (GeditOpenDocumentSelectorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->constructed = gedit_open_document_selector_constructed;
+ object_class->dispose = gedit_open_document_selector_dispose;
+
+ object_class->get_property = gedit_open_document_selector_get_property;
+ object_class->set_property = gedit_open_document_selector_set_property;
+
+ widget_class->get_request_mode = gedit_open_document_selector_get_request_mode;
+ widget_class->get_preferred_width = gedit_open_document_selector_get_preferred_width;
+ widget_class->map = gedit_open_document_selector_mapped;
+
+ properties[PROP_WINDOW] =
+ g_param_spec_object ("window",
+ "Window",
+ "The GeditWindow this GeditOpenDocumentSelector is associated with",
+ GEDIT_TYPE_WINDOW,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, LAST_PROP, properties);
+
+ signals[SELECTOR_FILE_ACTIVATED] =
+ g_signal_new_class_handler ("file-activated",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_CALLBACK (gedit_open_document_selector_file_activated),
+ NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/gedit/ui/gedit-open-document-selector.ui");
+
+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, open_button);
+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, treeview);
+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, placeholder_box);
+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, scrolled_window);
+ gtk_widget_class_bind_template_child (widget_class, GeditOpenDocumentSelector, search_entry);
+}
+
+static void
+on_treeview_allocate (GtkWidget *widget G_GNUC_UNUSED,
+ GdkRectangle *allocation G_GNUC_UNUSED,
+ GeditOpenDocumentSelector *selector)
+{
+ GeditOpenDocumentSelectorStore *selector_store;
+ GtkStyleContext *context;
+ gint name_renderer_natural_size;
+ gint path_renderer_natural_size;
+ GtkBorder padding;
+ gint ypad;
+ gint limit_capped;
+ gint treeview_height;
+ gint grid_line_width;
+ gint row_height;
+ gint recent_limit;
+
+ selector_store = selector->selector_store;
+
+ context = gtk_widget_get_style_context (selector->treeview);
+ gtk_style_context_get_padding (context,
+ gtk_style_context_get_state (context),
+ &padding);
+
+ /* Treeview height computation */
+ gtk_cell_renderer_get_preferred_height (selector->name_renderer,
+ selector->treeview,
+ NULL,
+ &name_renderer_natural_size);
+
+ gtk_cell_renderer_get_preferred_height (selector->path_renderer,
+ selector->treeview,
+ NULL,
+ &path_renderer_natural_size);
+
+ gtk_cell_renderer_get_padding (selector->name_renderer, NULL, &ypad);
+ gtk_widget_style_get (selector->treeview, "grid-line-width", &grid_line_width, NULL);
+
+ recent_limit = gedit_open_document_selector_store_get_recent_limit (selector_store);
+
+ limit_capped = (recent_limit > 0 ) ? MIN (recent_limit, OPEN_DOCUMENT_SELECTOR_MAX_VISIBLE_ROWS) :
+ OPEN_DOCUMENT_SELECTOR_MAX_VISIBLE_ROWS;
+
+ row_height = name_renderer_natural_size +
+ path_renderer_natural_size +
+ 2 * (padding.top + padding.bottom) +
+ ypad +
+ grid_line_width;
+
+ treeview_height = row_height * limit_capped;
+ gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (selector->scrolled_window),
+ treeview_height);
+ gtk_scrolled_window_set_max_content_height (GTK_SCROLLED_WINDOW (selector->scrolled_window),
+ treeview_height);
+
+ gtk_widget_set_size_request (selector->placeholder_box, -1, treeview_height);
+}
+
+static inline gchar *
+rgba_to_hex8 (GdkRGBA *rgba)
+{
+ guint red = (guint)(0.5 + CLAMP (rgba->red, 0.0, 1.0) * 255.0);
+ guint green = (guint)(0.5 + CLAMP (rgba->green, 0.0, 1.0) * 255.0);
+ guint blue = (guint)(0.5 + CLAMP (rgba->blue, 0.0, 1.0) * 255.0);
+ guint alpha = (guint)(0.5 + CLAMP (rgba->alpha, 0.0, 1.0) * 255.0);
+ gchar *str = g_strdup_printf ("#%02X%02X%02X%02X", red, green, blue, alpha);
+
+ return str;
+}
+
+static void
+on_treeview_style_updated (GtkWidget *widget,
+ GeditOpenDocumentSelector *selector)
+{
+ GtkStyleContext *context;
+ GdkRGBA match_foreground_rgba = {0.0, 0.0, 0.0, 0.0};
+ GdkRGBA match_background_rgba = {0.0, 0.0, 0.0, 0.0};
+ gchar *match_foreground_hex8;
+ gchar *match_background_hex8;
+
+ context = gtk_widget_get_style_context (widget);
+
+ /* Name label foreground and font size styling */
+ gtk_style_context_save (context);
+ gtk_style_context_add_class (context, "open-document-selector-name-label");
+
+ gtk_style_context_get_color (context,
+ gtk_style_context_get_state (context),
+ &selector->name_label_color);
+
+ g_clear_pointer (&selector->name_font, pango_font_description_free);
+ gtk_style_context_get (context,
+ gtk_style_context_get_state (context),
+ "font", &selector->name_font,
+ NULL);
+
+ gtk_style_context_restore (context);
+
+ /* Path label foreground and font size styling */
+ gtk_style_context_save (context);
+ gtk_style_context_add_class (context, "open-document-selector-path-label");
+
+ gtk_style_context_get_color (context,
+ gtk_style_context_get_state (context),
+ &selector->path_label_color);
+
+ g_clear_pointer (&selector->path_font, pango_font_description_free);
+ gtk_style_context_get (context,
+ gtk_style_context_get_state (context),
+ "font", &selector->path_font,
+ NULL);
+
+ gtk_style_context_restore (context);
+
+ /* Match styling */
+ gtk_style_context_save (context);
+ gtk_style_context_add_class (context, "open-document-selector-match");
+
+ gtk_style_context_get_color (context,
+ gtk_style_context_get_state (context),
+ &match_foreground_rgba);
+
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+ gtk_style_context_get_background_color (context,
+ gtk_style_context_get_state (context),
+ &match_background_rgba);
+ G_GNUC_END_IGNORE_DEPRECATIONS;
+
+ gtk_style_context_restore (context);
+ g_free (selector->match_markup_color);
+
+ match_foreground_hex8 = rgba_to_hex8 (&match_foreground_rgba);
+ match_background_hex8 = rgba_to_hex8 (&match_background_rgba);
+
+ selector->match_markup_color = g_strdup_printf ("",
+ match_foreground_hex8,
+ match_background_hex8);
+
+ g_free (match_foreground_hex8);
+ g_free (match_background_hex8);
+}
+
+static void
+name_renderer_datafunc (GtkTreeViewColumn *column G_GNUC_UNUSED,
+ GtkCellRenderer *name_renderer G_GNUC_UNUSED,
+ GtkTreeModel *liststore G_GNUC_UNUSED,
+ GtkTreeIter *iter G_GNUC_UNUSED,
+ GeditOpenDocumentSelector *selector)
+{
+ g_object_set (selector->name_renderer, "foreground-rgba", &selector->name_label_color, NULL);
+ g_object_set (selector->name_renderer, "font-desc", selector->name_font, NULL);
+}
+
+static void
+path_renderer_datafunc (GtkTreeViewColumn *column G_GNUC_UNUSED,
+ GtkCellRenderer *path_renderer G_GNUC_UNUSED,
+ GtkTreeModel *liststore G_GNUC_UNUSED,
+ GtkTreeIter *iter G_GNUC_UNUSED,
+ GeditOpenDocumentSelector *selector)
+{
+ g_object_set (selector->path_renderer, "foreground-rgba", &selector->path_label_color, NULL);
+ g_object_set (selector->path_renderer, "font-desc", selector->path_font, NULL);
+}
+
+static void
+setup_treeview (GeditOpenDocumentSelector *selector)
+{
+ GtkTreeViewColumn *column;
+ GtkCellArea *cell_area;
+ GtkStyleContext *context;
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (selector->treeview), GTK_TREE_MODEL (selector->liststore));
+ g_object_unref(GTK_TREE_MODEL (selector->liststore));
+
+ selector->name_renderer = gtk_cell_renderer_text_new ();
+ selector->path_renderer = gtk_cell_renderer_text_new ();
+
+ g_object_set (selector->name_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ g_object_set (selector->path_renderer, "ellipsize", PANGO_ELLIPSIZE_START, NULL);
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
+
+ gtk_tree_view_column_pack_start (column, selector->name_renderer, TRUE);
+ gtk_tree_view_column_pack_start (column, selector->path_renderer, TRUE);
+
+ gtk_tree_view_column_set_attributes (column, selector->name_renderer, "markup", NAME_COLUMN, NULL);
+ gtk_tree_view_column_set_attributes (column, selector->path_renderer, "markup", PATH_COLUMN, NULL);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (selector->treeview), column);
+ cell_area = gtk_cell_layout_get_area (GTK_CELL_LAYOUT (column));
+ gtk_orientable_set_orientation (GTK_ORIENTABLE (cell_area), GTK_ORIENTATION_VERTICAL);
+
+ context = gtk_widget_get_style_context (selector->treeview);
+ gtk_style_context_add_class (context, "open-document-selector-treeview");
+
+ gtk_tree_view_column_set_cell_data_func (column,
+ selector->name_renderer,
+ (GtkTreeCellDataFunc)name_renderer_datafunc,
+ selector,
+ NULL);
+
+ gtk_tree_view_column_set_cell_data_func (column,
+ selector->path_renderer,
+ (GtkTreeCellDataFunc)path_renderer_datafunc,
+ selector,
+ NULL);
+}
+
+static void
+gedit_open_document_selector_init (GeditOpenDocumentSelector *selector)
+{
+ gedit_debug (DEBUG_WINDOW);
+
+ gtk_widget_init_template (GTK_WIDGET (selector));
+
+ selector->selector_store = gedit_open_document_selector_store_get_default ();
+
+ selector->liststore = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ setup_treeview (selector);
+
+ g_signal_connect (selector->search_entry,
+ "changed",
+ G_CALLBACK (on_entry_changed),
+ selector);
+
+ g_signal_connect (selector->search_entry,
+ "activate",
+ G_CALLBACK (on_entry_activated),
+ selector);
+
+ g_signal_connect (selector->treeview,
+ "row-activated",
+ G_CALLBACK (on_row_activated),
+ selector);
+
+ g_signal_connect (selector->treeview,
+ "size-allocate",
+ G_CALLBACK (on_treeview_allocate),
+ selector);
+
+ g_signal_connect (selector->treeview,
+ "key-press-event",
+ G_CALLBACK (on_treeview_key_press),
+ selector);
+
+ g_signal_connect (selector->treeview,
+ "style-updated",
+ G_CALLBACK (on_treeview_style_updated),
+ selector);
+}
+
+GeditOpenDocumentSelector *
+gedit_open_document_selector_new (GeditWindow *window)
+{
+ g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
+
+ return g_object_new (GEDIT_TYPE_OPEN_DOCUMENT_SELECTOR,
+ "window", window,
+ NULL);
+}
+
+GeditWindow *
+gedit_open_document_selector_get_window (GeditOpenDocumentSelector *selector)
+{
+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR (selector), NULL);
+
+ return selector->window;
+}
+
+GtkWidget *
+gedit_open_document_selector_get_search_entry (GeditOpenDocumentSelector *selector)
+{
+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR (selector), NULL);
+
+ return selector->search_entry;
+}
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-open-document-selector.h gedit-41.0/gedit/gedit-open-document-selector.h
--- gedit-40.1/gedit/gedit-open-document-selector.h 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-open-document-selector.h 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,44 @@
+/*
+ * gedit-open-document-selector.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2014 - Sébastien Lafargue
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+#ifndef GEDIT_OPEN_DOCUMENT_SELECTOR_H
+#define GEDIT_OPEN_DOCUMENT_SELECTOR_H
+
+#include
+#include "gedit-window.h"
+
+#include
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_OPEN_DOCUMENT_SELECTOR (gedit_open_document_selector_get_type ())
+
+G_DECLARE_FINAL_TYPE (GeditOpenDocumentSelector, gedit_open_document_selector, GEDIT, OPEN_DOCUMENT_SELECTOR, GtkBox)
+
+GeditOpenDocumentSelector *gedit_open_document_selector_new (GeditWindow *window);
+
+GeditWindow *gedit_open_document_selector_get_window (GeditOpenDocumentSelector *selector);
+
+GtkWidget *gedit_open_document_selector_get_search_entry (GeditOpenDocumentSelector *selector);
+
+G_END_DECLS
+
+#endif /* GEDIT_OPEN_DOCUMENT_SELECTOR_H */
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-open-document-selector-helper.c gedit-41.0/gedit/gedit-open-document-selector-helper.c
--- gedit-40.1/gedit/gedit-open-document-selector-helper.c 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-open-document-selector-helper.c 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,104 @@
+/*
+ * gedit-open-document-selector-helper.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2015 - Sébastien Lafargue
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+#include "gedit-open-document-selector-helper.h"
+
+void
+gedit_open_document_selector_debug_print_list (const gchar *title,
+ GList *fileitem_list)
+{
+ FileItem *item;
+ GList *l;
+ char *accessed = NULL;
+
+ g_print ("%s\n", title);
+
+ for (l = fileitem_list; l != NULL; l = l->next)
+ {
+ item = (FileItem *)l->data;
+
+ accessed = g_date_time_format_iso8601 (item->accessed);
+
+ g_print ("%s uri:%s (%s %s)\n",
+ accessed,
+ item->uri,
+ item->name,
+ item->path);
+
+ g_clear_pointer (&accessed, g_free);
+ }
+}
+
+FileItem *
+gedit_open_document_selector_create_fileitem_item (void)
+{
+ FileItem *item;
+
+ item = g_slice_new0 (FileItem);
+
+ return item;
+}
+
+void
+gedit_open_document_selector_free_fileitem_item (FileItem *item)
+{
+ g_free (item->uri);
+ g_free (item->name);
+ g_free (item->path);
+ g_clear_pointer (&item->accessed, g_date_time_unref);
+
+ g_slice_free (FileItem, item);
+}
+
+FileItem *
+gedit_open_document_selector_copy_fileitem_item (FileItem *item)
+{
+ FileItem *new_item;
+
+ new_item = gedit_open_document_selector_create_fileitem_item ();
+
+ new_item->uri = g_strdup (item->uri);
+ new_item->name = g_strdup (item->name);
+ new_item->path = g_strdup (item->path);
+ new_item->accessed = g_date_time_ref (item->accessed);
+
+ return new_item;
+}
+
+inline GList *
+gedit_open_document_selector_copy_file_items_list (const GList *file_items_list)
+{
+ GList *new_file_items_list;
+
+ new_file_items_list = g_list_copy_deep ((GList *)file_items_list,
+ (GCopyFunc)gedit_open_document_selector_copy_fileitem_item,
+ NULL);
+
+ return new_file_items_list;
+}
+
+inline void
+gedit_open_document_selector_free_file_items_list (GList *file_items_list)
+{
+ g_list_free_full (file_items_list,
+ (GDestroyNotify)gedit_open_document_selector_free_fileitem_item);
+}
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-open-document-selector-helper.h gedit-41.0/gedit/gedit-open-document-selector-helper.h
--- gedit-40.1/gedit/gedit-open-document-selector-helper.h 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-open-document-selector-helper.h 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,103 @@
+/*
+ * gedit-open-document-selector-helper.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2015 - Sébastien Lafargue
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+#ifndef GEDIT_OPEN_DOCUMENT_SELECTOR_HELPER_H
+#define GEDIT_OPEN_DOCUMENT_SELECTOR_HELPER_H
+
+#include "gedit-open-document-selector.h"
+
+#include
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+ gchar *uri;
+ gchar *name;
+ gchar *path;
+ GDateTime *accessed;
+} FileItem;
+
+typedef enum
+{
+ GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST = 0,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_HOME_DIR_LIST,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_DESKTOP_DIR_LIST,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_LOCAL_BOOKMARKS_DIR_LIST,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_FILE_BROWSER_ROOT_DIR_LIST,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_ACTIVE_DOC_DIR_LIST,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_CURRENT_DOCS_LIST,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_LIST_TYPE_NUM_OF_LISTS
+} ListType;
+
+/* Use #if 1 and rebuild to activate selector debugging and timing */
+#if 0
+#define DEBUG_OPEN_DOCUMENT_SELECTOR
+#endif
+
+#ifdef DEBUG_OPEN_DOCUMENT_SELECTOR
+G_GNUC_UNUSED static const gchar *list_type_string[] =
+{
+ "RECENT_FILES_LIST",
+ "HOME_DIR_LIST",
+ "DESKTOP_DIR_LIST",
+ "LOCAL_BOOKMARKS_DIR_LIST",
+ "FILE_BROWSER_ROOT_DIR_LIST",
+ "ACTIVE_DOC_DIR_LIST",
+ "CURRENT_DOCS_LIST"
+};
+
+#define DEBUG_SELECTOR(x) do { x; } while (0)
+#define DEBUG_SELECTOR_TIMER_DECL G_GNUC_UNUSED GTimer *debug_timer;
+#define DEBUG_SELECTOR_TIMER_NEW debug_timer = g_timer_new ();
+#define DEBUG_SELECTOR_TIMER_DESTROY g_timer_destroy (debug_timer);
+#define DEBUG_SELECTOR_TIMER_GET g_timer_elapsed (debug_timer, NULL)
+#else
+#define DEBUG_SELECTOR(x)
+#define DEBUG_SELECTOR_TIMER_DECL
+#define DEBUG_SELECTOR_TIMER_NEW
+#define DEBUG_SELECTOR_TIMER_DESTROY
+#define DEBUG_SELECTOR_TIMER_GET
+#endif
+
+typedef struct
+{
+ GeditOpenDocumentSelector *selector;
+ ListType type;
+} PushMessage;
+
+void gedit_open_document_selector_debug_print_list (const gchar *title,
+ GList *fileitem_list);
+
+GList *gedit_open_document_selector_copy_file_items_list (const GList *file_items_list);
+
+void gedit_open_document_selector_free_file_items_list (GList *file_items_list);
+
+FileItem *gedit_open_document_selector_create_fileitem_item (void);
+
+void gedit_open_document_selector_free_fileitem_item (FileItem *item);
+
+FileItem *gedit_open_document_selector_copy_fileitem_item (FileItem *item);
+
+G_END_DECLS
+
+#endif /* GEDIT_OPEN_DOCUMENT_SELECTOR_HELPER_H */
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-open-document-selector-store.c gedit-41.0/gedit/gedit-open-document-selector-store.c
--- gedit-40.1/gedit/gedit-open-document-selector-store.c 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-open-document-selector-store.c 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,839 @@
+/*
+ * gedit-open-document-selector-store.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2015 - Sébastien Lafargue
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+/* You need to call gedit_open_document_selector_store_get_default()
+ * to get a singleton #GeditOpenDocumentSelectorStore object.
+ * #GeditOpenDocumentSelectorStore is responsible of managing
+ * the recent files list and computing others lists.
+ *
+ * The lists returned are lists of FileItem structs.
+ *
+ * #GeditOpenDocumentSelectorStore is destroyed automaticly at
+ * the end of your application.
+ *
+ * Call gedit_open_document_selector_store_update_list_async() with
+ * the corresponding ListType, then in your callback, call
+ * gedit_open_document_selector_store_update_list_finish() to get
+ * in return the list of FileItem structs.
+ *
+ * The recent files list can be filtered by calling
+ * gedit_open_document_selector_store_set_filter()
+ * and you can get the actual filter by calling
+ * gedit_open_document_selector_store_get_filter()
+ * ( this is in addition to the text mime type filter)
+ *
+ * The recent files list is not capped by Gedit settings like
+ * in gedit_recent_get_items() but you still can get the limit
+ * by calling gedit_open_document_selector_store_get_recent_limit().
+ *
+ * The original setting is stored in gsettings at :
+ * org.gnome.gedit.preferences.ui
+ * with the key : max-recents
+ */
+
+#include "gedit-open-document-selector-store.h"
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include "gedit-recent.h"
+#include "gedit-utils.h"
+#include "gedit-window.h"
+#include "gedit-debug.h"
+
+struct _GeditOpenDocumentSelectorStore
+{
+ GObject parent_instance;
+
+ GSource *recent_source;
+
+ GeditRecentConfiguration recent_config;
+ gchar *filter;
+ GList *recent_items;
+ gint recent_config_limit;
+ gboolean recent_items_need_update;
+};
+
+G_LOCK_DEFINE_STATIC (recent_files_filter_lock);
+
+G_DEFINE_TYPE (GeditOpenDocumentSelectorStore, gedit_open_document_selector_store, G_TYPE_OBJECT)
+
+G_DEFINE_QUARK (gedit-open-document-selector-store-error-quark,
+ gedit_open_document_selector_store_error)
+
+
+static GDateTime *
+_get_date_time (GFileInfo *info)
+{
+ guint32 time;
+ guint32 usecs;
+ GDateTime *dt = NULL, *dt2 = NULL;
+
+ g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
+
+ time = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
+ dt = g_date_time_new_from_unix_utc (time);
+
+ usecs = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
+ dt2 = g_date_time_add_seconds (dt, usecs / (gdouble) G_USEC_PER_SEC);
+
+ g_date_time_unref (dt);
+
+ return g_steal_pointer (&dt2);
+}
+
+
+static GList *
+get_current_docs_list (GeditOpenDocumentSelectorStore *selector_store G_GNUC_UNUSED,
+ GeditOpenDocumentSelector *selector)
+{
+ GeditWindow *window;
+ GList *docs;
+ GList *l;
+ GFile *file;
+ GFileInfo *info;
+ FileItem *item;
+ GList *file_items_list = NULL;
+
+ window = gedit_open_document_selector_get_window (selector);
+
+ docs = gedit_window_get_documents (window);
+ for (l = docs; l != NULL; l = l->next)
+ {
+ file = gtk_source_file_get_location (gedit_document_get_file (l->data));
+ if (file == NULL)
+ {
+ /* In case of not saved docs */
+ continue;
+ }
+
+ info = g_file_query_info (file,
+ "time::access,time::access-usec",
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ NULL);
+ if (info == NULL)
+ {
+ continue;
+ }
+
+ item = gedit_open_document_selector_create_fileitem_item ();
+
+ item->accessed = _get_date_time (info);
+ item->uri = g_file_get_uri (file);
+
+ file_items_list = g_list_prepend (file_items_list, item);
+
+ g_object_unref (info);
+ }
+
+ g_list_free (docs);
+ return file_items_list;
+}
+
+/* Notice that a content-type attribute must have been query to work */
+static gboolean
+check_mime_type (GFileInfo *info)
+{
+ const gchar *content_type;
+ G_GNUC_UNUSED gchar *mime_type;
+
+ content_type = g_file_info_get_attribute_string (info, "standard::fast-content-type");
+ if (content_type == NULL)
+ {
+ return FALSE;
+ }
+
+#ifdef G_OS_WIN32
+ if (g_content_type_is_a (content_type, "text"))
+ {
+ return TRUE;
+ }
+
+ mime_type = g_content_type_get_mime_type (content_type);
+ if (mime_type == NULL)
+ {
+ return FALSE;
+ }
+
+ if (g_strcmp0 (mime_type, "text/plain") == 0)
+ {
+ g_free (mime_type);
+ return TRUE;
+ }
+
+ g_free (mime_type);
+#else
+ if (g_content_type_is_a (content_type, "text/plain"))
+ {
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+static GList *
+get_children_from_dir (GeditOpenDocumentSelectorStore *selector_store G_GNUC_UNUSED,
+ GFile *dir)
+{
+ GList *file_items_list = NULL;
+ GFileEnumerator *file_enum;
+ GFileInfo *info;
+ GFileType filetype;
+ GFile *file;
+ FileItem *item;
+ gboolean is_text;
+ gboolean is_correct_type;
+
+ g_return_val_if_fail (G_IS_FILE (dir), NULL);
+
+ file_enum = g_file_enumerate_children (dir,
+ "standard::name,"
+ "standard::type,"
+ "standard::fast-content-type,"
+ "time::access,time::access-usec",
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ NULL);
+ if (file_enum == NULL)
+ {
+ return NULL;
+ }
+
+ while ((info = g_file_enumerator_next_file (file_enum, NULL, NULL)))
+ {
+ filetype = g_file_info_get_file_type (info);
+ is_text = check_mime_type (info);
+ is_correct_type = (filetype == G_FILE_TYPE_REGULAR ||
+ filetype == G_FILE_TYPE_SYMBOLIC_LINK ||
+ filetype == G_FILE_TYPE_SHORTCUT);
+
+ if (is_text &&
+ is_correct_type &&
+ (file = g_file_enumerator_get_child (file_enum, info)) != NULL)
+ {
+ item = gedit_open_document_selector_create_fileitem_item ();
+ item->uri = g_file_get_uri (file);
+
+ item->accessed = _get_date_time (info);
+
+ file_items_list = g_list_prepend (file_items_list, item);
+ g_object_unref (file);
+ }
+
+ g_object_unref (info);
+ }
+
+ g_file_enumerator_close (file_enum, NULL, NULL);
+ g_object_unref (file_enum);
+
+ return file_items_list;
+}
+
+static GList *
+get_active_doc_dir_list (GeditOpenDocumentSelectorStore *selector_store,
+ GeditOpenDocumentSelector *selector)
+{
+ GeditWindow *window;
+ GeditDocument *active_doc;
+ GtkSourceFile *source_file;
+ GList *file_items_list = NULL;
+
+ window = gedit_open_document_selector_get_window (selector);
+
+ active_doc = gedit_window_get_active_document (window);
+
+ if (active_doc == NULL)
+ {
+ return NULL;
+ }
+
+ source_file = gedit_document_get_file (active_doc);
+ if (gtk_source_file_is_local (source_file))
+ {
+ GFile *location;
+ GFile *parent_dir;
+
+ location = gtk_source_file_get_location (source_file);
+ parent_dir = g_file_get_parent (location);
+
+ if (parent_dir != NULL)
+ {
+ file_items_list = get_children_from_dir (selector_store, parent_dir);
+ g_object_unref (parent_dir);
+ }
+ }
+
+ return file_items_list;
+}
+
+static GFile *
+get_file_browser_root (GeditOpenDocumentSelectorStore *selector_store G_GNUC_UNUSED,
+ GeditOpenDocumentSelector *selector)
+{
+ GeditWindow *window;
+ GeditMessageBus *bus;
+ GeditMessage *msg;
+ GFile *root = NULL;
+
+ window = gedit_open_document_selector_get_window (selector);
+
+ bus = gedit_window_get_message_bus (window);
+ if (gedit_message_bus_is_registered (bus, "/plugins/filebrowser", "get_root"))
+ {
+ msg = gedit_message_bus_send_sync (bus, "/plugins/filebrowser", "get_root", NULL, NULL);
+ g_object_get (msg, "location", &root, NULL);
+ g_object_unref (msg);
+ }
+
+ return root;
+}
+
+static GList *
+get_file_browser_root_dir_list (GeditOpenDocumentSelectorStore *selector_store,
+ GeditOpenDocumentSelector *selector)
+{
+ GFile *root;
+ GList *file_items_list = NULL;
+
+ root = get_file_browser_root (selector_store, selector);
+ if (root != NULL && g_file_is_native (root))
+ {
+ file_items_list = get_children_from_dir (selector_store, root);
+ }
+
+ g_clear_object (&root);
+ return file_items_list;
+}
+
+/* Taken and adapted from gtk+ gtkbookmarksmanager.c */
+static GList *
+read_bookmarks_file (GFile *file)
+{
+ gchar *contents;
+ gchar **lines, *space;
+ GList *uri_list = NULL;
+ gint i;
+
+ if (!g_file_load_contents (file, NULL, &contents, NULL, NULL, NULL))
+ {
+ return NULL;
+ }
+
+ lines = g_strsplit (contents, "\n", -1);
+
+ for (i = 0; lines[i]; i++)
+ {
+ if (*lines[i] == '\0')
+ {
+ continue;
+ }
+
+ if (!g_utf8_validate (lines[i], -1, NULL))
+ {
+ continue;
+ }
+
+ if ((space = strchr (lines[i], ' ')) != NULL)
+ {
+ space[0] = '\0';
+ }
+
+ uri_list = g_list_prepend (uri_list, g_strdup (lines[i]));
+ }
+
+ g_strfreev (lines);
+ g_free (contents);
+
+ return uri_list;
+}
+
+static GList *
+get_local_bookmarks_list (GeditOpenDocumentSelectorStore *selector_store,
+ GeditOpenDocumentSelector *selector G_GNUC_UNUSED)
+{
+ GList *bookmarks_uri_list = NULL;
+ GList *file_items_list = NULL;
+ GList *new_file_items_list = NULL;
+ GFile *bookmarks_file;
+ GFile *file;
+ gchar *filename;
+ GList *l;
+
+ filename = g_build_filename (g_get_user_config_dir (), "gtk-3.0", "bookmarks", NULL);
+ bookmarks_file = g_file_new_for_path (filename);
+ g_free (filename);
+
+ bookmarks_uri_list = read_bookmarks_file (bookmarks_file);
+ g_object_unref (bookmarks_file);
+
+ for (l = bookmarks_uri_list; l != NULL; l = l->next)
+ {
+ file = g_file_new_for_uri (l->data);
+ if (g_file_is_native (file))
+ {
+ new_file_items_list = get_children_from_dir (selector_store, file);
+ file_items_list = g_list_concat (file_items_list, new_file_items_list);
+ }
+
+ g_object_unref (file);
+ }
+
+ g_list_free_full (bookmarks_uri_list, g_free);
+ return file_items_list;
+}
+
+/* Taken and adapted from gtk+ gtkplacessidebar.c */
+static gboolean
+path_is_home_dir (const gchar *path)
+{
+ GFile *home_dir;
+ GFile *location;
+ const gchar *home_path;
+ gboolean res;
+
+ home_path = g_get_home_dir ();
+ if (home_path == NULL)
+ {
+ return FALSE;
+ }
+
+ home_dir = g_file_new_for_path (home_path);
+ location = g_file_new_for_path (path);
+ res = g_file_equal (home_dir, location);
+
+ g_object_unref (home_dir);
+ g_object_unref (location);
+
+ return res;
+}
+
+static GList *
+get_desktop_dir_list (GeditOpenDocumentSelectorStore *selector_store,
+ GeditOpenDocumentSelector *selector G_GNUC_UNUSED)
+{
+ GList *file_items_list = NULL;
+ const gchar *desktop_dir_name;
+ gchar *desktop_uri;
+ GFile *desktop_file;
+
+ desktop_dir_name = g_get_user_special_dir (G_USER_DIRECTORY_DESKTOP);
+
+ /* "To disable a directory, point it to the homedir."
+ * See http://freedesktop.org/wiki/Software/xdg-user-dirs
+ */
+ if (path_is_home_dir (desktop_dir_name))
+ {
+ return NULL;
+ }
+
+ desktop_uri = g_strconcat ("file://", desktop_dir_name, NULL);
+ desktop_file = g_file_new_for_uri (desktop_uri);
+ file_items_list = get_children_from_dir (selector_store, desktop_file);
+
+ g_free (desktop_uri);
+ g_object_unref (desktop_file);
+
+ return file_items_list;
+}
+
+static GList *
+get_home_dir_list (GeditOpenDocumentSelectorStore *selector_store,
+ GeditOpenDocumentSelector *selector G_GNUC_UNUSED)
+{
+ GList *file_items_list = NULL;
+ const gchar *home_name;
+ gchar *home_uri;
+ GFile *home_file;
+
+ home_name = g_get_home_dir ();
+ if (home_name == NULL)
+ {
+ return NULL;
+ }
+
+ home_uri = g_strconcat ("file://", home_name, NULL);
+ home_file = g_file_new_for_uri (home_uri);
+ file_items_list = get_children_from_dir (selector_store, home_file);
+
+ g_free (home_uri);
+ g_object_unref (home_file);
+
+ return file_items_list;
+}
+
+static GList *
+convert_recent_item_list_to_fileitem_list (GList *uri_list)
+{
+ GList *l;
+ GList *fileitem_list = NULL;
+
+ for (l = uri_list; l != NULL; l = l->next)
+ {
+ gchar *uri;
+ FileItem *item;
+
+ uri = g_strdup (gtk_recent_info_get_uri (l->data));
+
+ item = gedit_open_document_selector_create_fileitem_item ();
+ item->uri = uri;
+
+ item->accessed = g_date_time_new_from_unix_local (gtk_recent_info_get_visited (l->data));
+
+ fileitem_list = g_list_prepend (fileitem_list, item);
+ }
+
+ fileitem_list = g_list_reverse (fileitem_list);
+ return fileitem_list;
+}
+
+static GList *
+get_recent_files_list (GeditOpenDocumentSelectorStore *selector_store,
+ GeditOpenDocumentSelector *selector G_GNUC_UNUSED)
+{
+ GList *recent_items_list;
+ GList *file_items_list;
+
+ G_LOCK (recent_files_filter_lock);
+ recent_items_list = gedit_recent_get_items (&selector_store->recent_config);
+ G_UNLOCK (recent_files_filter_lock);
+
+ file_items_list = convert_recent_item_list_to_fileitem_list (recent_items_list);
+ g_list_free_full (recent_items_list, (GDestroyNotify)gtk_recent_info_unref);
+
+ return file_items_list;
+}
+
+static void
+update_list_cb (GeditOpenDocumentSelectorStore *selector_store,
+ GAsyncResult *res,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ GList *list;
+ GError *error;
+ PushMessage *message;
+ ListType type;
+
+ list = gedit_open_document_selector_store_update_list_finish (selector_store, res, &error);
+
+ message = g_task_get_task_data (G_TASK (res));
+ type = message->type;
+
+ switch (type)
+ {
+ case GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST:
+ gedit_open_document_selector_free_file_items_list (selector_store->recent_items);
+ selector_store->recent_items = list;
+
+ DEBUG_SELECTOR (g_print ("\tStore(%p): update_list_cb: type:%s, length:%i\n",
+ selector_store, list_type_string[type], g_list_length (list)););
+
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+on_recent_manager_changed (GtkRecentManager *manager G_GNUC_UNUSED,
+ gpointer user_data)
+{
+ GeditOpenDocumentSelectorStore *selector_store = GEDIT_OPEN_DOCUMENT_SELECTOR_STORE (user_data);
+
+ selector_store->recent_items_need_update = TRUE;
+ gedit_open_document_selector_store_update_list_async (selector_store,
+ NULL,
+ NULL,
+ (GAsyncReadyCallback)update_list_cb,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST,
+ NULL);
+}
+
+static void
+gedit_open_document_selector_store_dispose (GObject *object)
+{
+ GeditOpenDocumentSelectorStore *selector_store = GEDIT_OPEN_DOCUMENT_SELECTOR_STORE (object);
+
+ gedit_recent_configuration_destroy (&selector_store->recent_config);
+
+ g_clear_pointer (&selector_store->recent_source, g_source_destroy);
+ g_clear_pointer (&selector_store->filter, g_free);
+
+ if (selector_store->recent_items)
+ {
+ gedit_open_document_selector_free_file_items_list (selector_store->recent_items);
+ selector_store->recent_items = NULL;
+ }
+
+ G_OBJECT_CLASS (gedit_open_document_selector_store_parent_class)->dispose (object);
+}
+
+static void
+gedit_open_document_selector_store_class_init (GeditOpenDocumentSelectorStoreClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->dispose = gedit_open_document_selector_store_dispose;
+}
+
+/* The order of functions pointers must be the same as in
+ * ListType enum define in ./gedit-open-document-selector-helper.h
+ */
+static GList * (*list_func [])(GeditOpenDocumentSelectorStore *selector_store,
+ GeditOpenDocumentSelector *selector) =
+{
+ get_recent_files_list,
+ get_home_dir_list,
+ get_desktop_dir_list,
+ get_local_bookmarks_list,
+ get_file_browser_root_dir_list,
+ get_active_doc_dir_list,
+ get_current_docs_list
+};
+
+static gboolean
+update_recent_list (gpointer user_data)
+{
+ GeditOpenDocumentSelectorStore *selector_store;
+ GeditOpenDocumentSelector *selector;
+ PushMessage *message;
+ /* The type variable is only used when debug code activated */
+ G_GNUC_UNUSED ListType type;
+ GList *file_items_list;
+ GTask *task = G_TASK(user_data);
+
+ selector_store = g_task_get_source_object (task);
+ message = g_task_get_task_data (task);
+ selector = message->selector;
+ type = message->type;
+
+ DEBUG_SELECTOR_TIMER_DECL
+ DEBUG_SELECTOR_TIMER_NEW
+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: type:%s\n",
+ selector, list_type_string[type]););
+
+ /* Update the recent list only when it changes, copy otherwise but keep it the first time */
+ if (selector_store->recent_items != NULL && selector_store->recent_items_need_update == FALSE)
+ {
+ file_items_list = gedit_open_document_selector_copy_file_items_list (selector_store->recent_items);
+
+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: recent list copy\n", selector););
+ }
+ else
+ {
+ selector_store->recent_items_need_update = FALSE;
+ file_items_list = get_recent_files_list (selector_store, selector);
+
+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: recent list compute\n", selector););
+
+ if (selector_store->recent_items == NULL)
+ {
+ selector_store->recent_items = gedit_open_document_selector_copy_file_items_list (file_items_list);
+ }
+ }
+
+ g_task_return_pointer (task,
+ file_items_list,
+ (GDestroyNotify)gedit_open_document_selector_free_file_items_list);
+
+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: type:%s, time:%lf\n",
+ selector, list_type_string[type], DEBUG_SELECTOR_TIMER_GET););
+ DEBUG_SELECTOR_TIMER_DESTROY
+
+ selector_store->recent_source = NULL;
+ return G_SOURCE_REMOVE;
+}
+
+static void
+update_list_dispatcher (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable G_GNUC_UNUSED)
+{
+ GeditOpenDocumentSelectorStore *selector_store = source_object;
+ GeditOpenDocumentSelector *selector;
+ PushMessage *message;
+ ListType type;
+ GList *file_items_list;
+
+ message = task_data;
+ selector = message->selector;
+ type = message->type;
+
+ DEBUG_SELECTOR_TIMER_DECL
+ DEBUG_SELECTOR_TIMER_NEW
+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: Thread:%p, type:%s\n",
+ selector, g_thread_self (), list_type_string[type]););
+
+ if (type >= GEDIT_OPEN_DOCUMENT_SELECTOR_LIST_TYPE_NUM_OF_LISTS)
+ {
+ g_task_return_new_error (task,
+ GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_ERROR, TYPE_OUT_OF_RANGE,
+ "List Type out of range");
+ g_object_unref (task);
+ return;
+ }
+
+ /* Here we call the corresponding list creator function */
+ file_items_list = (*list_func[type]) (selector_store, selector);
+
+ DEBUG_SELECTOR (g_print ("\tStore(%p): store dispatcher: Thread:%p, type:%s, time:%lf\n",
+ selector, g_thread_self (), list_type_string[type], DEBUG_SELECTOR_TIMER_GET););
+ DEBUG_SELECTOR_TIMER_DESTROY
+
+ g_task_return_pointer (task,
+ file_items_list,
+ (GDestroyNotify)gedit_open_document_selector_free_file_items_list);
+}
+
+GList *
+gedit_open_document_selector_store_update_list_finish (GeditOpenDocumentSelectorStore *open_document_selector_store,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (open_document_selector_store), NULL);
+ g_return_val_if_fail (g_task_is_valid (result, open_document_selector_store), NULL);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
+
+void
+gedit_open_document_selector_store_update_list_async (GeditOpenDocumentSelectorStore *selector_store,
+ GeditOpenDocumentSelector *selector,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ ListType type,
+ gpointer user_data)
+{
+ GTask *task;
+ PushMessage *message;
+
+ g_return_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (selector_store));
+ g_return_if_fail (selector == NULL || GEDIT_IS_OPEN_DOCUMENT_SELECTOR (selector));
+
+ message = g_new (PushMessage, 1);
+ message->selector = selector;
+ message->type = type;
+
+ task = g_task_new (selector_store, cancellable, callback, user_data);
+ g_task_set_source_tag (task, gedit_open_document_selector_store_update_list_async);
+ g_task_set_priority (task, G_PRIORITY_DEFAULT);
+ g_task_set_task_data (task, message, (GDestroyNotify)g_free);
+
+ if (type == GEDIT_OPEN_DOCUMENT_SELECTOR_RECENT_FILES_LIST &&
+ selector_store->recent_source == NULL)
+ {
+ selector_store->recent_source = g_idle_source_new ();
+ g_task_attach_source (task, selector_store->recent_source, update_recent_list);
+ }
+ else
+ {
+ g_task_run_in_thread (task, update_list_dispatcher);
+ }
+
+ g_object_unref (task);
+}
+
+static void
+gedit_open_document_selector_store_init (GeditOpenDocumentSelectorStore *selector_store)
+{
+ gedit_recent_configuration_init_default (&selector_store->recent_config);
+
+ /* We remove the recent files limit since we need the whole list but
+ * we back it up as gedit_open_document_selector_store_get_recent_limit
+ * use it
+ */
+ selector_store->recent_config_limit = selector_store->recent_config.limit;
+ selector_store->recent_config.limit = -1;
+
+ g_signal_connect_object (selector_store->recent_config.manager,
+ "changed",
+ G_CALLBACK (on_recent_manager_changed),
+ selector_store,
+ 0);
+
+ selector_store->recent_items_need_update = TRUE;
+}
+
+gint
+gedit_open_document_selector_store_get_recent_limit (GeditOpenDocumentSelectorStore *selector_store)
+{
+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (selector_store), -1);
+
+ return selector_store->recent_config_limit;
+}
+
+void
+gedit_open_document_selector_store_set_filter (GeditOpenDocumentSelectorStore *selector_store,
+ const gchar *filter)
+{
+ gchar *old_filter;
+
+ g_return_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (selector_store));
+ g_return_if_fail (filter != NULL);
+
+ G_LOCK (recent_files_filter_lock);
+
+ old_filter = selector_store->filter;
+ selector_store->filter = g_strdup (filter);
+
+ G_UNLOCK (recent_files_filter_lock);
+ g_free (old_filter);
+}
+
+gchar *
+gedit_open_document_selector_store_get_filter (GeditOpenDocumentSelectorStore *selector_store)
+{
+ gchar *recent_filter;
+
+ g_return_val_if_fail (GEDIT_IS_OPEN_DOCUMENT_SELECTOR_STORE (selector_store), NULL);
+
+ G_LOCK (recent_files_filter_lock);
+ recent_filter = g_strdup (selector_store->filter);
+ G_UNLOCK (recent_files_filter_lock);
+
+ return recent_filter;
+}
+
+/* Gets a unique instance of #GeditOpenDocumentSelectorStore
+ *
+ * Returns: (transfer none): A unique #GeditOpenDocumentSelectorStore.
+ * Do not ref or unref it, it will be destroyed at the end of the application.
+ */
+GeditOpenDocumentSelectorStore *
+gedit_open_document_selector_store_get_default (void)
+{
+ static GeditOpenDocumentSelectorStore *instance;
+
+ if (instance == NULL)
+ {
+ instance = g_object_new (GEDIT_TYPE_OPEN_DOCUMENT_SELECTOR_STORE, NULL);
+ g_object_add_weak_pointer (G_OBJECT (instance), (gpointer) &instance);
+ }
+
+ return instance;
+}
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-open-document-selector-store.h gedit-41.0/gedit/gedit-open-document-selector-store.h
--- gedit-40.1/gedit/gedit-open-document-selector-store.h 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-open-document-selector-store.h 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,68 @@
+/*
+ * gedit-open-document-selector-store.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2015 - Sébastien Lafargue
+ *
+ * gedit 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.
+ *
+ * gedit 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 gedit. If not, see .
+ */
+
+#ifndef GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_H
+#define GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_H
+
+#include "gedit-open-document-selector-helper.h"
+#include "gedit-open-document-selector.h"
+
+#include
+#include
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_OPEN_DOCUMENT_SELECTOR_STORE (gedit_open_document_selector_store_get_type ())
+
+G_DECLARE_FINAL_TYPE (GeditOpenDocumentSelectorStore, gedit_open_document_selector_store, GEDIT, OPEN_DOCUMENT_SELECTOR_STORE, GObject)
+
+#define GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_ERROR gedit_open_document_selector_store_error_quark ()
+
+typedef enum
+{
+ TYPE_OUT_OF_RANGE
+} GeditOpenDocumentSelectorStoreError;
+
+GQuark gedit_open_document_selector_store_error_quark (void);
+
+gint gedit_open_document_selector_store_get_recent_limit (GeditOpenDocumentSelectorStore *store);
+
+void gedit_open_document_selector_store_set_filter (GeditOpenDocumentSelectorStore *store,
+ const gchar *filter);
+
+gchar *gedit_open_document_selector_store_get_filter (GeditOpenDocumentSelectorStore *store);
+
+GList *gedit_open_document_selector_store_update_list_finish (GeditOpenDocumentSelectorStore *open_document_selector_store,
+ GAsyncResult *res,
+ GError **error);
+
+void gedit_open_document_selector_store_update_list_async (GeditOpenDocumentSelectorStore *open_document_selector_store,
+ GeditOpenDocumentSelector *open_document_selector,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ ListType type,
+ gpointer user_data);
+
+GeditOpenDocumentSelectorStore *gedit_open_document_selector_store_get_default (void);
+
+G_END_DECLS
+
+#endif /* GEDIT_OPEN_DOCUMENT_SELECTOR_STORE_H */
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-pango.c gedit-41.0/gedit/gedit-pango.c
--- gedit-40.1/gedit/gedit-pango.c 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-pango.c 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,230 @@
+/* gedit-pango.c
+ *
+ * This file is a copy of pango_font_description_to_css from gtk gtkfontbutton.c
+ *
+ * Copyright (C) 2016 Matthias Clasen
+ *
+ * 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 .
+ */
+
+#define G_LOG_DOMAIN "gedit-pango"
+
+#include "config.h"
+
+#include "gedit-pango.h"
+
+#if PANGO_VERSION_CHECK (1, 44, 0)
+static void
+add_css_variations (GString *s,
+ const char *variations)
+{
+ const char *p;
+ const char *sep = "";
+
+ if (variations == NULL || variations[0] == '\0')
+ {
+ g_string_append (s, "normal");
+ return;
+ }
+
+ p = variations;
+ while (p && *p)
+ {
+ const char *start;
+ const char *end, *end2;
+ double value;
+ char name[5];
+
+ while (g_ascii_isspace (*p)) p++;
+
+ start = p;
+ end = strchr (p, ',');
+ if (end && (end - p < 6))
+ goto skip;
+
+ name[0] = p[0];
+ name[1] = p[1];
+ name[2] = p[2];
+ name[3] = p[3];
+ name[4] = '\0';
+
+ p += 4;
+ while (g_ascii_isspace (*p)) p++;
+ if (*p == '=') p++;
+
+ if (p - start < 5)
+ goto skip;
+
+ value = g_ascii_strtod (p, (char **) &end2);
+
+ while (end2 && g_ascii_isspace (*end2)) end2++;
+
+ if (end2 && (*end2 != ',' && *end2 != '\0'))
+ goto skip;
+
+ g_string_append_printf (s, "%s\"%s\" %g", sep, name, value);
+ sep = ", ";
+
+skip:
+ p = end ? end + 1 : NULL;
+ }
+}
+#endif
+
+/**
+ * gedit_pango_font_description_to_css:
+ *
+ * This function will generate CSS suitable for Gtk's CSS engine
+ * based on the properties of the #PangoFontDescription.
+ *
+ * Returns: (transfer full): A newly allocated string containing the
+ * CSS describing the font description.
+ */
+gchar *
+gedit_pango_font_description_to_css (const PangoFontDescription *desc)
+{
+ GString *s;
+ PangoFontMask set;
+
+ s = g_string_new ("");
+
+ set = pango_font_description_get_set_fields (desc);
+ if (set & PANGO_FONT_MASK_FAMILY)
+ {
+ g_string_append (s, "font-family: \"");
+ g_string_append (s, pango_font_description_get_family (desc));
+ g_string_append (s, "\"; ");
+ }
+ if (set & PANGO_FONT_MASK_STYLE)
+ {
+ switch (pango_font_description_get_style (desc))
+ {
+ case PANGO_STYLE_NORMAL:
+ g_string_append (s, "font-style: normal; ");
+ break;
+ case PANGO_STYLE_OBLIQUE:
+ g_string_append (s, "font-style: oblique; ");
+ break;
+ case PANGO_STYLE_ITALIC:
+ g_string_append (s, "font-style: italic; ");
+ break;
+ default:
+ break;
+ }
+ }
+ if (set & PANGO_FONT_MASK_VARIANT)
+ {
+ switch (pango_font_description_get_variant (desc))
+ {
+ case PANGO_VARIANT_NORMAL:
+ g_string_append (s, "font-variant: normal; ");
+ break;
+ case PANGO_VARIANT_SMALL_CAPS:
+ g_string_append (s, "font-variant: small-caps; ");
+ break;
+ default:
+ break;
+ }
+ }
+ if (set & PANGO_FONT_MASK_WEIGHT)
+ {
+ switch (pango_font_description_get_weight (desc))
+ {
+ case PANGO_WEIGHT_THIN:
+ g_string_append (s, "font-weight: 100; ");
+ break;
+ case PANGO_WEIGHT_ULTRALIGHT:
+ g_string_append (s, "font-weight: 200; ");
+ break;
+ case PANGO_WEIGHT_LIGHT:
+ case PANGO_WEIGHT_SEMILIGHT:
+ g_string_append (s, "font-weight: 300; ");
+ break;
+ case PANGO_WEIGHT_BOOK:
+ case PANGO_WEIGHT_NORMAL:
+ g_string_append (s, "font-weight: 400; ");
+ break;
+ case PANGO_WEIGHT_MEDIUM:
+ g_string_append (s, "font-weight: 500; ");
+ break;
+ case PANGO_WEIGHT_SEMIBOLD:
+ g_string_append (s, "font-weight: 600; ");
+ break;
+ case PANGO_WEIGHT_BOLD:
+ g_string_append (s, "font-weight: 700; ");
+ break;
+ case PANGO_WEIGHT_ULTRABOLD:
+ g_string_append (s, "font-weight: 800; ");
+ break;
+ case PANGO_WEIGHT_HEAVY:
+ case PANGO_WEIGHT_ULTRAHEAVY:
+ g_string_append (s, "font-weight: 900; ");
+ break;
+ default:
+ break;
+ }
+ }
+ if (set & PANGO_FONT_MASK_STRETCH)
+ {
+ switch (pango_font_description_get_stretch (desc))
+ {
+ case PANGO_STRETCH_ULTRA_CONDENSED:
+ g_string_append (s, "font-stretch: ultra-condensed; ");
+ break;
+ case PANGO_STRETCH_EXTRA_CONDENSED:
+ g_string_append (s, "font-stretch: extra-condensed; ");
+ break;
+ case PANGO_STRETCH_CONDENSED:
+ g_string_append (s, "font-stretch: condensed; ");
+ break;
+ case PANGO_STRETCH_SEMI_CONDENSED:
+ g_string_append (s, "font-stretch: semi-condensed; ");
+ break;
+ case PANGO_STRETCH_NORMAL:
+ g_string_append (s, "font-stretch: normal; ");
+ break;
+ case PANGO_STRETCH_SEMI_EXPANDED:
+ g_string_append (s, "font-stretch: semi-expanded; ");
+ break;
+ case PANGO_STRETCH_EXPANDED:
+ g_string_append (s, "font-stretch: expanded; ");
+ break;
+ case PANGO_STRETCH_EXTRA_EXPANDED:
+ break;
+ case PANGO_STRETCH_ULTRA_EXPANDED:
+ g_string_append (s, "font-stretch: ultra-expanded; ");
+ break;
+ default:
+ break;
+ }
+ }
+ if (set & PANGO_FONT_MASK_SIZE)
+ {
+ g_string_append_printf (s, "font-size: %dpt; ", pango_font_description_get_size (desc) / PANGO_SCALE);
+ }
+
+#if PANGO_VERSION_CHECK (1, 44, 0)
+ if (set & PANGO_FONT_MASK_VARIATIONS)
+ {
+ const char *variations;
+
+ g_string_append (s, "font-variation-settings: ");
+ variations = pango_font_description_get_variations (desc);
+ add_css_variations (s, variations);
+ g_string_append (s, "; ");
+ }
+#endif
+
+ return g_string_free (s, FALSE);
+}
diff -Nru gedit-40.1/gedit/gedit-pango.h gedit-41.0/gedit/gedit-pango.h
--- gedit-40.1/gedit/gedit-pango.h 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-pango.h 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,28 @@
+/* gedit-pango.h
+ *
+ * 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 GEDIT_PANGO_H
+#define GEDIT_PANGO_H
+
+#include
+
+G_BEGIN_DECLS
+
+gchar *gedit_pango_font_description_to_css (const PangoFontDescription *font_desc);
+
+G_END_DECLS
+
+#endif /* GEDIT_PANGO_H */
diff -Nru gedit-40.1/gedit/gedit-preferences-dialog.c gedit-41.0/gedit/gedit-preferences-dialog.c
--- gedit-40.1/gedit/gedit-preferences-dialog.c 2021-04-17 05:45:36.120558300 +0000
+++ gedit-41.0/gedit/gedit-preferences-dialog.c 2022-02-14 13:58:26.000000000 +0000
@@ -23,14 +23,22 @@
#include "gedit-preferences-dialog.h"
+#include
+#include
+#include
+
#include
#include
-#include
+#include
#include
+#include "gedit-utils.h"
#include "gedit-debug.h"
+#include "gedit-document.h"
#include "gedit-dirs.h"
#include "gedit-settings.h"
+#include "gedit-utils.h"
+#include "gedit-file-chooser-dialog.h"
/*
* gedit-preferences dialog is a singleton since we don't
@@ -83,9 +91,11 @@
GtkWidget *schemes_list;
GtkWidget *install_scheme_button;
GtkWidget *uninstall_scheme_button;
+ GtkWidget *schemes_scrolled_window;
GtkWidget *schemes_toolbar;
- GtkFileChooserNative *
- install_scheme_file_chooser;
+
+ GeditFileChooserDialog *
+ install_scheme_file_schooser;
/* Tabs */
GtkWidget *tabs_width_spinbutton;
@@ -105,6 +115,7 @@
GtkWidget *display_line_numbers_checkbutton;
GtkWidget *display_statusbar_checkbutton;
+ GtkWidget *display_overview_map_checkbutton;
GtkWidget *display_grid_checkbutton;
/* Right margin */
@@ -170,6 +181,7 @@
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_line_numbers_checkbutton);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_statusbar_checkbutton);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_grid_checkbutton);
+ gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_overview_map_checkbutton);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, right_margin_checkbutton);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, right_margin_position_grid);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, right_margin_position_spinbutton);
@@ -187,6 +199,7 @@
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, font_button);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, font_grid);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, schemes_list);
+ gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, schemes_scrolled_window);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, install_scheme_button);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, uninstall_scheme_button);
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, schemes_toolbar);
@@ -387,6 +400,11 @@
"active",
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
g_settings_bind (dlg->editor,
+ GEDIT_SETTINGS_DISPLAY_OVERVIEW_MAP,
+ dlg->display_overview_map_checkbutton,
+ "active",
+ G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
+ g_settings_bind (dlg->editor,
GEDIT_SETTINGS_DISPLAY_RIGHT_MARGIN,
dlg->right_margin_checkbutton,
"active",
@@ -434,7 +452,7 @@
/* Get values */
settings = _gedit_settings_get_singleton ();
- system_font = _gedit_settings_get_system_font (settings);
+ system_font = gedit_settings_get_system_font (settings);
label = g_strdup_printf(_("_Use the system fixed width font (%s)"),
system_font);
@@ -462,172 +480,255 @@
}
static void
-update_style_scheme_buttons_sensisitivity (GeditPreferencesDialog *dlg)
+set_buttons_sensisitivity_according_to_scheme (GeditPreferencesDialog *dlg,
+ GtkSourceStyleScheme *scheme)
{
- GtkSourceStyleScheme *selected_style_scheme;
gboolean editable = FALSE;
- selected_style_scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
-
- if (selected_style_scheme != NULL)
+ if (scheme != NULL)
{
const gchar *filename;
- filename = gtk_source_style_scheme_get_filename (selected_style_scheme);
+ filename = gtk_source_style_scheme_get_filename (scheme);
if (filename != NULL)
{
editable = g_str_has_prefix (filename, gedit_dirs_get_user_styles_dir ());
}
}
- gtk_widget_set_sensitive (dlg->uninstall_scheme_button, editable);
+ gtk_widget_set_sensitive (dlg->uninstall_scheme_button,
+ editable);
}
static void
-style_scheme_notify_cb (GtkSourceStyleSchemeChooser *chooser,
- GParamSpec *pspec,
- GeditPreferencesDialog *dlg)
+style_scheme_changed (GtkSourceStyleSchemeChooser *chooser,
+ GParamSpec *pspec,
+ GeditPreferencesDialog *dlg)
{
- update_style_scheme_buttons_sensisitivity (dlg);
+ GtkSourceStyleScheme *scheme;
+ const gchar *id;
+
+ scheme = gtk_source_style_scheme_chooser_get_style_scheme (chooser);
+ id = gtk_source_style_scheme_get_id (scheme);
+
+ g_settings_set_string (dlg->editor, GEDIT_SETTINGS_SCHEME, id);
+ set_buttons_sensisitivity_according_to_scheme (dlg, scheme);
}
-static GFile *
-get_user_style_scheme_destination_file (GFile *src_file)
+static GtkSourceStyleScheme *
+get_default_color_scheme (GeditPreferencesDialog *dlg)
{
- gchar *basename;
- const gchar *styles_dir;
- GFile *dest_file;
+ GtkSourceStyleSchemeManager *manager;
+ GtkSourceStyleScheme *scheme = NULL;
+ gchar *pref_id;
- basename = g_file_get_basename (src_file);
- g_return_val_if_fail (basename != NULL, NULL);
+ manager = gtk_source_style_scheme_manager_get_default ();
- styles_dir = gedit_dirs_get_user_styles_dir ();
- dest_file = g_file_new_build_filename (styles_dir, basename, NULL);
+ pref_id = g_settings_get_string (dlg->editor,
+ GEDIT_SETTINGS_SCHEME);
- g_free (basename);
- return dest_file;
+ scheme = gtk_source_style_scheme_manager_get_scheme (manager,
+ pref_id);
+ g_free (pref_id);
+
+ if (scheme == NULL)
+ {
+ /* Fall-back to classic style scheme */
+ scheme = gtk_source_style_scheme_manager_get_scheme (manager,
+ "classic");
+ }
+
+ return scheme;
}
-/* Returns: whether @src_file has been correctly copied to @dest_file. */
+/*
+ * file_copy:
+ * @name: a pointer to a %NULL-terminated string, that names
+ * the file to be copied, in the GLib file name encoding
+ * @dest_name: a pointer to a %NULL-terminated string, that is the
+ * name for the destination file, in the GLib file name encoding
+ * @error: return location for a #GError, or %NULL
+ *
+ * Copies file @name to @dest_name.
+ *
+ * If the call was successful, it returns %TRUE. If the call was not
+ * successful, it returns %FALSE and sets @error. The error domain
+ * is #G_FILE_ERROR. Possible error
+ * codes are those in the #GFileError enumeration.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise.
+ */
static gboolean
-copy_file (GFile *src_file,
- GFile *dest_file,
- GError **error)
-{
- if (g_file_equal (src_file, dest_file))
- {
+file_copy (const gchar *name,
+ const gchar *dest_name,
+ GError **error)
+{
+ gchar *contents;
+ gsize length;
+ gchar *dest_dir;
+
+ /* FIXME - Paolo (Aug. 13, 2007):
+ * Since the style scheme files are relatively small, we can implement
+ * file copy getting all the content of the source file in a buffer and
+ * then write the content to the destination file. In this way we
+ * can use the g_file_get_contents and g_file_set_contents and avoid to
+ * write custom code to copy the file (with sane error management).
+ * If needed we can improve this code later. */
+
+ g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (dest_name != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ /* Note: we allow to copy a file to itself since this is not a problem
+ * in our use case */
+
+ /* Ensure the destination directory exists */
+ dest_dir = g_path_get_dirname (dest_name);
+
+ errno = 0;
+ if (g_mkdir_with_parents (dest_dir, 0755) != 0)
+ {
+ gint save_errno = errno;
+ gchar *display_filename = g_filename_display_name (dest_dir);
+
+ g_set_error (error,
+ G_FILE_ERROR,
+ g_file_error_from_errno (save_errno),
+ _("Directory “%s” could not be created: g_mkdir_with_parents() failed: %s"),
+ display_filename,
+ g_strerror (save_errno));
+
+ g_free (dest_dir);
+ g_free (display_filename);
+
return FALSE;
}
- if (!tepl_utils_create_parent_directories (dest_file, NULL, error))
+ g_free (dest_dir);
+
+ if (!g_file_get_contents (name, &contents, &length, error))
+ return FALSE;
+
+ if (!g_file_set_contents (dest_name, contents, length, error))
{
+ g_free (contents);
return FALSE;
}
- return g_file_copy (src_file,
- dest_file,
- G_FILE_COPY_OVERWRITE | G_FILE_COPY_TARGET_DEFAULT_PERMS,
- NULL, /* cancellable */
- NULL, NULL, /* progress callback */
- error);
+ g_free (contents);
+
+ return TRUE;
}
-/* Get the style scheme ID of @user_style_scheme_file if it has been correctly
- * installed and @user_style_scheme_file is a valid style scheme file.
+/*
+ * install_style_scheme:
+ * @manager: a #GtkSourceStyleSchemeManager
+ * @fname: the file name of the style scheme to be installed
+ *
+ * Install a new user scheme.
+ * This function copies @fname in #GEDIT_STYLES_DIR and ask the style manager to
+ * recompute the list of available style schemes. It then checks if a style
+ * scheme with the right file name exists.
+ *
+ * If the call was succesful, it returns the id of the installed scheme
+ * otherwise %NULL.
+ *
+ * Return value: the id of the installed scheme, %NULL otherwise.
*/
-static const gchar *
-get_style_scheme_id_after_installing_user_style_scheme (GFile *user_style_scheme_file)
+static GtkSourceStyleScheme *
+install_style_scheme (const gchar *fname)
{
GtkSourceStyleSchemeManager *manager;
- const gchar * const *scheme_ids;
- gint i;
+ gchar *new_file_name = NULL;
+ gchar *dirname;
+ const gchar *styles_dir;
+ GError *error = NULL;
+ gboolean copied = FALSE;
+ const gchar * const *ids;
+
+ g_return_val_if_fail (fname != NULL, NULL);
manager = gtk_source_style_scheme_manager_get_default ();
- gtk_source_style_scheme_manager_force_rescan (manager);
- scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
+ dirname = g_path_get_dirname (fname);
+ styles_dir = gedit_dirs_get_user_styles_dir ();
- for (i = 0; scheme_ids != NULL && scheme_ids[i] != NULL; i++)
+ if (strcmp (dirname, styles_dir) != 0)
{
- const gchar *cur_scheme_id = scheme_ids[i];
- GtkSourceStyleScheme *scheme;
- const gchar *filename;
- GFile *scheme_file;
+ gchar *basename;
- scheme = gtk_source_style_scheme_manager_get_scheme (manager, cur_scheme_id);
- filename = gtk_source_style_scheme_get_filename (scheme);
- if (filename == NULL)
- {
- continue;
- }
+ basename = g_path_get_basename (fname);
+ new_file_name = g_build_filename (styles_dir, basename, NULL);
+ g_free (basename);
- scheme_file = g_file_new_for_path (filename);
- if (g_file_equal (scheme_file, user_style_scheme_file))
+ /* Copy the style scheme file into GEDIT_STYLES_DIR */
+ if (!file_copy (fname, new_file_name, &error))
{
- g_object_unref (scheme_file);
- return cur_scheme_id;
+ g_free (new_file_name);
+ g_free (dirname);
+
+ g_message ("Cannot install style scheme:\n%s",
+ error->message);
+
+ g_error_free (error);
+
+ return NULL;
}
- g_object_unref (scheme_file);
+ copied = TRUE;
+ }
+ else
+ {
+ new_file_name = g_strdup (fname);
}
- return NULL;
-}
-
-/* Returns: (nullable): the installed style scheme ID, or %NULL on failure. */
-static const gchar *
-install_style_scheme (GFile *src_file,
- GError **error)
-{
- GFile *dest_file;
- gboolean copied;
- const gchar *installed_style_scheme_id = NULL;
- GError *my_error = NULL;
+ g_free (dirname);
- g_return_val_if_fail (G_IS_FILE (src_file), NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ /* Reload the available style schemes */
+ gtk_source_style_scheme_manager_force_rescan (manager);
- dest_file = get_user_style_scheme_destination_file (src_file);
- g_return_val_if_fail (dest_file != NULL, NULL);
+ /* Check the new style scheme has been actually installed */
+ ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
- copied = copy_file (src_file, dest_file, &my_error);
- if (my_error != NULL)
+ while (*ids != NULL)
{
- g_propagate_error (error, my_error);
- g_object_unref (dest_file);
- return NULL;
- }
+ GtkSourceStyleScheme *scheme;
+ const gchar *filename;
- installed_style_scheme_id = get_style_scheme_id_after_installing_user_style_scheme (dest_file);
+ scheme = gtk_source_style_scheme_manager_get_scheme (manager, *ids);
- if (installed_style_scheme_id == NULL && copied)
- {
- /* The style scheme has not been correctly installed. */
- g_file_delete (dest_file, NULL, &my_error);
- if (my_error != NULL)
- {
- gchar *dest_file_parse_name = g_file_get_parse_name (dest_file);
+ filename = gtk_source_style_scheme_get_filename (scheme);
- g_warning ("Failed to delete the file “%s”: %s",
- dest_file_parse_name,
- my_error->message);
+ if (filename && (strcmp (filename, new_file_name) == 0))
+ {
+ /* The style scheme has been correctly installed */
+ g_free (new_file_name);
- g_free (dest_file_parse_name);
- g_clear_error (&my_error);
+ return scheme;
}
+ ++ids;
}
- g_object_unref (dest_file);
- return installed_style_scheme_id;
+ /* The style scheme has not been correctly installed */
+ if (copied)
+ g_unlink (new_file_name);
+
+ g_free (new_file_name);
+
+ return NULL;
}
-/*
+/**
* uninstall_style_scheme:
+ * @manager: a #GtkSourceStyleSchemeManager
* @scheme: a #GtkSourceStyleScheme
*
* Uninstall a user scheme.
*
- * Returns: %TRUE on success, %FALSE otherwise.
+ * If the call was succesful, it returns %TRUE
+ * otherwise %FALSE.
+ *
+ * Return value: %TRUE on success, %FALSE otherwise.
*/
static gboolean
uninstall_style_scheme (GtkSourceStyleScheme *scheme)
@@ -653,94 +754,92 @@
}
static void
-add_scheme_chooser_response_cb (GtkFileChooserNative *chooser,
- gint response_id,
- GeditPreferencesDialog *dialog)
+add_scheme_chooser_response_cb (GeditFileChooserDialog *chooser,
+ gint res_id,
+ GeditPreferencesDialog *dlg)
{
GFile *file;
- const gchar *scheme_id;
- GeditSettings *settings;
- GSettings *editor_settings;
- GError *error = NULL;
+ gchar *filename;
+ GtkSourceStyleScheme *scheme;
- if (response_id != GTK_RESPONSE_ACCEPT)
+ if (res_id != GTK_RESPONSE_ACCEPT)
{
+ gedit_file_chooser_dialog_hide (chooser);
return;
}
- file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (chooser));
+ file = gedit_file_chooser_dialog_get_file (chooser);
+
if (file == NULL)
{
return;
}
- scheme_id = install_style_scheme (file, &error);
+ filename = g_file_get_path (file);
g_object_unref (file);
- if (scheme_id == NULL)
+ if (filename == NULL)
{
- if (error != NULL)
- {
- tepl_utils_show_warning_dialog (GTK_WINDOW (dialog),
- _("The selected color scheme cannot be installed: %s"),
- error->message);
- }
- else
- {
- tepl_utils_show_warning_dialog (GTK_WINDOW (dialog),
- _("The selected color scheme cannot be installed."));
- }
+ return;
+ }
+
+ gedit_file_chooser_dialog_hide (chooser);
+
+ scheme = install_style_scheme (filename);
+ g_free (filename);
+
+ if (scheme == NULL)
+ {
+ gedit_warning (GTK_WINDOW (dlg),
+ _("The selected color scheme cannot be installed."));
- g_clear_error (&error);
return;
}
- settings = _gedit_settings_get_singleton ();
- editor_settings = _gedit_settings_peek_editor_settings (settings);
- g_settings_set_string (editor_settings, GEDIT_SETTINGS_SCHEME, scheme_id);
+ g_settings_set_string (dlg->editor, GEDIT_SETTINGS_SCHEME,
+ gtk_source_style_scheme_get_id (scheme));
+
+ set_buttons_sensisitivity_according_to_scheme (dlg, scheme);
}
static void
install_scheme_clicked (GtkButton *button,
- GeditPreferencesDialog *dialog)
+ GeditPreferencesDialog *dlg)
{
- GtkFileChooserNative *chooser;
- GtkFileFilter *scheme_filter;
- GtkFileFilter *all_filter;
+ GeditFileChooserDialog *chooser;
- if (dialog->install_scheme_file_chooser != NULL)
+ if (dlg->install_scheme_file_schooser != NULL)
{
- gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog->install_scheme_file_chooser));
+ gedit_file_chooser_dialog_show (dlg->install_scheme_file_schooser);
return;
}
- chooser = gtk_file_chooser_native_new (_("Add Color Scheme"),
- GTK_WINDOW (dialog),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- _("_Add Scheme"),
- _("_Cancel"));
+ chooser = gedit_file_chooser_dialog_create (_("Add Scheme"),
+ GTK_WINDOW (dlg),
+ GEDIT_FILE_CHOOSER_FLAG_OPEN,
+ _("A_dd Scheme"),
+ _("_Cancel"));
/* Filters */
- scheme_filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (scheme_filter, _("Color Scheme Files"));
- gtk_file_filter_add_pattern (scheme_filter, "*.xml");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), scheme_filter);
-
- all_filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (all_filter, _("All Files"));
- gtk_file_filter_add_pattern (all_filter, "*");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), all_filter);
-
- gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), scheme_filter);
+ gedit_file_chooser_dialog_add_pattern_filter (chooser,
+ _("Color Scheme Files"),
+ "*.xml");
+
+ gedit_file_chooser_dialog_add_pattern_filter (chooser,
+ _("All Files"),
+ "*");
g_signal_connect (chooser,
"response",
G_CALLBACK (add_scheme_chooser_response_cb),
- dialog);
+ dlg);
- g_set_weak_pointer (&dialog->install_scheme_file_chooser, chooser);
+ dlg->install_scheme_file_schooser = chooser;
- gtk_native_dialog_show (GTK_NATIVE_DIALOG (chooser));
+ g_object_add_weak_pointer (G_OBJECT (chooser),
+ (gpointer) &dlg->install_scheme_file_schooser);
+
+ gedit_file_chooser_dialog_show (chooser);
}
static void
@@ -748,33 +847,14 @@
GeditPreferencesDialog *dlg)
{
GtkSourceStyleScheme *scheme;
- GtkSourceStyleScheme *new_selected_scheme;
scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
- if (scheme == NULL)
- {
- return;
- }
-
if (!uninstall_style_scheme (scheme))
{
- tepl_utils_show_warning_dialog (GTK_WINDOW (dlg),
- _("Could not remove color scheme “%s”."),
- gtk_source_style_scheme_get_name (scheme));
- return;
- }
-
- new_selected_scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
- if (new_selected_scheme == NULL)
- {
- GeditSettings *settings;
- GSettings *editor_settings;
-
- settings = _gedit_settings_get_singleton ();
- editor_settings = _gedit_settings_peek_editor_settings (settings);
-
- g_settings_reset (editor_settings, GEDIT_SETTINGS_SCHEME);
+ gedit_warning (GTK_WINDOW (dlg),
+ _("Could not remove color scheme “%s”."),
+ gtk_source_style_scheme_get_name (scheme));
}
}
@@ -782,13 +862,14 @@
setup_font_colors_page_style_scheme_section (GeditPreferencesDialog *dlg)
{
GtkStyleContext *context;
- GeditSettings *settings;
- GSettings *editor_settings;
+ GtkSourceStyleScheme *scheme;
gedit_debug (DEBUG_PREFS);
- /* junction between the schemes list and the toolbar */
- context = gtk_widget_get_style_context (dlg->schemes_list);
+ scheme = get_default_color_scheme (dlg);
+
+ /* junction between the scrolled window and the toolbar */
+ context = gtk_widget_get_style_context (dlg->schemes_scrolled_window);
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
context = gtk_widget_get_style_context (dlg->schemes_toolbar);
gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
@@ -796,7 +877,7 @@
/* Connect signals */
g_signal_connect (dlg->schemes_list,
"notify::style-scheme",
- G_CALLBACK (style_scheme_notify_cb),
+ G_CALLBACK (style_scheme_changed),
dlg);
g_signal_connect (dlg->install_scheme_button,
"clicked",
@@ -807,13 +888,11 @@
G_CALLBACK (uninstall_scheme_clicked),
dlg);
- settings = _gedit_settings_get_singleton ();
- editor_settings = _gedit_settings_peek_editor_settings (settings);
- g_settings_bind (editor_settings, GEDIT_SETTINGS_SCHEME,
- dlg->schemes_list, "tepl-style-scheme-id",
- G_SETTINGS_BIND_DEFAULT);
+ gtk_source_style_scheme_chooser_set_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list),
+ scheme);
- update_style_scheme_buttons_sensisitivity (dlg);
+ /* Set initial widget sensitivity */
+ set_buttons_sensisitivity_according_to_scheme (dlg, scheme);
}
static void
diff -Nru gedit-40.1/gedit/gedit-print-job.c gedit-41.0/gedit/gedit-print-job.c
--- gedit-40.1/gedit/gedit-print-job.c 2021-04-17 05:45:36.120558300 +0000
+++ gedit-41.0/gedit/gedit-print-job.c 2022-02-14 13:58:26.000000000 +0000
@@ -23,7 +23,7 @@
#include "gedit-print-job.h"
#include
-#include
+#include
#include "gedit-debug.h"
#include "gedit-document-private.h"
@@ -535,7 +535,7 @@
gchar *left;
doc_name = _gedit_document_get_uri_for_display (GEDIT_DOCUMENT (buf));
- name_to_display = tepl_utils_str_middle_truncate (doc_name, 60);
+ name_to_display = gedit_utils_str_middle_truncate (doc_name, 60);
left = g_strdup_printf (_("File: %s"), name_to_display);
diff -Nru gedit-40.1/gedit/gedit-progress-info-bar.c gedit-41.0/gedit/gedit-progress-info-bar.c
--- gedit-40.1/gedit/gedit-progress-info-bar.c 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-progress-info-bar.c 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,177 @@
+/*
+ * gedit-progress-info-bar.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ *
+ * 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 "gedit-progress-info-bar.h"
+#include
+
+enum {
+ PROP_0,
+ PROP_HAS_CANCEL_BUTTON,
+ LAST_PROP
+};
+
+static GParamSpec *properties[LAST_PROP];
+
+struct _GeditProgressInfoBar
+{
+ GtkInfoBar parent_instance;
+
+ GtkWidget *image;
+ GtkWidget *label;
+ GtkWidget *progress;
+};
+
+G_DEFINE_TYPE (GeditProgressInfoBar, gedit_progress_info_bar, GTK_TYPE_INFO_BAR)
+
+static void
+gedit_progress_info_bar_set_has_cancel_button (GeditProgressInfoBar *bar,
+ gboolean has_button)
+{
+ if (has_button)
+ {
+ gtk_info_bar_add_button (GTK_INFO_BAR (bar), _("_Cancel"), GTK_RESPONSE_CANCEL);
+ }
+}
+
+static void
+gedit_progress_info_bar_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GeditProgressInfoBar *bar;
+
+ bar = GEDIT_PROGRESS_INFO_BAR (object);
+
+ switch (prop_id)
+ {
+ case PROP_HAS_CANCEL_BUTTON:
+ gedit_progress_info_bar_set_has_cancel_button (bar,
+ g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gedit_progress_info_bar_class_init (GeditProgressInfoBarClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ gobject_class->set_property = gedit_progress_info_bar_set_property;
+
+ properties[PROP_HAS_CANCEL_BUTTON] =
+ g_param_spec_boolean ("has-cancel-button",
+ "Has Cancel Button",
+ "If the message bar has a cancel button",
+ TRUE,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (gobject_class, LAST_PROP, properties);
+
+ /* Bind class to template */
+ gtk_widget_class_set_template_from_resource (widget_class,
+ "/org/gnome/gedit/ui/gedit-progress-info-bar.ui");
+ gtk_widget_class_bind_template_child (widget_class, GeditProgressInfoBar, image);
+ gtk_widget_class_bind_template_child (widget_class, GeditProgressInfoBar, label);
+ gtk_widget_class_bind_template_child (widget_class, GeditProgressInfoBar, progress);
+}
+
+static void
+gedit_progress_info_bar_init (GeditProgressInfoBar *bar)
+{
+ gtk_widget_init_template (GTK_WIDGET (bar));
+}
+
+GtkWidget *
+gedit_progress_info_bar_new (const gchar *icon_name,
+ const gchar *markup,
+ gboolean has_cancel)
+{
+ GeditProgressInfoBar *bar;
+
+ g_return_val_if_fail (icon_name != NULL, NULL);
+ g_return_val_if_fail (markup != NULL, NULL);
+
+ bar = GEDIT_PROGRESS_INFO_BAR (g_object_new (GEDIT_TYPE_PROGRESS_INFO_BAR,
+ "has-cancel-button", has_cancel,
+ NULL));
+
+ gedit_progress_info_bar_set_icon_name (bar, icon_name);
+ gedit_progress_info_bar_set_markup (bar, markup);
+
+ return GTK_WIDGET (bar);
+}
+
+void
+gedit_progress_info_bar_set_icon_name (GeditProgressInfoBar *bar,
+ const gchar *icon_name)
+{
+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
+ g_return_if_fail (icon_name != NULL);
+
+ gtk_image_set_from_icon_name (GTK_IMAGE (bar->image),
+ icon_name,
+ GTK_ICON_SIZE_SMALL_TOOLBAR);
+}
+
+void
+gedit_progress_info_bar_set_markup (GeditProgressInfoBar *bar,
+ const gchar *markup)
+{
+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
+ g_return_if_fail (markup != NULL);
+
+ gtk_label_set_markup (GTK_LABEL (bar->label), markup);
+}
+
+void
+gedit_progress_info_bar_set_text (GeditProgressInfoBar *bar,
+ const gchar *text)
+{
+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
+ g_return_if_fail (text != NULL);
+
+ gtk_label_set_text (GTK_LABEL (bar->label), text);
+}
+
+void
+gedit_progress_info_bar_set_fraction (GeditProgressInfoBar *bar,
+ gdouble fraction)
+{
+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
+
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar->progress), fraction);
+}
+
+void
+gedit_progress_info_bar_pulse (GeditProgressInfoBar *bar)
+{
+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (bar));
+
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (bar->progress));
+}
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-progress-info-bar.h gedit-41.0/gedit/gedit-progress-info-bar.h
--- gedit-40.1/gedit/gedit-progress-info-bar.h 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-progress-info-bar.h 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,53 @@
+/*
+ * gedit-progress-info-bar.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ *
+ * 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 GEDIT_PROGRESS_INFO_BAR_H
+#define GEDIT_PROGRESS_INFO_BAR_H
+
+#include
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_PROGRESS_INFO_BAR (gedit_progress_info_bar_get_type ())
+G_DECLARE_FINAL_TYPE (GeditProgressInfoBar, gedit_progress_info_bar, GEDIT, PROGRESS_INFO_BAR, GtkInfoBar)
+
+GtkWidget *gedit_progress_info_bar_new (const gchar *icon_name,
+ const gchar *markup,
+ gboolean has_cancel);
+
+void gedit_progress_info_bar_set_icon_name (GeditProgressInfoBar *bar,
+ const gchar *icon_name);
+
+void gedit_progress_info_bar_set_markup (GeditProgressInfoBar *bar,
+ const gchar *markup);
+
+void gedit_progress_info_bar_set_text (GeditProgressInfoBar *bar,
+ const gchar *text);
+
+void gedit_progress_info_bar_set_fraction (GeditProgressInfoBar *bar,
+ gdouble fraction);
+
+void gedit_progress_info_bar_pulse (GeditProgressInfoBar *bar);
+
+G_END_DECLS
+
+#endif /* GEDIT_PROGRESS_INFO_BAR_H */
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-recent.c gedit-41.0/gedit/gedit-recent.c
--- gedit-40.1/gedit/gedit-recent.c 2021-04-17 05:45:36.120558300 +0000
+++ gedit-41.0/gedit/gedit-recent.c 2022-02-14 13:58:26.000000000 +0000
@@ -24,7 +24,7 @@
void
gedit_recent_add_document (GeditDocument *document)
{
- TeplFile *file;
+ GtkSourceFile *file;
GFile *location;
GtkRecentManager *recent_manager;
GtkRecentData recent_data;
@@ -33,8 +33,8 @@
g_return_if_fail (GEDIT_IS_DOCUMENT (document));
- file = tepl_buffer_get_file (TEPL_BUFFER (document));
- location = tepl_file_get_location (file);
+ file = gedit_document_get_file (document);
+ location = gtk_source_file_get_location (file);
if (location == NULL)
{
@@ -89,4 +89,229 @@
}
}
+static gint
+sort_recent_items_mru (GtkRecentInfo *a,
+ GtkRecentInfo *b,
+ gpointer unused)
+{
+ g_assert (a != NULL && b != NULL);
+ return gtk_recent_info_get_modified (b) - gtk_recent_info_get_modified (a);
+}
+
+static void
+populate_filter_info (GtkRecentInfo *info,
+ GtkRecentFilterInfo *filter_info,
+ GtkRecentFilterFlags needed)
+{
+ filter_info->uri = gtk_recent_info_get_uri (info);
+ filter_info->mime_type = gtk_recent_info_get_mime_type (info);
+
+ filter_info->contains = GTK_RECENT_FILTER_URI | GTK_RECENT_FILTER_MIME_TYPE;
+
+ if (needed & GTK_RECENT_FILTER_DISPLAY_NAME)
+ {
+ filter_info->display_name = gtk_recent_info_get_display_name (info);
+ filter_info->contains |= GTK_RECENT_FILTER_DISPLAY_NAME;
+ }
+ else
+ {
+ filter_info->uri = NULL;
+ }
+
+ if (needed & GTK_RECENT_FILTER_APPLICATION)
+ {
+ filter_info->applications = (const gchar **) gtk_recent_info_get_applications (info, NULL);
+ filter_info->contains |= GTK_RECENT_FILTER_APPLICATION;
+ }
+ else
+ {
+ filter_info->applications = NULL;
+ }
+
+ if (needed & GTK_RECENT_FILTER_GROUP)
+ {
+ filter_info->groups = (const gchar **) gtk_recent_info_get_groups (info, NULL);
+ filter_info->contains |= GTK_RECENT_FILTER_GROUP;
+ }
+ else
+ {
+ filter_info->groups = NULL;
+ }
+
+ if (needed & GTK_RECENT_FILTER_AGE)
+ {
+ filter_info->age = gtk_recent_info_get_age (info);
+ filter_info->contains |= GTK_RECENT_FILTER_AGE;
+ }
+ else
+ {
+ filter_info->age = -1;
+ }
+}
+
+/* The GeditRecentConfiguration struct is allocated and owned by the caller */
+void
+gedit_recent_configuration_init_default (GeditRecentConfiguration *config)
+{
+ config->manager = gtk_recent_manager_get_default ();
+
+ if (config->filter != NULL)
+ {
+ g_object_unref (config->filter);
+ }
+
+ config->filter = gtk_recent_filter_new ();
+ gtk_recent_filter_add_application (config->filter, g_get_application_name ());
+ gtk_recent_filter_add_mime_type (config->filter, "text/plain");
+ g_object_ref_sink (config->filter);
+
+ config->limit = 5;
+ config->show_not_found = TRUE;
+ config->show_private = FALSE;
+ config->local_only = FALSE;
+
+ config->substring_filter = NULL;
+}
+
+/* The GeditRecentConfiguration struct is owned and destroyed by the caller */
+void
+gedit_recent_configuration_destroy (GeditRecentConfiguration *config)
+{
+ g_clear_object (&config->filter);
+ config->manager = NULL;
+
+ g_clear_pointer (&config->substring_filter, (GDestroyNotify)g_free);
+}
+
+GList *
+gedit_recent_get_items (GeditRecentConfiguration *config)
+{
+ GtkRecentFilterFlags needed;
+ GList *items;
+ GList *retitems = NULL;
+ gint length;
+ char *substring_filter = NULL;
+
+ if (config->limit == 0)
+ {
+ return NULL;
+ }
+
+ items = gtk_recent_manager_get_items (config->manager);
+
+ if (!items)
+ {
+ return NULL;
+ }
+
+ needed = gtk_recent_filter_get_needed (config->filter);
+ if (config->substring_filter && *config->substring_filter != '\0')
+ {
+ gchar *filter_normalized;
+
+ filter_normalized = g_utf8_normalize (config->substring_filter, -1, G_NORMALIZE_ALL);
+ substring_filter = g_utf8_casefold (filter_normalized, -1);
+ g_free (filter_normalized);
+ }
+
+ while (items)
+ {
+ GtkRecentInfo *info;
+ GtkRecentFilterInfo filter_info;
+ gboolean is_filtered;
+
+ info = items->data;
+ is_filtered = FALSE;
+
+ if (config->local_only && !gtk_recent_info_is_local (info))
+ {
+ is_filtered = TRUE;
+ }
+ else if (!config->show_private && gtk_recent_info_get_private_hint (info))
+ {
+ is_filtered = TRUE;
+ }
+ else if (!config->show_not_found && !gtk_recent_info_exists (info))
+ {
+ is_filtered = TRUE;
+ }
+ else
+ {
+ if (substring_filter)
+ {
+ gchar *uri_normalized;
+ gchar *uri_casefolded;
+
+ uri_normalized = g_utf8_normalize (gtk_recent_info_get_uri_display (info), -1, G_NORMALIZE_ALL);
+ uri_casefolded = g_utf8_casefold (uri_normalized, -1);
+ g_free (uri_normalized);
+
+ if (strstr (uri_casefolded, substring_filter) == NULL)
+ {
+ is_filtered = TRUE;
+ }
+
+ g_free (uri_casefolded);
+ }
+
+ if (!is_filtered)
+ {
+ populate_filter_info (info, &filter_info, needed);
+ is_filtered = !gtk_recent_filter_filter (config->filter, &filter_info);
+
+ /* these we own */
+ if (filter_info.applications)
+ {
+ g_strfreev ((gchar **) filter_info.applications);
+ }
+
+ if (filter_info.groups)
+ {
+ g_strfreev ((gchar **) filter_info.groups);
+ }
+ }
+ }
+
+ if (!is_filtered)
+ {
+ retitems = g_list_prepend (retitems, info);
+ }
+ else
+ {
+ gtk_recent_info_unref (info);
+ }
+
+ items = g_list_delete_link (items, items);
+ }
+
+ g_free (substring_filter);
+
+ if (!retitems)
+ {
+ return NULL;
+ }
+
+ retitems = g_list_sort_with_data (retitems, (GCompareDataFunc) sort_recent_items_mru, NULL);
+ length = g_list_length (retitems);
+
+ if ((config->limit != -1) && (length > config->limit))
+ {
+ GList *clamp, *l;
+
+ clamp = g_list_nth (retitems, config->limit - 1);
+
+ if (!clamp)
+ {
+ return retitems;
+ }
+
+ l = clamp->next;
+ clamp->next = NULL;
+
+ g_list_free_full (l, (GDestroyNotify) gtk_recent_info_unref);
+ }
+
+ return retitems;
+}
+
/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-recent.h gedit-41.0/gedit/gedit-recent.h
--- gedit-40.1/gedit/gedit-recent.h 2021-04-17 05:45:36.120558300 +0000
+++ gedit-41.0/gedit/gedit-recent.h 2022-02-14 13:58:26.000000000 +0000
@@ -27,12 +27,29 @@
G_BEGIN_DECLS
-void gedit_recent_add_document (GeditDocument *document);
-
-void gedit_recent_remove_if_local (GFile *location);
+typedef struct
+{
+ GtkRecentManager *manager;
+ GtkRecentFilter *filter;
+
+ gint limit;
+ gchar *substring_filter;
+
+ guint show_private : 1;
+ guint show_not_found : 1;
+ guint local_only : 1;
+} GeditRecentConfiguration;
+
+void gedit_recent_add_document (GeditDocument *document);
+
+void gedit_recent_remove_if_local (GFile *location);
+
+void gedit_recent_configuration_init_default (GeditRecentConfiguration *config);
+void gedit_recent_configuration_destroy (GeditRecentConfiguration *config);
+GList *gedit_recent_get_items (GeditRecentConfiguration *config);
G_END_DECLS
-#endif /* GEDIT_RECENT_H */
+#endif /* GEDIT_RECENT_H */
/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-recent-osx.c gedit-41.0/gedit/gedit-recent-osx.c
--- gedit-40.1/gedit/gedit-recent-osx.c 2021-04-17 05:45:36.120558300 +0000
+++ gedit-41.0/gedit/gedit-recent-osx.c 1970-01-01 00:00:00.000000000 +0000
@@ -1,249 +0,0 @@
-/*
- * This file is part of gedit
- *
- * Copyright (C) 2005 - Paolo Maggi
- * Copyright (C) 2014 - Paolo Borelli
- * Copyright (C) 2014 - 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 "gedit-recent-osx.h"
-
-static gint
-sort_recent_items_mru (GtkRecentInfo *a,
- GtkRecentInfo *b,
- gpointer unused)
-{
- g_assert (a != NULL && b != NULL);
- return gtk_recent_info_get_modified (b) - gtk_recent_info_get_modified (a);
-}
-
-static void
-populate_filter_info (GtkRecentInfo *info,
- GtkRecentFilterInfo *filter_info,
- GtkRecentFilterFlags needed)
-{
- filter_info->uri = gtk_recent_info_get_uri (info);
- filter_info->mime_type = gtk_recent_info_get_mime_type (info);
-
- filter_info->contains = GTK_RECENT_FILTER_URI | GTK_RECENT_FILTER_MIME_TYPE;
-
- if (needed & GTK_RECENT_FILTER_DISPLAY_NAME)
- {
- filter_info->display_name = gtk_recent_info_get_display_name (info);
- filter_info->contains |= GTK_RECENT_FILTER_DISPLAY_NAME;
- }
- else
- {
- filter_info->uri = NULL;
- }
-
- if (needed & GTK_RECENT_FILTER_APPLICATION)
- {
- filter_info->applications = (const gchar **) gtk_recent_info_get_applications (info, NULL);
- filter_info->contains |= GTK_RECENT_FILTER_APPLICATION;
- }
- else
- {
- filter_info->applications = NULL;
- }
-
- if (needed & GTK_RECENT_FILTER_GROUP)
- {
- filter_info->groups = (const gchar **) gtk_recent_info_get_groups (info, NULL);
- filter_info->contains |= GTK_RECENT_FILTER_GROUP;
- }
- else
- {
- filter_info->groups = NULL;
- }
-
- if (needed & GTK_RECENT_FILTER_AGE)
- {
- filter_info->age = gtk_recent_info_get_age (info);
- filter_info->contains |= GTK_RECENT_FILTER_AGE;
- }
- else
- {
- filter_info->age = -1;
- }
-}
-
-/* The GeditRecentConfiguration struct is allocated and owned by the caller */
-void
-gedit_recent_configuration_init_default (GeditRecentConfiguration *config)
-{
- config->manager = gtk_recent_manager_get_default ();
-
- if (config->filter != NULL)
- {
- g_object_unref (config->filter);
- }
-
- config->filter = gtk_recent_filter_new ();
- gtk_recent_filter_add_application (config->filter, g_get_application_name ());
- gtk_recent_filter_add_mime_type (config->filter, "text/plain");
- g_object_ref_sink (config->filter);
-
- config->limit = 5;
- config->show_not_found = TRUE;
- config->show_private = FALSE;
- config->local_only = FALSE;
-
- config->substring_filter = NULL;
-}
-
-/* The GeditRecentConfiguration struct is owned and destroyed by the caller */
-void
-gedit_recent_configuration_destroy (GeditRecentConfiguration *config)
-{
- g_clear_object (&config->filter);
- config->manager = NULL;
-
- g_clear_pointer (&config->substring_filter, (GDestroyNotify)g_free);
-}
-
-GList *
-gedit_recent_get_items (GeditRecentConfiguration *config)
-{
- GtkRecentFilterFlags needed;
- GList *items;
- GList *retitems = NULL;
- gint length;
- char *substring_filter = NULL;
-
- if (config->limit == 0)
- {
- return NULL;
- }
-
- items = gtk_recent_manager_get_items (config->manager);
-
- if (!items)
- {
- return NULL;
- }
-
- needed = gtk_recent_filter_get_needed (config->filter);
- if (config->substring_filter && *config->substring_filter != '\0')
- {
- gchar *filter_normalized;
-
- filter_normalized = g_utf8_normalize (config->substring_filter, -1, G_NORMALIZE_ALL);
- substring_filter = g_utf8_casefold (filter_normalized, -1);
- g_free (filter_normalized);
- }
-
- while (items)
- {
- GtkRecentInfo *info;
- GtkRecentFilterInfo filter_info;
- gboolean is_filtered;
-
- info = items->data;
- is_filtered = FALSE;
-
- if (config->local_only && !gtk_recent_info_is_local (info))
- {
- is_filtered = TRUE;
- }
- else if (!config->show_private && gtk_recent_info_get_private_hint (info))
- {
- is_filtered = TRUE;
- }
- else if (!config->show_not_found && !gtk_recent_info_exists (info))
- {
- is_filtered = TRUE;
- }
- else
- {
- if (substring_filter)
- {
- gchar *uri_normalized;
- gchar *uri_casefolded;
-
- uri_normalized = g_utf8_normalize (gtk_recent_info_get_uri_display (info), -1, G_NORMALIZE_ALL);
- uri_casefolded = g_utf8_casefold (uri_normalized, -1);
- g_free (uri_normalized);
-
- if (strstr (uri_casefolded, substring_filter) == NULL)
- {
- is_filtered = TRUE;
- }
-
- g_free (uri_casefolded);
- }
-
- if (!is_filtered)
- {
- populate_filter_info (info, &filter_info, needed);
- is_filtered = !gtk_recent_filter_filter (config->filter, &filter_info);
-
- /* these we own */
- if (filter_info.applications)
- {
- g_strfreev ((gchar **) filter_info.applications);
- }
-
- if (filter_info.groups)
- {
- g_strfreev ((gchar **) filter_info.groups);
- }
- }
- }
-
- if (!is_filtered)
- {
- retitems = g_list_prepend (retitems, info);
- }
- else
- {
- gtk_recent_info_unref (info);
- }
-
- items = g_list_delete_link (items, items);
- }
-
- g_free (substring_filter);
-
- if (!retitems)
- {
- return NULL;
- }
-
- retitems = g_list_sort_with_data (retitems, (GCompareDataFunc) sort_recent_items_mru, NULL);
- length = g_list_length (retitems);
-
- if ((config->limit != -1) && (length > config->limit))
- {
- GList *clamp, *l;
-
- clamp = g_list_nth (retitems, config->limit - 1);
-
- if (!clamp)
- {
- return retitems;
- }
-
- l = clamp->next;
- clamp->next = NULL;
-
- g_list_free_full (l, (GDestroyNotify) gtk_recent_info_unref);
- }
-
- return retitems;
-}
-
-/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-recent-osx.h gedit-41.0/gedit/gedit-recent-osx.h
--- gedit-40.1/gedit/gedit-recent-osx.h 2021-04-17 05:45:36.120558300 +0000
+++ gedit-41.0/gedit/gedit-recent-osx.h 1970-01-01 00:00:00.000000000 +0000
@@ -1,54 +0,0 @@
-/*
- * This file is part of gedit
- *
- * Copyright (C) 2005 - Paolo Maggi
- * Copyright (C) 2014 - Paolo Borelli
- * Copyright (C) 2014 - 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
- * MERCHANWINDOWILITY 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 GEDIT_RECENT_OSX_H
-#define GEDIT_RECENT_OSX_H
-
-#include
-
-G_BEGIN_DECLS
-
-/* TODO: this code can be simplified, the struct can be made private, the dead
- * code can be removed, etc.
- */
-
-typedef struct
-{
- GtkRecentManager *manager;
- GtkRecentFilter *filter;
-
- gint limit;
- gchar *substring_filter;
-
- guint show_private : 1;
- guint show_not_found : 1;
- guint local_only : 1;
-} GeditRecentConfiguration;
-
-void gedit_recent_configuration_init_default (GeditRecentConfiguration *config);
-void gedit_recent_configuration_destroy (GeditRecentConfiguration *config);
-GList *gedit_recent_get_items (GeditRecentConfiguration *config);
-
-G_END_DECLS
-
-#endif /* GEDIT_RECENT_OSX_H */
-
-/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-settings.c gedit-41.0/gedit/gedit-settings.c
--- gedit-40.1/gedit/gedit-settings.c 2021-04-17 05:45:36.120558300 +0000
+++ gedit-41.0/gedit/gedit-settings.c 2022-02-14 13:58:26.000000000 +0000
@@ -37,13 +37,7 @@
GSettings *settings_file_chooser_state;
};
-enum
-{
- SIGNAL_FONTS_CHANGED,
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS];
+/* GeditSettings is a singleton. */
static GeditSettings *singleton = NULL;
G_DEFINE_TYPE (GeditSettings, gedit_settings, G_TYPE_OBJECT)
@@ -81,46 +75,92 @@
object_class->dispose = gedit_settings_dispose;
object_class->finalize = gedit_settings_finalize;
+}
- /* This signal is emitted when the return value of
- * _gedit_settings_get_selected_font() has potentially changed.
- */
- signals[SIGNAL_FONTS_CHANGED] =
- g_signal_new ("fonts-changed",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 0);
+static void
+set_font (GeditSettings *self,
+ const gchar *font)
+{
+ guint tabs_size;
+ GList *views;
+ GList *l;
+
+ tabs_size = g_settings_get_uint (self->settings_editor, GEDIT_SETTINGS_TABS_SIZE);
+
+ views = gedit_app_get_views (GEDIT_APP (g_application_get_default ()));
+
+ for (l = views; l != NULL; l = l->next)
+ {
+ /* Note: we use def=FALSE to avoid GeditView to query dconf. */
+ gedit_view_set_font (GEDIT_VIEW (l->data), FALSE, font);
+
+ /* FIXME: setting the tab width seems unrelated to set_font(). */
+ gtk_source_view_set_tab_width (GTK_SOURCE_VIEW (l->data), tabs_size);
+ }
+
+ g_list_free (views);
}
static void
-system_font_changed_cb (GSettings *settings,
+on_system_font_changed (GSettings *settings,
const gchar *key,
GeditSettings *self)
{
- if (g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT))
+
+ gboolean use_default_font;
+
+ use_default_font = g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT);
+
+ if (use_default_font)
{
- g_signal_emit (self, signals[SIGNAL_FONTS_CHANGED], 0);
+ gchar *font;
+
+ font = g_settings_get_string (settings, key);
+ set_font (self, font);
+ g_free (font);
}
}
static void
-use_default_font_changed_cb (GSettings *settings,
+on_use_default_font_changed (GSettings *settings,
const gchar *key,
GeditSettings *self)
{
- g_signal_emit (self, signals[SIGNAL_FONTS_CHANGED], 0);
+ gboolean use_default_font;
+ gchar *font;
+
+ use_default_font = g_settings_get_boolean (settings, key);
+
+ if (use_default_font)
+ {
+ font = g_settings_get_string (self->settings_interface, GEDIT_SETTINGS_SYSTEM_FONT);
+ }
+ else
+ {
+ font = g_settings_get_string (self->settings_editor, GEDIT_SETTINGS_EDITOR_FONT);
+ }
+
+ set_font (self, font);
+
+ g_free (font);
}
static void
-editor_font_changed_cb (GSettings *settings,
+on_editor_font_changed (GSettings *settings,
const gchar *key,
GeditSettings *self)
{
- if (!g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT))
+ gboolean use_default_font;
+
+ use_default_font = g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT);
+
+ if (!use_default_font)
{
- g_signal_emit (self, signals[SIGNAL_FONTS_CHANGED], 0);
+ gchar *font;
+
+ font = g_settings_get_string (settings, key);
+ set_font (self, font);
+ g_free (font);
}
}
@@ -207,47 +247,43 @@
static void
gedit_settings_init (GeditSettings *self)
{
- self->settings_interface = g_settings_new ("org.gnome.desktop.interface");
-
self->settings_editor = g_settings_new ("org.gnome.gedit.preferences.editor");
self->settings_ui = g_settings_new ("org.gnome.gedit.preferences.ui");
self->settings_file_chooser_state = g_settings_new ("org.gnome.gedit.state.file-chooser");
- g_signal_connect_object (self->settings_interface,
- "changed::" GEDIT_SETTINGS_SYSTEM_FONT,
- G_CALLBACK (system_font_changed_cb),
- self,
- 0);
-
- g_signal_connect_object (self->settings_editor,
- "changed::" GEDIT_SETTINGS_USE_DEFAULT_FONT,
- G_CALLBACK (use_default_font_changed_cb),
- self,
- 0);
-
- g_signal_connect_object (self->settings_editor,
- "changed::" GEDIT_SETTINGS_EDITOR_FONT,
- G_CALLBACK (editor_font_changed_cb),
- self,
- 0);
-
- g_signal_connect_object (self->settings_editor,
- "changed::auto-save",
- G_CALLBACK (on_auto_save_changed),
- self,
- 0);
-
- g_signal_connect_object (self->settings_editor,
- "changed::auto-save-interval",
- G_CALLBACK (on_auto_save_interval_changed),
- self,
- 0);
-
- g_signal_connect_object (self->settings_editor,
- "changed::syntax-highlighting",
- G_CALLBACK (on_syntax_highlighting_changed),
- self,
- 0);
+ self->settings_interface = g_settings_new ("org.gnome.desktop.interface");
+
+ g_signal_connect (self->settings_interface,
+ "changed::monospace-font-name",
+ G_CALLBACK (on_system_font_changed),
+ self);
+
+ /* editor changes */
+
+ g_signal_connect (self->settings_editor,
+ "changed::use-default-font",
+ G_CALLBACK (on_use_default_font_changed),
+ self);
+
+ g_signal_connect (self->settings_editor,
+ "changed::editor-font",
+ G_CALLBACK (on_editor_font_changed),
+ self);
+
+ g_signal_connect (self->settings_editor,
+ "changed::auto-save",
+ G_CALLBACK (on_auto_save_changed),
+ self);
+
+ g_signal_connect (self->settings_editor,
+ "changed::auto-save-interval",
+ G_CALLBACK (on_auto_save_interval_changed),
+ self);
+
+ g_signal_connect (self->settings_editor,
+ "changed::syntax-highlighting",
+ G_CALLBACK (on_syntax_highlighting_changed),
+ self);
}
GeditSettings *
@@ -292,24 +328,11 @@
}
gchar *
-_gedit_settings_get_system_font (GeditSettings *self)
-{
- g_return_val_if_fail (GEDIT_IS_SETTINGS (self), NULL);
-
- return g_settings_get_string (self->settings_interface, GEDIT_SETTINGS_SYSTEM_FONT);
-}
-
-gchar *
-_gedit_settings_get_selected_font (GeditSettings *self)
+gedit_settings_get_system_font (GeditSettings *self)
{
g_return_val_if_fail (GEDIT_IS_SETTINGS (self), NULL);
- if (g_settings_get_boolean (self->settings_editor, GEDIT_SETTINGS_USE_DEFAULT_FONT))
- {
- return _gedit_settings_get_system_font (self);
- }
-
- return g_settings_get_string (self->settings_editor, GEDIT_SETTINGS_EDITOR_FONT);
+ return g_settings_get_string (self->settings_interface, "monospace-font-name");
}
static gboolean
diff -Nru gedit-40.1/gedit/gedit-settings.h gedit-41.0/gedit/gedit-settings.h
--- gedit-40.1/gedit/gedit-settings.h 2021-04-17 05:45:36.120558300 +0000
+++ gedit-41.0/gedit/gedit-settings.h 2022-02-14 13:58:26.000000000 +0000
@@ -43,11 +43,7 @@
G_GNUC_INTERNAL
GSettings * _gedit_settings_peek_file_chooser_state_settings (GeditSettings *self);
-G_GNUC_INTERNAL
-gchar * _gedit_settings_get_system_font (GeditSettings *self);
-
-G_GNUC_INTERNAL
-gchar * _gedit_settings_get_selected_font (GeditSettings *self);
+gchar * gedit_settings_get_system_font (GeditSettings *self);
GSList * gedit_settings_get_candidate_encodings (gboolean *default_candidates);
@@ -73,6 +69,7 @@
#define GEDIT_SETTINGS_RESTORE_CURSOR_POSITION "restore-cursor-position"
#define GEDIT_SETTINGS_SYNTAX_HIGHLIGHTING "syntax-highlighting"
#define GEDIT_SETTINGS_SEARCH_HIGHLIGHTING "search-highlighting"
+#define GEDIT_SETTINGS_DISPLAY_OVERVIEW_MAP "display-overview-map"
#define GEDIT_SETTINGS_BACKGROUND_PATTERN "background-pattern"
#define GEDIT_SETTINGS_STATUSBAR_VISIBLE "statusbar-visible"
#define GEDIT_SETTINGS_SIDE_PANEL_VISIBLE "side-panel-visible"
diff -Nru gedit-40.1/gedit/gedit-tab.c gedit-41.0/gedit/gedit-tab.c
--- gedit-40.1/gedit/gedit-tab.c 2021-04-17 05:45:36.196560000 +0000
+++ gedit-41.0/gedit/gedit-tab.c 2022-02-14 13:58:26.000000000 +0000
@@ -24,7 +24,6 @@
#include
#include
-#include
#include "gedit-app.h"
#include "gedit-app-private.h"
@@ -33,6 +32,7 @@
#include "gedit-io-error-info-bar.h"
#include "gedit-print-job.h"
#include "gedit-print-preview.h"
+#include "gedit-progress-info-bar.h"
#include "gedit-debug.h"
#include "gedit-document.h"
#include "gedit-document-private.h"
@@ -143,6 +143,9 @@
static void launch_saver (GTask *saving_task);
+static void continue_loading(GTask *loading_task);
+
+
static SaverData *
saver_data_new (void)
{
@@ -574,9 +577,9 @@
}
static void
-document_shortname_notify_handler (TeplFile *file,
- GParamSpec *pspec,
- GeditTab *tab)
+document_shortname_notify_handler (GeditDocument *document,
+ GParamSpec *pspec,
+ GeditTab *tab)
{
gedit_debug (DEBUG_TAB);
@@ -688,6 +691,14 @@
g_object_unref (loading_task);
break;
+
+ case GTK_RESPONSE_ACCEPT:
+ set_info_bar (data->tab, NULL, GTK_RESPONSE_NONE);
+ gedit_tab_set_state (data->tab, GEDIT_TAB_STATE_LOADING);
+
+ continue_loading (loading_task);
+ break;
+
default:
if (location != NULL)
{
@@ -726,7 +737,7 @@
{
LoaderData *data = g_task_get_task_data (loading_task);
- g_return_if_fail (TEPL_IS_PROGRESS_INFO_BAR (data->tab->info_bar));
+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (data->tab->info_bar));
g_cancellable_cancel (g_task_get_cancellable (loading_task));
remove_tab (data->tab);
@@ -757,7 +768,7 @@
show_loading_info_bar (GTask *loading_task)
{
LoaderData *data = g_task_get_task_data (loading_task);
- TeplProgressInfoBar *bar;
+ GtkWidget *bar;
GeditDocument *doc;
gchar *name;
gchar *dirname = NULL;
@@ -785,7 +796,7 @@
{
gchar *str;
- str = tepl_utils_str_middle_truncate (name, MAX_MSG_LENGTH);
+ str = gedit_utils_str_middle_truncate (name, MAX_MSG_LENGTH);
g_free (name);
name = str;
}
@@ -804,8 +815,8 @@
* we have a title long 99 + 20, but I think it's a rare enough
* case to be acceptable. It's justa darn title afterall :)
*/
- dirname = tepl_utils_str_middle_truncate (str,
- MAX (20, MAX_MSG_LENGTH - len));
+ dirname = gedit_utils_str_middle_truncate (str,
+ MAX (20, MAX_MSG_LENGTH - len));
g_free (str);
}
}
@@ -830,7 +841,7 @@
msg = g_strdup_printf (_("Reverting %s"), name_markup);
}
- bar = tepl_progress_info_bar_new ("document-revert", msg, TRUE);
+ bar = gedit_progress_info_bar_new ("document-revert", msg, TRUE);
}
else
{
@@ -850,7 +861,7 @@
msg = g_strdup_printf (_("Loading %s"), name_markup);
}
- bar = tepl_progress_info_bar_new ("document-open", msg, TRUE);
+ bar = gedit_progress_info_bar_new ("document-open", msg, TRUE);
}
g_signal_connect_object (bar,
@@ -859,7 +870,7 @@
loading_task,
0);
- set_info_bar (data->tab, GTK_WIDGET (bar), GTK_RESPONSE_NONE);
+ set_info_bar (data->tab, bar, GTK_RESPONSE_NONE);
g_free (msg);
g_free (name);
@@ -871,7 +882,7 @@
show_saving_info_bar (GTask *saving_task)
{
GeditTab *tab = g_task_get_source_object (saving_task);
- TeplProgressInfoBar *bar;
+ GtkWidget *bar;
GeditDocument *doc;
gchar *short_name;
gchar *from;
@@ -899,7 +910,7 @@
*/
if (len > MAX_MSG_LENGTH)
{
- from = tepl_utils_str_middle_truncate (short_name, MAX_MSG_LENGTH);
+ from = gedit_utils_str_middle_truncate (short_name, MAX_MSG_LENGTH);
g_free (short_name);
}
else
@@ -913,7 +924,7 @@
from = short_name;
to = g_file_get_parse_name (location);
- str = tepl_utils_str_middle_truncate (to, MAX (20, MAX_MSG_LENGTH - len));
+ str = gedit_utils_str_middle_truncate (to, MAX (20, MAX_MSG_LENGTH - len));
g_free (to);
to = str;
@@ -935,9 +946,9 @@
msg = g_strdup_printf (_("Saving %s"), from_markup);
}
- bar = tepl_progress_info_bar_new ("document-save", msg, FALSE);
+ bar = gedit_progress_info_bar_new ("document-save", msg, FALSE);
- set_info_bar (tab, GTK_WIDGET (bar), GTK_RESPONSE_NONE);
+ set_info_bar (tab, bar, GTK_RESPONSE_NONE);
g_free (msg);
g_free (to);
@@ -950,7 +961,7 @@
goffset size,
goffset total_size)
{
- TeplProgressInfoBar *progress_info_bar;
+ GeditProgressInfoBar *progress_info_bar;
if (tab->info_bar == NULL)
{
@@ -959,23 +970,23 @@
gedit_debug_message (DEBUG_TAB, "%" G_GOFFSET_FORMAT "/%" G_GOFFSET_FORMAT, size, total_size);
- g_return_if_fail (TEPL_IS_PROGRESS_INFO_BAR (tab->info_bar));
+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (tab->info_bar));
- progress_info_bar = TEPL_PROGRESS_INFO_BAR (tab->info_bar);
+ progress_info_bar = GEDIT_PROGRESS_INFO_BAR (tab->info_bar);
if (total_size != 0)
{
gdouble frac = (gdouble)size / (gdouble)total_size;
- tepl_progress_info_bar_set_fraction (progress_info_bar, frac);
+ gedit_progress_info_bar_set_fraction (progress_info_bar, frac);
}
else if (size != 0)
{
- tepl_progress_info_bar_pulse (progress_info_bar);
+ gedit_progress_info_bar_pulse (progress_info_bar);
}
else
{
- tepl_progress_info_bar_set_fraction (progress_info_bar, 0);
+ gedit_progress_info_bar_set_fraction (progress_info_bar, 0);
}
}
@@ -1034,7 +1045,7 @@
GeditView *view;
view = gedit_tab_get_view (tab);
- tepl_view_scroll_to_cursor (TEPL_VIEW (view));
+ gedit_view_scroll_to_cursor (view);
tab->idle_scroll = 0;
return G_SOURCE_REMOVE;
@@ -1118,9 +1129,9 @@
}
static void
-cant_create_backup_error_info_bar_response (GtkWidget *info_bar,
- gint response_id,
- GTask *saving_task)
+no_backup_error_info_bar_response (GtkWidget *info_bar,
+ gint response_id,
+ GTask *saving_task)
{
if (response_id == GTK_RESPONSE_YES)
{
@@ -1226,7 +1237,7 @@
static void
display_externally_modified_notification (GeditTab *tab)
{
- TeplInfoBar *info_bar;
+ GtkWidget *info_bar;
GeditDocument *doc;
GtkSourceFile *file;
GFile *location;
@@ -1240,9 +1251,9 @@
g_return_if_fail (location != NULL);
document_modified = gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc));
- info_bar = tepl_io_error_info_bar_externally_modified (location, document_modified);
+ info_bar = gedit_externally_modified_info_bar_new (location, document_modified);
- set_info_bar (tab, GTK_WIDGET (info_bar), GTK_RESPONSE_OK);
+ set_info_bar (tab, info_bar, GTK_RESPONSE_OK);
g_signal_connect (info_bar,
"response",
@@ -1307,7 +1318,6 @@
GeditDocument *doc;
GeditView *view;
GtkSourceFile *file;
- TeplFile *tepl_file;
tab->state = GEDIT_TAB_STATE_NORMAL;
@@ -1338,7 +1348,6 @@
g_object_set_data (G_OBJECT (doc), GEDIT_TAB_KEY, tab);
file = gedit_document_get_file (doc);
- tepl_file = tepl_buffer_get_file (TEPL_BUFFER (doc));
g_signal_connect_object (file,
"notify::location",
@@ -1346,11 +1355,10 @@
tab,
0);
- g_signal_connect_object (tepl_file,
- "notify::short-name",
- G_CALLBACK (document_shortname_notify_handler),
- tab,
- 0);
+ g_signal_connect (doc,
+ "notify::shortname",
+ G_CALLBACK (document_shortname_notify_handler),
+ tab);
g_signal_connect (doc,
"modified_changed",
@@ -1434,7 +1442,7 @@
name = gedit_document_get_short_name_for_display (doc);
/* Truncate the name so it doesn't get insanely wide. */
- docname = tepl_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
+ docname = gedit_utils_str_middle_truncate (name, MAX_DOC_NAME_LENGTH);
if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
{
@@ -1467,7 +1475,7 @@
uri = _gedit_document_get_uri_for_display (doc);
g_return_val_if_fail (uri != NULL, NULL);
- ruri = tepl_utils_replace_home_dir_with_tilde (uri);
+ ruri = gedit_utils_replace_home_dir_with_tilde (uri);
g_free (uri);
ruri_markup = g_markup_printf_escaped ("%s", ruri);
@@ -1576,6 +1584,8 @@
{
GdkScreen *screen;
GtkIconTheme *theme;
+ GtkIconInfo *info;
+ GtkStyleContext *context;
gint icon_size;
screen = gtk_widget_get_screen (GTK_WIDGET (tab));
@@ -1584,7 +1594,10 @@
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &icon_size);
- pixbuf = gtk_icon_theme_load_icon (theme, icon_name, icon_size, 0, NULL);
+ context = gtk_widget_get_style_context (GTK_WIDGET (tab));
+ info = gtk_icon_theme_lookup_icon (theme, icon_name, icon_size, 0);
+
+ pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL);
}
return pixbuf;
@@ -1633,11 +1646,9 @@
/* Move the cursor at the requested line if any. */
if (data->line_pos > 0)
{
- TeplView *view = TEPL_VIEW (gedit_tab_get_view (data->tab));
-
- tepl_view_goto_line_offset (view,
- data->line_pos - 1,
- MAX (0, data->column_pos - 1));
+ gedit_document_goto_line_offset (doc,
+ data->line_pos - 1,
+ MAX (0, data->column_pos - 1));
return;
}
@@ -1753,18 +1764,18 @@
if (!gtk_source_file_is_readonly (file) &&
file_already_opened (doc, location))
{
- TeplInfoBar *info_bar;
+ GtkWidget *info_bar;
set_editable (data->tab, FALSE);
- info_bar = tepl_io_error_info_bar_file_already_open (location);
+ info_bar = gedit_file_already_open_warning_info_bar_new (location);
g_signal_connect (info_bar,
"response",
G_CALLBACK (file_already_open_warning_info_bar_response),
data->tab);
- set_info_bar (data->tab, GTK_WIDGET (info_bar), GTK_RESPONSE_CANCEL);
+ set_info_bar (data->tab, info_bar, GTK_RESPONSE_CANCEL);
}
/* When loading from stdin, the contents may not be saved, so set the
@@ -1979,12 +1990,56 @@
}
static void
+continue_loading(GTask *loading_task)
+{
+ LoaderData *data = g_task_get_task_data (loading_task);
+ // Pre loader
+ gtk_source_file_loader_load_async (data->loader,
+ G_PRIORITY_DEFAULT,
+ g_task_get_cancellable (loading_task),
+ (GFileProgressCallback) loader_progress_cb,
+ loading_task,
+ NULL,
+ (GAsyncReadyCallback) load_cb,
+ loading_task);
+}
+
+
+
+static
+guint64 get_file_size (GFile *file)
+{
+ GFileInfo *info;
+ GError *error = NULL;
+ guint64 res = 0;
+
+ if (file == NULL)
+ {
+ return 0;
+ }
+
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, &error);
+
+ if (error)
+ {
+ g_error_free (error);
+ return 0;
+ }
+
+ res = g_file_info_get_size(info);
+ g_object_unref (info);
+ return res;
+}
+
+static void
launch_loader (GTask *loading_task,
const GtkSourceEncoding *encoding)
{
LoaderData *data = g_task_get_task_data (loading_task);
GSList *candidate_encodings = NULL;
GeditDocument *doc;
+ const int MB = 1024*1024;
+ const int FILE_TOO_LARGE = 100*MB;
if (encoding != NULL)
{
@@ -2010,6 +2065,47 @@
data->timer = g_timer_new ();
+
+ GFile * file = gtk_source_file_loader_get_location (data->loader);
+ guint64 size = get_file_size (file);
+
+ if (size > FILE_TOO_LARGE)
+ {
+ GtkWidget *info_bar;
+ GError *error = NULL;
+ GFile *location = gtk_source_file_loader_get_location (data->loader);
+ set_editable (data->tab, FALSE);
+
+ error = g_error_new_literal (GTK_SOURCE_FILE_LOADER_ERROR, 0, "");
+ error->code = GTK_SOURCE_FILE_LOADER_ERROR_TOO_BIG;
+
+ info_bar = gedit_io_loading_error_info_bar_new (location, NULL, error);
+
+ g_signal_connect (info_bar,
+ "response",
+ G_CALLBACK (io_loading_error_info_bar_response),
+ loading_task);
+
+ set_info_bar (data->tab, info_bar, GTK_RESPONSE_CANCEL);
+
+ if (data->tab->state == GEDIT_TAB_STATE_LOADING)
+ {
+ gtk_widget_show (GTK_WIDGET (data->tab->frame));
+ gedit_tab_set_state (data->tab, GEDIT_TAB_STATE_LOADING_ERROR);
+ }
+ else
+ {
+ gedit_tab_set_state (data->tab, GEDIT_TAB_STATE_REVERTING_ERROR);
+ }
+
+ successful_load (loading_task);
+ gedit_recent_add_document (doc);
+
+ g_error_free (error);
+ return;
+ }
+
+ // Pre loader
gtk_source_file_loader_load_async (data->loader,
G_PRIORITY_DEFAULT,
g_task_get_cancellable (loading_task),
@@ -2310,12 +2406,12 @@
error->code == G_IO_ERROR_CANT_CREATE_BACKUP)
{
/* This error is recoverable */
- info_bar = GTK_WIDGET (tepl_io_error_info_bar_cant_create_backup (location, error));
+ info_bar = gedit_no_backup_saving_error_info_bar_new (location, error);
g_return_if_fail (info_bar != NULL);
g_signal_connect (info_bar,
"response",
- G_CALLBACK (cant_create_backup_error_info_bar_response),
+ G_CALLBACK (no_backup_error_info_bar_response),
saving_task);
}
else if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR &&
@@ -2324,7 +2420,7 @@
/* If we have any invalid char in the document we must warn the user
* as it can make the document useless if it is saved.
*/
- info_bar = GTK_WIDGET (tepl_io_error_info_bar_invalid_characters (location));
+ info_bar = gedit_invalid_character_info_bar_new (location);
g_return_if_fail (info_bar != NULL);
g_signal_connect (info_bar,
@@ -2596,6 +2692,7 @@
g_return_if_fail (GEDIT_IS_TAB (tab));
g_return_if_fail (tab->state == GEDIT_TAB_STATE_NORMAL ||
tab->state == GEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION ||
+ tab->state == GEDIT_TAB_STATE_SAVING_ERROR ||
tab->state == GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
g_return_if_fail (G_IS_FILE (location));
g_return_if_fail (encoding != NULL);
@@ -2626,6 +2723,11 @@
set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_MODIFICATION_TIME;
}
+ else if (tab->state == GEDIT_TAB_STATE_SAVING_ERROR)
+ {
+ set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
+ gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
+ }
file = gedit_document_get_file (doc);
@@ -2706,15 +2808,15 @@
GeditPrintJobStatus status,
GeditTab *tab)
{
- g_return_if_fail (TEPL_IS_PROGRESS_INFO_BAR (tab->info_bar));
+ g_return_if_fail (GEDIT_IS_PROGRESS_INFO_BAR (tab->info_bar));
gtk_widget_show (tab->info_bar);
- tepl_progress_info_bar_set_text (TEPL_PROGRESS_INFO_BAR (tab->info_bar),
- gedit_print_job_get_status_string (job));
+ gedit_progress_info_bar_set_text (GEDIT_PROGRESS_INFO_BAR (tab->info_bar),
+ gedit_print_job_get_status_string (job));
- tepl_progress_info_bar_set_fraction (TEPL_PROGRESS_INFO_BAR (tab->info_bar),
- gedit_print_job_get_progress (job));
+ gedit_progress_info_bar_set_fraction (GEDIT_PROGRESS_INFO_BAR (tab->info_bar),
+ gedit_print_job_get_progress (job));
}
static void
@@ -2824,19 +2926,21 @@
static void
add_printing_info_bar (GeditTab *tab)
{
- TeplProgressInfoBar *bar;
+ GtkWidget *bar;
- bar = tepl_progress_info_bar_new ("document-print", NULL, TRUE);
+ bar = gedit_progress_info_bar_new ("document-print",
+ "",
+ TRUE);
g_signal_connect (bar,
"response",
G_CALLBACK (print_cancelled),
tab);
- set_info_bar (tab, GTK_WIDGET (bar), GTK_RESPONSE_NONE);
+ set_info_bar (tab, bar, GTK_RESPONSE_NONE);
/* hide until we start printing */
- gtk_widget_hide (GTK_WIDGET (bar));
+ gtk_widget_hide (bar);
}
void
diff -Nru gedit-40.1/gedit/gedit-utils.c gedit-41.0/gedit/gedit-utils.c
--- gedit-40.1/gedit/gedit-utils.c 2021-04-17 05:45:36.196560000 +0000
+++ gedit-41.0/gedit/gedit-utils.c 2022-02-14 13:58:26.000000000 +0000
@@ -23,7 +23,6 @@
#include "gedit-utils.h"
#include
#include
-#include
#include "gedit-debug.h"
gboolean
@@ -87,6 +86,122 @@
atk_object_set_description (aobj, description);
}
+void
+gedit_warning (GtkWindow *parent, const gchar *format, ...)
+{
+ va_list args;
+ gchar *str;
+ GtkWidget *dialog;
+ GtkWindowGroup *wg = NULL;
+
+ g_return_if_fail (format != NULL);
+
+ if (parent != NULL)
+ wg = gtk_window_get_group (parent);
+
+ va_start (args, format);
+ str = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ dialog = gtk_message_dialog_new_with_markup (
+ parent,
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "%s", str);
+
+ g_free (str);
+
+ if (wg != NULL)
+ gtk_window_group_add_window (wg, GTK_WINDOW (dialog));
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+
+ g_signal_connect (G_OBJECT (dialog),
+ "response",
+ G_CALLBACK (gtk_widget_destroy),
+ NULL);
+
+ gtk_widget_show (dialog);
+}
+
+/* the following functions are taken from eel */
+
+static gchar *
+gedit_utils_str_truncate (const gchar *string,
+ guint truncate_length,
+ gboolean middle)
+{
+ GString *truncated;
+ guint length;
+ guint n_chars;
+ guint num_left_chars;
+ guint right_offset;
+ guint delimiter_length;
+ const gchar *delimiter = "\342\200\246";
+
+ g_return_val_if_fail (string != NULL, NULL);
+
+ length = strlen (string);
+
+ g_return_val_if_fail (g_utf8_validate (string, length, NULL), NULL);
+
+ /* It doesnt make sense to truncate strings to less than
+ * the size of the delimiter plus 2 characters (one on each
+ * side)
+ */
+ delimiter_length = g_utf8_strlen (delimiter, -1);
+ if (truncate_length < (delimiter_length + 2))
+ {
+ return g_strdup (string);
+ }
+
+ n_chars = g_utf8_strlen (string, length);
+
+ /* Make sure the string is not already small enough. */
+ if (n_chars <= truncate_length)
+ {
+ return g_strdup (string);
+ }
+
+ /* Find the 'middle' where the truncation will occur. */
+ if (middle)
+ {
+ num_left_chars = (truncate_length - delimiter_length) / 2;
+ right_offset = n_chars - truncate_length + num_left_chars + delimiter_length;
+
+ truncated = g_string_new_len (string,
+ g_utf8_offset_to_pointer (string, num_left_chars) - string);
+ g_string_append (truncated, delimiter);
+ g_string_append (truncated, g_utf8_offset_to_pointer (string, right_offset));
+ }
+ else
+ {
+ num_left_chars = truncate_length - delimiter_length;
+ truncated = g_string_new_len (string,
+ g_utf8_offset_to_pointer (string, num_left_chars) - string);
+ g_string_append (truncated, delimiter);
+ }
+
+ return g_string_free (truncated, FALSE);
+}
+
+gchar *
+gedit_utils_str_middle_truncate (const gchar *string,
+ guint truncate_length)
+{
+ return gedit_utils_str_truncate (string, truncate_length, TRUE);
+}
+
+gchar *
+gedit_utils_str_end_truncate (const gchar *string,
+ guint truncate_length)
+{
+ return gedit_utils_str_truncate (string, truncate_length, FALSE);
+}
+
static gchar *
uri_get_dirname (const gchar *uri)
{
@@ -106,7 +221,7 @@
return NULL;
}
- res = tepl_utils_replace_home_dir_with_tilde (str);
+ res = gedit_utils_replace_home_dir_with_tilde (str);
g_free (str);
@@ -149,10 +264,10 @@
g_object_unref (mount);
/* obtain the "path" part of the uri */
- tepl_utils_decode_uri (uri,
- NULL, NULL,
- NULL, NULL,
- &path);
+ gedit_utils_decode_uri (uri,
+ NULL, NULL,
+ NULL, NULL,
+ &path);
if (path == NULL)
{
@@ -187,6 +302,51 @@
return res;
}
+gchar *
+gedit_utils_replace_home_dir_with_tilde (const gchar *uri)
+{
+ gchar *tmp;
+ gchar *home;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ /* Note that g_get_home_dir returns a const string */
+ tmp = (gchar *)g_get_home_dir ();
+
+ if (tmp == NULL)
+ return g_strdup (uri);
+
+ home = g_filename_to_utf8 (tmp, -1, NULL, NULL, NULL);
+ if (home == NULL)
+ return g_strdup (uri);
+
+ if (strcmp (uri, home) == 0)
+ {
+ g_free (home);
+
+ return g_strdup ("~/");
+ }
+
+ tmp = home;
+ home = g_strdup_printf ("%s/", tmp);
+ g_free (tmp);
+
+ if (g_str_has_prefix (uri, home))
+ {
+ gchar *res;
+
+ res = g_strdup_printf ("~/%s", uri + strlen (home));
+
+ g_free (home);
+
+ return res;
+ }
+
+ g_free (home);
+
+ return g_strdup (uri);
+}
+
static gboolean
is_valid_scheme_character (gchar c)
{
@@ -353,7 +513,7 @@
}
}
else if (g_file_has_parent (location, NULL) ||
- !tepl_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL))
+ !gedit_utils_decode_uri (uri, NULL, NULL, &hn, NULL, NULL))
{
/* For remote files with a parent (so not just http://foo.com)
or remote file for which the decoding of the host name fails,
@@ -438,6 +598,165 @@
return uri_list;
}
+static void
+null_ptr (gchar **ptr)
+{
+ if (ptr)
+ *ptr = NULL;
+}
+
+/**
+ * gedit_utils_decode_uri:
+ * @uri: the uri to decode
+ * @scheme: (out) (allow-none): return value pointer for the uri's
+ * scheme (e.g. http, sftp, ...), or %NULL
+ * @user: (out) (allow-none): return value pointer for the uri user info, or %NULL
+ * @port: (out) (allow-none): return value pointer for the uri port, or %NULL
+ * @host: (out) (allow-none): return value pointer for the uri host, or %NULL
+ * @path: (out) (allow-none): return value pointer for the uri path, or %NULL
+ *
+ * Parse and break an uri apart in its individual components like the uri
+ * scheme, user info, port, host and path. The return value pointer can be
+ * %NULL to ignore certain parts of the uri. If the function returns %TRUE, then
+ * all return value pointers should be freed using g_free
+ *
+ * Return value: %TRUE if the uri could be properly decoded, %FALSE otherwise.
+ */
+gboolean
+gedit_utils_decode_uri (const gchar *uri,
+ gchar **scheme,
+ gchar **user,
+ gchar **host,
+ gchar **port,
+ gchar **path)
+{
+ /* Largely copied from glib/gio/gdummyfile.c:_g_decode_uri. This
+ * functionality should be in glib/gio, but for now we implement it
+ * ourselves (see bug #546182) */
+
+ const char *p, *in, *hier_part_start, *hier_part_end;
+ char *out;
+ char c;
+
+ /* From RFC 3986 Decodes:
+ * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+ */
+
+ p = uri;
+
+ null_ptr (scheme);
+ null_ptr (user);
+ null_ptr (port);
+ null_ptr (host);
+ null_ptr (path);
+
+ /* Decode scheme:
+ * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ */
+
+ if (!g_ascii_isalpha (*p))
+ return FALSE;
+
+ while (1)
+ {
+ c = *p++;
+
+ if (c == ':')
+ break;
+
+ if (!(g_ascii_isalnum(c) ||
+ c == '+' ||
+ c == '-' ||
+ c == '.'))
+ {
+ return FALSE;
+ }
+ }
+
+ if (scheme)
+ {
+ *scheme = g_malloc (p - uri);
+ out = *scheme;
+
+ for (in = uri; in < p - 1; in++)
+ {
+ *out++ = g_ascii_tolower (*in);
+ }
+
+ *out = '\0';
+ }
+
+ hier_part_start = p;
+ hier_part_end = p + strlen (p);
+
+ if (hier_part_start[0] == '/' && hier_part_start[1] == '/')
+ {
+ const char *authority_start, *authority_end;
+ const char *userinfo_start, *userinfo_end;
+ const char *host_start, *host_end;
+ const char *port_start;
+
+ authority_start = hier_part_start + 2;
+ /* authority is always followed by / or nothing */
+ authority_end = memchr (authority_start, '/', hier_part_end - authority_start);
+
+ if (authority_end == NULL)
+ authority_end = hier_part_end;
+
+ /* 3.2:
+ * authority = [ userinfo "@" ] host [ ":" port ]
+ */
+
+ userinfo_end = memchr (authority_start, '@', authority_end - authority_start);
+
+ if (userinfo_end)
+ {
+ userinfo_start = authority_start;
+
+ if (user)
+ *user = g_uri_unescape_segment (userinfo_start, userinfo_end, NULL);
+
+ if (user && *user == NULL)
+ {
+ if (scheme)
+ g_free (*scheme);
+
+ return FALSE;
+ }
+
+ host_start = userinfo_end + 1;
+ }
+ else
+ {
+ host_start = authority_start;
+ }
+
+ port_start = memchr (host_start, ':', authority_end - host_start);
+
+ if (port_start)
+ {
+ host_end = port_start++;
+
+ if (port)
+ *port = g_strndup (port_start, authority_end - port_start);
+ }
+ else
+ {
+ host_end = authority_end;
+ }
+
+ if (host)
+ *host = g_strndup (host_start, host_end - host_start);
+
+ hier_part_start = authority_end;
+ }
+
+ if (path)
+ *path = g_uri_unescape_segment (hier_part_start, hier_part_end, "/");
+
+ return TRUE;
+}
+
GtkSourceCompressionType
gedit_utils_get_compression_type_from_content_type (const gchar *content_type)
{
diff -Nru gedit-40.1/gedit/gedit-utils.h gedit-41.0/gedit/gedit-utils.h
--- gedit-40.1/gedit/gedit-utils.h 2021-04-17 05:45:36.272561600 +0000
+++ gedit-41.0/gedit/gedit-utils.h 2022-02-14 13:58:26.000000000 +0000
@@ -27,19 +27,38 @@
G_BEGIN_DECLS
+/* useful macro */
+#define GBOOLEAN_TO_POINTER(i) (GINT_TO_POINTER ((i) ? 2 : 1))
+#define GPOINTER_TO_BOOLEAN(i) ((gboolean) ((GPOINTER_TO_INT(i) == 2) ? TRUE : FALSE))
+
gboolean gedit_utils_menu_position_under_tree_view (GtkTreeView *tree_view,
GdkRectangle *rect);
+gchar *gedit_utils_str_middle_truncate (const gchar *string,
+ guint truncate_length);
+gchar *gedit_utils_str_end_truncate (const gchar *string,
+ guint truncate_length);
void gedit_utils_set_atk_name_description (GtkWidget *widget,
const gchar *name,
const gchar *description);
+void gedit_warning (GtkWindow *parent,
+ const gchar *format,
+ ...) G_GNUC_PRINTF(2, 3);
-gchar *gedit_utils_location_get_dirname_for_display (GFile *location);
+gchar *gedit_utils_location_get_dirname_for_display (GFile *location);
+gchar *gedit_utils_replace_home_dir_with_tilde (const gchar *uri);
gboolean gedit_utils_is_valid_location (GFile *location);
gchar *gedit_utils_basename_for_display (GFile *location);
+gboolean gedit_utils_decode_uri (const gchar *uri,
+ gchar **scheme,
+ gchar **user,
+ gchar **host,
+ gchar **port,
+ gchar **path);
+
/* Turns data from a drop into a list of well formatted uris */
gchar **gedit_utils_drop_get_uris (GtkSelectionData *selection_data);
diff -Nru gedit-40.1/gedit/gedit-view.c gedit-41.0/gedit/gedit-view.c
--- gedit-40.1/gedit/gedit-view.c 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/gedit-view.c 2022-02-14 13:58:26.000000000 +0000
@@ -24,16 +24,21 @@
#include "gedit-view-activatable.h"
#include "gedit-plugins-engine.h"
#include "gedit-debug.h"
+#include "gedit-pango.h"
#include "gedit-utils.h"
#include "gedit-settings.h"
+#define GEDIT_VIEW_SCROLL_MARGIN 0.02
+
struct _GeditViewPrivate
{
+ GeditDocument *current_document;
PeasExtensionSet *extensions;
gchar *direct_save_uri;
- TeplSignalGroup *file_signal_group;
+ GtkCssProvider *css_provider;
+ PangoFontDescription *font_desc;
};
enum
@@ -50,7 +55,7 @@
static guint signals[N_SIGNALS];
-G_DEFINE_TYPE_WITH_PRIVATE (GeditView, gedit_view, TEPL_TYPE_VIEW)
+G_DEFINE_TYPE_WITH_PRIVATE (GeditView, gedit_view, GTK_SOURCE_TYPE_VIEW)
static void
update_editable (GeditView *view)
@@ -74,22 +79,45 @@
}
static void
+current_document_removed (GeditView *view)
+{
+ if (view->priv->current_document != NULL)
+ {
+ GtkSourceFile *file;
+
+ file = gedit_document_get_file (view->priv->current_document);
+
+ g_signal_handlers_disconnect_by_func (file,
+ file_read_only_notify_cb,
+ view);
+
+ g_object_unref (view->priv->current_document);
+ view->priv->current_document = NULL;
+ }
+}
+
+static void
buffer_changed (GeditView *view)
{
- GeditDocument *doc;
GtkSourceFile *file;
+ GtkTextBuffer *buffer;
- doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
- file = gedit_document_get_file (doc);
+ current_document_removed (view);
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
- tepl_signal_group_clear (&view->priv->file_signal_group);
- view->priv->file_signal_group = tepl_signal_group_new (G_OBJECT (file));
+ if (!GEDIT_IS_DOCUMENT (buffer))
+ {
+ return;
+ }
- tepl_signal_group_add (view->priv->file_signal_group,
- g_signal_connect (file,
- "notify::read-only",
- G_CALLBACK (file_read_only_notify_cb),
- view));
+ view->priv->current_document = g_object_ref (GEDIT_DOCUMENT (buffer));
+
+ file = gedit_document_get_file (view->priv->current_document);
+ g_signal_connect_object (file,
+ "notify::read-only",
+ G_CALLBACK (file_read_only_notify_cb),
+ view,
+ 0);
update_editable (view);
}
@@ -106,7 +134,7 @@
gedit_view_init (GeditView *view)
{
GtkTargetList *target_list;
- GtkStyleContext *style_context;
+ GtkStyleContext *context;
gedit_debug (DEBUG_VIEW);
@@ -140,8 +168,13 @@
NULL);
/* CSS stuff */
- style_context = gtk_widget_get_style_context (GTK_WIDGET (view));
- gtk_style_context_add_class (style_context, "gedit-view");
+ context = gtk_widget_get_style_context (GTK_WIDGET (view));
+ gtk_style_context_add_class (context, "gedit-view");
+
+ view->priv->css_provider = gtk_css_provider_new ();
+ gtk_style_context_add_provider (context,
+ GTK_STYLE_PROVIDER (view->priv->css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
static void
@@ -150,7 +183,8 @@
GeditView *view = GEDIT_VIEW (object);
g_clear_object (&view->priv->extensions);
- tepl_signal_group_clear (&view->priv->file_signal_group);
+
+ current_document_removed (view);
/* Disconnect notify buffer because the destroy of the textview will set
* the buffer to NULL, and we call get_buffer in the notify which would
@@ -160,26 +194,10 @@
*/
g_signal_handlers_disconnect_by_func (view, buffer_notify_cb, NULL);
- G_OBJECT_CLASS (gedit_view_parent_class)->dispose (object);
-}
+ g_clear_object (&view->priv->css_provider);
+ g_clear_pointer (&view->priv->font_desc, pango_font_description_free);
-static void
-update_font (GeditView *view)
-{
- GeditSettings *settings;
- gchar *selected_font;
-
- settings = _gedit_settings_get_singleton ();
- selected_font = _gedit_settings_get_selected_font (settings);
- tepl_utils_override_font (GTK_WIDGET (view), selected_font);
- g_free (selected_font);
-}
-
-static void
-fonts_changed_cb (GeditSettings *settings,
- GeditView *view)
-{
- update_font (view);
+ G_OBJECT_CLASS (gedit_view_parent_class)->dispose (object);
}
static void
@@ -188,18 +206,27 @@
GeditView *view = GEDIT_VIEW (object);
GeditSettings *settings;
GSettings *editor_settings;
+ gboolean use_default_font;
G_OBJECT_CLASS (gedit_view_parent_class)->constructed (object);
settings = _gedit_settings_get_singleton ();
editor_settings = _gedit_settings_peek_editor_settings (settings);
- update_font (view);
- g_signal_connect_object (settings,
- "fonts-changed",
- G_CALLBACK (fonts_changed_cb),
- view,
- 0);
+ use_default_font = g_settings_get_boolean (editor_settings, GEDIT_SETTINGS_USE_DEFAULT_FONT);
+
+ if (use_default_font)
+ {
+ gedit_view_set_font (view, TRUE, NULL);
+ }
+ else
+ {
+ gchar *editor_font;
+
+ editor_font = g_settings_get_string (editor_settings, GEDIT_SETTINGS_EDITOR_FONT);
+ gedit_view_set_font (view, FALSE, editor_font);
+ g_free (editor_font);
+ }
g_settings_bind (editor_settings, GEDIT_SETTINGS_DISPLAY_LINE_NUMBERS,
view, "show-line-numbers",
@@ -720,4 +747,217 @@
NULL);
}
+void
+gedit_view_cut_clipboard (GeditView *view)
+{
+ GtkTextBuffer *buffer;
+ GtkClipboard *clipboard;
+
+ gedit_debug (DEBUG_VIEW);
+
+ g_return_if_fail (GEDIT_IS_VIEW (view));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
+ GDK_SELECTION_CLIPBOARD);
+
+ gtk_text_buffer_cut_clipboard (buffer,
+ clipboard,
+ gtk_text_view_get_editable (GTK_TEXT_VIEW (view)));
+
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
+ gtk_text_buffer_get_insert (buffer),
+ GEDIT_VIEW_SCROLL_MARGIN,
+ FALSE,
+ 0.0,
+ 0.0);
+}
+
+void
+gedit_view_copy_clipboard (GeditView *view)
+{
+ GtkTextBuffer *buffer;
+ GtkClipboard *clipboard;
+
+ gedit_debug (DEBUG_VIEW);
+
+ g_return_if_fail (GEDIT_IS_VIEW (view));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
+ GDK_SELECTION_CLIPBOARD);
+
+ gtk_text_buffer_copy_clipboard (buffer, clipboard);
+
+ /* on copy do not scroll, we are already on screen */
+}
+
+void
+gedit_view_paste_clipboard (GeditView *view)
+{
+ GtkTextBuffer *buffer;
+ GtkClipboard *clipboard;
+
+ gedit_debug (DEBUG_VIEW);
+
+ g_return_if_fail (GEDIT_IS_VIEW (view));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
+ GDK_SELECTION_CLIPBOARD);
+
+ gtk_text_buffer_paste_clipboard (buffer,
+ clipboard,
+ NULL,
+ gtk_text_view_get_editable (GTK_TEXT_VIEW (view)));
+
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
+ gtk_text_buffer_get_insert (buffer),
+ GEDIT_VIEW_SCROLL_MARGIN,
+ FALSE,
+ 0.0,
+ 0.0);
+}
+
+/**
+ * gedit_view_delete_selection:
+ * @view: a #GeditView
+ *
+ * Deletes the text currently selected in the #GtkTextBuffer associated
+ * to the view and scroll to the cursor position.
+ */
+void
+gedit_view_delete_selection (GeditView *view)
+{
+ GtkTextBuffer *buffer;
+
+ gedit_debug (DEBUG_VIEW);
+
+ g_return_if_fail (GEDIT_IS_VIEW (view));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ gtk_text_buffer_delete_selection (buffer,
+ TRUE,
+ gtk_text_view_get_editable (GTK_TEXT_VIEW (view)));
+
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
+ gtk_text_buffer_get_insert (buffer),
+ GEDIT_VIEW_SCROLL_MARGIN,
+ FALSE,
+ 0.0,
+ 0.0);
+}
+
+/**
+ * gedit_view_select_all:
+ * @view: a #GeditView
+ *
+ * Selects all the text.
+ */
+void
+gedit_view_select_all (GeditView *view)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter start;
+ GtkTextIter end;
+
+ gedit_debug (DEBUG_VIEW);
+
+ g_return_if_fail (GEDIT_IS_VIEW (view));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ gtk_text_buffer_select_range (buffer, &start, &end);
+}
+
+/**
+ * gedit_view_scroll_to_cursor:
+ * @view: a #GeditView
+ *
+ * Scrolls the @view to the cursor position.
+ */
+void
+gedit_view_scroll_to_cursor (GeditView *view)
+{
+ GtkTextBuffer *buffer;
+
+ gedit_debug (DEBUG_VIEW);
+
+ g_return_if_fail (GEDIT_IS_VIEW (view));
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+ gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
+ gtk_text_buffer_get_insert (buffer),
+ 0.25,
+ FALSE,
+ 0.0,
+ 0.0);
+}
+
+static void
+update_css_provider (GeditView *view)
+{
+ gchar *str;
+ gchar *css;
+
+ g_assert (GEDIT_IS_VIEW (view));
+ g_assert (view->priv->font_desc != NULL);
+
+ str = gedit_pango_font_description_to_css (view->priv->font_desc);
+ css = g_strdup_printf ("textview { %s }", str ? str : "");
+ gtk_css_provider_load_from_data (view->priv->css_provider, css, -1, NULL);
+
+ g_free (css);
+ g_free (str);
+}
+
+/**
+ * gedit_view_set_font:
+ * @view: a #GeditView
+ * @default_font: whether to reset to the default font
+ * @font_name: the name of the font to use
+ *
+ * If @default_font is #TRUE, resets the font of the @view to the default font.
+ * Otherwise sets it to @font_name.
+ */
+void
+gedit_view_set_font (GeditView *view,
+ gboolean default_font,
+ const gchar *font_name)
+{
+ gedit_debug (DEBUG_VIEW);
+
+ g_return_if_fail (GEDIT_IS_VIEW (view));
+
+ g_clear_pointer (&view->priv->font_desc, pango_font_description_free);
+
+ if (default_font)
+ {
+ GeditSettings *settings;
+ gchar *font;
+
+ settings = _gedit_settings_get_singleton ();
+ font = gedit_settings_get_system_font (settings);
+
+ view->priv->font_desc = pango_font_description_from_string (font);
+ g_free (font);
+ }
+ else
+ {
+ g_return_if_fail (font_name != NULL);
+
+ view->priv->font_desc = pango_font_description_from_string (font_name);
+ }
+
+ g_return_if_fail (view->priv->font_desc != NULL);
+
+ update_css_provider (view);
+}
+
/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-view-centering.c gedit-41.0/gedit/gedit-view-centering.c
--- gedit-40.1/gedit/gedit-view-centering.c 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-view-centering.c 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,495 @@
+/*
+ * gedit-view-centering.c
+ * This file is part of gedit
+ *
+ * Copyright (C) 2014 - Sébastien Lafargue
+ *
+ * Gedit is free software; you can redistribute this file 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.
+ *
+ * Gedit 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Based on Christian Hergert's prototype.
+ */
+
+#include "gedit-view-centering.h"
+
+#include
+
+#include "gedit-view.h"
+#include "gedit-debug.h"
+
+struct _GeditViewCenteringPrivate
+{
+ GtkWidget *box;
+ GtkWidget *scrolled_window;
+ GtkWidget *sourceview;
+ GtkWidget *spacer;
+
+ GtkStyleContext *view_context;
+ GdkRGBA view_background;
+ GdkRGBA view_line_margin_fg;
+ GdkRGBA view_margin_background;
+ guint view_text_width;
+
+ guint centered : 1;
+ guint view_background_set : 1;
+ guint view_line_margin_fg_set : 1;
+ guint view_margin_background_set : 1;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (GeditViewCentering, gedit_view_centering, GTK_TYPE_BIN)
+
+#define STYLE_TEXT "text"
+#define STYLE_RIGHT_MARGIN "right-margin"
+
+#define RIGHT_MARGIN_LINE_ALPHA 40
+#define RIGHT_MARGIN_OVERLAY_ALPHA 15
+
+static gboolean
+get_style (GtkSourceStyleScheme *scheme,
+ const gchar *style_id,
+ const gchar *attribute,
+ GdkRGBA *color)
+{
+ GtkSourceStyle *style;
+ gchar *style_string;
+
+ style = gtk_source_style_scheme_get_style (scheme, style_id);
+ if (!style)
+ {
+ return FALSE;
+ }
+
+ g_object_get (style, attribute, &style_string, NULL);
+ if (style_string)
+ {
+ gdk_rgba_parse (color, style_string);
+ g_free (style_string);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+get_spacer_colors (GeditViewCentering *container,
+ GtkSourceStyleScheme *scheme)
+{
+ GeditViewCenteringPrivate *priv = container->priv;
+
+ if (scheme)
+ {
+ priv->view_background_set = get_style (scheme,
+ STYLE_TEXT, "background",
+ &priv->view_background);
+
+ priv->view_line_margin_fg_set = get_style (scheme,
+ STYLE_RIGHT_MARGIN, "foreground",
+ &priv->view_line_margin_fg);
+ priv->view_line_margin_fg.alpha = RIGHT_MARGIN_LINE_ALPHA / 255.0;
+
+ priv->view_margin_background_set = get_style (scheme,
+ STYLE_RIGHT_MARGIN, "background",
+ &priv->view_margin_background);
+ priv->view_margin_background.alpha = RIGHT_MARGIN_OVERLAY_ALPHA / 255.0;
+ }
+}
+
+/* FIXME: when GeditViewCentering will be transfered to GtkSourceView,
+ * this method will be replaced by a call to a new method called
+ * gtk_source_view_get_right_margin_pixel_position ()
+ */
+static guint
+_gedit_view_centering_get_right_margin_pixel_position (GeditViewCentering *container)
+{
+ GeditViewCenteringPrivate *priv;
+ gchar *str;
+ PangoFontDescription *font_desc;
+ PangoLayout *layout;
+ guint right_margin_position;
+ gint width = 0;
+
+ g_return_val_if_fail (GEDIT_IS_VIEW_CENTERING (container), 0);
+
+ priv = container->priv;
+
+ right_margin_position = gtk_source_view_get_right_margin_position (GTK_SOURCE_VIEW (priv->sourceview));
+
+ gtk_style_context_save (priv->view_context);
+ gtk_style_context_set_state (priv->view_context, GTK_STATE_FLAG_NORMAL);
+ gtk_style_context_get (priv->view_context,
+ gtk_style_context_get_state (priv->view_context),
+ GTK_STYLE_PROPERTY_FONT, &font_desc,
+ NULL);
+ gtk_style_context_restore (priv->view_context);
+
+ str = g_strnfill (right_margin_position, '_');
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (priv->sourceview), str);
+ g_free (str);
+
+ pango_layout_set_font_description (layout, font_desc);
+ pango_font_description_free (font_desc);
+ pango_layout_get_pixel_size (layout, &width, NULL);
+
+ g_object_unref (G_OBJECT (layout));
+
+ return width;
+}
+
+static void
+on_view_right_margin_visibility_changed (GeditView *view,
+ GParamSpec *pspec,
+ GeditViewCentering *container)
+{
+ GeditViewCenteringPrivate *priv = container->priv;
+ gboolean visibility;
+
+ visibility = gtk_source_view_get_show_right_margin (GTK_SOURCE_VIEW (priv->sourceview));
+
+ gtk_widget_set_visible (GTK_WIDGET (container->priv->spacer), visibility && priv->centered);
+}
+
+static void
+on_view_right_margin_position_changed (GeditView *view,
+ GParamSpec *pspec,
+ GeditViewCentering *container)
+{
+ GeditViewCenteringPrivate *priv = container->priv;
+ gboolean visibility;
+
+ priv->view_text_width = _gedit_view_centering_get_right_margin_pixel_position (container);
+
+ visibility = gtk_source_view_get_show_right_margin (GTK_SOURCE_VIEW (priv->sourceview));
+
+ if (visibility)
+ {
+ gtk_widget_queue_resize (priv->spacer);
+ }
+}
+
+static void
+on_view_context_changed (GtkStyleContext *stylecontext,
+ GeditViewCentering *container)
+{
+ GeditViewCenteringPrivate *priv = container->priv;
+ GtkTextBuffer *buffer;
+ GtkSourceStyleScheme *scheme;
+ gboolean visibility;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->sourceview));
+ scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
+ get_spacer_colors (container, scheme);
+
+ priv->view_text_width = _gedit_view_centering_get_right_margin_pixel_position (container);
+
+ visibility = gtk_source_view_get_show_right_margin (GTK_SOURCE_VIEW (priv->sourceview));
+
+ if (visibility)
+ {
+ gtk_widget_queue_resize (priv->spacer);
+ }
+}
+
+static gboolean
+on_spacer_draw (GeditViewCentering *container,
+ cairo_t *cr,
+ GtkDrawingArea *spacer)
+{
+ GeditViewCenteringPrivate *priv = container->priv;
+ GtkStyleContext *context;
+ guint width, height;
+
+ if (!container->priv->sourceview)
+ {
+ return FALSE;
+ }
+
+ width = gtk_widget_get_allocated_width (GTK_WIDGET (spacer));
+ height = gtk_widget_get_allocated_height (GTK_WIDGET (spacer));
+
+ context = gtk_widget_get_style_context (GTK_WIDGET (spacer));
+ gtk_style_context_save (context);
+ gtk_style_context_add_class (context, GTK_STYLE_CLASS_VIEW);
+ gtk_render_background (context, cr, 0, 0, width, height);
+ gtk_style_context_restore (context);
+
+ cairo_set_line_width (cr, 1.0);
+
+ if (priv->view_background_set)
+ {
+ gdk_cairo_set_source_rgba (cr, &container->priv->view_background);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ }
+
+ if (priv->view_margin_background_set)
+ {
+ gdk_cairo_set_source_rgba (cr, &container->priv->view_margin_background);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
+ }
+
+ if (priv->view_line_margin_fg_set)
+ {
+ gdk_cairo_set_source_rgba (cr, &container->priv->view_line_margin_fg);
+ cairo_move_to (cr, width - 0.5, 0);
+ cairo_line_to (cr, width - 0.5, height);
+ cairo_stroke (cr);
+ }
+
+ return FALSE;
+}
+
+static void
+gedit_view_centering_remove (GtkContainer *container,
+ GtkWidget *child)
+{
+ GeditViewCenteringPrivate *priv;
+
+ g_assert (GEDIT_IS_VIEW_CENTERING (container));
+
+ priv = GEDIT_VIEW_CENTERING (container)->priv;
+
+ if (priv->sourceview == child)
+ {
+ gtk_container_remove (GTK_CONTAINER (priv->scrolled_window), priv->sourceview);
+ g_object_remove_weak_pointer (G_OBJECT (priv->sourceview), (gpointer *)&priv->sourceview);
+ priv->sourceview = NULL;
+ priv->view_context = NULL;
+ }
+ else
+ {
+ GTK_CONTAINER_CLASS (gedit_view_centering_parent_class)->remove (container, child);
+ }
+}
+
+static void
+gedit_view_centering_add (GtkContainer *container,
+ GtkWidget *child)
+{
+ GeditViewCenteringPrivate *priv;
+ GtkTextBuffer *buffer;
+ GtkSourceStyleScheme *scheme;
+
+ g_assert (GEDIT_IS_VIEW_CENTERING (container));
+
+ priv = GEDIT_VIEW_CENTERING (container)->priv;
+
+ if (GEDIT_IS_VIEW (child))
+ {
+ if (priv->sourceview)
+ {
+ gedit_view_centering_remove (container, priv->sourceview);
+ }
+
+ priv->sourceview = child;
+ g_object_add_weak_pointer (G_OBJECT (child), (gpointer *)&priv->sourceview);
+ gtk_container_add (GTK_CONTAINER (priv->scrolled_window), child);
+
+ priv->view_context = gtk_widget_get_style_context (child);
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->sourceview));
+ scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (buffer));
+ get_spacer_colors (GEDIT_VIEW_CENTERING (container), scheme);
+
+ g_signal_connect (priv->sourceview,
+ "notify::right-margin-position",
+ G_CALLBACK (on_view_right_margin_position_changed),
+ container);
+
+ g_signal_connect (priv->sourceview,
+ "notify::show-right-margin",
+ G_CALLBACK (on_view_right_margin_visibility_changed),
+ container);
+
+ g_signal_connect (priv->view_context,
+ "changed",
+ G_CALLBACK (on_view_context_changed),
+ container);
+
+ gtk_widget_queue_resize (GTK_WIDGET (container));
+ }
+ else
+ {
+ GTK_CONTAINER_CLASS (gedit_view_centering_parent_class)->add (container, child);
+ }
+}
+
+static gboolean
+on_spacer_scroll_event (GtkWidget *widget,
+ GdkEvent *event,
+ GeditViewCentering *container)
+{
+ GdkEventScroll *new_scroll_event;
+
+ new_scroll_event = (GdkEventScroll *)gdk_event_copy (event);
+ g_object_unref (new_scroll_event->window);
+
+ new_scroll_event->window = g_object_ref (gtk_widget_get_window (container->priv->sourceview));
+ new_scroll_event->send_event = TRUE;
+
+ new_scroll_event->x = 0;
+ new_scroll_event->y = 0;
+ new_scroll_event->x_root = 0;
+ new_scroll_event->y_root = 0;
+
+ gtk_main_do_event ((GdkEvent *)new_scroll_event);
+ gdk_event_free ((GdkEvent *)new_scroll_event);
+
+ return TRUE;
+}
+
+static void
+gedit_view_centering_size_allocate (GtkWidget *widget,
+ GtkAllocation *alloc)
+{
+ GeditViewCenteringPrivate *priv;
+ GtkTextView *view;
+ gint container_width;
+ gint gutter_width;
+ gint text_width;
+ gint spacer_width;
+ gint current_spacer_width;
+ GdkWindow *gutter_window;
+
+ g_assert (GEDIT_IS_VIEW_CENTERING (widget));
+
+ priv = GEDIT_VIEW_CENTERING (widget)->priv;
+
+ view = GTK_TEXT_VIEW (priv->sourceview);
+
+ if (view)
+ {
+ container_width = alloc->width;
+
+ gutter_window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_LEFT);
+ gutter_width = (gutter_window) ? gdk_window_get_width (gutter_window) : 0;
+
+ text_width = priv->view_text_width;
+ spacer_width = MAX (0, container_width - text_width - gutter_width) / 2;
+
+ g_object_get(priv->spacer, "width-request", ¤t_spacer_width, NULL);
+
+ if (current_spacer_width != spacer_width)
+ {
+ g_object_set(priv->spacer, "width-request", spacer_width, NULL);
+ }
+ }
+
+ GTK_WIDGET_CLASS (gedit_view_centering_parent_class)->size_allocate (widget, alloc);
+}
+
+static void
+gedit_view_centering_finalize (GObject *object)
+{
+ GeditViewCentering *container = GEDIT_VIEW_CENTERING (object);
+ GeditViewCenteringPrivate *priv = container->priv;
+
+ if (priv->sourceview)
+ {
+ gedit_view_centering_remove (GTK_CONTAINER (container), priv->sourceview);
+ }
+
+ G_OBJECT_CLASS (gedit_view_centering_parent_class)->finalize (object);
+}
+
+static void
+gedit_view_centering_class_init (GeditViewCenteringClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+
+ gobject_class->finalize = gedit_view_centering_finalize;
+
+ widget_class->size_allocate = gedit_view_centering_size_allocate;
+
+ container_class->add = gedit_view_centering_add;
+ container_class->remove = gedit_view_centering_remove;
+}
+
+static void
+gedit_view_centering_init (GeditViewCentering *container)
+{
+ GeditViewCenteringPrivate *priv;
+
+ container->priv = gedit_view_centering_get_instance_private (container);
+ priv = container->priv;
+ priv->view_text_width = 0;
+
+ priv->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ priv->spacer = gtk_drawing_area_new ();
+ priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+
+ gtk_container_add (GTK_CONTAINER (container), priv->box);
+ gtk_box_pack_start (GTK_BOX (priv->box), priv->spacer, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->box), priv->scrolled_window, TRUE, TRUE, 0);
+
+ gtk_widget_set_no_show_all (GTK_WIDGET (priv->spacer), TRUE);
+ gtk_widget_show_all (GTK_WIDGET (priv->box));
+
+ g_signal_connect_swapped (priv->spacer, "draw",
+ G_CALLBACK (on_spacer_draw),
+ container);
+
+ gtk_widget_add_events(GTK_WIDGET(priv->spacer), GDK_SCROLL_MASK);
+ g_signal_connect (priv->spacer, "scroll-event",
+ G_CALLBACK (on_spacer_scroll_event),
+ container);
+}
+
+/**
+ * gedit_view_centering_set_centered:
+ * @container: a #GeditViewCentering.
+ * @centered: whether to center the sourceview child or not.
+ *
+ * If @centered is %TRUE, the sourceview child is centered
+ * horizontally on the #GeditViewCentering container.
+ **/
+void
+gedit_view_centering_set_centered (GeditViewCentering *container,
+ gboolean centered)
+{
+ g_return_if_fail (GEDIT_IS_VIEW_CENTERING (container));
+
+ container->priv->centered = centered != FALSE;
+
+ on_view_right_margin_visibility_changed (GEDIT_VIEW (container->priv->sourceview), NULL, container);
+}
+
+/**
+ * gedit_view_centering_get_centered:
+ * @container: a #GeditViewCentering.
+ *
+ * Return whether the #GtkSourceView child is centered or not.
+ *
+ * Return value: %TRUE if the #GtkSourceView child is centered
+ * horizontally on the #GeditViewCentering container.
+ **/
+gboolean
+gedit_view_centering_get_centered (GeditViewCentering *container)
+{
+ g_return_val_if_fail (GEDIT_IS_VIEW_CENTERING (container), FALSE);
+
+ return container->priv->centered;
+}
+
+GeditViewCentering *
+gedit_view_centering_new (void)
+{
+ return g_object_new (GEDIT_TYPE_VIEW_CENTERING,
+ NULL);
+}
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-view-centering.h gedit-41.0/gedit/gedit-view-centering.h
--- gedit-40.1/gedit/gedit-view-centering.h 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/gedit-view-centering.h 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,67 @@
+/*
+ * gedit-view-centering.h
+ * This file is part of gedit
+ *
+ * Copyright (C) 2014 - Sébastien Lafargue
+ * Copyright (C) 2015 - Sébastien Wilmet
+ *
+ * Gedit is free software; you can redistribute this file 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.
+ *
+ * Gedit 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef GEDIT_VIEW_CENTERING_H
+#define GEDIT_VIEW_CENTERING_H
+
+#include
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_VIEW_CENTERING (gedit_view_centering_get_type())
+#define GEDIT_VIEW_CENTERING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_VIEW_CENTERING, GeditViewCentering))
+#define GEDIT_VIEW_CENTERING_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEDIT_TYPE_VIEW_CENTERING, GeditViewCentering const))
+#define GEDIT_VIEW_CENTERING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_VIEW_CENTERING, GeditViewCenteringClass))
+#define GEDIT_IS_VIEW_CENTERING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEDIT_TYPE_VIEW_CENTERING))
+#define GEDIT_IS_VIEW_CENTERING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_VIEW_CENTERING))
+#define GEDIT_VIEW_CENTERING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_VIEW_CENTERING, GeditViewCenteringClass))
+
+typedef struct _GeditViewCentering GeditViewCentering;
+typedef struct _GeditViewCenteringClass GeditViewCenteringClass;
+typedef struct _GeditViewCenteringPrivate GeditViewCenteringPrivate;
+
+struct _GeditViewCentering
+{
+ GtkBin parent;
+
+ GeditViewCenteringPrivate *priv;
+};
+
+struct _GeditViewCenteringClass
+{
+ GtkBinClass parent_class;
+};
+
+GType gedit_view_centering_get_type (void) G_GNUC_CONST;
+
+GeditViewCentering * gedit_view_centering_new (void);
+
+void gedit_view_centering_set_centered (GeditViewCentering *container,
+ gboolean centered);
+
+gboolean gedit_view_centering_get_centered (GeditViewCentering *container);
+
+G_END_DECLS
+
+#endif /* GEDIT_VIEW_CENTERING_H */
+
+/* ex:set ts=8 noet: */
diff -Nru gedit-40.1/gedit/gedit-view-frame.c gedit-41.0/gedit/gedit-view-frame.c
--- gedit-40.1/gedit/gedit-view-frame.c 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/gedit-view-frame.c 2022-02-14 13:58:26.000000000 +0000
@@ -3,7 +3,7 @@
* This file is part of gedit
*
* Copyright (C) 2010 - Ignacio Casal Quinteiro
- * Copyright (C) 2013, 2019 - Sébastien Wilmet
+ * Copyright (C) 2013 - Sébastien Wilmet
*
* gedit is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,6 +28,7 @@
#include
#include
+#include "gedit-view-centering.h"
#include "gedit-debug.h"
#include "gedit-utils.h"
#include "gedit-settings.h"
@@ -53,7 +54,11 @@
{
GtkOverlay parent_instance;
+ GSettings *editor_settings;
+
GeditView *view;
+ GeditViewCentering *view_centering;
+ GtkFrame *map_frame;
SearchMode search_mode;
@@ -159,6 +164,7 @@
gtk_source_file_set_mount_operation_factory (file, NULL, NULL, NULL);
}
+ g_clear_object (&frame->editor_settings);
g_clear_object (&frame->entry_tag);
g_clear_object (&frame->search_settings);
g_clear_object (&frame->old_search_settings);
@@ -213,7 +219,7 @@
frame->start_mark);
gtk_text_buffer_place_cursor (buffer, &iter);
- tepl_view_scroll_to_cursor (TEPL_VIEW (frame->view));
+ gedit_view_scroll_to_cursor (frame->view);
}
if (frame->start_mark != NULL)
@@ -297,7 +303,7 @@
if (found || (entry_text[0] == '\0'))
{
- tepl_view_scroll_to_cursor (TEPL_VIEW (frame->view));
+ gedit_view_scroll_to_cursor (frame->view);
set_search_state (frame, SEARCH_STATE_NORMAL);
}
@@ -1061,6 +1067,7 @@
gchar **split_text = NULL;
const gchar *text;
GtkTextIter iter;
+ GeditDocument *doc;
entry_text = gtk_entry_get_text (GTK_ENTRY (frame->search_entry));
@@ -1116,8 +1123,11 @@
g_strfreev (split_text);
- moved = tepl_view_goto_line (TEPL_VIEW (frame->view), line);
- moved_offset = tepl_view_goto_line_offset (TEPL_VIEW (frame->view), line, line_offset);
+ doc = get_document (frame);
+ moved = gedit_document_goto_line (doc, line);
+ moved_offset = gedit_document_goto_line_offset (doc, line, line_offset);
+
+ gedit_view_scroll_to_cursor (frame->view);
if (!moved || !moved_offset)
{
@@ -1428,6 +1438,8 @@
gtk_widget_class_set_template_from_resource (widget_class,
"/org/gnome/gedit/ui/gedit-view-frame.ui");
gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, view);
+ gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, view_centering);
+ gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, map_frame);
gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, revealer);
gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, search_entry);
gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, go_up_button);
@@ -1454,6 +1466,13 @@
gtk_widget_init_template (GTK_WIDGET (frame));
+ frame->editor_settings = g_settings_new ("org.gnome.gedit.preferences.editor");
+ g_settings_bind (frame->editor_settings,
+ GEDIT_SETTINGS_DISPLAY_OVERVIEW_MAP,
+ frame->map_frame,
+ "visible",
+ G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
+
doc = get_document (frame);
file = gedit_document_get_file (doc);
@@ -1551,6 +1570,14 @@
return g_object_new (GEDIT_TYPE_VIEW_FRAME, NULL);
}
+GeditViewCentering *
+gedit_view_frame_get_view_centering (GeditViewFrame *frame)
+{
+ g_return_val_if_fail (GEDIT_IS_VIEW_FRAME (frame), NULL);
+
+ return frame->view_centering;
+}
+
GeditView *
gedit_view_frame_get_view (GeditViewFrame *frame)
{
diff -Nru gedit-40.1/gedit/gedit-view-frame.h gedit-41.0/gedit/gedit-view-frame.h
--- gedit-40.1/gedit/gedit-view-frame.h 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/gedit-view-frame.h 2022-02-14 13:58:26.000000000 +0000
@@ -24,6 +24,7 @@
#include
#include "gedit-document.h"
#include "gedit-view.h"
+#include "gedit-view-centering.h"
G_BEGIN_DECLS
@@ -32,6 +33,9 @@
GeditViewFrame *gedit_view_frame_new (void);
+GeditViewCentering
+ *gedit_view_frame_get_view_centering (GeditViewFrame *frame);
+
GeditView *gedit_view_frame_get_view (GeditViewFrame *frame);
void gedit_view_frame_popup_search (GeditViewFrame *frame);
diff -Nru gedit-40.1/gedit/gedit-view.h gedit-41.0/gedit/gedit-view.h
--- gedit-40.1/gedit/gedit-view.h 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/gedit-view.h 2022-02-14 13:58:26.000000000 +0000
@@ -22,8 +22,10 @@
#ifndef GEDIT_VIEW_H
#define GEDIT_VIEW_H
+#include
+
#include
-#include
+#include
G_BEGIN_DECLS
@@ -40,7 +42,7 @@
struct _GeditView
{
- TeplView view;
+ GtkSourceView view;
/*< private >*/
GeditViewPrivate *priv;
@@ -48,7 +50,7 @@
struct _GeditViewClass
{
- TeplViewClass parent_class;
+ GtkSourceViewClass parent_class;
void (*drop_uris) (GeditView *view,
gchar **uri_list);
@@ -60,6 +62,22 @@
GtkWidget * gedit_view_new (GeditDocument *doc);
+void gedit_view_cut_clipboard (GeditView *view);
+
+void gedit_view_copy_clipboard (GeditView *view);
+
+void gedit_view_paste_clipboard (GeditView *view);
+
+void gedit_view_delete_selection (GeditView *view);
+
+void gedit_view_select_all (GeditView *view);
+
+void gedit_view_scroll_to_cursor (GeditView *view);
+
+void gedit_view_set_font (GeditView *view,
+ gboolean default_font,
+ const gchar *font_name);
+
G_END_DECLS
#endif /* GEDIT_VIEW_H */
diff -Nru gedit-40.1/gedit/gedit-window.c gedit-41.0/gedit/gedit-window.c
--- gedit-40.1/gedit/gedit-window.c 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/gedit-window.c 2022-02-14 13:58:26.000000000 +0000
@@ -28,11 +28,11 @@
#include
#include
-#include
#include "gedit-window-private.h"
#include "gedit-app.h"
#include "gedit-app-private.h"
+#include "gedit-recent.h"
#include "gedit-notebook.h"
#include "gedit-notebook-popup-menu.h"
#include "gedit-multi-notebook.h"
@@ -40,6 +40,7 @@
#include "gedit-tab.h"
#include "gedit-tab-private.h"
#include "gedit-view-frame.h"
+#include "gedit-view-centering.h"
#include "gedit-utils.h"
#include "gedit-commands.h"
#include "gedit-commands-private.h"
@@ -54,6 +55,11 @@
#include "gedit-status-menu-button.h"
#include "gedit-settings.h"
#include "gedit-menu-stack-switcher.h"
+#include "gedit-highlight-mode-selector.h"
+#include "gedit-open-document-selector.h"
+
+#define TAB_WIDTH_DATA "GeditWindowTabWidthData"
+#define FULLSCREEN_ANIMATION_SPEED 500
enum
{
@@ -158,9 +164,9 @@
GeditWindow *window = GEDIT_WINDOW (widget);
if ((window->priv->window_state &
- (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
+ (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
{
- gtk_window_get_size (GTK_WINDOW (widget), &window->priv->width, &window->priv->height);
+ gtk_window_get_size (GTK_WINDOW (widget), &window->priv->width, &window->priv->height);
g_settings_set (window->priv->window_settings, GEDIT_SETTINGS_WINDOW_SIZE,
"(ii)", window->priv->width, window->priv->height);
@@ -231,8 +237,6 @@
*/
remove_actions (window);
- window->priv->fullscreen_open_recent_button = NULL;
-
G_OBJECT_CLASS (gedit_window_parent_class)->dispose (object);
}
@@ -247,6 +251,22 @@
G_OBJECT_CLASS (gedit_window_parent_class)->finalize (object);
}
+/* Center the view when the window is in fullscreen mode. */
+static void
+update_view_centering (GeditTab *tab,
+ gpointer user_data)
+{
+ GeditViewFrame *view_frame;
+ GeditViewCentering *view_centering;
+ gboolean is_fullscreen;
+
+ view_frame = _gedit_tab_get_view_frame (tab);
+ view_centering = gedit_view_frame_get_view_centering (view_frame);
+
+ is_fullscreen = GPOINTER_TO_BOOLEAN (user_data);
+ gedit_view_centering_set_centered (view_centering, is_fullscreen);
+}
+
static void
update_fullscreen (GeditWindow *window,
gboolean is_fullscreen)
@@ -267,6 +287,10 @@
}
}
+ gedit_multi_notebook_foreach_tab (window->priv->multi_notebook,
+ (GtkCallback)update_view_centering,
+ GBOOLEAN_TO_POINTER (is_fullscreen));
+
#ifndef OS_OSX
if (is_fullscreen)
{
@@ -312,7 +336,7 @@
if (gtk_widget_get_realized (widget) &&
(window->priv->window_state &
- (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
+ (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
{
save_window_state (widget);
}
@@ -454,6 +478,7 @@
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, side_headerbar);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, headerbar);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, new_button);
+ gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, open_button);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, gear_button);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, hpaned);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, side_panel);
@@ -466,10 +491,11 @@
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, language_button);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, tab_width_button);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, line_col_button);
+ gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_controls);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_eventbox);
- gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_revealer);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_headerbar);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_new_button);
+ gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_open_button);
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, fullscreen_gear_button);
}
@@ -765,8 +791,48 @@
}
static void
-language_chooser_show_cb (TeplLanguageChooser *language_chooser,
- GeditWindow *window)
+on_recent_chooser_item_activated (GeditOpenDocumentSelector *open_document_selector,
+ gchar *uri,
+ GeditWindow *window)
+{
+ GFile *location;
+ GeditView *active_view;
+
+ g_return_if_fail (GEDIT_WINDOW (window));
+ g_return_if_fail (GEDIT_OPEN_DOCUMENT_SELECTOR (open_document_selector));
+
+ /* TODO: get_current_file when exists */
+ location = g_file_new_for_uri (uri);
+
+ if (location)
+ {
+ GSList *locations = NULL;
+ GSList *loaded = NULL;
+
+ locations = g_slist_prepend (locations, (gpointer) location);
+ loaded = gedit_commands_load_locations (window, locations, NULL, 0, 0);
+
+ /* if it doesn't contain just 1 element */
+ if (!loaded || loaded->next)
+ {
+ gedit_recent_remove_if_local (location);
+ }
+
+ g_slist_free (locations);
+ g_slist_free (loaded);
+
+ g_object_unref (location);
+ }
+
+ /* Needed to close the popover when activating the same
+ * document as the current one */
+ active_view = gedit_window_get_active_view (window);
+ gtk_widget_grab_focus (GTK_WIDGET (active_view));
+}
+
+static void
+language_selector_show_cb (GeditHighlightModeSelector *selector,
+ GeditWindow *window)
{
GeditDocument *active_document;
@@ -776,14 +842,14 @@
GtkSourceLanguage *language;
language = gedit_document_get_language (active_document);
- tepl_language_chooser_select_language (language_chooser, language);
+ gedit_highlight_mode_selector_select_language (selector, language);
}
}
static void
-language_activated_cb (TeplLanguageChooser *language_chooser,
- GtkSourceLanguage *language,
- GeditWindow *window)
+language_selected_cb (GeditHighlightModeSelector *selector,
+ GtkSourceLanguage *language,
+ GeditWindow *window)
{
GeditDocument *active_document;
@@ -793,13 +859,13 @@
gedit_document_set_language (active_document, language);
}
- gtk_widget_hide (window->priv->language_popover);
+ gtk_widget_hide (GTK_WIDGET (window->priv->language_popover));
}
static void
setup_statusbar (GeditWindow *window)
{
- TeplLanguageChooserWidget *language_chooser;
+ GeditHighlightModeSelector *selector;
gedit_debug (DEBUG_WINDOW);
@@ -829,20 +895,20 @@
gtk_menu_button_set_popover (GTK_MENU_BUTTON (window->priv->language_button),
window->priv->language_popover);
- language_chooser = tepl_language_chooser_widget_new ();
+ selector = gedit_highlight_mode_selector_new ();
- g_signal_connect (language_chooser,
+ g_signal_connect (selector,
"show",
- G_CALLBACK (language_chooser_show_cb),
+ G_CALLBACK (language_selector_show_cb),
window);
- g_signal_connect (language_chooser,
- "language-activated",
- G_CALLBACK (language_activated_cb),
+ g_signal_connect (selector,
+ "language-selected",
+ G_CALLBACK (language_selected_cb),
window);
- gtk_container_add (GTK_CONTAINER (window->priv->language_popover), GTK_WIDGET (language_chooser));
- gtk_widget_show (GTK_WIDGET (language_chooser));
+ gtk_container_add (GTK_CONTAINER (window->priv->language_popover), GTK_WIDGET (selector));
+ gtk_widget_show (GTK_WIDGET (selector));
}
static GeditWindow *
@@ -1044,8 +1110,8 @@
{
gchar *tmp;
- tmp = tepl_utils_str_middle_truncate (name,
- MAX_TITLE_LENGTH);
+ tmp = gedit_utils_str_middle_truncate (name,
+ MAX_TITLE_LENGTH);
g_free (name);
name = tmp;
}
@@ -1063,8 +1129,8 @@
* we have a title long 99 + 20, but I think it's a rare enough
* case to be acceptable. It's justa darn title afterall :)
*/
- dirname = tepl_utils_str_middle_truncate (str,
- MAX (20, MAX_TITLE_LENGTH - len));
+ dirname = gedit_utils_str_middle_truncate (str,
+ MAX (20, MAX_TITLE_LENGTH - len));
g_free (str);
}
}
@@ -1690,88 +1756,84 @@
load_uris_from_drop (window, uri_list);
}
-static void
-update_fullscreen_revealer_state (GeditWindow *window)
+static gboolean
+on_fullscreen_controls_enter_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event,
+ GeditWindow *window)
{
- gboolean open_recent_menu_is_active;
- gboolean hamburger_menu_is_active;
+ window->priv->in_fullscreen_eventbox = TRUE;
- open_recent_menu_is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window->priv->fullscreen_open_recent_button));
- hamburger_menu_is_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window->priv->fullscreen_gear_button));
+ gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls), TRUE);
- gtk_revealer_set_reveal_child (window->priv->fullscreen_revealer,
- (window->priv->in_fullscreen_eventbox ||
- open_recent_menu_is_active ||
- hamburger_menu_is_active));
+ return FALSE;
}
static gboolean
-on_fullscreen_eventbox_enter_notify_event (GtkWidget *fullscreen_eventbox,
- GdkEventCrossing *event,
- GeditWindow *window)
+real_fullscreen_controls_leave_notify_event (gpointer data)
{
- window->priv->in_fullscreen_eventbox = TRUE;
- update_fullscreen_revealer_state (window);
+ GeditWindow *window = GEDIT_WINDOW (data);
+ gboolean hamburger_menu_state;
+ gboolean fullscreen_open_button_state;
+
+ hamburger_menu_state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window->priv->fullscreen_gear_button));
+ fullscreen_open_button_state =
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (window->priv->fullscreen_open_button));
- return GDK_EVENT_PROPAGATE;
-}
+ window->priv->in_fullscreen_eventbox = FALSE;
-static gboolean
-on_fullscreen_eventbox_leave_notify_event (GtkWidget *fullscreen_eventbox,
- GdkEventCrossing *event,
- GeditWindow *window)
-{
- if (-1.0 <= event->y && event->y <= 0.0)
- {
- /* Ignore the event.
- *
- * Leave notify events are received with -1 <= y <= 0
- * coordinates, although the GeditWindow is in fullscreen mode
- * and when there are no screens above (it's maybe a bug in an
- * underlying library).
- * If we hide the headerbar when those events happen, then it
- * makes the headerbar to be shown/hidden a lot of time in a
- * short period of time, i.e. a "stuttering". In other words
- * lots of leave/enter events are received when moving the mouse
- * upwards on the screen when the mouse is already at the top.
- * The expected leave event has a positive event->y value being
- * >= to the height of the headerbar (approximately
- * 40 <= y <= 50). So clearly when we receive a leave event with
- * event->y <= 0, it means that the mouse has left the eventbox
- * on the wrong side.
- * The -1.0 <= event->y is there (instead of just <= 0.0) in the
- * case that there is another screen *above*, even if this
- * heuristic/workaround is not perfect in that case. But that
- * case is quite rare, so it's probably a good enough solution.
- *
- * Note that apparently the "stuttering" occurs only on an Xorg
- * session, not on Wayland (tested with GNOME).
- *
- * If you see a better solution...
- */
- return GDK_EVENT_PROPAGATE;
+ if (!hamburger_menu_state && !fullscreen_open_button_state)
+ {
+ gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls), FALSE);
}
- window->priv->in_fullscreen_eventbox = FALSE;
- update_fullscreen_revealer_state (window);
+ return G_SOURCE_REMOVE;
+}
+
+/* this idle is needed because the toggled signal from gear button is received
+ * after the leave event from the event box ( which is automatically triggered when user
+ * bring up the gear menu */
+static gboolean
+on_fullscreen_controls_leave_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event,
+ GeditWindow *window)
+{
+ g_idle_add (real_fullscreen_controls_leave_notify_event, window);
return GDK_EVENT_PROPAGATE;
}
static void
-setup_fullscreen_eventbox (GeditWindow *window)
+fullscreen_controls_setup (GeditWindow *window)
{
- gtk_widget_set_size_request (window->priv->fullscreen_eventbox, -1, 1);
- gtk_widget_hide (window->priv->fullscreen_eventbox);
+ GeditWindowPrivate *priv = window->priv;
- g_signal_connect (window->priv->fullscreen_eventbox,
+ g_signal_connect (priv->fullscreen_eventbox,
"enter-notify-event",
- G_CALLBACK (on_fullscreen_eventbox_enter_notify_event),
+ G_CALLBACK (on_fullscreen_controls_enter_notify_event),
window);
- g_signal_connect (window->priv->fullscreen_eventbox,
+ g_signal_connect (priv->fullscreen_eventbox,
"leave-notify-event",
- G_CALLBACK (on_fullscreen_eventbox_leave_notify_event),
+ G_CALLBACK (on_fullscreen_controls_leave_notify_event),
+ window);
+
+ gtk_widget_set_size_request (GTK_WIDGET (window->priv->fullscreen_eventbox), -1, 1);
+ gtk_widget_hide (window->priv->fullscreen_eventbox);
+
+ priv->fullscreen_open_document_popover = gtk_popover_new (priv->fullscreen_open_button);
+ gtk_menu_button_set_popover (GTK_MENU_BUTTON (priv->fullscreen_open_button),
+ priv->fullscreen_open_document_popover);
+
+ window->priv->fullscreen_open_document_selector = gedit_open_document_selector_new (window);
+
+ gtk_container_add (GTK_CONTAINER (priv->fullscreen_open_document_popover),
+ GTK_WIDGET (priv->fullscreen_open_document_selector));
+
+ gtk_widget_show_all (GTK_WIDGET (priv->fullscreen_open_document_selector));
+
+ g_signal_connect (window->priv->fullscreen_open_document_selector,
+ "file-activated",
+ G_CALLBACK (on_recent_chooser_item_activated),
window);
}
@@ -1885,7 +1947,7 @@
G_CALLBACK (bracket_matched_cb),
window);
g_signal_connect (doc,
- "tepl-cursor-moved",
+ "cursor-moved",
G_CALLBACK (update_cursor_position_statusbar),
window);
g_signal_connect (doc,
@@ -2144,10 +2206,23 @@
}
static void
-on_fullscreen_toggle_button_toggled (GtkToggleButton *fullscreen_toggle_button,
- GeditWindow *window)
+on_fullscreen_gear_button_toggled (GtkToggleButton *fullscreen_gear_button,
+ GeditWindow *window)
{
- update_fullscreen_revealer_state (window);
+ gboolean button_active = gtk_toggle_button_get_active (fullscreen_gear_button);
+
+ gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls),
+ button_active || window->priv->in_fullscreen_eventbox);
+}
+
+static void
+on_fullscreen_file_menu_button_toggled (GtkMenuButton *fullscreen_open_button,
+ GeditWindow *window)
+{
+ gboolean button_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fullscreen_open_button));
+
+ gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->fullscreen_controls),
+ button_active || window->priv->in_fullscreen_eventbox);
}
static void
@@ -2538,6 +2613,18 @@
}
static void
+check_window_is_active (GeditWindow *window,
+ GParamSpec *property,
+ gpointer useless)
+{
+ if (window->priv->window_state & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ gtk_widget_set_visible (window->priv->fullscreen_eventbox,
+ gtk_window_is_active (GTK_WINDOW (window)));
+ }
+}
+
+static void
extension_added (PeasExtensionSet *extensions,
PeasPluginInfo *info,
PeasExtension *exten,
@@ -2609,76 +2696,6 @@
}
static void
-init_amtk_application_window (GeditWindow *gedit_window)
-{
- AmtkApplicationWindow *amtk_window;
-
- amtk_window = amtk_application_window_get_from_gtk_application_window (GTK_APPLICATION_WINDOW (gedit_window));
- amtk_application_window_set_statusbar (amtk_window, GTK_STATUSBAR (gedit_window->priv->statusbar));
-}
-
-static GtkWidget *
-create_open_buttons (GeditWindow *window,
- GtkMenuButton **open_recent_button)
-{
- GtkWidget *hbox;
- GtkStyleContext *style_context;
- GtkWidget *open_dialog_button;
- GtkWidget *my_open_recent_button;
- AmtkApplicationWindow *amtk_window;
- GtkWidget *recent_menu;
-
- /* It currently needs to be a GtkBox, not a GtkGrid, because GtkGrid and
- * GTK_STYLE_CLASS_LINKED doesn't work as expected in a RTL locale.
- * Probably a GtkGrid bug.
- */
- hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
- style_context = gtk_widget_get_style_context (hbox);
- gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_LINKED);
-
- open_dialog_button = gtk_button_new_with_mnemonic (_("_Open"));
- gtk_widget_set_tooltip_text (open_dialog_button, _("Open a file"));
- gtk_actionable_set_action_name (GTK_ACTIONABLE (open_dialog_button), "win.open");
-
- my_open_recent_button = gtk_menu_button_new ();
- gtk_widget_set_tooltip_text (my_open_recent_button, _("Open a recently used file"));
-
- amtk_window = amtk_application_window_get_from_gtk_application_window (GTK_APPLICATION_WINDOW (window));
- recent_menu = amtk_application_window_create_open_recent_menu (amtk_window);
- gtk_menu_button_set_popup (GTK_MENU_BUTTON (my_open_recent_button), recent_menu);
-
- gtk_container_add (GTK_CONTAINER (hbox), open_dialog_button);
- gtk_container_add (GTK_CONTAINER (hbox), my_open_recent_button);
- gtk_widget_show_all (hbox);
-
- if (open_recent_button != NULL)
- {
- *open_recent_button = GTK_MENU_BUTTON (my_open_recent_button);
- }
-
- return hbox;
-}
-
-static void
-init_open_buttons (GeditWindow *window)
-{
- gtk_container_add_with_properties (GTK_CONTAINER (window->priv->headerbar),
- create_open_buttons (window, NULL),
- "position", 0, /* The first on the left. */
- NULL);
-
- gtk_container_add_with_properties (GTK_CONTAINER (window->priv->fullscreen_headerbar),
- create_open_buttons (window, &(window->priv->fullscreen_open_recent_button)),
- "position", 0, /* The first on the left. */
- NULL);
-
- g_signal_connect (GTK_TOGGLE_BUTTON (window->priv->fullscreen_open_recent_button),
- "toggled",
- G_CALLBACK (on_fullscreen_toggle_button_toggled),
- window);
-}
-
-static void
gedit_window_init (GeditWindow *window)
{
GtkTargetList *tl;
@@ -2692,6 +2709,7 @@
window->priv->state = GEDIT_WINDOW_STATE_NORMAL;
window->priv->inhibition_cookie = 0;
window->priv->dispose_has_run = FALSE;
+ window->priv->fullscreen_controls = NULL;
window->priv->direct_save_uri = NULL;
window->priv->closed_docs_stack = NULL;
window->priv->editor_settings = g_settings_new ("org.gnome.gedit.preferences.editor");
@@ -2705,8 +2723,6 @@
window->priv->message_bus = gedit_message_bus_new ();
gtk_widget_init_template (GTK_WIDGET (window));
- init_amtk_application_window (window);
- init_open_buttons (window);
g_action_map_add_action_entries (G_ACTION_MAP (window),
win_entries,
@@ -2716,9 +2732,32 @@
window->priv->window_group = gtk_window_group_new ();
gtk_window_group_add_window (window->priv->window_group, GTK_WINDOW (window));
- setup_fullscreen_eventbox (window);
+ /* Setup file popover and file dialog */
+ window->priv->open_document_popover = gtk_popover_new (window->priv->open_button);
+ gtk_menu_button_set_popover (GTK_MENU_BUTTON (window->priv->open_button),
+ window->priv->open_document_popover);
+
+ window->priv->open_document_selector = gedit_open_document_selector_new (window);
+
+ gtk_container_add (GTK_CONTAINER (window->priv->open_document_popover),
+ GTK_WIDGET (window->priv->open_document_selector));
+
+ gtk_widget_show_all (GTK_WIDGET (window->priv->open_document_selector));
+
+ g_signal_connect (window->priv->open_document_selector,
+ "file-activated",
+ G_CALLBACK (on_recent_chooser_item_activated),
+ window);
+
+ fullscreen_controls_setup (window);
sync_fullscreen_actions (window, FALSE);
+ g_object_bind_property (gedit_open_document_selector_get_search_entry (window->priv->open_document_selector),
+ "text",
+ gedit_open_document_selector_get_search_entry (window->priv->fullscreen_open_document_selector),
+ "text",
+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
hamburger_menu = _gedit_app_get_hamburger_menu (GEDIT_APP (g_application_get_default ()));
if (hamburger_menu)
{
@@ -2733,9 +2772,14 @@
gtk_widget_set_no_show_all (GTK_WIDGET (window->priv->fullscreen_gear_button), TRUE);
}
+ g_signal_connect (GTK_TOGGLE_BUTTON (window->priv->fullscreen_open_button),
+ "toggled",
+ G_CALLBACK (on_fullscreen_file_menu_button_toggled),
+ window);
+
g_signal_connect (GTK_TOGGLE_BUTTON (window->priv->fullscreen_gear_button),
"toggled",
- G_CALLBACK (on_fullscreen_toggle_button_toggled),
+ G_CALLBACK (on_fullscreen_gear_button_toggled),
window);
/* Setup status bar */
@@ -2849,6 +2893,12 @@
G_CALLBACK (window_unrealized),
NULL);
+ /* Check if the window is active for fullscreen */
+ g_signal_connect (window,
+ "notify::is-active",
+ G_CALLBACK (check_window_is_active),
+ NULL);
+
gedit_debug_message (DEBUG_WINDOW, "Update plugins ui");
window->priv->extensions = peas_extension_set_new (PEAS_ENGINE (gedit_plugins_engine_get_default ()),
diff -Nru gedit-40.1/gedit/gedit-window-private.h gedit-41.0/gedit/gedit-window-private.h
--- gedit-40.1/gedit/gedit-window-private.h 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/gedit-window-private.h 2022-02-14 13:58:26.000000000 +0000
@@ -27,6 +27,7 @@
#include "gedit-message-bus.h"
#include "gedit-settings.h"
#include "gedit-multi-notebook.h"
+#include "gedit-open-document-selector.h"
G_BEGIN_DECLS
@@ -53,12 +54,15 @@
PeasExtensionSet *extensions;
/* Widgets for fullscreen mode */
+ GtkWidget *fullscreen_controls;
GtkWidget *fullscreen_eventbox;
- GtkRevealer *fullscreen_revealer;
GtkWidget *fullscreen_headerbar;
- GtkWidget *fullscreen_new_button;
GtkMenuButton *fullscreen_gear_button;
- GtkMenuButton *fullscreen_open_recent_button;
+
+ GtkWidget *fullscreen_new_button;
+ GtkWidget *fullscreen_open_button;
+ GtkWidget *fullscreen_open_document_popover;
+ GeditOpenDocumentSelector *fullscreen_open_document_selector;
/* statusbar and context ids for statusbar messages */
GtkWidget *statusbar;
@@ -79,7 +83,10 @@
GtkWidget *side_headerbar;
GtkWidget *headerbar;
- GtkWidget *new_button;
+ GtkWidget *open_document_popover;
+ GtkWidget *new_button;
+ GtkWidget *open_button;
+ GeditOpenDocumentSelector *open_document_selector;
GtkMenuButton *gear_button;
diff -Nru gedit-40.1/gedit/meson.build gedit-41.0/gedit/meson.build
--- gedit-40.1/gedit/meson.build 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/meson.build 2022-02-14 13:58:26.000000000 +0000
@@ -8,6 +8,7 @@
'gedit-menu-extension.h',
'gedit-message-bus.h',
'gedit-message.h',
+ 'gedit-progress-info-bar.h',
'gedit-statusbar.h',
'gedit-tab.h',
'gedit-utils.h',
@@ -27,11 +28,13 @@
'gedit-menu-extension.c',
'gedit-message-bus.c',
'gedit-message.c',
+ 'gedit-progress-info-bar.c',
'gedit-statusbar.c',
'gedit-tab.c',
'gedit-utils.c',
'gedit-view-activatable.c',
'gedit-view.c',
+ 'gedit-view-centering.c',
'gedit-window-activatable.c',
'gedit-window.c',
]
@@ -45,30 +48,37 @@
'gedit-documents-panel.h',
'gedit-encoding-items.h',
'gedit-encodings-dialog.h',
- 'gedit-factory.h',
'gedit-file-chooser-dialog-gtk.h',
'gedit-file-chooser-dialog.h',
'gedit-file-chooser.h',
'gedit-file-chooser-open-dialog.h',
'gedit-file-chooser-open.h',
'gedit-file-chooser-open-native.h',
+ 'gedit-highlight-mode-dialog.h',
+ 'gedit-highlight-mode-selector.h',
'gedit-history-entry.h',
'gedit-io-error-info-bar.h',
'gedit-menu-stack-switcher.h',
+ 'gedit-metadata-manager.h',
'gedit-multi-notebook.h',
'gedit-notebook.h',
'gedit-notebook-popup-menu.h',
'gedit-notebook-stack-switcher.h',
+ 'gedit-open-document-selector.h',
+ 'gedit-open-document-selector-helper.h',
+ 'gedit-open-document-selector-store.h',
+ 'gedit-pango.h',
'gedit-plugins-engine.h',
'gedit-preferences-dialog.h',
'gedit-print-job.h',
'gedit-print-preview.h',
'gedit-recent.h',
- 'gedit-recent-osx.h',
'gedit-replace-dialog.h',
'gedit-settings.h',
'gedit-status-menu-button.h',
'gedit-tab-label.h',
+ 'gedit-tab-private.h',
+ 'gedit-view-centering.h',
'gedit-view-frame.h',
'gedit-window-private.h',
]
@@ -85,20 +95,26 @@
'gedit-documents-panel.c',
'gedit-encoding-items.c',
'gedit-encodings-dialog.c',
- 'gedit-factory.c',
'gedit-file-chooser.c',
'gedit-file-chooser-dialog.c',
'gedit-file-chooser-dialog-gtk.c',
'gedit-file-chooser-open.c',
'gedit-file-chooser-open-dialog.c',
'gedit-file-chooser-open-native.c',
+ 'gedit-highlight-mode-dialog.c',
+ 'gedit-highlight-mode-selector.c',
'gedit-history-entry.c',
'gedit-io-error-info-bar.c',
'gedit-menu-stack-switcher.c',
+ 'gedit-metadata-manager.c',
'gedit-multi-notebook.c',
'gedit-notebook.c',
'gedit-notebook-popup-menu.c',
'gedit-notebook-stack-switcher.c',
+ 'gedit-open-document-selector.c',
+ 'gedit-open-document-selector-helper.c',
+ 'gedit-open-document-selector-store.c',
+ 'gedit-pango.c',
'gedit-plugins-engine.c',
'gedit-preferences-dialog.c',
'gedit-print-job.c',
@@ -117,6 +133,7 @@
libgedit_deps = [
deps_basic_list,
libgd_dep,
+ libxml_dep,
]
if host_machine.system() == 'darwin'
@@ -197,10 +214,12 @@
install_dir_typelib: get_option('libdir') / 'gedit/girepository-1.0',
)
-python3.install_sources(
- 'Gedit.py',
- subdir: 'gi/overrides',
-)
+if get_option('python')
+ python3.install_sources(
+ 'Gedit.py',
+ subdir: 'gi/overrides',
+ )
+endif
# Vala API
libgedit_vapi = gnome.generate_vapi(
diff -Nru gedit-40.1/gedit/resources/css/gedit.adwaita.css gedit-41.0/gedit/resources/css/gedit.adwaita.css
--- gedit-40.1/gedit/resources/css/gedit.adwaita.css 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/resources/css/gedit.adwaita.css 2022-02-14 13:58:26.000000000 +0000
@@ -1,3 +1,28 @@
+.open-document-selector-treeview:hover {
+ background-color: alpha(@theme_fg_color, 0.05);
+}
+
+.open-document-selector-treeview:selected:hover {
+ background-color: @theme_selected_bg_color;
+}
+
+/* Only normal state is handle */
+.open-document-selector-name-label {
+ color: @theme_fg_color;
+}
+
+/* Only normal state is handle */
+.open-document-selector-path-label {
+ color: @theme_unfocused_fg_color;
+ font-size: smaller;
+}
+
+/* Only normal state is handle */
+.open-document-selector-match {
+ color: shade (@theme_fg_color, 0.6);
+ background-color: alpha(@warning_color, 0.4);
+}
+
.gedit-document-panel {
background-color: @sidebar_bg;
}
diff -Nru gedit-40.1/gedit/resources/css/gedit-style.css gedit-41.0/gedit/resources/css/gedit-style.css
--- gedit-40.1/gedit/resources/css/gedit-style.css 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/resources/css/gedit-style.css 2022-02-14 13:58:26.000000000 +0000
@@ -14,6 +14,18 @@
padding: 12px;
}
+.gedit-map-frame:dir(ltr) border {
+ border-width: 0 0 0 1px;
+}
+
+.gedit-map-frame:dir(rtl) border {
+ border-width: 0 1px 0 0;
+}
+
+.open-document-selector-treeview {
+ padding: 3px 6px 3px 6px;
+}
+
statusbar frame {
border: none;
padding-left: 6px;
diff -Nru gedit-40.1/gedit/resources/gedit.gresource.xml.in gedit-41.0/gedit/resources/gedit.gresource.xml.in
--- gedit-40.1/gedit/resources/gedit.gresource.xml.in 2021-04-17 05:45:36.276561500 +0000
+++ gedit-41.0/gedit/resources/gedit.gresource.xml.in 2022-02-14 13:58:26.000000000 +0000
@@ -8,10 +8,14 @@
ui/gedit-replace-dialog.uiui/gedit-print-preview.uiui/gedit-print-preferences.ui
+ ui/gedit-progress-info-bar.uiui/gedit-status-menu-button.uiui/gedit-tab-label.uiui/gedit-view-frame.ui
+ ui/gedit-highlight-mode-dialog.ui
+ ui/gedit-highlight-mode-selector.uiui/gedit-window.ui
+ ui/gedit-open-document-selector.uiui/gedit-shortcuts.uiui/gedit-statusbar.uicss/gedit-style.css
diff -Nru gedit-40.1/gedit/resources/ui/gedit-highlight-mode-dialog.ui gedit-41.0/gedit/resources/ui/gedit-highlight-mode-dialog.ui
--- gedit-40.1/gedit/resources/ui/gedit-highlight-mode-dialog.ui 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/resources/ui/gedit-highlight-mode-dialog.ui 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,87 @@
+
+
+
+
+ 300
+ 400
+ False
+ False
+ False
+ 5
+ Highlight Mode
+ dialog
+ True
+
+
+ False
+ False
+ False
+ vertical
+ 2
+
+
+ False
+ False
+ False
+ end
+ 5
+ 6
+
+
+ _Cancel
+ True
+ True
+ False
+ False
+ True
+ True
+
+
+ False
+ True
+ 0
+
+
+
+
+ _Select
+ True
+ True
+ False
+ False
+ True
+ True
+ True
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ end
+ 0
+
+
+
+
+ True
+
+
+ False
+ True
+ 1
+
+
+
+
+
+ cancel_button
+ ok_button
+
+
+
diff -Nru gedit-40.1/gedit/resources/ui/gedit-highlight-mode-selector.ui gedit-41.0/gedit/resources/ui/gedit-highlight-mode-selector.ui
--- gedit-40.1/gedit/resources/ui/gedit-highlight-mode-selector.ui 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/resources/ui/gedit-highlight-mode-selector.ui 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ liststore
+
+
+ 300
+ 400
+ True
+ False
+ False
+ False
+ 3
+ 6
+
+
+ True
+ True
+ True
+ False
+ True
+ Search highlight mode…
+
+
+ 0
+ 0
+ 1
+ 1
+
+
+
+
+ True
+ True
+ False
+ False
+ True
+ True
+ in
+
+
+ True
+ True
+ False
+ False
+ treemodelfilter
+ False
+ False
+ False
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+ 0
+ 1
+ 1
+ 1
+
+
+
+
diff -Nru gedit-40.1/gedit/resources/ui/gedit-open-document-selector.ui gedit-41.0/gedit/resources/ui/gedit-open-document-selector.ui
--- gedit-40.1/gedit/resources/ui/gedit-open-document-selector.ui 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/resources/ui/gedit-open-document-selector.ui 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,115 @@
+
+
+
+
+ True
+ False
+ 9
+ vertical
+ 6
+
+
+ True
+ True
+ edit-find-symbolic
+ False
+ False
+
+
+ False
+ False
+ 0
+
+
+
+
+ False
+ False
+ True
+ True
+ in
+
+
+ True
+ vertical
+ center
+ center
+
+
+ True
+ edit-find-symbolic
+ 64
+ False
+
+
+
+
+
+ True
+ False
+ False
+ No results
+
+
+
+
+
+
+
+ True
+ True
+ 1
+
+
+
+
+ True
+ True
+ True
+ never
+ in
+
+
+ True
+ True
+ True
+ True
+ False
+ True
+ horizontal
+ False
+ True
+
+
+
+
+ True
+ True
+ 2
+
+
+
+
+ Other _Documents…
+ True
+ True
+ True
+ Open another file
+ 6
+ win.open
+
+
+
+ False
+ True
+ 3
+
+
+
+
diff -Nru gedit-40.1/gedit/resources/ui/gedit-preferences-dialog.ui gedit-41.0/gedit/resources/ui/gedit-preferences-dialog.ui
--- gedit-40.1/gedit/resources/ui/gedit-preferences-dialog.ui 2021-04-17 05:45:36.368563400 +0000
+++ gedit-41.0/gedit/resources/ui/gedit-preferences-dialog.ui 2022-02-14 13:58:26.000000000 +0000
@@ -106,6 +106,21 @@
+
+ Display _overview map
+ True
+ True
+ False
+ True
+ True
+
+
+ 0
+ 3
+ 2
+
+
+ Display _grid patternTrue
@@ -116,7 +131,7 @@
0
- 3
+ 42
@@ -630,8 +645,19 @@
TrueTrue
-
+ True
+ True
+ True
+ True
+ etched-in
+ 200
+
+
+ True
+ True
+
+ 0
diff -Nru gedit-40.1/gedit/resources/ui/gedit-progress-info-bar.ui gedit-41.0/gedit/resources/ui/gedit-progress-info-bar.ui
--- gedit-40.1/gedit/resources/ui/gedit-progress-info-bar.ui 1970-01-01 00:00:00.000000000 +0000
+++ gedit-41.0/gedit/resources/ui/gedit-progress-info-bar.ui 2022-02-14 13:58:26.000000000 +0000
@@ -0,0 +1,88 @@
+
+
+
+
+ True
+ False
+ other
+
+
+ False
+ vertical
+ 6
+
+
+ True
+ False
+ 4
+
+
+ True
+ False
+ 2
+ image-missing
+
+
+ False
+ True
+ 4
+ 0
+
+
+
+
+ True
+ False
+ start
+ label
+ True
+ end
+
+
+ False
+ True
+ 1
+
+
+
+
+ False
+ True
+ 0
+
+
+
+
+ 15
+ True
+ False
+ True
+
+
+ False
+ True
+ 1
+
+
+
+
+ True
+ True
+ 0
+
+
+
+
+ False
+
+
+
+
+
+ False
+ True
+ 1
+
+
+
+
diff -Nru gedit-40.1/gedit/resources/ui/gedit-view-frame.ui gedit-41.0/gedit/resources/ui/gedit-view-frame.ui
--- gedit-40.1/gedit/resources/ui/gedit-view-frame.ui 2021-04-17 05:45:36.368563400 +0000
+++ gedit-41.0/gedit/resources/ui/gedit-view-frame.ui 2022-02-14 13:58:26.000000000 +0000
@@ -7,15 +7,33 @@
FalseFalse
-
+ True
- True
- True
- False
-
+ True
- True
+ True
+ True
+
+
+ True
+ True
+
+
+
+
+
+
+ True
+
+
+
+ True
+ view
+
+
diff -Nru gedit-40.1/gedit/resources/ui/gedit-window.ui gedit-41.0/gedit/resources/ui/gedit-window.ui
--- gedit-40.1/gedit/resources/ui/gedit-window.ui 2021-04-17 05:45:36.368563400 +0000
+++ gedit-41.0/gedit/resources/ui/gedit-window.ui 2022-02-14 13:58:26.000000000 +0000
@@ -28,6 +28,50 @@
TrueTrue
+
+ True
+ Open a file
+ center
+ True
+
+
+
+ True
+ False
+ False
+ False
+
+
+ _Open
+ True
+ True
+ baseline
+
+
+
+
+ True
+ baseline
+ pan-down-symbolic
+
+
+
+
+
+
+ Open
+ Open a file
+
+
+
+
+ start
+
+
+ TrueTrue
@@ -310,7 +354,7 @@
Falsestart
-
+ TrueFalseFalse
@@ -319,6 +363,47 @@
True
+
+ True
+ Open a file dialog
+ center
+ True
+
+
+
+ True
+ False
+ False
+ False
+
+
+ Open
+ True
+
+
+
+
+ True
+ pan-down-symbolic
+
+
+
+
+
+
+ Open
+ Open a file
+
+
+
+
+ start
+
+
+ TrueTrue
diff -Nru gedit-40.1/gedit.doap gedit-41.0/gedit.doap
--- gedit-40.1/gedit.doap 2021-04-17 05:45:35.404543200 +0000
+++ gedit-41.0/gedit.doap 2022-02-14 13:58:26.000000000 +0000
@@ -29,6 +29,7 @@
+