20234 lines
611 KiB
Diff
20234 lines
611 KiB
Diff
From b190bdb716fc8bb0cd515ee10fb3c51debede5fa Mon Sep 17 00:00:00 2001
|
||
From: Zander Brown <zbrown@gnome.org>
|
||
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 | 27 +-
|
||
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(+), 1283 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,30 +1,42 @@
|
||
+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, 2021-03-19
|
||
----------------------------
|
||
* Remove all the deprecated API.
|
||
* file-browser: drop use of confirm-trash
|
||
* Translation updates.
|
||
|
||
Tepl-ification:
|
||
* Use tepl_pango_font_description_to_css().
|
||
* Use TeplLanguageChooser's.
|
||
* Use TeplProgressInfoBar.
|
||
* Start to use TeplBuffer and TeplFile APIs.
|
||
As a result the new tabs are now named "Untitled File", not
|
||
"Untitled Document".
|
||
|
||
News in 3.38.1, 2020-11-20
|
||
--------------------------
|
||
* AppData: change donation URL to Liberapay.
|
||
* Improvements to the user manual.
|
||
* Translation updates.
|
||
|
||
News in 3.38.0, 2020-09-11
|
||
--------------------------
|
||
* Translation updates.
|
||
|
||
News in 3.37.92, 2020-09-04
|
||
---------------------------
|
||
* A few code refactorings.
|
||
* CI: small update.
|
||
* Translation updates.
|
||
|
||
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
|
||
@@ -32,56 +32,51 @@ cleanup:
|
||
- "/share/aclocal"
|
||
- "/man"
|
||
- "/share/man"
|
||
- "/share/gtk-doc"
|
||
- "/share/vala"
|
||
- "/share/gir-1.0"
|
||
- "*.la"
|
||
- "*.a"
|
||
|
||
modules:
|
||
- name: libpeas
|
||
buildsystem: meson
|
||
config-opts:
|
||
- "-Dlua51=false"
|
||
- "-Dvapi=true"
|
||
- "-Ddemos=false"
|
||
- "-Dglade_catalog=false"
|
||
sources:
|
||
- type: archive
|
||
url: https://download.gnome.org/sources/libpeas/1.28/libpeas-1.28.0.tar.xz
|
||
sha256: 42d91993b46ed50f16add6d9577ecc22beb8e2dffa7101e2232c2b63733b8b15
|
||
|
||
- name: gspell
|
||
cleanup:
|
||
- "/bin"
|
||
sources:
|
||
- type: archive
|
||
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
|
||
sources:
|
||
- type: git
|
||
url: https://gitlab.gnome.org/GNOME/gedit.git
|
||
# To build a local branch, comment out 'url' and uncomment:
|
||
# path: ../../
|
||
# branch: wip/misc
|
||
|
||
- name: gedit-plugins
|
||
buildsystem: meson
|
||
sources:
|
||
- type: git
|
||
url: https://gitlab.gnome.org/GNOME/gedit-plugins.git
|
||
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
|
||
@@ -14,121 +14,98 @@ layout:
|
||
symlink: $SNAP/usr/share/gedit
|
||
|
||
slots:
|
||
# for GtkApplication registration
|
||
gedit:
|
||
interface: dbus
|
||
bus: session
|
||
name: org.gnome.gedit
|
||
|
||
apps:
|
||
gedit:
|
||
command: usr/bin/gedit
|
||
extensions: [gnome-3-28]
|
||
plugs:
|
||
- avahi-observe
|
||
- cups-control
|
||
- gsettings
|
||
- home
|
||
- network
|
||
- mount-observe
|
||
- removable-media
|
||
common-id: org.gnome.gedit.desktop
|
||
environment:
|
||
GSETTINGS_SCHEMA_DIR: $SNAP/share/glib-2.0/schemas
|
||
LD_LIBRARY_PATH: $LD_LIBRARY_PATH:$SNAP/lib/$SNAPCRAFT_ARCH_TRIPLET/gedit:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET:$SNAP/gnome-platform/usr/lib/$SNAPCRAFT_ARCH_TRIPLET
|
||
GI_TYPELIB_PATH: $SNAP/usr/lib/girepository-1.0:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/gedit/girepository-1.0:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/girepository-1.0:$SNAP/gnome-platform/usr/lib/girepository-1.0:$SNAP/gnome-platform/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/girepository-1.0
|
||
PYTHONPATH: $SNAP/usr/lib/python3/dist-packages:$SNAP/gnome-platform/usr/lib/python3/dist-packages
|
||
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
|
||
plugin: meson
|
||
meson-parameters:
|
||
- --prefix=/usr
|
||
- -Dc_args="-Wno-error=undef"
|
||
organize:
|
||
snap/gedit/current/usr: usr
|
||
build-packages:
|
||
- autoconf-archive
|
||
- gettext
|
||
- gobject-introspection
|
||
- gtk-doc-tools
|
||
- libfribidi-dev
|
||
- libgirepository1.0-dev
|
||
- libglib2.0-dev
|
||
- libgtk-3-dev
|
||
- libpeas-dev
|
||
- libxml2-dev
|
||
- libxml2-utils
|
||
- valac
|
||
# meson gir overrides don't work well
|
||
override-build: |
|
||
snapcraftctl build
|
||
cp $SNAPCRAFT_PART_INSTALL/usr/share/gir-1.0/GtkSource* /usr/share/gir-1.0
|
||
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]
|
||
plugin: meson
|
||
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: |
|
||
sed -i.bak -e 's|Icon=org.gnome.gedit$|Icon=${SNAP}/meta/gui/org.gnome.gedit.svg|g' data/org.gnome.gedit.desktop.in
|
||
sed -i.bak -e "s|symlink_media: true|symlink_media: false|g" help/meson.build
|
||
snapcraftctl build
|
||
mkdir -p $SNAPCRAFT_PART_INSTALL/meta/gui/
|
||
cp data/icons/org.gnome.gedit.svg $SNAPCRAFT_PART_INSTALL/meta/gui/
|
||
cp ../install/usr/share/applications/org.gnome.gedit.desktop $SNAPCRAFT_PART_INSTALL/meta/gui/
|
||
build-packages:
|
||
- desktop-file-utils
|
||
- gettext
|
||
- gsettings-desktop-schemas-dev
|
||
- gtk-doc-tools
|
||
- itstool
|
||
- libsoup2.4-dev
|
||
- libgspell-1-dev
|
||
- libxml2-dev
|
||
- libglib2.0-dev
|
||
- libgtk-3-dev
|
||
- libpeas-dev
|
||
- libx11-dev
|
||
- python3
|
||
- python-gi-dev
|
||
- gobject-introspection
|
||
- libgirepository1.0-dev
|
||
- valac
|
||
stage-packages:
|
||
- libfribidi0
|
||
|
||
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
|
||
@@ -99,60 +99,65 @@
|
||
<key name="auto-indent" type="b">
|
||
<default>true</default>
|
||
<summary>Automatic indent</summary>
|
||
<description>Whether gedit should enable automatic indentation.</description>
|
||
</key>
|
||
<key name="display-line-numbers" type="b">
|
||
<default>true</default>
|
||
<summary>Display Line Numbers</summary>
|
||
<description>Whether gedit should display line numbers in the editing area.</description>
|
||
</key>
|
||
<key name="highlight-current-line" type="b">
|
||
<default>true</default>
|
||
<summary>Highlight Current Line</summary>
|
||
<description>Whether gedit should highlight the current line.</description>
|
||
</key>
|
||
<key name="bracket-matching" type="b">
|
||
<default>true</default>
|
||
<summary>Highlight Matching Brackets</summary>
|
||
<description>Whether gedit should highlight matching brackets.</description>
|
||
</key>
|
||
<key name="display-right-margin" type="b">
|
||
<default>false</default>
|
||
<summary>Display Right Margin</summary>
|
||
<description>Whether gedit should display the right margin in the editing area.</description>
|
||
</key>
|
||
<key name="right-margin-position" type="u">
|
||
<default>80</default>
|
||
<summary>Right Margin Position</summary>
|
||
<description>Specifies the position of the right margin.</description>
|
||
</key>
|
||
+ <key name="display-overview-map" type="b">
|
||
+ <default>false</default>
|
||
+ <summary>Display Overview Map</summary>
|
||
+ <description>Whether gedit should display the overview map for the document.</description>
|
||
+ </key>
|
||
<key name="background-pattern" enum="org.gnome.gedit.BackgroundPatternType">
|
||
<default>'none'</default>
|
||
<summary>Document background pattern type</summary>
|
||
<description>Whether the document will get a background pattern painted.</description>
|
||
</key>
|
||
<key name="smart-home-end" enum="org.gnome.gedit.SmartHomeEnd">
|
||
<aliases>
|
||
<alias value='DISABLED' target='disabled'/>
|
||
<alias value='BEFORE' target='before'/>
|
||
<alias value='AFTER' target='after'/>
|
||
<alias value='ALWAYS' target='always'/>
|
||
</aliases>
|
||
<default>'after'</default>
|
||
<summary>Smart Home End</summary>
|
||
<description>Specifies how the cursor moves when the HOME and END keys are pressed. Use “disabled” to always move at the start/end of the line, “after” to move to the start/end of the line the first time the keys are pressed and to the start/end of the text ignoring whitespaces the second time the keys are pressed, “before” to move to the start/end of the text before moving to the start/end of the line and “always” to always move to the start/end of the text instead of the start/end of the line.</description>
|
||
</key>
|
||
<key name="restore-cursor-position" type="b">
|
||
<default>true</default>
|
||
<summary>Restore Previous Cursor Position</summary>
|
||
<description>Whether gedit should restore the previous cursor position when a file is loaded.</description>
|
||
</key>
|
||
<key name="syntax-highlighting" type="b">
|
||
<default>true</default>
|
||
<summary>Enable Syntax Highlighting</summary>
|
||
<description>Whether gedit should enable syntax highlighting.</description>
|
||
</key>
|
||
<key name="search-highlighting" type="b">
|
||
<default>true</default>
|
||
<summary>Enable Search Highlighting</summary>
|
||
<description>Whether gedit should highlight all the occurrences of the searched text.</description>
|
||
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
|
||
@@ -4,65 +4,63 @@ gedit development - getting started
|
||
The following explanations can be improved over time, if you see something
|
||
missing, a feedback is welcome.
|
||
|
||
Programming languages and paradigms
|
||
-----------------------------------
|
||
|
||
gedit is mostly written in C, with some plugins in Python or
|
||
[Vala](https://wiki.gnome.org/Projects/Vala/). The build system is in
|
||
[Meson](https://mesonbuild.com/).
|
||
|
||
The code is object-oriented and event-driven. In C, it's thanks to the use of
|
||
the GObject library (see next section). If you open some `*.c` or `*.h` files,
|
||
you may think “what is this horror?!” but – don't panic – it's just some
|
||
C/GObject boilerplate code, and that boilerplate can be generated by a tool. So
|
||
once you've learned GObject, you will no longer be afraid ;-)
|
||
|
||
Libraries used
|
||
--------------
|
||
|
||
As every GNOME application, gedit uses the GLib, GObject and GTK libraries. To
|
||
modify the gedit source code, you should be familiar with those libraries. See
|
||
the [GTK website](https://www.gtk.org/) and the document
|
||
[The GLib/GTK Development Platform – A Getting Started Guide](https://people.gnome.org/~swilmet/glib-gtk-book/).
|
||
|
||
The main widget used by gedit is GtkTextView, a general-purpose multiline text
|
||
editor. To learn that widget API, read the excellent
|
||
[GtkTextView tutorial](http://www.bravegnu.org/gtktext/) (a bit old but still
|
||
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.
|
||
|
||
Plugins may have other dependencies, for example the spell-checking plugin uses
|
||
[gspell](https://wiki.gnome.org/Projects/gspell).
|
||
|
||
gedit architecture
|
||
------------------
|
||
|
||
The [gedit Git repository](https://gitlab.gnome.org/GNOME/gedit) contains the
|
||
_gedit core_ plus the default plugins. There is also the
|
||
[gedit-plugins Git repository](https://gitlab.gnome.org/GNOME/gedit-plugins)
|
||
for additional official plugins. The gedit core source code is in the `gedit/`
|
||
directory. The plugins are in … `plugins/`!
|
||
|
||
gedit core provides:
|
||
- A basic text editor.
|
||
- The integration of libpeas, with an API for plugins.
|
||
|
||
There is a class diagram of gedit core in the file
|
||
[class-diagram.dia](class-diagram.dia) (but it may be outdated, see the Git log
|
||
for that file).
|
||
|
||
Build/Installation
|
||
------------------
|
||
|
||
See the file [build.md](build.md).
|
||
|
||
First contribution
|
||
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
|
||
@@ -1,53 +1,103 @@
|
||
<?xml version="1.0"?>
|
||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
|
||
[
|
||
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
|
||
]>
|
||
|
||
<part id="api-breaks">
|
||
<title>API Breaks</title>
|
||
|
||
<para>
|
||
gedit is a quite old piece of software (created in 1998, at the beginnings
|
||
of the GNOME project), and as every software, the code evolves during its
|
||
lifetime. So there are sometimes API breaks for gedit plugins, there are no
|
||
API stability guarantees.
|
||
</para>
|
||
|
||
<para>
|
||
When it is possible, instead of directly removing an API, that API is first
|
||
marked as deprecated, and then removed for the next API break. See the
|
||
<link linkend="api-index-deprecated">index of deprecated symbols</link>.
|
||
</para>
|
||
|
||
+ <refsect1>
|
||
+ <title>40 -> 41</title>
|
||
+ <itemizedlist>
|
||
+ <listitem>
|
||
+ <para>
|
||
+ The <code>GeditProgressInfoBar</code> class has been restored
|
||
+ </para>
|
||
+ </listitem>
|
||
+ <listitem>
|
||
+ <para>
|
||
+ <link linkend="GeditDocument">GeditDocument</link> is no longer a subclass
|
||
+ of <link linkend="TeplBuffer">TeplBuffer</link>.
|
||
+ </para>
|
||
+ </listitem>
|
||
+ <listitem>
|
||
+ <para>
|
||
+ The <code>GeditDocument::cursor-moved</code> signal has been restored.
|
||
+ </para>
|
||
+ </listitem>
|
||
+ <listitem>
|
||
+ <para>
|
||
+ The <code>GeditDocument:shortname</code> property has been restored.
|
||
+ </para>
|
||
+ </listitem>
|
||
+ <listitem>
|
||
+ <para>
|
||
+ The <code>gedit_document_is_untouched()</code> function has been
|
||
+ restored.
|
||
+ </para>
|
||
+ </listitem>
|
||
+ <listitem>
|
||
+ <para>
|
||
+ The <code>gedit_view_set_font()</code> function has been restored.
|
||
+ </para>
|
||
+ </listitem>
|
||
+ <listitem>
|
||
+ <para>
|
||
+ <code>DEBUG_METADATA</code> has been restored.
|
||
+ </para>
|
||
+ </listitem>
|
||
+ <listitem>
|
||
+ <para>
|
||
+ The <code>GBOOLEAN_TO_POINTER()</code> and
|
||
+ <code>GPOINTER_TO_BOOLEAN()</code> macros have been restored to
|
||
+ <code>gedit-utils.h</code>.
|
||
+ </para>
|
||
+ </listitem>
|
||
+ </itemizedlist>
|
||
+ </refsect1>
|
||
+
|
||
<refsect1>
|
||
<title>3.38 -> 40</title>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
All previously deprecated APIs have been removed.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The <code>GeditProgressInfoBar</code> class has been removed, you can
|
||
use <link linkend="TeplProgressInfoBar">TeplProgressInfoBar</link>
|
||
instead.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
<link linkend="GeditDocument">GeditDocument</link> is now a subclass
|
||
of <link linkend="TeplBuffer">TeplBuffer</link>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
The <code>GeditDocument::cursor-moved</code> signal has been removed.
|
||
You can use the <link linkend="TeplBuffer">TeplBuffer</link> API
|
||
instead.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>
|
||
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
|
||
@@ -1,48 +1,49 @@
|
||
<?xml version="1.0"?>
|
||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
||
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
|
||
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
|
||
<bookinfo>
|
||
<title>gedit Reference Manual</title>
|
||
</bookinfo>
|
||
|
||
<part id="api-reference">
|
||
<title>API Reference</title>
|
||
<xi:include href="xml/gedit-app.xml"/>
|
||
<xi:include href="xml/gedit-app-activatable.xml"/>
|
||
<xi:include href="xml/gedit-commands.xml"/>
|
||
<xi:include href="xml/gedit-document.xml"/>
|
||
<xi:include href="xml/gedit-encodings-combo-box.xml"/>
|
||
<xi:include href="xml/gedit-menu-extension.xml"/>
|
||
<xi:include href="xml/gedit-message-bus.xml"/>
|
||
<xi:include href="xml/gedit-message.xml"/>
|
||
+ <xi:include href="xml/gedit-progress-info-bar.xml"/>
|
||
<xi:include href="xml/gedit-statusbar.xml"/>
|
||
<xi:include href="xml/gedit-tab.xml"/>
|
||
<xi:include href="xml/gedit-view.xml"/>
|
||
<xi:include href="xml/gedit-view-activatable.xml"/>
|
||
<xi:include href="xml/gedit-window.xml"/>
|
||
<xi:include href="xml/gedit-window-activatable.xml"/>
|
||
<xi:include href="xml/gedit-debug.xml"/>
|
||
<xi:include href="xml/gedit-utils.xml"/>
|
||
</part>
|
||
|
||
<xi:include href="api-breaks.xml"/>
|
||
|
||
<part id="annexes">
|
||
<title>Annexes</title>
|
||
|
||
<chapter>
|
||
<title>Object Hierarchy</title>
|
||
<xi:include href="xml/tree_index.sgml"/>
|
||
</chapter>
|
||
|
||
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
|
||
|
||
<index>
|
||
<title>Index of all symbols</title>
|
||
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
|
||
</index>
|
||
<index role="deprecated">
|
||
<title>Index of deprecated symbols</title>
|
||
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
|
||
</index>
|
||
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
|
||
@@ -27,61 +27,64 @@ gedit_app_activatable_activate
|
||
gedit_app_activatable_deactivate
|
||
gedit_app_activatable_extend_menu
|
||
<SUBSECTION Standard>
|
||
GEDIT_TYPE_APP_ACTIVATABLE
|
||
GEDIT_APP_ACTIVATABLE
|
||
GEDIT_APP_ACTIVATABLE_IFACE
|
||
GEDIT_IS_APP_ACTIVATABLE
|
||
GEDIT_APP_ACTIVATABLE_GET_IFACE
|
||
gedit_app_activatable_get_type
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-commands</FILE>
|
||
<TITLE>GeditCommands</TITLE>
|
||
gedit_commands_load_location
|
||
gedit_commands_load_locations
|
||
gedit_commands_save_document
|
||
gedit_commands_save_document_async
|
||
gedit_commands_save_document_finish
|
||
gedit_commands_save_all_documents
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-document</FILE>
|
||
<TITLE>GeditDocument</TITLE>
|
||
GeditDocument
|
||
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
|
||
gedit_document_set_metadata
|
||
gedit_document_set_search_context
|
||
gedit_document_get_search_context
|
||
<SUBSECTION Standard>
|
||
GEDIT_DOCUMENT
|
||
GEDIT_IS_DOCUMENT
|
||
GEDIT_TYPE_DOCUMENT
|
||
gedit_document_get_type
|
||
GEDIT_DOCUMENT_CLASS
|
||
GEDIT_IS_DOCUMENT_CLASS
|
||
GEDIT_DOCUMENT_GET_CLASS
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-encodings-combo-box</FILE>
|
||
<TITLE>GeditEncodingsComboBox</TITLE>
|
||
GeditEncodingsComboBox
|
||
gedit_encodings_combo_box_new
|
||
gedit_encodings_combo_box_get_selected_encoding
|
||
gedit_encodings_combo_box_set_selected_encoding
|
||
<SUBSECTION Standard>
|
||
GEDIT_ENCODINGS_COMBO_BOX
|
||
GEDIT_IS_ENCODINGS_COMBO_BOX
|
||
GEDIT_TYPE_ENCODINGS_COMBO_BOX
|
||
gedit_encodings_combo_box_get_type
|
||
GEDIT_ENCODINGS_COMBO_BOX_CLASS
|
||
GEDIT_IS_ENCODINGS_COMBO_BOX_CLASS
|
||
@@ -121,111 +124,138 @@ GEDIT_TYPE_MESSAGE_BUS
|
||
gedit_message_bus_get_type
|
||
GEDIT_MESSAGE_BUS_CLASS
|
||
GEDIT_IS_MESSAGE_BUS_CLASS
|
||
GEDIT_MESSAGE_BUS_GET_CLASS
|
||
GeditMessageBusPrivate
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-message</FILE>
|
||
<TITLE>GeditMessage</TITLE>
|
||
GeditMessage
|
||
gedit_message_get_object_path
|
||
gedit_message_get_method
|
||
gedit_message_type_has
|
||
gedit_message_type_check
|
||
gedit_message_has
|
||
gedit_message_is_valid_object_path
|
||
gedit_message_type_identifier
|
||
<SUBSECTION Standard>
|
||
GEDIT_MESSAGE
|
||
GEDIT_MESSAGE_CONST
|
||
GEDIT_IS_MESSAGE
|
||
GEDIT_TYPE_MESSAGE
|
||
gedit_message_get_type
|
||
GEDIT_MESSAGE_CLASS
|
||
GEDIT_IS_MESSAGE_CLASS
|
||
GEDIT_MESSAGE_GET_CLASS
|
||
GeditMessagePrivate
|
||
</SECTION>
|
||
|
||
+<SECTION>
|
||
+<FILE>gedit-progress-info-bar</FILE>
|
||
+<TITLE>GeditProgressInfoBar</TITLE>
|
||
+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
|
||
+<SUBSECTION Standard>
|
||
+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
|
||
+</SECTION>
|
||
+
|
||
<SECTION>
|
||
<FILE>gedit-statusbar</FILE>
|
||
<TITLE>GeditStatusbar</TITLE>
|
||
GeditStatusbar
|
||
gedit_statusbar_new
|
||
gedit_statusbar_set_window_state
|
||
gedit_statusbar_set_overwrite
|
||
gedit_statusbar_clear_overwrite
|
||
gedit_statusbar_flash_message
|
||
<SUBSECTION Standard>
|
||
GEDIT_STATUSBAR
|
||
GEDIT_IS_STATUSBAR
|
||
GEDIT_TYPE_STATUSBAR
|
||
gedit_statusbar_get_type
|
||
GEDIT_STATUSBAR_CLASS
|
||
GEDIT_IS_STATUSBAR_CLASS
|
||
GEDIT_STATUSBAR_GET_CLASS
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-tab</FILE>
|
||
<TITLE>GeditTab</TITLE>
|
||
GeditTab
|
||
GeditTabState
|
||
gedit_tab_get_view
|
||
gedit_tab_get_document
|
||
gedit_tab_get_from_document
|
||
gedit_tab_get_state
|
||
gedit_tab_get_auto_save_enabled
|
||
gedit_tab_set_auto_save_enabled
|
||
gedit_tab_get_auto_save_interval
|
||
gedit_tab_set_auto_save_interval
|
||
gedit_tab_set_info_bar
|
||
<SUBSECTION Standard>
|
||
GEDIT_TAB
|
||
GEDIT_IS_TAB
|
||
GEDIT_TYPE_TAB
|
||
gedit_tab_get_type
|
||
GEDIT_TAB_CLASS
|
||
GEDIT_IS_TAB_CLASS
|
||
GEDIT_TAB_GET_CLASS
|
||
GEDIT_TYPE_TAB_STATE
|
||
gedit_tab_state_get_type
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-view</FILE>
|
||
GeditViewPrivate
|
||
<TITLE>GeditView</TITLE>
|
||
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
|
||
<SUBSECTION Standard>
|
||
GEDIT_VIEW
|
||
GEDIT_IS_VIEW
|
||
GEDIT_TYPE_VIEW
|
||
gedit_view_get_type
|
||
GEDIT_VIEW_CLASS
|
||
GEDIT_IS_VIEW_CLASS
|
||
GEDIT_VIEW_GET_CLASS
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-view-activatable</FILE>
|
||
<TITLE>GeditViewActivatable</TITLE>
|
||
GeditViewActivatable
|
||
gedit_view_activatable_activate
|
||
gedit_view_activatable_deactivate
|
||
<SUBSECTION Standard>
|
||
GEDIT_TYPE_VIEW_ACTIVATABLE
|
||
GEDIT_VIEW_ACTIVATABLE
|
||
GEDIT_VIEW_ACTIVATABLE_IFACE
|
||
GEDIT_IS_VIEW_ACTIVATABLE
|
||
GEDIT_VIEW_ACTIVATABLE_GET_IFACE
|
||
gedit_view_activatable_get_type
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-window</FILE>
|
||
<TITLE>GeditWindow</TITLE>
|
||
GeditWindow
|
||
GeditWindowState
|
||
@@ -264,70 +294,76 @@ gedit_window_state_get_type
|
||
|
||
<SECTION>
|
||
<FILE>gedit-window-activatable</FILE>
|
||
<TITLE>GeditWindowActivatable</TITLE>
|
||
GeditWindowActivatable
|
||
gedit_window_activatable_activate
|
||
gedit_window_activatable_deactivate
|
||
gedit_window_activatable_update_state
|
||
<SUBSECTION Standard>
|
||
GEDIT_TYPE_WINDOW_ACTIVATABLE
|
||
GEDIT_WINDOW_ACTIVATABLE
|
||
GEDIT_WINDOW_ACTIVATABLE_IFACE
|
||
GEDIT_IS_WINDOW_ACTIVATABLE
|
||
GEDIT_WINDOW_ACTIVATABLE_GET_IFACE
|
||
gedit_window_activatable_get_type
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-debug</FILE>
|
||
GeditDebugSection
|
||
DEBUG_VIEW
|
||
DEBUG_PREFS
|
||
DEBUG_WINDOW
|
||
DEBUG_PANEL
|
||
DEBUG_PLUGINS
|
||
DEBUG_TAB
|
||
DEBUG_DOCUMENT
|
||
DEBUG_COMMANDS
|
||
DEBUG_APP
|
||
DEBUG_UTILS
|
||
+DEBUG_METADATA
|
||
gedit_debug_init
|
||
gedit_debug
|
||
gedit_debug_message
|
||
gedit_debug_plugin_message
|
||
<SUBSECTION Standard>
|
||
GEDIT_TYPE_DEBUG_SECTION
|
||
gedit_debug_section_get_type
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-menu-extension</FILE>
|
||
GeditMenuExtension
|
||
gedit_menu_extension_new
|
||
gedit_menu_extension_append_menu_item
|
||
gedit_menu_extension_prepend_menu_item
|
||
gedit_menu_extension_remove_items
|
||
<SUBSECTION Standard>
|
||
GEDIT_IS_MENU_EXTENSION
|
||
GEDIT_IS_MENU_EXTENSION_CLASS
|
||
GEDIT_MENU_EXTENSION
|
||
GEDIT_MENU_EXTENSION_CLASS
|
||
GEDIT_MENU_EXTENSION_CONST
|
||
GEDIT_MENU_EXTENSION_GET_CLASS
|
||
GEDIT_TYPE_MENU_EXTENSION
|
||
GeditMenuExtensionClass
|
||
gedit_menu_extension_get_type
|
||
</SECTION>
|
||
|
||
<SECTION>
|
||
<FILE>gedit-utils</FILE>
|
||
+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
|
||
gedit_utils_location_get_dirname_for_display
|
||
gedit_utils_set_direct_save_filename
|
||
gedit_utils_newline_type_to_string
|
||
</SECTION>
|
||
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
|
||
@@ -1,42 +1,38 @@
|
||
html_dir = get_option('prefix') / gnome.gtkdoc_html_dir('gedit')
|
||
|
||
glib_docpath = dependency('glib-2.0').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/glib'
|
||
gobject_docpath = dependency('gobject-2.0').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/gobject'
|
||
gio_docpath = dependency('gio-2.0').get_pkgconfig_variable('prefix') / 'share/gtk-doc/html/gio'
|
||
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(
|
||
'gedit',
|
||
main_xml: 'gedit-docs.xml',
|
||
src_dir: include_directories('../../gedit/'),
|
||
dependencies: gedit_doc_dep,
|
||
scan_args: ['--rebuild-types'],
|
||
fixxref_args: [
|
||
'--html-dir=@0@'.format(html_dir),
|
||
'--extra-dir=@0@'.format(glib_docpath),
|
||
'--extra-dir=@0@'.format(gobject_docpath),
|
||
'--extra-dir=@0@'.format(gio_docpath),
|
||
'--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: [
|
||
'api-breaks.xml'
|
||
],
|
||
ignore_headers: libgedit_private_headers,
|
||
install: true,
|
||
)
|
||
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
|
||
@@ -1,57 +1,40 @@
|
||
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
|
||
------------------------
|
||
|
||
Status: **in progress**
|
||
|
||
[gedit is now available on the Microsoft Store](https://www.microsoft.com/store/apps/9PL1J21XF0PT).
|
||
The integration with Windows is not perfect, but it works. It is planned to
|
||
improve gedit for Windows over time.
|
||
|
||
Replace search and replace dialog window by an horizontal bar below the text
|
||
----------------------------------------------------------------------------
|
||
|
||
Status: **todo**
|
||
|
||
To not hide the text.
|
||
|
||
Be able to quit the application with all documents saved, and restored on next start
|
||
------------------------------------------------------------------------------------
|
||
|
||
Status: **todo**
|
||
|
||
Even for unsaved and untitled files, be able to quit gedit, restart it later and
|
||
come back to the state before with all tabs restored.
|
||
|
||
Improve the workflow for printing to paper
|
||
------------------------------------------
|
||
|
||
Status: **todo**
|
||
|
||
Implement it like in Firefox, show first a preview of the file to print.
|
||
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
|
||
@@ -1,23 +1,24 @@
|
||
App cheader_filename="gedit/gedit-app.h"
|
||
AppActivatable cheader_filename="gedit/gedit-app-activatable.h"
|
||
DebugSection cheader_filename="gedit/gedit-debug.h"
|
||
Document cheader_filename="gedit/gedit-document.h"
|
||
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"
|
||
View cheader_filename="gedit/gedit-view.h"
|
||
ViewActivatable cheader_filename="gedit/gedit-view-activatable.h"
|
||
Window cheader_filename="gedit/gedit-window.h"
|
||
WindowActivatable cheader_filename="gedit/gedit-window-activatable.h"
|
||
WindowState cheader_filename="gedit/gedit-window.h"
|
||
|
||
commands_* cheader_filename="gedit/gedit-commands.h"
|
||
debug* cheader_filename="gedit/gedit-debug.h"
|
||
utils_* cheader_filename="gedit/gedit-utils.h"
|
||
|
||
MessageBusForeach cheader_filename="gedit/gedit-message-bus.h"
|
||
MessageCallback cheader_filename="gedit/gedit-message-bus.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
|
||
@@ -4,61 +4,61 @@
|
||
*
|
||
* Copyright (C) 2010 - Jesse van den Kieboom
|
||
*
|
||
* 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, write to the Free Software
|
||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||
* Boston, MA 02110-1301 USA
|
||
*/
|
||
|
||
#include "gedit-app-osx.h"
|
||
|
||
#include <gdk/gdkquartz.h>
|
||
#include <string.h>
|
||
#include <glib/gi18n.h>
|
||
|
||
#include "gedit-app-private.h"
|
||
#include "gedit-dirs.h"
|
||
#include "gedit-debug.h"
|
||
#include "gedit-commands.h"
|
||
#include "gedit-commands-private.h"
|
||
-#include "gedit-recent-osx.h"
|
||
+#include "gedit-recent.h"
|
||
#import <AppKit/AppKit.h>
|
||
|
||
NSWindow *gdk_quartz_window_get_nswindow(GdkWindow *window);
|
||
NSEvent *gdk_quartz_event_get_nsevent(GdkEvent *event);
|
||
|
||
static GeditWindow *
|
||
ensure_window (GeditAppOSX *app,
|
||
gboolean with_empty_document)
|
||
{
|
||
GList *windows;
|
||
GeditWindow *ret = NULL;
|
||
|
||
windows = gtk_application_get_windows (GTK_APPLICATION (app));
|
||
|
||
while (windows)
|
||
{
|
||
GtkWindow *window;
|
||
GdkWindow *win;
|
||
NSWindow *nswin;
|
||
|
||
window = windows->data;
|
||
windows = g_list_next (windows);
|
||
|
||
if (!gtk_widget_get_realized (GTK_WIDGET (window)))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
if (!GEDIT_IS_WINDOW (window))
|
||
{
|
||
@@ -259,61 +259,61 @@ gedit_app_osx_set_window_title_impl (GeditApp *app,
|
||
}
|
||
|
||
native = gdk_quartz_window_get_nswindow (wnd);
|
||
document = gedit_window_get_active_document (window);
|
||
|
||
if (document)
|
||
{
|
||
bool ismodified;
|
||
|
||
if (gedit_document_is_untitled (document))
|
||
{
|
||
[native setRepresentedURL:nil];
|
||
}
|
||
else
|
||
{
|
||
GtkSourceFile *file;
|
||
GFile *location;
|
||
gchar *uri;
|
||
|
||
file = gedit_document_get_file (document);
|
||
location = gtk_source_file_get_location (file);
|
||
|
||
uri = g_file_get_uri (location);
|
||
|
||
NSURL *nsurl = [NSURL URLWithString:[NSString stringWithUTF8String:uri]];
|
||
|
||
[native setRepresentedURL:nsurl];
|
||
g_free (uri);
|
||
}
|
||
|
||
- ismodified = !tepl_buffer_is_untouched (TEPL_BUFFER (document));
|
||
+ ismodified = !gedit_document_is_untouched (document);
|
||
[native setDocumentEdited:ismodified];
|
||
}
|
||
else
|
||
{
|
||
[native setRepresentedURL:nil];
|
||
[native setDocumentEdited:false];
|
||
}
|
||
|
||
GEDIT_APP_CLASS (gedit_app_osx_parent_class)->set_window_title (app, window, title);
|
||
}
|
||
|
||
typedef struct
|
||
{
|
||
GeditAppOSX *app;
|
||
GtkRecentInfo *info;
|
||
} RecentFileInfo;
|
||
|
||
static void
|
||
recent_file_info_free (gpointer data,
|
||
GClosure *closure)
|
||
{
|
||
RecentFileInfo *info = data;
|
||
|
||
g_object_unref (info->app);
|
||
gtk_recent_info_unref (info->info);
|
||
|
||
g_slice_free (RecentFileInfo, data);
|
||
}
|
||
|
||
static void
|
||
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
|
||
@@ -1,52 +1,55 @@
|
||
/*
|
||
* gedit-app-private.h
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 2015 - Sébastien Wilmet <swilmet@gnome.org>
|
||
*
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_APP_PRIVATE_H
|
||
#define GEDIT_APP_PRIVATE_H
|
||
|
||
#include "gedit-app.h"
|
||
+#include "gedit-metadata-manager.h"
|
||
#include "gedit-menu-extension.h"
|
||
|
||
G_BEGIN_DECLS
|
||
|
||
/* global print config */
|
||
GtkPageSetup *_gedit_app_get_default_page_setup (GeditApp *app);
|
||
void _gedit_app_set_default_page_setup (GeditApp *app,
|
||
GtkPageSetup *page_setup);
|
||
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);
|
||
|
||
GMenuModel *_gedit_app_get_tab_width_menu (GeditApp *app);
|
||
|
||
GMenuModel *_gedit_app_get_line_col_menu (GeditApp *app);
|
||
|
||
GeditMenuExtension *_gedit_app_extend_menu (GeditApp *app,
|
||
const gchar *extension_point);
|
||
|
||
G_END_DECLS
|
||
|
||
#endif /* GEDIT_APP_PRIVATE_H */
|
||
|
||
/* ex:set ts=8 noet: */
|
||
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
|
||
@@ -1,83 +1,92 @@
|
||
/*
|
||
* gedit-app.c
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 2005-2006 - 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include "gedit-app.h"
|
||
#include "gedit-app-private.h"
|
||
|
||
#include <string.h>
|
||
#include <unistd.h>
|
||
#include <stdlib.h>
|
||
|
||
#include <glib/gi18n.h>
|
||
+#include <gio/gio.h>
|
||
#include <libpeas/peas-extension-set.h>
|
||
-#include <tepl/tepl.h>
|
||
+#include <gtksourceview/gtksource.h>
|
||
|
||
#include "gedit-commands-private.h"
|
||
#include "gedit-notebook.h"
|
||
#include "gedit-debug.h"
|
||
#include "gedit-utils.h"
|
||
#include "gedit-enum-types.h"
|
||
#include "gedit-dirs.h"
|
||
#include "gedit-settings.h"
|
||
#include "gedit-app-activatable.h"
|
||
#include "gedit-plugins-engine.h"
|
||
#include "gedit-commands.h"
|
||
#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"
|
||
|
||
typedef struct
|
||
{
|
||
GeditPluginsEngine *engine;
|
||
|
||
+#ifndef ENABLE_GVFS_METADATA
|
||
+ GeditMetadataManager *metadata_manager;
|
||
+#endif
|
||
+
|
||
GtkCssProvider *theme_provider;
|
||
|
||
GtkPageSetup *page_setup;
|
||
GtkPrintSettings *print_settings;
|
||
|
||
GSettings *ui_settings;
|
||
GSettings *window_settings;
|
||
|
||
GMenuModel *hamburger_menu;
|
||
GMenuModel *notebook_menu;
|
||
GMenuModel *tab_width_menu;
|
||
GMenuModel *line_col_menu;
|
||
|
||
PeasExtensionSet *extensions;
|
||
|
||
/* command line parsing */
|
||
gboolean new_window;
|
||
gboolean new_document;
|
||
const GtkSourceEncoding *encoding;
|
||
GInputStream *stdin_stream;
|
||
GSList *file_list;
|
||
gint line_position;
|
||
gint column_position;
|
||
GApplicationCommandLine *command_line;
|
||
} GeditAppPrivate;
|
||
|
||
static const GOptionEntry options[] =
|
||
{
|
||
/* Version */
|
||
{
|
||
@@ -118,60 +127,64 @@ static const GOptionEntry options[] =
|
||
"wait", 'w', 0, G_OPTION_ARG_NONE, NULL,
|
||
N_("Open files and block process until files are closed"),
|
||
NULL
|
||
},
|
||
|
||
/* New instance */
|
||
{
|
||
"standalone", 's', 0, G_OPTION_ARG_NONE, NULL,
|
||
N_("Run gedit in standalone mode"),
|
||
NULL
|
||
},
|
||
|
||
/* collects file arguments */
|
||
{
|
||
G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL, NULL,
|
||
N_("[FILE…] [+LINE[:COLUMN]]")
|
||
},
|
||
|
||
{NULL}
|
||
};
|
||
|
||
G_DEFINE_TYPE_WITH_PRIVATE (GeditApp, gedit_app, GTK_TYPE_APPLICATION)
|
||
|
||
static void
|
||
gedit_app_dispose (GObject *object)
|
||
{
|
||
GeditAppPrivate *priv;
|
||
|
||
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);
|
||
|
||
g_clear_object (&priv->page_setup);
|
||
g_clear_object (&priv->print_settings);
|
||
|
||
/* Note that unreffing the extensions will automatically remove
|
||
* all extensions which in turn will deactivate the extension
|
||
*/
|
||
g_clear_object (&priv->extensions);
|
||
|
||
g_clear_object (&priv->engine);
|
||
|
||
if (priv->theme_provider != NULL)
|
||
{
|
||
gtk_style_context_remove_provider_for_screen (gdk_screen_get_default (),
|
||
GTK_STYLE_PROVIDER (priv->theme_provider));
|
||
g_clear_object (&priv->theme_provider);
|
||
}
|
||
|
||
g_clear_object (&priv->hamburger_menu);
|
||
g_clear_object (&priv->notebook_menu);
|
||
g_clear_object (&priv->tab_width_menu);
|
||
g_clear_object (&priv->line_col_menu);
|
||
|
||
G_OBJECT_CLASS (gedit_app_parent_class)->dispose (object);
|
||
}
|
||
|
||
static gchar *
|
||
gedit_app_help_link_id_impl (GeditApp *app,
|
||
@@ -616,71 +629,82 @@ add_accelerator (GtkApplication *app,
|
||
const gchar *action_name,
|
||
const gchar *accel)
|
||
{
|
||
const gchar *vaccels[] = {
|
||
accel,
|
||
NULL
|
||
};
|
||
|
||
gtk_application_set_accels_for_action (app, action_name, vaccels);
|
||
}
|
||
|
||
static gboolean
|
||
show_menubar (void)
|
||
{
|
||
GtkSettings *settings = gtk_settings_get_default ();
|
||
gboolean result;
|
||
|
||
g_object_get (settings,
|
||
"gtk-shell-shows-menubar", &result,
|
||
NULL);
|
||
|
||
return result;
|
||
}
|
||
|
||
static void
|
||
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));
|
||
|
||
G_APPLICATION_CLASS (gedit_app_parent_class)->startup (application);
|
||
|
||
/* Setup debugging */
|
||
gedit_debug_init ();
|
||
gedit_debug_message (DEBUG_APP, "Startup");
|
||
|
||
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");
|
||
priv->window_settings = g_settings_new ("org.gnome.gedit.state.window");
|
||
|
||
g_action_map_add_action_entries (G_ACTION_MAP (application),
|
||
app_entries,
|
||
G_N_ELEMENTS (app_entries),
|
||
application);
|
||
|
||
/* menus */
|
||
if (!show_menubar ())
|
||
{
|
||
gtk_application_set_menubar (GTK_APPLICATION (application), NULL);
|
||
priv->hamburger_menu = get_menu_model (GEDIT_APP (application),
|
||
"hamburger-menu");
|
||
}
|
||
|
||
priv->notebook_menu = get_menu_model (GEDIT_APP (application), "notebook-menu");
|
||
priv->tab_width_menu = get_menu_model (GEDIT_APP (application), "tab-width-menu");
|
||
priv->line_col_menu = get_menu_model (GEDIT_APP (application), "line-col-menu");
|
||
|
||
/* Accelerators */
|
||
add_accelerator (GTK_APPLICATION (application), "app.new-window", "<Primary>N");
|
||
add_accelerator (GTK_APPLICATION (application), "app.quit", "<Primary>Q");
|
||
add_accelerator (GTK_APPLICATION (application), "app.help", "F1");
|
||
add_accelerator (GTK_APPLICATION (application), "app.shortcuts", "<Primary>question");
|
||
|
||
add_accelerator (GTK_APPLICATION (application), "win.hamburger-menu", "F10");
|
||
add_accelerator (GTK_APPLICATION (application), "win.open", "<Primary>O");
|
||
@@ -1087,60 +1111,64 @@ save_print_settings (GeditApp *app)
|
||
gchar *filename;
|
||
GError *error = NULL;
|
||
|
||
filename = get_print_settings_file ();
|
||
|
||
gtk_print_settings_to_file (priv->print_settings,
|
||
filename,
|
||
&error);
|
||
if (error)
|
||
{
|
||
g_warning ("%s", error->message);
|
||
g_error_free (error);
|
||
}
|
||
|
||
g_free (filename);
|
||
}
|
||
}
|
||
|
||
static void
|
||
gedit_app_shutdown (GApplication *app)
|
||
{
|
||
gedit_debug_message (DEBUG_APP, "Quitting\n");
|
||
|
||
/* Last window is gone... save some settings and exit */
|
||
ensure_user_config_dir ();
|
||
|
||
save_accels ();
|
||
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);
|
||
}
|
||
|
||
static gboolean
|
||
window_delete_event (GeditWindow *window,
|
||
GdkEvent *event,
|
||
GeditApp *app)
|
||
{
|
||
GeditWindowState ws;
|
||
|
||
ws = gedit_window_get_state (window);
|
||
|
||
if (ws &
|
||
(GEDIT_WINDOW_STATE_SAVING | GEDIT_WINDOW_STATE_PRINTING))
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
_gedit_cmd_file_quit (NULL, NULL, window);
|
||
|
||
/* Do not destroy the window */
|
||
return TRUE;
|
||
}
|
||
|
||
static GeditWindow *
|
||
gedit_app_create_window_impl (GeditApp *app)
|
||
{
|
||
GeditWindow *window;
|
||
|
||
window = g_object_new (GEDIT_TYPE_WINDOW, "application", app, NULL);
|
||
@@ -1226,69 +1254,64 @@ load_print_settings (GeditApp *app)
|
||
|
||
priv->print_settings = gtk_print_settings_new_from_file (filename, &error);
|
||
if (error != NULL)
|
||
{
|
||
/* - Ignore file not found error.
|
||
* - Ignore empty file error, i.e. group not found. This happens
|
||
* when we click on cancel in the print dialog, when using the
|
||
* printing for the first time in gedit.
|
||
*/
|
||
if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) &&
|
||
!g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND))
|
||
{
|
||
g_warning ("Load print settings error: %s", error->message);
|
||
}
|
||
|
||
g_error_free (error);
|
||
}
|
||
|
||
g_free (filename);
|
||
|
||
/* fall back to default settings */
|
||
if (priv->print_settings == NULL)
|
||
{
|
||
priv->print_settings = gtk_print_settings_new ();
|
||
}
|
||
}
|
||
|
||
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);
|
||
}
|
||
|
||
/**
|
||
* gedit_app_create_window:
|
||
* @app: the #GeditApp
|
||
* @screen: (allow-none):
|
||
*
|
||
* Create a new #GeditWindow part of @app.
|
||
*
|
||
* Return value: (transfer none): the new #GeditWindow
|
||
*/
|
||
GeditWindow *
|
||
gedit_app_create_window (GeditApp *app,
|
||
GdkScreen *screen)
|
||
{
|
||
GeditAppPrivate *priv;
|
||
GeditWindow *window;
|
||
GdkWindowState state;
|
||
gint w, h;
|
||
|
||
gedit_debug (DEBUG_APP);
|
||
|
||
priv = gedit_app_get_instance_private (app);
|
||
|
||
window = GEDIT_APP_GET_CLASS (app)->create_window (app);
|
||
|
||
if (screen != NULL)
|
||
{
|
||
gtk_window_set_screen (GTK_WINDOW (window), screen);
|
||
}
|
||
@@ -1544,60 +1567,79 @@ _gedit_app_get_default_print_settings (GeditApp *app)
|
||
|
||
priv = gedit_app_get_instance_private (app);
|
||
|
||
if (priv->print_settings == NULL)
|
||
{
|
||
load_print_settings (app);
|
||
}
|
||
|
||
return gtk_print_settings_copy (priv->print_settings);
|
||
}
|
||
|
||
void
|
||
_gedit_app_set_default_print_settings (GeditApp *app,
|
||
GtkPrintSettings *settings)
|
||
{
|
||
GeditAppPrivate *priv;
|
||
|
||
g_return_if_fail (GEDIT_IS_APP (app));
|
||
g_return_if_fail (GTK_IS_PRINT_SETTINGS (settings));
|
||
|
||
priv = gedit_app_get_instance_private (app);
|
||
|
||
if (priv->print_settings != NULL)
|
||
{
|
||
g_object_unref (priv->print_settings);
|
||
}
|
||
|
||
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)
|
||
{
|
||
GeditAppPrivate *priv;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_APP (app), NULL);
|
||
|
||
priv = gedit_app_get_instance_private (app);
|
||
|
||
return priv->hamburger_menu;
|
||
}
|
||
|
||
GMenuModel *
|
||
_gedit_app_get_notebook_menu (GeditApp *app)
|
||
{
|
||
GeditAppPrivate *priv;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_APP (app), NULL);
|
||
|
||
priv = gedit_app_get_instance_private (app);
|
||
|
||
return priv->notebook_menu;
|
||
}
|
||
|
||
GMenuModel *
|
||
_gedit_app_get_tab_width_menu (GeditApp *app)
|
||
{
|
||
GeditAppPrivate *priv;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_APP (app), NULL);
|
||
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
|
||
@@ -17,180 +17,180 @@
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include "gedit-commands.h"
|
||
#include "gedit-commands-private.h"
|
||
|
||
#include <gtk/gtk.h>
|
||
|
||
#include "gedit-window.h"
|
||
#include "gedit-debug.h"
|
||
#include "gedit-view.h"
|
||
#include "gedit-preferences-dialog.h"
|
||
|
||
void
|
||
_gedit_cmd_edit_undo (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
GeditView *active_view;
|
||
GtkSourceBuffer *active_document;
|
||
|
||
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));
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_edit_redo (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
GeditView *active_view;
|
||
GtkSourceBuffer *active_document;
|
||
|
||
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));
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_edit_cut (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
GeditView *active_view;
|
||
|
||
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));
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_edit_copy (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
GeditView *active_view;
|
||
|
||
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));
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_edit_paste (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
GeditView *active_view;
|
||
|
||
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));
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_edit_delete (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
GeditView *active_view;
|
||
|
||
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));
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_edit_select_all (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
GeditView *active_view;
|
||
|
||
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));
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_edit_preferences (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
gedit_show_preferences_dialog (window);
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_edit_overwrite_mode (GSimpleAction *action,
|
||
GVariant *state,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
GeditView *active_view;
|
||
gboolean overwrite;
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
active_view = gedit_window_get_active_view (window);
|
||
g_return_if_fail (active_view);
|
||
|
||
diff --git a/gedit/gedit-commands-file.c b/gedit/gedit-commands-file.c
|
||
index fb64f880d..d1d440a3e 100644
|
||
--- a/gedit/gedit-commands-file.c
|
||
+++ b/gedit/gedit-commands-file.c
|
||
@@ -1,80 +1,75 @@
|
||
/*
|
||
* gedit-commands-file.c
|
||
* This file is part of gedit
|
||
*
|
||
* 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 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include "gedit-commands.h"
|
||
#include "gedit-commands-private.h"
|
||
|
||
#include <glib/gi18n.h>
|
||
-#include <tepl/tepl.h>
|
||
|
||
#include "gedit-app.h"
|
||
#include "gedit-debug.h"
|
||
#include "gedit-document.h"
|
||
#include "gedit-document-private.h"
|
||
#include "gedit-tab.h"
|
||
#include "gedit-tab-private.h"
|
||
#include "gedit-window.h"
|
||
#include "gedit-window-private.h"
|
||
#include "gedit-notebook.h"
|
||
#include "gedit-statusbar.h"
|
||
#include "gedit-utils.h"
|
||
#include "gedit-file-chooser-dialog.h"
|
||
#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"
|
||
#define GEDIT_IS_QUITTING_ALL "gedit-is-quitting-all"
|
||
|
||
void
|
||
_gedit_cmd_file_new (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
gedit_window_create_tab (window, TRUE);
|
||
}
|
||
|
||
static GeditTab *
|
||
get_tab_from_file (GList *docs,
|
||
GFile *file)
|
||
{
|
||
GList *l;
|
||
|
||
for (l = docs; l != NULL; l = l->next)
|
||
{
|
||
GeditDocument *doc;
|
||
GtkSourceFile *source_file;
|
||
GFile *location;
|
||
|
||
doc = l->data;
|
||
@@ -123,105 +118,107 @@ load_file_list (GeditWindow *window,
|
||
gboolean jump_to = TRUE; /* Whether to jump to the new tab */
|
||
const GSList *l;
|
||
gint num_loaded_files = 0;
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
win_docs = gedit_window_get_documents (window);
|
||
|
||
/* Remove the files corresponding to documents already opened in
|
||
* "window" and remove duplicates from the "files" list.
|
||
*/
|
||
for (l = files; l != NULL; l = l->next)
|
||
{
|
||
GFile *file = l->data;
|
||
|
||
if (is_duplicated_file (files_to_load, file))
|
||
{
|
||
continue;
|
||
}
|
||
|
||
tab = get_tab_from_file (win_docs, file);
|
||
|
||
if (tab == NULL)
|
||
{
|
||
files_to_load = g_slist_prepend (files_to_load, file);
|
||
}
|
||
else
|
||
{
|
||
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));
|
||
}
|
||
}
|
||
|
||
++num_loaded_files;
|
||
loaded_files = g_slist_prepend (loaded_files,
|
||
gedit_tab_get_document (tab));
|
||
}
|
||
}
|
||
|
||
g_list_free (win_docs);
|
||
|
||
if (files_to_load == NULL)
|
||
{
|
||
return g_slist_reverse (loaded_files);
|
||
}
|
||
|
||
files_to_load = g_slist_reverse (files_to_load);
|
||
l = files_to_load;
|
||
|
||
tab = gedit_window_get_active_tab (window);
|
||
if (tab != NULL)
|
||
{
|
||
GeditDocument *doc;
|
||
|
||
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,
|
||
l->data,
|
||
encoding,
|
||
line_pos,
|
||
column_pos,
|
||
create);
|
||
|
||
/* make sure the view has focus */
|
||
gtk_widget_grab_focus (GTK_WIDGET (gedit_tab_get_view (tab)));
|
||
|
||
l = g_slist_next (l);
|
||
jump_to = FALSE;
|
||
|
||
++num_loaded_files;
|
||
loaded_files = g_slist_prepend (loaded_files,
|
||
gedit_tab_get_document (tab));
|
||
}
|
||
}
|
||
|
||
while (l != NULL)
|
||
{
|
||
g_return_val_if_fail (l->data != NULL, NULL);
|
||
|
||
tab = gedit_window_create_tab_from_location (window,
|
||
l->data,
|
||
encoding,
|
||
line_pos,
|
||
column_pos,
|
||
@@ -446,113 +443,113 @@ _gedit_cmd_file_reopen_closed_tab (GSimpleAction *action,
|
||
GFile *file;
|
||
|
||
file = _gedit_window_pop_last_closed_doc (window);
|
||
if (file != NULL)
|
||
{
|
||
gedit_commands_load_location (window, file, NULL, 0, 0);
|
||
}
|
||
}
|
||
|
||
/* File saving */
|
||
|
||
/* FIXME: modify this dialog to be similar to the one provided by gtk+ for
|
||
* already existing files - Paolo (Oct. 11, 2005) */
|
||
static gboolean
|
||
replace_read_only_file (GtkWindow *parent,
|
||
GFile *file)
|
||
{
|
||
GtkWidget *dialog;
|
||
gint ret;
|
||
gchar *parse_name;
|
||
gchar *name_for_display;
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
parse_name = g_file_get_parse_name (file);
|
||
|
||
/* Truncate the name so it doesn't get insanely wide. Note that even
|
||
* 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,
|
||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||
GTK_MESSAGE_QUESTION,
|
||
GTK_BUTTONS_NONE,
|
||
_("The file “%s” is read-only."),
|
||
name_for_display);
|
||
g_free (name_for_display);
|
||
|
||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||
_("Do you want to try to replace it "
|
||
"with the one you are saving?"));
|
||
|
||
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
|
||
_("_Cancel"), GTK_RESPONSE_CANCEL,
|
||
_("_Replace"), GTK_RESPONSE_YES,
|
||
NULL);
|
||
|
||
gtk_dialog_set_default_response (GTK_DIALOG (dialog),
|
||
GTK_RESPONSE_CANCEL);
|
||
|
||
gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
|
||
|
||
ret = gtk_dialog_run (GTK_DIALOG (dialog));
|
||
|
||
gtk_widget_destroy (dialog);
|
||
|
||
return ret == GTK_RESPONSE_YES;
|
||
}
|
||
|
||
static gboolean
|
||
change_compression (GtkWindow *parent,
|
||
GFile *file,
|
||
gboolean compressed)
|
||
{
|
||
GtkWidget *dialog;
|
||
gint ret;
|
||
gchar *parse_name;
|
||
gchar *name_for_display;
|
||
const gchar *primary_message;
|
||
const gchar *button_label;
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
parse_name = g_file_get_parse_name (file);
|
||
|
||
/* Truncate the name so it doesn't get insanely wide. Note that even
|
||
* 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)
|
||
{
|
||
primary_message = _("Save the file using compression?");
|
||
}
|
||
else
|
||
{
|
||
primary_message = _("Save the file as plain text?");
|
||
}
|
||
|
||
dialog = gtk_message_dialog_new (parent,
|
||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||
GTK_MESSAGE_QUESTION,
|
||
GTK_BUTTONS_NONE,
|
||
"%s",
|
||
primary_message);
|
||
|
||
if (compressed)
|
||
{
|
||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||
_("The file “%s” was previously saved as plain "
|
||
"text and will now be saved using compression."),
|
||
name_for_display);
|
||
|
||
button_label = _("_Save Using Compression");
|
||
}
|
||
else
|
||
{
|
||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
|
||
@@ -760,60 +757,61 @@ confirm_overwrite_callback (GeditFileChooserDialog *dialog,
|
||
|
||
/* Call save_as_tab_finish() in @callback. */
|
||
static void
|
||
save_as_tab_async (GeditTab *tab,
|
||
GeditWindow *window,
|
||
GCancellable *cancellable,
|
||
GAsyncReadyCallback callback,
|
||
gpointer user_data)
|
||
{
|
||
GTask *task;
|
||
GeditFileChooserDialog *save_dialog;
|
||
GtkWindowGroup *window_group;
|
||
GtkWindow *dialog_window;
|
||
GeditDocument *doc;
|
||
GtkSourceFile *file;
|
||
GFile *location;
|
||
const GtkSourceEncoding *encoding;
|
||
GtkSourceNewlineType newline_type;
|
||
|
||
g_return_if_fail (GEDIT_IS_TAB (tab));
|
||
g_return_if_fail (GEDIT_IS_WINDOW (window));
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
task = g_task_new (tab, cancellable, callback, user_data);
|
||
g_task_set_task_data (task, g_object_ref (window), g_object_unref);
|
||
|
||
/* 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"));
|
||
|
||
gedit_file_chooser_dialog_set_do_overwrite_confirmation (save_dialog, TRUE);
|
||
|
||
g_signal_connect (save_dialog,
|
||
"confirm-overwrite",
|
||
G_CALLBACK (confirm_overwrite_callback),
|
||
NULL);
|
||
|
||
window_group = gedit_window_get_group (window);
|
||
|
||
dialog_window = gedit_file_chooser_dialog_get_window (save_dialog);
|
||
|
||
if (dialog_window != NULL)
|
||
{
|
||
gtk_window_group_add_window (window_group, dialog_window);
|
||
}
|
||
|
||
/* Save As dialog is modal to its main window */
|
||
gedit_file_chooser_dialog_set_modal (save_dialog, TRUE);
|
||
|
||
/* Set the suggested file name */
|
||
doc = gedit_tab_get_document (tab);
|
||
file = gedit_document_get_file (doc);
|
||
location = gtk_source_file_get_location (file);
|
||
|
||
if (location != NULL)
|
||
{
|
||
gedit_file_chooser_dialog_set_file (save_dialog, location);
|
||
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
|
||
@@ -2,61 +2,60 @@
|
||
* gedit-commands-search.c
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
|
||
* Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
|
||
* Copyright (C) 2002-2006 Paolo Maggi
|
||
* Copyright (C) 2013 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include "gedit-commands.h"
|
||
#include "gedit-commands-private.h"
|
||
|
||
#include <string.h>
|
||
#include <glib/gi18n.h>
|
||
#include <gdk/gdkkeysyms.h>
|
||
-#include <tepl/tepl.h>
|
||
|
||
#include "gedit-debug.h"
|
||
#include "gedit-statusbar.h"
|
||
#include "gedit-tab.h"
|
||
#include "gedit-tab-private.h"
|
||
#include "gedit-view-frame.h"
|
||
#include "gedit-window.h"
|
||
#include "gedit-window-private.h"
|
||
#include "gedit-utils.h"
|
||
#include "gedit-replace-dialog.h"
|
||
|
||
#define GEDIT_REPLACE_DIALOG_KEY "gedit-replace-dialog-key"
|
||
#define GEDIT_LAST_SEARCH_DATA_KEY "gedit-last-search-data-key"
|
||
|
||
typedef struct _LastSearchData LastSearchData;
|
||
struct _LastSearchData
|
||
{
|
||
gint x;
|
||
gint y;
|
||
};
|
||
|
||
static void
|
||
last_search_data_free (LastSearchData *data)
|
||
{
|
||
g_slice_free (LastSearchData, data);
|
||
}
|
||
|
||
static void
|
||
last_search_data_restore_position (GeditReplaceDialog *dlg)
|
||
{
|
||
@@ -105,117 +104,117 @@ text_found (GeditWindow *window,
|
||
window->priv->generic_message_cid,
|
||
ngettext("Found and replaced %d occurrence",
|
||
"Found and replaced %d occurrences",
|
||
occurrences),
|
||
occurrences);
|
||
}
|
||
else if (occurrences == 1)
|
||
{
|
||
gedit_statusbar_flash_message (GEDIT_STATUSBAR (window->priv->statusbar),
|
||
window->priv->generic_message_cid,
|
||
_("Found and replaced one occurrence"));
|
||
}
|
||
else
|
||
{
|
||
gedit_statusbar_flash_message (GEDIT_STATUSBAR (window->priv->statusbar),
|
||
window->priv->generic_message_cid,
|
||
" ");
|
||
}
|
||
}
|
||
|
||
#define MAX_MSG_LENGTH 40
|
||
|
||
static void
|
||
text_not_found (GeditWindow *window,
|
||
GeditReplaceDialog *replace_dialog)
|
||
{
|
||
const gchar *search_text;
|
||
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,
|
||
/* Translators: %s is replaced by the text
|
||
entered by the user in the search box */
|
||
_("“%s” not found"), truncated_text);
|
||
|
||
g_free (truncated_text);
|
||
}
|
||
|
||
static void
|
||
finish_search_from_dialog (GeditWindow *window,
|
||
gboolean found)
|
||
{
|
||
GeditReplaceDialog *replace_dialog;
|
||
|
||
replace_dialog = g_object_get_data (G_OBJECT (window), GEDIT_REPLACE_DIALOG_KEY);
|
||
|
||
g_return_if_fail (replace_dialog != NULL);
|
||
|
||
if (found)
|
||
{
|
||
text_found (window, 0);
|
||
}
|
||
else
|
||
{
|
||
text_not_found (window, replace_dialog);
|
||
}
|
||
}
|
||
|
||
static gboolean
|
||
forward_search_finished (GtkSourceSearchContext *search_context,
|
||
GAsyncResult *result,
|
||
GeditView *view)
|
||
{
|
||
gboolean found;
|
||
GtkSourceBuffer *buffer;
|
||
GtkTextIter match_start;
|
||
GtkTextIter match_end;
|
||
|
||
found = gtk_source_search_context_forward_finish (search_context,
|
||
result,
|
||
&match_start,
|
||
&match_end,
|
||
NULL,
|
||
NULL);
|
||
|
||
buffer = gtk_source_search_context_get_buffer (search_context);
|
||
|
||
if (found)
|
||
{
|
||
gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer),
|
||
&match_start,
|
||
&match_end);
|
||
|
||
- tepl_view_scroll_to_cursor (TEPL_VIEW (view));
|
||
+ gedit_view_scroll_to_cursor (view);
|
||
}
|
||
else
|
||
{
|
||
GtkTextIter end_selection;
|
||
|
||
gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (buffer),
|
||
NULL,
|
||
&end_selection);
|
||
|
||
gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer),
|
||
&end_selection,
|
||
&end_selection);
|
||
}
|
||
|
||
return found;
|
||
}
|
||
|
||
static void
|
||
forward_search_from_dialog_finished (GtkSourceSearchContext *search_context,
|
||
GAsyncResult *result,
|
||
GeditWindow *window)
|
||
{
|
||
GeditView *view = gedit_window_get_active_view (window);
|
||
gboolean found;
|
||
|
||
if (view == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
@@ -267,61 +266,61 @@ run_forward_search (GeditWindow *window,
|
||
(GAsyncReadyCallback)forward_search_finished,
|
||
view);
|
||
}
|
||
}
|
||
|
||
static gboolean
|
||
backward_search_finished (GtkSourceSearchContext *search_context,
|
||
GAsyncResult *result,
|
||
GeditView *view)
|
||
{
|
||
gboolean found;
|
||
GtkTextIter match_start;
|
||
GtkTextIter match_end;
|
||
GtkSourceBuffer *buffer;
|
||
|
||
found = gtk_source_search_context_backward_finish (search_context,
|
||
result,
|
||
&match_start,
|
||
&match_end,
|
||
NULL,
|
||
NULL);
|
||
|
||
buffer = gtk_source_search_context_get_buffer (search_context);
|
||
|
||
if (found)
|
||
{
|
||
gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer),
|
||
&match_start,
|
||
&match_end);
|
||
|
||
- tepl_view_scroll_to_cursor (TEPL_VIEW (view));
|
||
+ gedit_view_scroll_to_cursor (view);
|
||
}
|
||
else
|
||
{
|
||
GtkTextIter start_selection;
|
||
|
||
gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (buffer),
|
||
&start_selection,
|
||
NULL);
|
||
|
||
gtk_text_buffer_select_range (GTK_TEXT_BUFFER (buffer),
|
||
&start_selection,
|
||
&start_selection);
|
||
}
|
||
|
||
return found;
|
||
}
|
||
|
||
static void
|
||
backward_search_from_dialog_finished (GtkSourceSearchContext *search_context,
|
||
GAsyncResult *result,
|
||
GeditWindow *window)
|
||
{
|
||
GeditView *view = gedit_window_get_active_view (window);
|
||
gboolean found;
|
||
|
||
if (view == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
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
|
||
@@ -1,58 +1,63 @@
|
||
/*
|
||
* gedit-view-commands.c
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
|
||
* Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
|
||
* Copyright (C) 2002-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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
+
|
||
#include "gedit-commands.h"
|
||
#include "gedit-commands-private.h"
|
||
-#include <tepl/tepl.h>
|
||
+
|
||
+#include <gtk/gtk.h>
|
||
+
|
||
#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,
|
||
GVariant *state,
|
||
gpointer user_data)
|
||
{
|
||
GeditView *active_view;
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
active_view = gedit_window_get_active_view (window);
|
||
|
||
if (active_view)
|
||
{
|
||
gtk_widget_grab_focus (GTK_WIDGET (active_view));
|
||
}
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_view_toggle_side_panel (GSimpleAction *action,
|
||
GVariant *state,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
GtkWidget *panel;
|
||
gboolean visible;
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
@@ -94,88 +99,75 @@ _gedit_cmd_view_toggle_bottom_panel (GSimpleAction *action,
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_view_toggle_fullscreen_mode (GSimpleAction *action,
|
||
GVariant *state,
|
||
gpointer user_data)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (user_data);
|
||
|
||
gedit_debug (DEBUG_COMMANDS);
|
||
|
||
if (g_variant_get_boolean (state))
|
||
{
|
||
_gedit_window_fullscreen (window);
|
||
}
|
||
else
|
||
{
|
||
_gedit_window_unfullscreen (window);
|
||
}
|
||
}
|
||
|
||
void
|
||
_gedit_cmd_view_leave_fullscreen_mode (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
gpointer user_data)
|
||
{
|
||
_gedit_window_unfullscreen (GEDIT_WINDOW (user_data));
|
||
}
|
||
|
||
static void
|
||
-language_activated_cb (TeplLanguageChooserDialog *dialog,
|
||
- GtkSourceLanguage *language,
|
||
- GeditWindow *window)
|
||
+language_selected_cb (GeditHighlightModeSelector *selector,
|
||
+ GtkSourceLanguage *language,
|
||
+ GeditWindow *window)
|
||
{
|
||
GeditDocument *active_document;
|
||
|
||
active_document = gedit_window_get_active_document (window);
|
||
if (active_document != NULL)
|
||
{
|
||
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
|
||
_gedit_cmd_view_highlight_mode (GSimpleAction *action,
|
||
GVariant *parameter,
|
||
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)
|
||
{
|
||
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));
|
||
}
|
||
|
||
/* ex:set ts=8 noet: */
|
||
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
|
||
@@ -73,60 +73,64 @@ gedit_debug_init (void)
|
||
enabled_sections |= GEDIT_DEBUG_WINDOW;
|
||
}
|
||
if (g_getenv ("GEDIT_DEBUG_PANEL") != NULL)
|
||
{
|
||
enabled_sections |= GEDIT_DEBUG_PANEL;
|
||
}
|
||
if (g_getenv ("GEDIT_DEBUG_PLUGINS") != NULL)
|
||
{
|
||
enabled_sections |= GEDIT_DEBUG_PLUGINS;
|
||
}
|
||
if (g_getenv ("GEDIT_DEBUG_TAB") != NULL)
|
||
{
|
||
enabled_sections |= GEDIT_DEBUG_TAB;
|
||
}
|
||
if (g_getenv ("GEDIT_DEBUG_DOCUMENT") != NULL)
|
||
{
|
||
enabled_sections |= GEDIT_DEBUG_DOCUMENT;
|
||
}
|
||
if (g_getenv ("GEDIT_DEBUG_COMMANDS") != NULL)
|
||
{
|
||
enabled_sections |= GEDIT_DEBUG_COMMANDS;
|
||
}
|
||
if (g_getenv ("GEDIT_DEBUG_APP") != NULL)
|
||
{
|
||
enabled_sections |= GEDIT_DEBUG_APP;
|
||
}
|
||
if (g_getenv ("GEDIT_DEBUG_UTILS") != NULL)
|
||
{
|
||
enabled_sections |= GEDIT_DEBUG_UTILS;
|
||
}
|
||
+ if (g_getenv ("GEDIT_DEBUG_METADATA") != NULL)
|
||
+ {
|
||
+ enabled_sections |= GEDIT_DEBUG_METADATA;
|
||
+ }
|
||
|
||
out:
|
||
|
||
#ifdef ENABLE_PROFILING
|
||
if (enabled_sections != GEDIT_NO_DEBUG)
|
||
{
|
||
timer = g_timer_new ();
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/**
|
||
* gedit_debug:
|
||
* @section: debug section.
|
||
* @file: file name.
|
||
* @line: line number.
|
||
* @function: name of the function that is calling gedit_debug().
|
||
*
|
||
* If @section is enabled, then logs the trace information @file, @line, and
|
||
* @function.
|
||
*/
|
||
void
|
||
gedit_debug (GeditDebugSection section,
|
||
const gchar *file,
|
||
gint line,
|
||
const gchar *function)
|
||
{
|
||
gedit_debug_message (section, file, line, function, "%s", "");
|
||
}
|
||
|
||
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
|
||
@@ -21,63 +21,65 @@
|
||
*/
|
||
|
||
#ifndef GEDIT_DEBUG_H
|
||
#define GEDIT_DEBUG_H
|
||
|
||
#include <glib.h>
|
||
|
||
/**
|
||
* GeditDebugSection:
|
||
*
|
||
* Enumeration of debug sections.
|
||
*
|
||
* Debugging output for a section is enabled by setting an environment variable
|
||
* of the same name. For example, setting the <code>GEDIT_DEBUG_PLUGINS</code>
|
||
* environment variable enables all debugging output for the %GEDIT_DEBUG_PLUGINS
|
||
* section. Setting the special environment variable <code>GEDIT_DEBUG</code>
|
||
* enables output for all sections.
|
||
*/
|
||
typedef enum {
|
||
GEDIT_NO_DEBUG = 0,
|
||
GEDIT_DEBUG_VIEW = 1 << 0,
|
||
GEDIT_DEBUG_PREFS = 1 << 1,
|
||
GEDIT_DEBUG_WINDOW = 1 << 2,
|
||
GEDIT_DEBUG_PANEL = 1 << 3,
|
||
GEDIT_DEBUG_PLUGINS = 1 << 4,
|
||
GEDIT_DEBUG_TAB = 1 << 5,
|
||
GEDIT_DEBUG_DOCUMENT = 1 << 6,
|
||
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
|
||
#define DEBUG_PREFS GEDIT_DEBUG_PREFS, __FILE__, __LINE__, G_STRFUNC
|
||
#define DEBUG_WINDOW GEDIT_DEBUG_WINDOW, __FILE__, __LINE__, G_STRFUNC
|
||
#define DEBUG_PANEL GEDIT_DEBUG_PANEL, __FILE__, __LINE__, G_STRFUNC
|
||
#define DEBUG_PLUGINS GEDIT_DEBUG_PLUGINS, __FILE__, __LINE__, G_STRFUNC
|
||
#define DEBUG_TAB GEDIT_DEBUG_TAB, __FILE__, __LINE__, G_STRFUNC
|
||
#define DEBUG_DOCUMENT GEDIT_DEBUG_DOCUMENT,__FILE__, __LINE__, G_STRFUNC
|
||
#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);
|
||
|
||
void gedit_debug (GeditDebugSection section,
|
||
const gchar *file,
|
||
gint line,
|
||
const gchar *function);
|
||
|
||
void gedit_debug_message (GeditDebugSection section,
|
||
const gchar *file,
|
||
gint line,
|
||
const gchar *function,
|
||
const gchar *format, ...) G_GNUC_PRINTF(5, 6);
|
||
|
||
void gedit_debug_plugin_message (const gchar *file,
|
||
gint line,
|
||
const gchar *function,
|
||
const gchar *message);
|
||
|
||
#endif /* GEDIT_DEBUG_H */
|
||
/* ex:set ts=8 noet: */
|
||
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
|
||
@@ -1,57 +1,63 @@
|
||
/*
|
||
* gedit-document.h
|
||
* This file is part of gedit
|
||
*
|
||
* 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
|
||
*
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_DOCUMENT_PRIVATE_H
|
||
#define GEDIT_DOCUMENT_PRIVATE_H
|
||
|
||
#include "gedit-document.h"
|
||
|
||
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);
|
||
|
||
G_GNUC_INTERNAL
|
||
gboolean _gedit_document_needs_saving (GeditDocument *doc);
|
||
|
||
G_GNUC_INTERNAL
|
||
gboolean _gedit_document_get_empty_search (GeditDocument *doc);
|
||
|
||
G_GNUC_INTERNAL
|
||
void _gedit_document_set_create (GeditDocument *doc,
|
||
gboolean create);
|
||
|
||
G_GNUC_INTERNAL
|
||
gboolean _gedit_document_get_create (GeditDocument *doc);
|
||
|
||
G_GNUC_INTERNAL
|
||
gchar * _gedit_document_get_uri_for_display (GeditDocument *doc);
|
||
|
||
G_END_DECLS
|
||
|
||
#endif /* GEDIT_DOCUMENT_PRIVATE_H */
|
||
/* ex:set ts=8 noet: */
|
||
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
|
||
@@ -1,156 +1,177 @@
|
||
/*
|
||
* gedit-document.c
|
||
* This file is part of gedit
|
||
*
|
||
* 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
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
+
|
||
#include "gedit-document.h"
|
||
#include "gedit-document-private.h"
|
||
+
|
||
#include <string.h>
|
||
#include <glib/gi18n.h>
|
||
+
|
||
+#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_"
|
||
|
||
static void gedit_document_loaded_real (GeditDocument *doc);
|
||
|
||
static void gedit_document_saved_real (GeditDocument *doc);
|
||
|
||
static void set_content_type (GeditDocument *doc,
|
||
const gchar *content_type);
|
||
|
||
typedef struct
|
||
{
|
||
GtkSourceFile *file;
|
||
|
||
- TeplMetadata *metadata;
|
||
+ GSettings *editor_settings;
|
||
+
|
||
+ gint untitled_number;
|
||
+
|
||
+ GFileInfo *metadata_info;
|
||
|
||
gchar *content_type;
|
||
|
||
GDateTime *time_of_last_save_or_load;
|
||
|
||
/* The search context for the incremental search, or the search and
|
||
* replace. They are mutually exclusive.
|
||
*/
|
||
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
|
||
* actions.
|
||
*/
|
||
guint empty_search : 1;
|
||
|
||
/* Create file if location points to a non existing file (for example
|
||
* when opened from the command line).
|
||
*/
|
||
guint create : 1;
|
||
} GeditDocumentPrivate;
|
||
|
||
enum
|
||
{
|
||
PROP_0,
|
||
+ PROP_SHORTNAME,
|
||
PROP_CONTENT_TYPE,
|
||
PROP_MIME_TYPE,
|
||
PROP_EMPTY_SEARCH,
|
||
+ PROP_USE_GVFS_METADATA,
|
||
LAST_PROP
|
||
};
|
||
|
||
static GParamSpec *properties[LAST_PROP];
|
||
|
||
enum
|
||
{
|
||
+ CURSOR_MOVED,
|
||
LOAD,
|
||
LOADED,
|
||
SAVE,
|
||
SAVED,
|
||
LAST_SIGNAL
|
||
};
|
||
|
||
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
|
||
update_time_of_last_save_or_load (GeditDocument *doc)
|
||
{
|
||
GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
|
||
|
||
if (priv->time_of_last_save_or_load != NULL)
|
||
{
|
||
g_date_time_unref (priv->time_of_last_save_or_load);
|
||
}
|
||
|
||
priv->time_of_last_save_or_load = g_date_time_new_now_utc ();
|
||
}
|
||
|
||
static const gchar *
|
||
get_language_string (GeditDocument *doc)
|
||
{
|
||
GtkSourceLanguage *lang = gedit_document_get_language (doc);
|
||
|
||
return lang != NULL ? gtk_source_language_get_id (lang) : NO_LANGUAGE_NAME;
|
||
}
|
||
|
||
static void
|
||
save_metadata (GeditDocument *doc)
|
||
{
|
||
GeditDocumentPrivate *priv;
|
||
const gchar *language = NULL;
|
||
GtkTextIter iter;
|
||
gchar *position;
|
||
@@ -168,215 +189,361 @@ save_metadata (GeditDocument *doc)
|
||
position = g_strdup_printf ("%d", gtk_text_iter_get_offset (&iter));
|
||
|
||
if (language == NULL)
|
||
{
|
||
gedit_document_set_metadata (doc,
|
||
GEDIT_METADATA_ATTRIBUTE_POSITION, position,
|
||
NULL);
|
||
}
|
||
else
|
||
{
|
||
gedit_document_set_metadata (doc,
|
||
GEDIT_METADATA_ATTRIBUTE_POSITION, position,
|
||
GEDIT_METADATA_ATTRIBUTE_LANGUAGE, language,
|
||
NULL);
|
||
}
|
||
|
||
g_free (position);
|
||
}
|
||
|
||
static void
|
||
gedit_document_dispose (GObject *object)
|
||
{
|
||
GeditDocument *doc = GEDIT_DOCUMENT (object);
|
||
GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
|
||
|
||
gedit_debug (DEBUG_DOCUMENT);
|
||
|
||
/* 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);
|
||
}
|
||
|
||
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)
|
||
{
|
||
g_date_time_unref (priv->time_of_last_save_or_load);
|
||
}
|
||
|
||
G_OBJECT_CLASS (gedit_document_parent_class)->finalize (object);
|
||
}
|
||
|
||
static void
|
||
gedit_document_get_property (GObject *object,
|
||
guint prop_id,
|
||
GValue *value,
|
||
GParamSpec *pspec)
|
||
{
|
||
GeditDocument *doc = GEDIT_DOCUMENT (object);
|
||
GeditDocumentPrivate *priv;
|
||
|
||
priv = gedit_document_get_instance_private (doc);
|
||
|
||
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;
|
||
|
||
case PROP_MIME_TYPE:
|
||
g_value_take_string (value, gedit_document_get_mime_type (doc));
|
||
break;
|
||
|
||
case PROP_EMPTY_SEARCH:
|
||
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;
|
||
}
|
||
}
|
||
|
||
static void
|
||
gedit_document_set_property (GObject *object,
|
||
guint prop_id,
|
||
const GValue *value,
|
||
GParamSpec *pspec)
|
||
{
|
||
GeditDocument *doc = GEDIT_DOCUMENT (object);
|
||
+ GeditDocumentPrivate *priv = gedit_document_get_instance_private (doc);
|
||
|
||
switch (prop_id)
|
||
{
|
||
case PROP_CONTENT_TYPE:
|
||
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",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
|
||
|
||
G_OBJECT_CLASS (gedit_document_parent_class)->constructed (object);
|
||
}
|
||
|
||
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;
|
||
object_class->get_property = gedit_document_get_property;
|
||
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.
|
||
*/
|
||
properties[PROP_CONTENT_TYPE] =
|
||
g_param_spec_string ("content-type",
|
||
"Content Type",
|
||
"The document's Content Type",
|
||
NULL,
|
||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||
|
||
/**
|
||
* GeditDocument:mime-type:
|
||
*
|
||
* The document's MIME type.
|
||
*/
|
||
properties[PROP_MIME_TYPE] =
|
||
g_param_spec_string ("mime-type",
|
||
"MIME Type",
|
||
"The document's MIME Type",
|
||
"text/plain",
|
||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||
|
||
/**
|
||
* GeditDocument:empty-search:
|
||
*
|
||
* <warning>
|
||
* 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.
|
||
* </warning>
|
||
*/
|
||
properties[PROP_EMPTY_SEARCH] =
|
||
g_param_spec_boolean ("empty-search",
|
||
"Empty search",
|
||
"Whether the search is empty",
|
||
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.
|
||
+ *
|
||
+ * <warning>
|
||
+ * 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.
|
||
+ * </warning>
|
||
+ */
|
||
+ 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.
|
||
*
|
||
* The "load" signal is emitted at the beginning of a file loading.
|
||
*
|
||
* Before gedit 3.14 this signal contained parameters to configure the
|
||
* file loading (the location, encoding, etc). Plugins should not need
|
||
* those parameters.
|
||
*/
|
||
document_signals[LOAD] =
|
||
g_signal_new ("load",
|
||
G_OBJECT_CLASS_TYPE (object_class),
|
||
G_SIGNAL_RUN_LAST,
|
||
G_STRUCT_OFFSET (GeditDocumentClass, load),
|
||
NULL, NULL, NULL,
|
||
G_TYPE_NONE, 0);
|
||
|
||
/**
|
||
* GeditDocument::loaded:
|
||
* @document: the #GeditDocument.
|
||
*
|
||
* The "loaded" signal is emitted at the end of a successful file
|
||
* loading.
|
||
*
|
||
* Before gedit 3.14 this signal contained a #GError parameter, and the
|
||
* signal was also emitted if an error occurred. Plugins should not need
|
||
* the error parameter.
|
||
*/
|
||
document_signals[LOADED] =
|
||
@@ -605,128 +772,188 @@ static void
|
||
on_content_type_changed (GeditDocument *doc,
|
||
GParamSpec *pspec,
|
||
gpointer useless)
|
||
{
|
||
GeditDocumentPrivate *priv;
|
||
|
||
priv = gedit_document_get_instance_private (doc);
|
||
|
||
if (!priv->language_set_by_user)
|
||
{
|
||
GtkSourceLanguage *language = guess_language (doc);
|
||
|
||
gedit_debug_message (DEBUG_DOCUMENT, "Language: %s",
|
||
language != NULL ? gtk_source_language_get_name (language) : "None");
|
||
|
||
set_language (doc, language, FALSE);
|
||
}
|
||
}
|
||
|
||
static gchar *
|
||
get_default_content_type (void)
|
||
{
|
||
return g_content_type_from_mime_type ("text/plain");
|
||
}
|
||
|
||
static void
|
||
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;
|
||
|
||
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",
|
||
G_CALLBACK (on_location_changed),
|
||
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);
|
||
|
||
g_settings_bind (editor_settings, GEDIT_SETTINGS_SYNTAX_HIGHLIGHTING,
|
||
doc, "highlight-syntax",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
|
||
|
||
g_settings_bind (editor_settings, GEDIT_SETTINGS_BRACKET_MATCHING,
|
||
doc, "highlight-matching-brackets",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
|
||
|
||
g_signal_connect_object (editor_settings,
|
||
"changed::" GEDIT_SETTINGS_SCHEME,
|
||
G_CALLBACK (editor_settings_scheme_changed_cb),
|
||
doc,
|
||
0);
|
||
|
||
update_style_scheme (doc);
|
||
|
||
g_signal_connect (doc,
|
||
"notify::content-type",
|
||
G_CALLBACK (on_content_type_changed),
|
||
NULL);
|
||
}
|
||
|
||
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 *
|
||
get_content_type_from_content (GeditDocument *doc)
|
||
{
|
||
gchar *content_type;
|
||
gchar *data;
|
||
GtkTextBuffer *buffer;
|
||
GtkTextIter start;
|
||
GtkTextIter end;
|
||
|
||
buffer = GTK_TEXT_BUFFER (doc);
|
||
|
||
gtk_text_buffer_get_start_iter (buffer, &start);
|
||
end = start;
|
||
gtk_text_iter_forward_chars (&end, 255);
|
||
|
||
data = gtk_text_buffer_get_text (buffer, &start, &end, TRUE);
|
||
|
||
content_type = g_content_type_guess (NULL,
|
||
(const guchar *)data,
|
||
strlen (data),
|
||
NULL);
|
||
|
||
g_free (data);
|
||
|
||
return content_type;
|
||
}
|
||
|
||
static void
|
||
@@ -787,93 +1014,107 @@ set_content_type (GeditDocument *doc,
|
||
if (content_type == NULL)
|
||
{
|
||
GFile *location;
|
||
gchar *guessed_type = NULL;
|
||
|
||
/* If content type is null, we guess from the filename */
|
||
location = gtk_source_file_get_location (priv->file);
|
||
if (location != NULL)
|
||
{
|
||
gchar *basename;
|
||
|
||
basename = g_file_get_basename (location);
|
||
guessed_type = g_content_type_guess (basename, NULL, 0, NULL);
|
||
|
||
g_free (basename);
|
||
}
|
||
|
||
set_content_type_no_guess (doc, guessed_type);
|
||
g_free (guessed_type);
|
||
}
|
||
else
|
||
{
|
||
set_content_type_no_guess (doc, content_type);
|
||
}
|
||
}
|
||
|
||
/* Note: this never returns %NULL. */
|
||
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
|
||
{
|
||
return g_file_get_parse_name (location);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* gedit_document_get_short_name_for_display:
|
||
* @doc: a #GeditDocument.
|
||
*
|
||
* Note: this never returns %NULL.
|
||
**/
|
||
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 *
|
||
gedit_document_get_content_type (GeditDocument *doc)
|
||
{
|
||
GeditDocumentPrivate *priv;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
|
||
|
||
priv = gedit_document_get_instance_private (doc);
|
||
|
||
return g_strdup (priv->content_type);
|
||
}
|
||
|
||
/**
|
||
* gedit_document_get_mime_type:
|
||
* @doc: a #GeditDocument.
|
||
*
|
||
* Note: this never returns %NULL.
|
||
**/
|
||
gchar *
|
||
gedit_document_get_mime_type (GeditDocument *doc)
|
||
{
|
||
GeditDocumentPrivate *priv;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), g_strdup ("text/plain"));
|
||
|
||
priv = gedit_document_get_instance_private (doc);
|
||
|
||
if (priv->content_type != NULL &&
|
||
@@ -1005,225 +1246,398 @@ saved_query_info_cb (GFile *location,
|
||
priv->create = FALSE;
|
||
|
||
save_encoding_metadata (doc);
|
||
|
||
/* Async operation finished. */
|
||
g_object_unref (doc);
|
||
}
|
||
|
||
static void
|
||
gedit_document_saved_real (GeditDocument *doc)
|
||
{
|
||
GeditDocumentPrivate *priv;
|
||
GFile *location;
|
||
|
||
priv = gedit_document_get_instance_private (doc);
|
||
|
||
location = gtk_source_file_get_location (priv->file);
|
||
|
||
/* Keep the doc alive during the async operation. */
|
||
g_object_ref (doc);
|
||
|
||
g_file_query_info_async (location,
|
||
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
|
||
G_FILE_QUERY_INFO_NONE,
|
||
G_PRIORITY_DEFAULT,
|
||
NULL,
|
||
(GAsyncReadyCallback) saved_query_info_cb,
|
||
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;
|
||
}
|
||
|
||
/*
|
||
* Deletion and external modification is only checked for local files.
|
||
*/
|
||
gboolean
|
||
_gedit_document_needs_saving (GeditDocument *doc)
|
||
{
|
||
GeditDocumentPrivate *priv;
|
||
gboolean externally_modified = FALSE;
|
||
gboolean deleted = FALSE;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
|
||
|
||
priv = gedit_document_get_instance_private (doc);
|
||
|
||
if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
if (gtk_source_file_is_local (priv->file))
|
||
{
|
||
gtk_source_file_check_file_on_disk (priv->file);
|
||
externally_modified = gtk_source_file_is_externally_modified (priv->file);
|
||
deleted = gtk_source_file_is_deleted (priv->file);
|
||
}
|
||
|
||
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:
|
||
* @lang: (allow-none):
|
||
**/
|
||
void
|
||
gedit_document_set_language (GeditDocument *doc,
|
||
GtkSourceLanguage *lang)
|
||
{
|
||
g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
|
||
|
||
set_language (doc, lang, TRUE);
|
||
}
|
||
|
||
/**
|
||
* gedit_document_get_language:
|
||
* @doc:
|
||
*
|
||
* Return value: (transfer none):
|
||
*/
|
||
GtkSourceLanguage *
|
||
gedit_document_get_language (GeditDocument *doc)
|
||
{
|
||
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
|
||
|
||
return gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (doc));
|
||
}
|
||
|
||
glong
|
||
_gedit_document_get_seconds_since_last_save_or_load (GeditDocument *doc)
|
||
{
|
||
GeditDocumentPrivate *priv;
|
||
GDateTime *now;
|
||
GTimeSpan n_microseconds;
|
||
|
||
gedit_debug (DEBUG_DOCUMENT);
|
||
|
||
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), -1);
|
||
|
||
priv = gedit_document_get_instance_private (doc);
|
||
|
||
if (priv->time_of_last_save_or_load == NULL)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
now = g_date_time_new_now_utc ();
|
||
if (now == NULL)
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
n_microseconds = g_date_time_difference (now, priv->time_of_last_save_or_load);
|
||
g_date_time_unref (now);
|
||
|
||
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
|
||
* @key: name of the key
|
||
*
|
||
* Gets the metadata assigned to @key.
|
||
*
|
||
* Returns: the value assigned to @key. Free with g_free().
|
||
*/
|
||
gchar *
|
||
gedit_document_get_metadata (GeditDocument *doc,
|
||
const gchar *key)
|
||
{
|
||
GeditDocumentPrivate *priv;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
|
||
g_return_val_if_fail (key != NULL, NULL);
|
||
|
||
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);
|
||
}
|
||
|
||
/**
|
||
* gedit_document_set_metadata:
|
||
* @doc: a #GeditDocument
|
||
* @first_key: name of the first key to set
|
||
* @...: (allow-none): value for the first key, followed optionally by more key/value pairs,
|
||
* followed by %NULL.
|
||
*
|
||
* Sets metadata on a document.
|
||
*/
|
||
void
|
||
gedit_document_set_metadata (GeditDocument *doc,
|
||
const gchar *first_key,
|
||
...)
|
||
{
|
||
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
|
||
update_empty_search (GeditDocument *doc)
|
||
{
|
||
GeditDocumentPrivate *priv;
|
||
gboolean new_value;
|
||
|
||
priv = gedit_document_get_instance_private (doc);
|
||
|
||
if (priv->search_context == NULL)
|
||
{
|
||
new_value = TRUE;
|
||
}
|
||
else
|
||
{
|
||
GtkSourceSearchSettings *search_settings;
|
||
|
||
search_settings = gtk_source_search_context_get_settings (priv->search_context);
|
||
|
||
new_value = gtk_source_search_settings_get_search_text (search_settings) == NULL;
|
||
}
|
||
|
||
if (priv->empty_search != new_value)
|
||
{
|
||
priv->empty_search = new_value;
|
||
g_object_notify_by_pspec (G_OBJECT (doc), properties[PROP_EMPTY_SEARCH]);
|
||
}
|
||
}
|
||
|
||
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
|
||
@@ -1,83 +1,93 @@
|
||
/*
|
||
* gedit-document.h
|
||
* This file is part of gedit
|
||
*
|
||
* 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
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_DOCUMENT_H
|
||
#define GEDIT_DOCUMENT_H
|
||
|
||
-#include <tepl/tepl.h>
|
||
+#include <gtksourceview/gtksource.h>
|
||
|
||
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);
|
||
|
||
void (* loaded) (GeditDocument *document);
|
||
|
||
void (* save) (GeditDocument *document);
|
||
|
||
void (* saved) (GeditDocument *document);
|
||
};
|
||
|
||
GeditDocument *gedit_document_new (void);
|
||
|
||
GtkSourceFile *gedit_document_get_file (GeditDocument *doc);
|
||
|
||
gchar *gedit_document_get_short_name_for_display (GeditDocument *doc);
|
||
|
||
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
|
||
*gedit_document_get_language (GeditDocument *doc);
|
||
|
||
gchar *gedit_document_get_metadata (GeditDocument *doc,
|
||
const gchar *key);
|
||
|
||
void gedit_document_set_metadata (GeditDocument *doc,
|
||
const gchar *first_key,
|
||
...);
|
||
|
||
void gedit_document_set_search_context (GeditDocument *doc,
|
||
GtkSourceSearchContext *search_context);
|
||
|
||
GtkSourceSearchContext *
|
||
gedit_document_get_search_context (GeditDocument *doc);
|
||
|
||
G_END_DECLS
|
||
|
||
#endif /* GEDIT_DOCUMENT_H */
|
||
/* ex:set ts=8 noet: */
|
||
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
|
||
@@ -1,56 +1,55 @@
|
||
/*
|
||
* gedit-documents-panel.c
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 2014 - Sébastien Lafargue <slafargue@gnome.org>
|
||
*
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include "gedit-documents-panel.h"
|
||
|
||
#include <glib/gi18n.h>
|
||
-#include <tepl/tepl.h>
|
||
|
||
#include "gedit-debug.h"
|
||
#include "gedit-document.h"
|
||
#include "gedit-multi-notebook.h"
|
||
#include "gedit-notebook.h"
|
||
#include "gedit-notebook-popup-menu.h"
|
||
#include "gedit-tab.h"
|
||
#include "gedit-tab-private.h"
|
||
#include "gedit-utils.h"
|
||
#include "gedit-commands-private.h"
|
||
|
||
typedef struct _GeditDocumentsGenericRow GeditDocumentsGenericRow;
|
||
typedef struct _GeditDocumentsGenericRow GeditDocumentsGroupRow;
|
||
typedef struct _GeditDocumentsGenericRow GeditDocumentsDocumentRow;
|
||
|
||
struct _GeditDocumentsGenericRow
|
||
{
|
||
GtkListBoxRow parent_instance;
|
||
|
||
GeditDocumentsPanel *panel;
|
||
GtkWidget *ref;
|
||
|
||
GtkWidget *box;
|
||
GtkWidget *label;
|
||
GtkWidget *close_button;
|
||
|
||
/* Not used in GeditDocumentsGroupRow */
|
||
GtkWidget *image;
|
||
GtkWidget *status_label;
|
||
};
|
||
@@ -420,61 +419,61 @@ group_row_update_names (GeditDocumentsPanel *panel,
|
||
{
|
||
group_row_set_notebook_name (row);
|
||
}
|
||
}
|
||
|
||
g_list_free (children);
|
||
}
|
||
|
||
static void
|
||
group_row_refresh_visibility (GeditDocumentsPanel *panel)
|
||
{
|
||
gboolean notebook_is_unique;
|
||
GtkWidget *first_group_row;
|
||
|
||
notebook_is_unique = gedit_multi_notebook_get_n_notebooks (panel->mnb) <= 1;
|
||
first_group_row = GTK_WIDGET (get_first_notebook_found (panel));
|
||
|
||
gtk_widget_set_no_show_all (first_group_row, notebook_is_unique);
|
||
gtk_widget_set_visible (first_group_row, !notebook_is_unique);
|
||
}
|
||
|
||
static gchar *
|
||
doc_get_name (GeditDocument *doc)
|
||
{
|
||
gchar *name;
|
||
gchar *docname;
|
||
|
||
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);
|
||
|
||
return docname;
|
||
}
|
||
|
||
static void
|
||
document_row_sync_tab_name_and_icon (GeditTab *tab,
|
||
GParamSpec *pspec,
|
||
GtkWidget *row)
|
||
{
|
||
GeditDocumentsDocumentRow *document_row = GEDIT_DOCUMENTS_DOCUMENT_ROW (row);
|
||
GeditDocument *doc;
|
||
GtkSourceFile *file;
|
||
gchar *name;
|
||
GdkPixbuf *pixbuf;
|
||
|
||
doc = gedit_tab_get_document (tab);
|
||
name = doc_get_name (doc);
|
||
|
||
if (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
|
||
{
|
||
gtk_label_set_text (GTK_LABEL (document_row->label), name);
|
||
}
|
||
else
|
||
{
|
||
gchar *markup;
|
||
|
||
markup = g_markup_printf_escaped ("<b>%s</b>", name);
|
||
gtk_label_set_markup (GTK_LABEL (document_row->label), markup);
|
||
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 <swilmet@gnome.org>
|
||
- *
|
||
- * 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 <http://www.gnu.org/licenses/>.
|
||
- */
|
||
-
|
||
-#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 <swilmet@gnome.org>
|
||
- *
|
||
- * 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 <http://www.gnu.org/licenses/>.
|
||
- */
|
||
-
|
||
-#ifndef GEDIT_FACTORY_H
|
||
-#define GEDIT_FACTORY_H
|
||
-
|
||
-#include <tepl/tepl.h>
|
||
-
|
||
-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
|
||
@@ -165,131 +165,160 @@ chooser_set_current_name (GeditFileChooserDialog *dialog,
|
||
gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), name);
|
||
}
|
||
|
||
static void
|
||
chooser_set_file (GeditFileChooserDialog *dialog,
|
||
GFile *file)
|
||
{
|
||
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (dialog), file, NULL);
|
||
}
|
||
|
||
static GFile *
|
||
chooser_get_file (GeditFileChooserDialog *dialog)
|
||
{
|
||
return gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
|
||
}
|
||
|
||
static void
|
||
chooser_set_do_overwrite_confirmation (GeditFileChooserDialog *dialog,
|
||
gboolean overwrite_confirmation)
|
||
{
|
||
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), overwrite_confirmation);
|
||
}
|
||
|
||
static void
|
||
chooser_show (GeditFileChooserDialog *dialog)
|
||
{
|
||
gtk_window_present (GTK_WINDOW (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)
|
||
{
|
||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||
}
|
||
|
||
static void
|
||
chooser_set_modal (GeditFileChooserDialog *dialog,
|
||
gboolean is_modal)
|
||
{
|
||
gtk_window_set_modal (GTK_WINDOW (dialog), is_modal);
|
||
}
|
||
|
||
static GtkWindow *
|
||
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)
|
||
{
|
||
GeditFileChooserDialogInterface *iface = g_iface;
|
||
|
||
iface->set_encoding = chooser_set_encoding;
|
||
iface->get_encoding = chooser_get_encoding;
|
||
|
||
iface->set_newline_type = chooser_set_newline_type;
|
||
iface->get_newline_type = chooser_get_newline_type;
|
||
|
||
iface->set_current_folder = chooser_set_current_folder;
|
||
iface->set_current_name = chooser_set_current_name;
|
||
iface->set_file = chooser_set_file;
|
||
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
|
||
gedit_file_chooser_dialog_gtk_dispose (GObject *object)
|
||
{
|
||
GeditFileChooserDialogGtk *dialog = GEDIT_FILE_CHOOSER_DIALOG_GTK (object);
|
||
|
||
g_clear_object (&dialog->gedit_file_chooser);
|
||
|
||
G_OBJECT_CLASS (gedit_file_chooser_dialog_gtk_parent_class)->dispose (object);
|
||
}
|
||
|
||
static void
|
||
gedit_file_chooser_dialog_gtk_class_init (GeditFileChooserDialogGtkClass *klass)
|
||
{
|
||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||
|
||
object_class->dispose = gedit_file_chooser_dialog_gtk_dispose;
|
||
}
|
||
|
||
static void
|
||
-create_option_menu (GeditFileChooserDialogGtk *dialog)
|
||
+create_option_menu (GeditFileChooserDialogGtk *dialog,
|
||
+ GeditFileChooserFlags flags)
|
||
{
|
||
GtkWidget *label;
|
||
GtkWidget *menu;
|
||
gboolean save_mode;
|
||
|
||
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);
|
||
|
||
gtk_box_pack_start (GTK_BOX (dialog->extra_widget),
|
||
label,
|
||
FALSE,
|
||
TRUE,
|
||
0);
|
||
|
||
gtk_box_pack_start (GTK_BOX (dialog->extra_widget),
|
||
menu,
|
||
TRUE,
|
||
TRUE,
|
||
0);
|
||
|
||
gtk_widget_show (label);
|
||
gtk_widget_show (menu);
|
||
|
||
dialog->option_menu = menu;
|
||
}
|
||
|
||
static void
|
||
update_newline_visibility (GeditFileChooserDialogGtk *dialog)
|
||
{
|
||
gboolean visible = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog)) == GTK_FILE_CHOOSER_ACTION_SAVE;
|
||
|
||
gtk_widget_set_visible (dialog->newline_label, visible);
|
||
gtk_widget_set_visible (dialog->newline_combo, visible);
|
||
}
|
||
@@ -347,119 +376,138 @@ create_newline_combo (GeditFileChooserDialogGtk *dialog)
|
||
GTK_SOURCE_NEWLINE_TYPE_CR);
|
||
|
||
newline_combo_append (GTK_COMBO_BOX (combo),
|
||
store,
|
||
&iter,
|
||
gedit_utils_newline_type_to_string (GTK_SOURCE_NEWLINE_TYPE_CR_LF),
|
||
GTK_SOURCE_NEWLINE_TYPE_CR_LF);
|
||
|
||
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
|
||
|
||
gtk_box_pack_start (GTK_BOX (dialog->extra_widget),
|
||
label,
|
||
FALSE,
|
||
TRUE,
|
||
0);
|
||
|
||
gtk_box_pack_start (GTK_BOX (dialog->extra_widget),
|
||
combo,
|
||
TRUE,
|
||
TRUE,
|
||
0);
|
||
|
||
dialog->newline_combo = combo;
|
||
dialog->newline_label = label;
|
||
dialog->newline_store = store;
|
||
|
||
update_newline_visibility (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);
|
||
}
|
||
|
||
static void
|
||
action_changed (GeditFileChooserDialogGtk *dialog,
|
||
GParamSpec *pspec,
|
||
gpointer data)
|
||
{
|
||
GtkFileChooserAction action;
|
||
|
||
action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (dialog));
|
||
|
||
switch (action)
|
||
{
|
||
case GTK_FILE_CHOOSER_ACTION_OPEN:
|
||
g_object_set (dialog->option_menu,
|
||
"save_mode", FALSE,
|
||
NULL);
|
||
gtk_widget_show (dialog->option_menu);
|
||
break;
|
||
case GTK_FILE_CHOOSER_ACTION_SAVE:
|
||
g_object_set (dialog->option_menu,
|
||
"save_mode", TRUE,
|
||
NULL);
|
||
gtk_widget_show (dialog->option_menu);
|
||
break;
|
||
default:
|
||
gtk_widget_hide (dialog->option_menu);
|
||
}
|
||
|
||
update_newline_visibility (dialog);
|
||
}
|
||
|
||
static void
|
||
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",
|
||
G_CALLBACK (action_changed),
|
||
NULL);
|
||
|
||
/* FIXME: attention, there is a ref cycle here. This will be fixed when
|
||
* GeditFileChooserSave will be created (and this class removed).
|
||
*/
|
||
result->gedit_file_chooser = _gedit_file_chooser_new ();
|
||
_gedit_file_chooser_set_gtk_file_chooser (result->gedit_file_chooser,
|
||
GTK_FILE_CHOOSER (result));
|
||
|
||
if (parent != NULL)
|
||
{
|
||
gtk_window_set_transient_for (GTK_WINDOW (result), parent);
|
||
gtk_window_set_destroy_with_parent (GTK_WINDOW (result), TRUE);
|
||
}
|
||
|
||
gtk_dialog_add_button (GTK_DIALOG (result), cancel_label, GTK_RESPONSE_CANCEL);
|
||
gtk_dialog_add_button (GTK_DIALOG (result), accept_label, GTK_RESPONSE_ACCEPT);
|
||
gtk_dialog_set_default_response (GTK_DIALOG (result), GTK_RESPONSE_ACCEPT);
|
||
|
||
return GEDIT_FILE_CHOOSER_DIALOG (result);
|
||
}
|
||
|
||
/* ex:set ts=8 noet: */
|
||
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
|
||
@@ -6,40 +6,41 @@
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_FILE_CHOOSER_DIALOG_GTK_H
|
||
#define GEDIT_FILE_CHOOSER_DIALOG_GTK_H
|
||
|
||
#include <gtk/gtk.h>
|
||
#include "gedit-file-chooser-dialog.h"
|
||
|
||
G_BEGIN_DECLS
|
||
|
||
#define GEDIT_TYPE_FILE_CHOOSER_DIALOG_GTK (gedit_file_chooser_dialog_gtk_get_type ())
|
||
|
||
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
|
||
|
||
#endif /* GEDIT_FILE_CHOOSER_DIALOG_GTK_H */
|
||
|
||
/* ex:set ts=8 noet: */
|
||
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
|
||
@@ -35,67 +35,69 @@ confirm_overwrite_accumulator (GSignalInvocationHint *ihint,
|
||
|
||
conf = g_value_get_enum (handler_return);
|
||
g_value_set_enum (return_accu, conf);
|
||
continue_emission = (conf == GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM);
|
||
|
||
return continue_emission;
|
||
}
|
||
|
||
static void
|
||
gedit_file_chooser_dialog_default_init (GeditFileChooserDialogInterface *iface)
|
||
{
|
||
g_signal_new ("response",
|
||
G_TYPE_FROM_INTERFACE (iface),
|
||
G_SIGNAL_RUN_LAST,
|
||
0,
|
||
NULL, NULL, NULL,
|
||
G_TYPE_NONE,
|
||
1,
|
||
G_TYPE_INT);
|
||
|
||
g_signal_new ("confirm-overwrite",
|
||
G_TYPE_FROM_INTERFACE (iface),
|
||
G_SIGNAL_RUN_LAST,
|
||
0,
|
||
confirm_overwrite_accumulator, NULL, NULL,
|
||
GTK_TYPE_FILE_CHOOSER_CONFIRMATION,
|
||
0);
|
||
}
|
||
|
||
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);
|
||
}
|
||
|
||
void
|
||
gedit_file_chooser_dialog_set_encoding (GeditFileChooserDialog *dialog,
|
||
const GtkSourceEncoding *encoding)
|
||
{
|
||
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->set_encoding != NULL);
|
||
|
||
iface->set_encoding (dialog, encoding);
|
||
}
|
||
|
||
const GtkSourceEncoding *
|
||
gedit_file_chooser_dialog_get_encoding (GeditFileChooserDialog *dialog)
|
||
{
|
||
GeditFileChooserDialogInterface *iface;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_FILE_CHOOSER_DIALOG (dialog), NULL);
|
||
|
||
iface = GEDIT_FILE_CHOOSER_DIALOG_GET_IFACE (dialog);
|
||
g_return_val_if_fail (iface->get_encoding != NULL, NULL);
|
||
|
||
return iface->get_encoding (dialog);
|
||
}
|
||
@@ -184,75 +186,105 @@ gedit_file_chooser_dialog_get_file (GeditFileChooserDialog *dialog)
|
||
return iface->get_file (dialog);
|
||
}
|
||
|
||
void
|
||
gedit_file_chooser_dialog_set_do_overwrite_confirmation (GeditFileChooserDialog *dialog,
|
||
gboolean overwrite_confirmation)
|
||
{
|
||
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->set_do_overwrite_confirmation != NULL);
|
||
|
||
iface->set_do_overwrite_confirmation (dialog, overwrite_confirmation);
|
||
}
|
||
|
||
void
|
||
gedit_file_chooser_dialog_show (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->show != NULL);
|
||
|
||
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)
|
||
{
|
||
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->destroy != NULL);
|
||
|
||
iface->destroy (dialog);
|
||
}
|
||
|
||
void
|
||
gedit_file_chooser_dialog_set_modal (GeditFileChooserDialog *dialog,
|
||
gboolean is_modal)
|
||
{
|
||
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->set_modal != NULL);
|
||
|
||
iface->set_modal (dialog, is_modal);
|
||
}
|
||
|
||
GtkWindow *
|
||
gedit_file_chooser_dialog_get_window (GeditFileChooserDialog *dialog)
|
||
{
|
||
GeditFileChooserDialogInterface *iface;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_FILE_CHOOSER_DIALOG (dialog), NULL);
|
||
|
||
iface = GEDIT_FILE_CHOOSER_DIALOG_GET_IFACE (dialog);
|
||
|
||
if (iface->get_window)
|
||
{
|
||
return iface->get_window (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
|
||
@@ -37,87 +37,104 @@ struct _GeditFileChooserDialogInterface
|
||
|
||
/* Virtual public methods */
|
||
void (*set_encoding) (GeditFileChooserDialog *dialog,
|
||
const GtkSourceEncoding *encoding);
|
||
|
||
const GtkSourceEncoding *
|
||
(*get_encoding) (GeditFileChooserDialog *dialog);
|
||
|
||
void (*set_newline_type) (GeditFileChooserDialog *dialog,
|
||
GtkSourceNewlineType newline_type);
|
||
|
||
GtkSourceNewlineType
|
||
(*get_newline_type) (GeditFileChooserDialog *dialog);
|
||
|
||
void (*set_current_folder) (GeditFileChooserDialog *dialog,
|
||
GFile *folder);
|
||
|
||
void (*set_current_name) (GeditFileChooserDialog *dialog,
|
||
const gchar *name);
|
||
|
||
void (*set_file) (GeditFileChooserDialog *dialog,
|
||
GFile *file);
|
||
|
||
GFile * (*get_file) (GeditFileChooserDialog *dialog);
|
||
|
||
void (*set_do_overwrite_confirmation)
|
||
(GeditFileChooserDialog *dialog,
|
||
gboolean overwrite_confirmation);
|
||
|
||
void (*show) (GeditFileChooserDialog *dialog);
|
||
+ void (*hide) (GeditFileChooserDialog *dialog);
|
||
|
||
void (*destroy) (GeditFileChooserDialog *dialog);
|
||
|
||
void (*set_modal) (GeditFileChooserDialog *dialog,
|
||
gboolean is_modal);
|
||
|
||
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);
|
||
|
||
void gedit_file_chooser_dialog_destroy (GeditFileChooserDialog *dialog);
|
||
|
||
void gedit_file_chooser_dialog_set_encoding (GeditFileChooserDialog *dialog,
|
||
const GtkSourceEncoding *encoding);
|
||
|
||
const GtkSourceEncoding *
|
||
gedit_file_chooser_dialog_get_encoding (GeditFileChooserDialog *dialog);
|
||
|
||
void gedit_file_chooser_dialog_set_newline_type (GeditFileChooserDialog *dialog,
|
||
GtkSourceNewlineType newline_type);
|
||
|
||
GtkSourceNewlineType
|
||
gedit_file_chooser_dialog_get_newline_type (GeditFileChooserDialog *dialog);
|
||
|
||
void gedit_file_chooser_dialog_set_current_folder (GeditFileChooserDialog *dialog,
|
||
GFile *folder);
|
||
|
||
void gedit_file_chooser_dialog_set_current_name (GeditFileChooserDialog *dialog,
|
||
const gchar *name);
|
||
|
||
void gedit_file_chooser_dialog_set_file (GeditFileChooserDialog *dialog,
|
||
GFile *file);
|
||
|
||
GFile *gedit_file_chooser_dialog_get_file (GeditFileChooserDialog *dialog);
|
||
|
||
void gedit_file_chooser_dialog_set_do_overwrite_confirmation (
|
||
GeditFileChooserDialog *dialog,
|
||
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 */
|
||
|
||
/* ex:set ts=8 noet: */
|
||
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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+
|
||
+#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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#include "gedit-highlight-mode-selector.h"
|
||
+#include <glib/gi18n.h>
|
||
+
|
||
+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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#ifndef GEDIT_HIGHLIGHT_MODE_SELECTOR_H
|
||
+#define GEDIT_HIGHLIGHT_MODE_SELECTOR_H
|
||
+
|
||
+#include <gtksourceview/gtksource.h>
|
||
+
|
||
+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 1edbe313a..1539e3b7b 100644
|
||
--- a/gedit/gedit-io-error-info-bar.c
|
||
+++ b/gedit/gedit-io-error-info-bar.c
|
||
@@ -1,58 +1,65 @@
|
||
/*
|
||
* gedit-io-error-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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
/*
|
||
* Verbose error reporting for file I/O operations (load, save, revert, create)
|
||
*/
|
||
|
||
#include "gedit-io-error-info-bar.h"
|
||
+
|
||
+#include <errno.h>
|
||
+#include <string.h>
|
||
#include <glib/gi18n.h>
|
||
-#include <tepl/tepl.h>
|
||
+#include <gio/gio.h>
|
||
+
|
||
#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
|
||
|
||
static gboolean
|
||
is_recoverable_error (const GError *error)
|
||
{
|
||
gboolean is_recoverable = FALSE;
|
||
|
||
if (error->domain == G_IO_ERROR)
|
||
{
|
||
switch (error->code)
|
||
{
|
||
case G_IO_ERROR_PERMISSION_DENIED:
|
||
case G_IO_ERROR_NOT_FOUND:
|
||
case G_IO_ERROR_HOST_NOT_FOUND:
|
||
case G_IO_ERROR_TIMED_OUT:
|
||
case G_IO_ERROR_NOT_MOUNTABLE_FILE:
|
||
case G_IO_ERROR_NOT_MOUNTED:
|
||
case G_IO_ERROR_BUSY:
|
||
is_recoverable = TRUE;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
return is_recoverable;
|
||
}
|
||
|
||
static gboolean
|
||
@@ -193,61 +200,61 @@ parse_gio_error (gint code,
|
||
|
||
case G_IO_ERROR_IS_DIRECTORY:
|
||
*error_message = g_strdup_printf (_("“%s” is a directory."),
|
||
uri_for_display);
|
||
*message_details = g_strdup (_("Please check that you typed the "
|
||
"location correctly and try again."));
|
||
break;
|
||
|
||
case G_IO_ERROR_INVALID_FILENAME:
|
||
*error_message = g_strdup_printf (_("“%s” is not a valid location."),
|
||
uri_for_display);
|
||
*message_details = g_strdup (_("Please check that you typed the "
|
||
"location correctly and try again."));
|
||
break;
|
||
|
||
case G_IO_ERROR_HOST_NOT_FOUND:
|
||
/* This case can be hit for user-typed strings like "foo" due to
|
||
* the code that guesses web addresses when there's no initial "/".
|
||
* But this case is also hit for legitimate web addresses when
|
||
* the proxy is set up wrong.
|
||
*/
|
||
{
|
||
gchar *hn = NULL;
|
||
gchar *uri = NULL;
|
||
|
||
if (location)
|
||
{
|
||
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)
|
||
{
|
||
gchar *host_markup;
|
||
gchar *host_name;
|
||
|
||
host_name = g_utf8_make_valid (hn, -1);
|
||
g_free (hn);
|
||
|
||
host_markup = g_markup_escape_text (host_name, -1);
|
||
g_free (host_name);
|
||
|
||
*message_details = g_strdup_printf (
|
||
/* Translators: %s is a host name */
|
||
_("Host “%s” could not be found. "
|
||
"Please check that your proxy settings "
|
||
"are correct and try again."),
|
||
host_markup);
|
||
|
||
g_free (host_markup);
|
||
}
|
||
}
|
||
|
||
g_free (uri);
|
||
|
||
if (!*message_details)
|
||
{
|
||
/* use the same string as INVALID_HOST */
|
||
*message_details = g_strdup_printf (
|
||
_("Hostname was invalid. "
|
||
@@ -296,62 +303,62 @@ parse_error (const GError *error,
|
||
{
|
||
g_warning ("Hit unhandled case %d (%s) in %s.",
|
||
error->code, error->message, G_STRFUNC);
|
||
*message_details = g_strdup_printf (_("Unexpected error: %s"),
|
||
error->message);
|
||
}
|
||
}
|
||
|
||
GtkWidget *
|
||
gedit_unrecoverable_reverting_error_info_bar_new (GFile *location,
|
||
const GError *error)
|
||
{
|
||
gchar *error_message = NULL;
|
||
gchar *message_details = NULL;
|
||
gchar *full_formatted_uri;
|
||
gchar *uri_for_display;
|
||
gchar *temp_uri_for_display;
|
||
GtkWidget *info_bar;
|
||
|
||
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 == GTK_SOURCE_FILE_LOADER_ERROR ||
|
||
error->domain == G_IO_ERROR, 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 = 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);
|
||
g_free (temp_uri_for_display);
|
||
|
||
if (is_gio_error (error, G_IO_ERROR_NOT_FOUND))
|
||
{
|
||
message_details = g_strdup (_("Cannot find the requested file. "
|
||
"Perhaps it has recently been deleted."));
|
||
}
|
||
else
|
||
{
|
||
parse_error (error, &error_message, &message_details, location, uri_for_display);
|
||
}
|
||
|
||
if (error_message == NULL)
|
||
{
|
||
error_message = g_strdup_printf (_("Could not revert the file “%s”."),
|
||
uri_for_display);
|
||
}
|
||
|
||
info_bar = create_io_loading_error_info_bar (error_message,
|
||
message_details,
|
||
FALSE);
|
||
|
||
g_free (uri_for_display);
|
||
g_free (error_message);
|
||
g_free (message_details);
|
||
|
||
return info_bar;
|
||
@@ -472,62 +479,62 @@ gedit_io_loading_error_info_bar_new (GFile *location,
|
||
const GtkSourceEncoding *encoding,
|
||
const GError *error)
|
||
{
|
||
gchar *error_message = NULL;
|
||
gchar *message_details = NULL;
|
||
gchar *full_formatted_uri;
|
||
gchar *uri_for_display;
|
||
gchar *temp_uri_for_display;
|
||
GtkWidget *info_bar;
|
||
gboolean edit_anyway = FALSE;
|
||
gboolean convert_error = FALSE;
|
||
|
||
g_return_val_if_fail (error != NULL, NULL);
|
||
g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_LOADER_ERROR ||
|
||
error->domain == G_IO_ERROR ||
|
||
error->domain == G_CONVERT_ERROR, NULL);
|
||
|
||
if (location != NULL)
|
||
{
|
||
full_formatted_uri = g_file_get_parse_name (location);
|
||
}
|
||
else
|
||
{
|
||
full_formatted_uri = g_strdup ("stdin");
|
||
}
|
||
|
||
/* 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 = 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);
|
||
g_free (temp_uri_for_display);
|
||
|
||
if (is_gio_error (error, G_IO_ERROR_TOO_MANY_LINKS))
|
||
{
|
||
message_details = g_strdup (_("The number of followed links is limited and the actual file could not be found within this limit."));
|
||
}
|
||
else if (is_gio_error (error, G_IO_ERROR_PERMISSION_DENIED))
|
||
{
|
||
message_details = g_strdup (_("You do not have the permissions necessary to open the file."));
|
||
}
|
||
else if ((is_gio_error (error, G_IO_ERROR_INVALID_DATA) && encoding == NULL) ||
|
||
(error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
|
||
error->code == GTK_SOURCE_FILE_LOADER_ERROR_ENCODING_AUTO_DETECTION_FAILED))
|
||
{
|
||
message_details = g_strconcat (_("Unable to detect the character encoding."), "\n",
|
||
_("Please check that you are not trying to open a binary file."), "\n",
|
||
_("Select a character encoding from the menu and try again."), NULL);
|
||
convert_error = TRUE;
|
||
}
|
||
else if (error->domain == GTK_SOURCE_FILE_LOADER_ERROR &&
|
||
error->code == GTK_SOURCE_FILE_LOADER_ERROR_CONVERSION_FALLBACK)
|
||
{
|
||
error_message = g_strdup_printf (_("There was a problem opening the file “%s”."),
|
||
uri_for_display);
|
||
message_details = g_strconcat (_("The file you opened has some invalid characters. "
|
||
"If you continue editing this file you could corrupt this "
|
||
"document."), "\n",
|
||
@@ -578,219 +585,405 @@ gedit_io_loading_error_info_bar_new (GFile *location,
|
||
g_free (message_details);
|
||
|
||
return info_bar;
|
||
}
|
||
|
||
GtkWidget *
|
||
gedit_conversion_error_while_saving_info_bar_new (GFile *location,
|
||
const GtkSourceEncoding *encoding,
|
||
const GError *error)
|
||
{
|
||
gchar *error_message = NULL;
|
||
gchar *message_details = NULL;
|
||
gchar *full_formatted_uri;
|
||
gchar *encoding_name;
|
||
gchar *uri_for_display;
|
||
gchar *temp_uri_for_display;
|
||
GtkWidget *info_bar;
|
||
|
||
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_CONVERT_ERROR ||
|
||
error->domain == G_IO_ERROR, NULL);
|
||
g_return_val_if_fail (encoding != NULL, 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 = 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);
|
||
g_free (temp_uri_for_display);
|
||
|
||
encoding_name = gtk_source_encoding_to_string (encoding);
|
||
|
||
error_message = g_strdup_printf (_("Could not save the file “%s” using the “%s” character encoding."),
|
||
uri_for_display,
|
||
encoding_name);
|
||
message_details = g_strconcat (_("The document contains one or more characters that cannot be encoded "
|
||
"using the specified character encoding."), "\n",
|
||
_("Select a different character encoding from the menu and try again."), NULL);
|
||
|
||
info_bar = create_conversion_error_info_bar (error_message,
|
||
message_details,
|
||
FALSE);
|
||
|
||
g_free (uri_for_display);
|
||
g_free (encoding_name);
|
||
g_free (error_message);
|
||
g_free (message_details);
|
||
|
||
return info_bar;
|
||
}
|
||
|
||
const GtkSourceEncoding *
|
||
gedit_conversion_error_info_bar_get_encoding (GtkWidget *info_bar)
|
||
{
|
||
gpointer menu;
|
||
|
||
g_return_val_if_fail (GTK_IS_INFO_BAR (info_bar), NULL);
|
||
|
||
menu = g_object_get_data (G_OBJECT (info_bar),
|
||
"gedit-info-bar-encoding-menu");
|
||
if (menu != NULL)
|
||
{
|
||
return gedit_encodings_combo_box_get_selected_encoding (GEDIT_ENCODINGS_COMBO_BOX (menu));
|
||
}
|
||
|
||
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 ("<b>%s</b>", 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 ("<small>%s</small>",
|
||
+ 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)
|
||
{
|
||
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);
|
||
g_return_val_if_fail (error != NULL, NULL);
|
||
g_return_val_if_fail (error->domain == GTK_SOURCE_FILE_SAVER_ERROR, NULL);
|
||
g_return_val_if_fail (error->code == GTK_SOURCE_FILE_SAVER_ERROR_EXTERNALLY_MODIFIED, 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 = 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);
|
||
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);
|
||
|
||
/* FIXME: review this message, it's not clear since for the user the "modification"
|
||
* could be interpreted as the changes he made in the document. beside "reading" is
|
||
* not accurate (since last load/save)
|
||
*/
|
||
primary_text = g_strdup_printf (_("The file “%s” has been modified since reading it."),
|
||
uri_for_display);
|
||
g_free (uri_for_display);
|
||
|
||
primary_markup = g_strdup_printf ("<b>%s</b>", 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 save it, all the external changes could be lost. Save it anyway?");
|
||
secondary_markup = g_strdup_printf ("<small>%s</small>",
|
||
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_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 ("<b>%s</b>", 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 ("<small>%s</small>",
|
||
+ 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)
|
||
{
|
||
gchar *error_message = NULL;
|
||
gchar *message_details = NULL;
|
||
gchar *full_formatted_uri;
|
||
gchar *scheme_string;
|
||
gchar *scheme_markup;
|
||
gchar *uri_for_display;
|
||
gchar *temp_uri_for_display;
|
||
GtkWidget *info_bar;
|
||
|
||
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 == GTK_SOURCE_FILE_SAVER_ERROR ||
|
||
error->domain == G_IO_ERROR, 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 = 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);
|
||
g_free (temp_uri_for_display);
|
||
|
||
if (is_gio_error (error, G_IO_ERROR_NOT_SUPPORTED))
|
||
{
|
||
scheme_string = g_file_get_uri_scheme (location);
|
||
|
||
if ((scheme_string != NULL) && g_utf8_validate (scheme_string, -1, NULL))
|
||
{
|
||
scheme_markup = g_markup_escape_text (scheme_string, -1);
|
||
|
||
/* Translators: %s is a URI scheme (like for example http:, ftp:, etc.) */
|
||
message_details = g_strdup_printf (_("Cannot handle “%s:” locations in write mode. "
|
||
"Please check that you typed the "
|
||
"location correctly and try again."),
|
||
scheme_markup);
|
||
g_free (scheme_markup);
|
||
}
|
||
else
|
||
{
|
||
message_details = g_strdup (_("Cannot handle this location in write mode. "
|
||
"Please check that you typed the "
|
||
"location correctly and try again."));
|
||
}
|
||
|
||
g_free (scheme_string);
|
||
}
|
||
else if (is_gio_error (error, G_IO_ERROR_INVALID_FILENAME))
|
||
@@ -840,31 +1033,176 @@ gedit_unrecoverable_saving_error_info_bar_new (GFile *location,
|
||
"a smaller file or saving it to a disk that does not "
|
||
"have this limitation."));
|
||
}
|
||
#endif
|
||
else
|
||
{
|
||
parse_error (error,
|
||
&error_message,
|
||
&message_details,
|
||
location,
|
||
uri_for_display);
|
||
}
|
||
|
||
if (error_message == NULL)
|
||
{
|
||
error_message = g_strdup_printf (_("Could not save the file “%s”."),
|
||
uri_for_display);
|
||
}
|
||
|
||
info_bar = create_io_loading_error_info_bar (error_message,
|
||
message_details,
|
||
FALSE);
|
||
|
||
g_free (uri_for_display);
|
||
g_free (error_message);
|
||
g_free (message_details);
|
||
|
||
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 ("<b>%s</b>", 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 ("<small>%s</small>",
|
||
+ 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
|
||
@@ -12,41 +12,51 @@
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_IO_ERROR_INFO_BAR_H
|
||
#define GEDIT_IO_ERROR_INFO_BAR_H
|
||
|
||
#include <gtksourceview/gtksource.h>
|
||
|
||
G_BEGIN_DECLS
|
||
|
||
GtkWidget *gedit_io_loading_error_info_bar_new (GFile *location,
|
||
const GtkSourceEncoding *encoding,
|
||
const GError *error);
|
||
|
||
GtkWidget *gedit_unrecoverable_reverting_error_info_bar_new (GFile *location,
|
||
const GError *error);
|
||
|
||
GtkWidget *gedit_conversion_error_while_saving_info_bar_new (GFile *location,
|
||
const GtkSourceEncoding *encoding,
|
||
const GError *error);
|
||
|
||
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 */
|
||
|
||
/* ex:set ts=8 noet: */
|
||
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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#include "gedit-metadata-manager.h"
|
||
+#include <libxml/xmlreader.h>
|
||
+#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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#ifndef GEDIT_METADATA_MANAGER_H
|
||
+#define GEDIT_METADATA_MANAGER_H
|
||
+
|
||
+#include <gio/gio.h>
|
||
+
|
||
+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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#ifndef GEDIT_OPEN_DOCUMENT_SELECTOR_HELPER_H
|
||
+#define GEDIT_OPEN_DOCUMENT_SELECTOR_HELPER_H
|
||
+
|
||
+#include "gedit-open-document-selector.h"
|
||
+
|
||
+#include <glib-object.h>
|
||
+
|
||
+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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+/* 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 <time.h>
|
||
+
|
||
+#include <glib/gi18n.h>
|
||
+#include <gtk/gtk.h>
|
||
+
|
||
+#include <glib.h>
|
||
+#include <gio/gio.h>
|
||
+
|
||
+#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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#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 <glib-object.h>
|
||
+#include <gtk/gtk.h>
|
||
+
|
||
+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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#include "gedit-open-document-selector.h"
|
||
+#include "gedit-open-document-selector-store.h"
|
||
+#include "gedit-open-document-selector-helper.h"
|
||
+
|
||
+#include <time.h>
|
||
+
|
||
+#include <glib.h>
|
||
+#include <glib/gi18n.h>
|
||
+#include <gtk/gtk.h>
|
||
+
|
||
+#include <glib/gstdio.h>
|
||
+#include <gio/gio.h>
|
||
+
|
||
+#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, "</span>");
|
||
+ }
|
||
+ 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 ("<span weight =\"heavy\" foreground =\"%s\" background =\"%s\">",
|
||
+ 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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#ifndef GEDIT_OPEN_DOCUMENT_SELECTOR_H
|
||
+#define GEDIT_OPEN_DOCUMENT_SELECTOR_H
|
||
+
|
||
+#include <glib-object.h>
|
||
+#include "gedit-window.h"
|
||
+
|
||
+#include <gtk/gtk.h>
|
||
+
|
||
+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 <mclasen@redhat.com>
|
||
+ *
|
||
+ * 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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#ifndef GEDIT_PANGO_H
|
||
+#define GEDIT_PANGO_H
|
||
+
|
||
+#include <pango/pango.h>
|
||
+
|
||
+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
|
||
@@ -1,137 +1,148 @@
|
||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
|
||
/*
|
||
* gedit-preferences-dialog.c
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 2001-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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include "gedit-preferences-dialog.h"
|
||
|
||
+#include <stdio.h>
|
||
+#include <string.h>
|
||
+#include <errno.h>
|
||
+
|
||
#include <glib/gi18n.h>
|
||
#include <glib/gstdio.h>
|
||
-#include <tepl/tepl.h>
|
||
+#include <gtksourceview/gtksource.h>
|
||
#include <libpeas-gtk/peas-gtk.h>
|
||
|
||
+#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
|
||
* want two dialogs showing an inconsistent state of the
|
||
* preferences.
|
||
* When gedit_show_preferences_dialog is called and there
|
||
* is already a prefs dialog dialog open, it is reparented
|
||
* and shown.
|
||
*/
|
||
|
||
static GtkWidget *preferences_dialog = NULL;
|
||
|
||
#define GEDIT_SCHEME_ROW_ID_KEY "gedit-scheme-row-id"
|
||
|
||
#define GEDIT_TYPE_PREFERENCES_DIALOG (gedit_preferences_dialog_get_type())
|
||
|
||
G_DECLARE_FINAL_TYPE (GeditPreferencesDialog, gedit_preferences_dialog, GEDIT, PREFERENCES_DIALOG, GtkWindow)
|
||
|
||
enum
|
||
{
|
||
ID_COLUMN = 0,
|
||
NAME_COLUMN,
|
||
DESC_COLUMN,
|
||
NUM_COLUMNS
|
||
};
|
||
|
||
enum
|
||
{
|
||
CLOSE,
|
||
LAST_SIGNAL
|
||
};
|
||
|
||
static guint signals[LAST_SIGNAL];
|
||
|
||
struct _GeditPreferencesDialog
|
||
{
|
||
GtkWindow parent_instance;
|
||
|
||
GSettings *editor;
|
||
GSettings *uisettings; /* unfortunately our settings are split for historical reasons */
|
||
|
||
GtkWidget *notebook;
|
||
|
||
/* Font */
|
||
GtkWidget *default_font_checkbutton;
|
||
GtkWidget *font_button;
|
||
GtkWidget *font_grid;
|
||
|
||
/* Style Scheme */
|
||
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;
|
||
GtkWidget *insert_spaces_checkbutton;
|
||
|
||
/* Auto indentation */
|
||
GtkWidget *auto_indent_checkbutton;
|
||
|
||
/* Text Wrapping */
|
||
GtkWidget *wrap_text_checkbutton;
|
||
GtkWidget *split_checkbutton;
|
||
|
||
/* File Saving */
|
||
GtkWidget *backup_copy_checkbutton;
|
||
GtkWidget *auto_save_checkbutton;
|
||
GtkWidget *auto_save_spinbutton;
|
||
|
||
GtkWidget *display_line_numbers_checkbutton;
|
||
GtkWidget *display_statusbar_checkbutton;
|
||
+ GtkWidget *display_overview_map_checkbutton;
|
||
GtkWidget *display_grid_checkbutton;
|
||
|
||
/* Right margin */
|
||
GtkWidget *right_margin_checkbutton;
|
||
GtkWidget *right_margin_position_grid;
|
||
GtkWidget *right_margin_position_spinbutton;
|
||
|
||
/* Highlighting */
|
||
GtkWidget *highlight_current_line_checkbutton;
|
||
GtkWidget *bracket_matching_checkbutton;
|
||
|
||
/* Plugin manager */
|
||
GtkWidget *plugin_manager;
|
||
};
|
||
|
||
G_DEFINE_TYPE (GeditPreferencesDialog, gedit_preferences_dialog, GTK_TYPE_WINDOW)
|
||
|
||
static void
|
||
gedit_preferences_dialog_dispose (GObject *object)
|
||
{
|
||
GeditPreferencesDialog *dlg = GEDIT_PREFERENCES_DIALOG (object);
|
||
|
||
g_clear_object (&dlg->editor);
|
||
g_clear_object (&dlg->uisettings);
|
||
|
||
G_OBJECT_CLASS (gedit_preferences_dialog_parent_class)->dispose (object);
|
||
}
|
||
|
||
static void
|
||
gedit_preferences_dialog_close (GeditPreferencesDialog *dialog)
|
||
@@ -143,77 +154,79 @@ static void
|
||
gedit_preferences_dialog_class_init (GeditPreferencesDialogClass *klass)
|
||
{
|
||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||
GtkBindingSet *binding_set;
|
||
|
||
/* Otherwise libpeas-gtk might not be linked */
|
||
g_type_ensure (PEAS_GTK_TYPE_PLUGIN_MANAGER);
|
||
|
||
object_class->dispose = gedit_preferences_dialog_dispose;
|
||
|
||
signals[CLOSE] =
|
||
g_signal_new_class_handler ("close",
|
||
G_TYPE_FROM_CLASS (klass),
|
||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||
G_CALLBACK (gedit_preferences_dialog_close),
|
||
NULL, NULL, NULL,
|
||
G_TYPE_NONE,
|
||
0);
|
||
|
||
binding_set = gtk_binding_set_by_class (klass);
|
||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0);
|
||
|
||
/* Bind class to template */
|
||
gtk_widget_class_set_template_from_resource (widget_class,
|
||
"/org/gnome/gedit/ui/gedit-preferences-dialog.ui");
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, notebook);
|
||
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);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, highlight_current_line_checkbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, bracket_matching_checkbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, wrap_text_checkbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, split_checkbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, tabs_width_spinbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, insert_spaces_checkbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, auto_indent_checkbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, backup_copy_checkbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, auto_save_checkbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, auto_save_spinbutton);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, default_font_checkbutton);
|
||
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);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, plugin_manager);
|
||
}
|
||
|
||
static void
|
||
setup_editor_page (GeditPreferencesDialog *dlg)
|
||
{
|
||
gedit_debug (DEBUG_PREFS);
|
||
|
||
/* Connect signal */
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_TABS_SIZE,
|
||
dlg->tabs_width_spinbutton,
|
||
"value",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_INSERT_SPACES,
|
||
dlg->insert_spaces_checkbutton,
|
||
"active",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_AUTO_INDENT,
|
||
dlg->auto_indent_checkbutton,
|
||
"active",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_CREATE_BACKUP_COPY,
|
||
dlg->backup_copy_checkbutton,
|
||
@@ -359,488 +372,554 @@ setup_view_page (GeditPreferencesDialog *dlg)
|
||
gtk_toggle_button_set_inconsistent (
|
||
GTK_TOGGLE_BUTTON (dlg->split_checkbutton), TRUE);
|
||
}
|
||
|
||
gtk_toggle_button_set_active (
|
||
GTK_TOGGLE_BUTTON (dlg->right_margin_checkbutton),
|
||
display_right_margin);
|
||
gtk_toggle_button_set_active (
|
||
GTK_TOGGLE_BUTTON (dlg->display_grid_checkbutton),
|
||
background_pattern == GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID);
|
||
|
||
/* Set widgets sensitivity */
|
||
gtk_widget_set_sensitive (dlg->split_checkbutton,
|
||
(wrap_mode != GTK_WRAP_NONE));
|
||
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_DISPLAY_LINE_NUMBERS,
|
||
dlg->display_line_numbers_checkbutton,
|
||
"active",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_HIGHLIGHT_CURRENT_LINE,
|
||
dlg->highlight_current_line_checkbutton,
|
||
"active",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_settings_bind (dlg->uisettings,
|
||
GEDIT_SETTINGS_STATUSBAR_VISIBLE,
|
||
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,
|
||
"active",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_DISPLAY_RIGHT_MARGIN,
|
||
dlg->right_margin_position_grid,
|
||
"sensitive",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_RIGHT_MARGIN_POSITION,
|
||
dlg->right_margin_position_spinbutton,
|
||
"value",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_AUTO_SAVE_INTERVAL,
|
||
dlg->auto_save_spinbutton,
|
||
"value",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_signal_connect (dlg->wrap_text_checkbutton,
|
||
"toggled",
|
||
G_CALLBACK (wrap_mode_checkbutton_toggled),
|
||
dlg);
|
||
g_signal_connect (dlg->split_checkbutton,
|
||
"toggled",
|
||
G_CALLBACK (wrap_mode_checkbutton_toggled),
|
||
dlg);
|
||
g_signal_connect (dlg->display_grid_checkbutton,
|
||
"toggled",
|
||
G_CALLBACK (grid_checkbutton_toggled),
|
||
dlg);
|
||
}
|
||
|
||
static void
|
||
setup_font_colors_page_font_section (GeditPreferencesDialog *dlg)
|
||
{
|
||
GeditSettings *settings;
|
||
gchar *system_font = NULL;
|
||
gchar *label;
|
||
|
||
gedit_debug (DEBUG_PREFS);
|
||
|
||
gtk_widget_set_tooltip_text (dlg->font_button,
|
||
_("Click on this button to select the font to be used by the editor"));
|
||
|
||
/* 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);
|
||
gtk_button_set_label (GTK_BUTTON (dlg->default_font_checkbutton),
|
||
label);
|
||
g_free (system_font);
|
||
g_free (label);
|
||
|
||
/* Bind settings */
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_USE_DEFAULT_FONT,
|
||
dlg->default_font_checkbutton,
|
||
"active",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_USE_DEFAULT_FONT,
|
||
dlg->font_grid,
|
||
"sensitive",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET | G_SETTINGS_BIND_INVERT_BOOLEAN);
|
||
g_settings_bind (dlg->editor,
|
||
GEDIT_SETTINGS_EDITOR_FONT,
|
||
dlg->font_button,
|
||
"font-name",
|
||
G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
|
||
}
|
||
|
||
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)
|
||
{
|
||
GtkSourceStyleSchemeManager *manager;
|
||
const gchar *filename;
|
||
|
||
g_return_val_if_fail (GTK_SOURCE_IS_STYLE_SCHEME (scheme), FALSE);
|
||
|
||
manager = gtk_source_style_scheme_manager_get_default ();
|
||
|
||
filename = gtk_source_style_scheme_get_filename (scheme);
|
||
if (filename == NULL)
|
||
return FALSE;
|
||
|
||
if (g_unlink (filename) == -1)
|
||
return FALSE;
|
||
|
||
/* Reload the available style schemes */
|
||
gtk_source_style_scheme_manager_force_rescan (manager);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
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
|
||
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));
|
||
}
|
||
}
|
||
|
||
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);
|
||
|
||
/* 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",
|
||
G_CALLBACK (install_scheme_clicked),
|
||
dlg);
|
||
g_signal_connect (dlg->uninstall_scheme_button,
|
||
"clicked",
|
||
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
|
||
setup_font_colors_page (GeditPreferencesDialog *dlg)
|
||
{
|
||
setup_font_colors_page_font_section (dlg);
|
||
setup_font_colors_page_style_scheme_section (dlg);
|
||
}
|
||
|
||
static void
|
||
setup_plugins_page (GeditPreferencesDialog *dlg)
|
||
{
|
||
gtk_widget_show_all (dlg->plugin_manager);
|
||
}
|
||
|
||
static void
|
||
gedit_preferences_dialog_init (GeditPreferencesDialog *dlg)
|
||
{
|
||
gedit_debug (DEBUG_PREFS);
|
||
|
||
dlg->editor = g_settings_new ("org.gnome.gedit.preferences.editor");
|
||
dlg->uisettings = g_settings_new ("org.gnome.gedit.preferences.ui");
|
||
|
||
gtk_widget_init_template (GTK_WIDGET (dlg));
|
||
|
||
setup_editor_page (dlg);
|
||
setup_view_page (dlg);
|
||
setup_font_colors_page (dlg);
|
||
setup_plugins_page (dlg);
|
||
}
|
||
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
|
||
@@ -1,56 +1,56 @@
|
||
/*
|
||
* gedit-print-job.c
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 2000-2001 Chema Celorio, Paolo Maggi
|
||
* Copyright (C) 2002-2008 Paolo Maggi
|
||
* Copyright (C) 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
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "gedit-print-job.h"
|
||
|
||
#include <glib/gi18n.h>
|
||
-#include <tepl/tepl.h>
|
||
+#include <gtksourceview/gtksource.h>
|
||
|
||
#include "gedit-debug.h"
|
||
#include "gedit-document-private.h"
|
||
#include "gedit-print-preview.h"
|
||
#include "gedit-utils.h"
|
||
#include "gedit-dirs.h"
|
||
#include "gedit-settings.h"
|
||
|
||
struct _GeditPrintJob
|
||
{
|
||
GObject parent_instance;
|
||
|
||
GSettings *gsettings;
|
||
|
||
GeditView *view;
|
||
|
||
GtkPrintOperation *operation;
|
||
GtkSourcePrintCompositor *compositor;
|
||
|
||
GtkWidget *preview;
|
||
|
||
gchar *status_string;
|
||
gdouble progress;
|
||
|
||
/* Widgets part of the custom print preferences widget.
|
||
* These pointers are valid just when the dialog is displayed.
|
||
*/
|
||
GtkToggleButton *syntax_checkbutton;
|
||
GtkToggleButton *page_header_checkbutton;
|
||
GtkToggleButton *line_numbers_checkbutton;
|
||
@@ -508,61 +508,61 @@ create_compositor (GeditPrintJob *job)
|
||
"tab-width", tab_width,
|
||
"highlight-syntax", syntax_hl,
|
||
"wrap-mode", wrap_mode,
|
||
"print-line-numbers", print_line_numbers,
|
||
"print-header", print_header,
|
||
"print-footer", FALSE,
|
||
"body-font-name", print_font_body,
|
||
"line-numbers-font-name", print_font_numbers,
|
||
"header-font-name", print_font_header,
|
||
NULL));
|
||
|
||
margin = g_settings_get_double (job->gsettings, GEDIT_SETTINGS_PRINT_MARGIN_LEFT);
|
||
gtk_source_print_compositor_set_left_margin (job->compositor, margin, GTK_UNIT_MM);
|
||
|
||
margin = g_settings_get_double (job->gsettings, GEDIT_SETTINGS_PRINT_MARGIN_TOP);
|
||
gtk_source_print_compositor_set_top_margin (job->compositor, margin, GTK_UNIT_MM);
|
||
|
||
margin = g_settings_get_double (job->gsettings, GEDIT_SETTINGS_PRINT_MARGIN_RIGHT);
|
||
gtk_source_print_compositor_set_right_margin (job->compositor, margin, GTK_UNIT_MM);
|
||
|
||
margin = g_settings_get_double (job->gsettings, GEDIT_SETTINGS_PRINT_MARGIN_BOTTOM);
|
||
gtk_source_print_compositor_set_bottom_margin (job->compositor, margin, GTK_UNIT_MM);
|
||
|
||
if (print_header)
|
||
{
|
||
gchar *doc_name;
|
||
gchar *name_to_display;
|
||
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);
|
||
|
||
gtk_source_print_compositor_set_header_format (job->compositor,
|
||
TRUE,
|
||
left,
|
||
NULL,
|
||
/* Translators: %N is the current page number, %Q is the total
|
||
* number of pages (ex. Page 2 of 10)
|
||
*/
|
||
_("Page %N of %Q"));
|
||
|
||
g_free (doc_name);
|
||
g_free (name_to_display);
|
||
g_free (left);
|
||
}
|
||
|
||
g_free (print_font_body);
|
||
g_free (print_font_header);
|
||
g_free (print_font_numbers);
|
||
}
|
||
|
||
static void
|
||
begin_print_cb (GtkPrintOperation *operation,
|
||
GtkPrintContext *context,
|
||
GeditPrintJob *job)
|
||
{
|
||
create_compositor (job);
|
||
|
||
job->progress = 0.0;
|
||
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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#include "gedit-progress-info-bar.h"
|
||
+#include <glib/gi18n.h>
|
||
+
|
||
+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 <http://www.gnu.org/licenses/>.
|
||
+ */
|
||
+
|
||
+#ifndef GEDIT_PROGRESS_INFO_BAR_H
|
||
+#define GEDIT_PROGRESS_INFO_BAR_H
|
||
+
|
||
+#include <gtk/gtk.h>
|
||
+
|
||
+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 <http://www.gnu.org/licenses/>.
|
||
- */
|
||
-
|
||
-#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 <http://www.gnu.org/licenses/>.
|
||
- */
|
||
-
|
||
-#ifndef GEDIT_RECENT_OSX_H
|
||
-#define GEDIT_RECENT_OSX_H
|
||
-
|
||
-#include <gtk/gtk.h>
|
||
-
|
||
-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
|
||
@@ -1,92 +1,317 @@
|
||
/*
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "gedit-recent.h"
|
||
|
||
void
|
||
gedit_recent_add_document (GeditDocument *document)
|
||
{
|
||
- TeplFile *file;
|
||
+ GtkSourceFile *file;
|
||
GFile *location;
|
||
GtkRecentManager *recent_manager;
|
||
GtkRecentData recent_data;
|
||
gchar *uri;
|
||
static gchar *groups[2];
|
||
|
||
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)
|
||
{
|
||
return;
|
||
}
|
||
|
||
recent_manager = gtk_recent_manager_get_default ();
|
||
|
||
groups[0] = (gchar *) g_get_application_name ();
|
||
groups[1] = NULL;
|
||
|
||
recent_data.display_name = NULL;
|
||
recent_data.description = NULL;
|
||
recent_data.mime_type = gedit_document_get_mime_type (document);
|
||
recent_data.app_name = (gchar *) g_get_application_name ();
|
||
recent_data.app_exec = g_strjoin (" ", g_get_prgname (), "%u", NULL);
|
||
recent_data.groups = groups;
|
||
recent_data.is_private = FALSE;
|
||
|
||
uri = g_file_get_uri (location);
|
||
|
||
if (!gtk_recent_manager_add_full (recent_manager, uri, &recent_data))
|
||
{
|
||
g_warning ("Failed to add uri '%s' to the recent manager.", uri);
|
||
}
|
||
|
||
g_free (uri);
|
||
g_free (recent_data.app_exec);
|
||
g_free (recent_data.mime_type);
|
||
}
|
||
|
||
void
|
||
gedit_recent_remove_if_local (GFile *location)
|
||
{
|
||
g_return_if_fail (G_IS_FILE (location));
|
||
|
||
/* If a file is local chances are that if load/save fails the file has
|
||
* beed removed and the failure is permanent so we remove it from the
|
||
* list of recent files. For remote files the failure may be just
|
||
* transitory and we keep the file in the list.
|
||
*/
|
||
if (g_file_has_uri_scheme (location, "file"))
|
||
{
|
||
GtkRecentManager *recent_manager;
|
||
gchar *uri;
|
||
|
||
recent_manager = gtk_recent_manager_get_default ();
|
||
|
||
uri = g_file_get_uri (location);
|
||
gtk_recent_manager_remove_item (recent_manager, uri, NULL);
|
||
g_free (uri);
|
||
}
|
||
}
|
||
|
||
+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
|
||
@@ -1,38 +1,55 @@
|
||
/*
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_RECENT_H
|
||
#define GEDIT_RECENT_H
|
||
|
||
#include <gtk/gtk.h>
|
||
#include <gedit/gedit-document.h>
|
||
|
||
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
|
||
@@ -10,144 +10,184 @@
|
||
* 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, write to the Free Software
|
||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||
* Boston, MA 02110-1301 USA
|
||
*/
|
||
|
||
#include "gedit-settings.h"
|
||
#include <gtksourceview/gtksource.h>
|
||
#include "gedit-app.h"
|
||
|
||
#define GEDIT_SETTINGS_SYSTEM_FONT "monospace-font-name"
|
||
|
||
struct _GeditSettings
|
||
{
|
||
GObject parent_instance;
|
||
|
||
GSettings *settings_interface;
|
||
GSettings *settings_editor;
|
||
GSettings *settings_ui;
|
||
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)
|
||
|
||
static void
|
||
gedit_settings_dispose (GObject *object)
|
||
{
|
||
GeditSettings *self = GEDIT_SETTINGS (object);
|
||
|
||
g_clear_object (&self->settings_interface);
|
||
g_clear_object (&self->settings_editor);
|
||
g_clear_object (&self->settings_ui);
|
||
g_clear_object (&self->settings_file_chooser_state);
|
||
|
||
G_OBJECT_CLASS (gedit_settings_parent_class)->dispose (object);
|
||
}
|
||
|
||
static void
|
||
gedit_settings_finalize (GObject *object)
|
||
{
|
||
GeditSettings *self = GEDIT_SETTINGS (object);
|
||
|
||
if (singleton == self)
|
||
{
|
||
singleton = NULL;
|
||
}
|
||
|
||
G_OBJECT_CLASS (gedit_settings_parent_class)->finalize (object);
|
||
}
|
||
|
||
static void
|
||
gedit_settings_class_init (GeditSettingsClass *klass)
|
||
{
|
||
GObjectClass *object_class = G_OBJECT_CLASS (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);
|
||
}
|
||
}
|
||
|
||
static void
|
||
on_auto_save_changed (GSettings *settings,
|
||
const gchar *key,
|
||
GeditSettings *self)
|
||
{
|
||
gboolean auto_save;
|
||
GList *docs;
|
||
GList *l;
|
||
|
||
auto_save = g_settings_get_boolean (settings, key);
|
||
|
||
docs = gedit_app_get_documents (GEDIT_APP (g_application_get_default ()));
|
||
|
||
for (l = docs; l != NULL; l = l->next)
|
||
{
|
||
GeditTab *tab = gedit_tab_get_from_document (GEDIT_DOCUMENT (l->data));
|
||
gedit_tab_set_auto_save_enabled (tab, auto_save);
|
||
}
|
||
|
||
g_list_free (docs);
|
||
}
|
||
|
||
static void
|
||
on_auto_save_interval_changed (GSettings *settings,
|
||
const gchar *key,
|
||
GeditSettings *self)
|
||
{
|
||
@@ -180,163 +220,146 @@ on_syntax_highlighting_changed (GSettings *settings,
|
||
|
||
enable = g_settings_get_boolean (settings, key);
|
||
|
||
docs = gedit_app_get_documents (GEDIT_APP (g_application_get_default ()));
|
||
|
||
for (l = docs; l != NULL; l = l->next)
|
||
{
|
||
GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (l->data);
|
||
gtk_source_buffer_set_highlight_syntax (buffer, enable);
|
||
}
|
||
|
||
g_list_free (docs);
|
||
|
||
/* update the sensitivity of the Higlight Mode menu item */
|
||
windows = gedit_app_get_main_windows (GEDIT_APP (g_application_get_default ()));
|
||
|
||
for (l = windows; l != NULL; l = l->next)
|
||
{
|
||
GAction *action;
|
||
|
||
action = g_action_map_lookup_action (G_ACTION_MAP (l->data), "highlight-mode");
|
||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enable);
|
||
}
|
||
|
||
g_list_free (windows);
|
||
}
|
||
|
||
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 *
|
||
_gedit_settings_get_singleton (void)
|
||
{
|
||
if (singleton == NULL)
|
||
{
|
||
singleton = g_object_new (GEDIT_TYPE_SETTINGS, NULL);
|
||
}
|
||
|
||
return singleton;
|
||
}
|
||
|
||
void
|
||
gedit_settings_unref_singleton (void)
|
||
{
|
||
if (singleton != NULL)
|
||
{
|
||
g_object_unref (singleton);
|
||
}
|
||
|
||
/* singleton is not set to NULL here, it is set to NULL in
|
||
* gedit_settings_finalize() (i.e. when we are sure that the ref count
|
||
* reaches 0).
|
||
*/
|
||
}
|
||
|
||
GSettings *
|
||
_gedit_settings_peek_editor_settings (GeditSettings *self)
|
||
{
|
||
g_return_val_if_fail (GEDIT_IS_SETTINGS (self), NULL);
|
||
|
||
return self->settings_editor;
|
||
}
|
||
|
||
GSettings *
|
||
_gedit_settings_peek_file_chooser_state_settings (GeditSettings *self)
|
||
{
|
||
g_return_val_if_fail (GEDIT_IS_SETTINGS (self), NULL);
|
||
|
||
return self->settings_file_chooser_state;
|
||
}
|
||
|
||
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
|
||
strv_is_empty (gchar **strv)
|
||
{
|
||
if (strv == NULL || strv[0] == NULL)
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
/* Contains one empty string. */
|
||
if (strv[1] == NULL && strv[0][0] == '\0')
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
static GSList *
|
||
encoding_strv_to_list (const gchar * const *encoding_strv)
|
||
{
|
||
GSList *list = NULL;
|
||
gchar **p;
|
||
|
||
for (p = (gchar **)encoding_strv; p != NULL && *p != NULL; p++)
|
||
{
|
||
const gchar *charset = *p;
|
||
const GtkSourceEncoding *encoding;
|
||
|
||
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
|
||
@@ -16,90 +16,87 @@
|
||
* GNU General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with gedit; if not, write to the Free Software
|
||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||
* Boston, MA 02110-1301 USA
|
||
*/
|
||
|
||
#ifndef GEDIT_SETTINGS_H
|
||
#define GEDIT_SETTINGS_H
|
||
|
||
#include <gio/gio.h>
|
||
|
||
G_BEGIN_DECLS
|
||
|
||
#define GEDIT_TYPE_SETTINGS (gedit_settings_get_type ())
|
||
|
||
G_DECLARE_FINAL_TYPE (GeditSettings, gedit_settings, GEDIT, SETTINGS, GObject)
|
||
|
||
G_GNUC_INTERNAL
|
||
GeditSettings * _gedit_settings_get_singleton (void);
|
||
|
||
void gedit_settings_unref_singleton (void);
|
||
|
||
G_GNUC_INTERNAL
|
||
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);
|
||
|
||
/* key constants */
|
||
#define GEDIT_SETTINGS_USE_DEFAULT_FONT "use-default-font"
|
||
#define GEDIT_SETTINGS_EDITOR_FONT "editor-font"
|
||
#define GEDIT_SETTINGS_SCHEME "scheme"
|
||
#define GEDIT_SETTINGS_CREATE_BACKUP_COPY "create-backup-copy"
|
||
#define GEDIT_SETTINGS_AUTO_SAVE "auto-save"
|
||
#define GEDIT_SETTINGS_AUTO_SAVE_INTERVAL "auto-save-interval"
|
||
#define GEDIT_SETTINGS_MAX_UNDO_ACTIONS "max-undo-actions"
|
||
#define GEDIT_SETTINGS_WRAP_MODE "wrap-mode"
|
||
#define GEDIT_SETTINGS_WRAP_LAST_SPLIT_MODE "wrap-last-split-mode"
|
||
#define GEDIT_SETTINGS_TABS_SIZE "tabs-size"
|
||
#define GEDIT_SETTINGS_INSERT_SPACES "insert-spaces"
|
||
#define GEDIT_SETTINGS_AUTO_INDENT "auto-indent"
|
||
#define GEDIT_SETTINGS_DISPLAY_LINE_NUMBERS "display-line-numbers"
|
||
#define GEDIT_SETTINGS_HIGHLIGHT_CURRENT_LINE "highlight-current-line"
|
||
#define GEDIT_SETTINGS_BRACKET_MATCHING "bracket-matching"
|
||
#define GEDIT_SETTINGS_DISPLAY_RIGHT_MARGIN "display-right-margin"
|
||
#define GEDIT_SETTINGS_RIGHT_MARGIN_POSITION "right-margin-position"
|
||
#define GEDIT_SETTINGS_SMART_HOME_END "smart-home-end"
|
||
#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"
|
||
#define GEDIT_SETTINGS_BOTTOM_PANEL_VISIBLE "bottom-panel-visible"
|
||
#define GEDIT_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING "print-syntax-highlighting"
|
||
#define GEDIT_SETTINGS_PRINT_HEADER "print-header"
|
||
#define GEDIT_SETTINGS_PRINT_WRAP_MODE "print-wrap-mode"
|
||
#define GEDIT_SETTINGS_PRINT_LINE_NUMBERS "print-line-numbers"
|
||
#define GEDIT_SETTINGS_PRINT_FONT_BODY_PANGO "print-font-body-pango"
|
||
#define GEDIT_SETTINGS_PRINT_FONT_HEADER_PANGO "print-font-header-pango"
|
||
#define GEDIT_SETTINGS_PRINT_FONT_NUMBERS_PANGO "print-font-numbers-pango"
|
||
#define GEDIT_SETTINGS_PRINT_MARGIN_LEFT "margin-left"
|
||
#define GEDIT_SETTINGS_PRINT_MARGIN_TOP "margin-top"
|
||
#define GEDIT_SETTINGS_PRINT_MARGIN_RIGHT "margin-right"
|
||
#define GEDIT_SETTINGS_PRINT_MARGIN_BOTTOM "margin-bottom"
|
||
#define GEDIT_SETTINGS_CANDIDATE_ENCODINGS "candidate-encodings"
|
||
#define GEDIT_SETTINGS_ACTIVE_PLUGINS "active-plugins"
|
||
#define GEDIT_SETTINGS_ENSURE_TRAILING_NEWLINE "ensure-trailing-newline"
|
||
|
||
/* window state keys */
|
||
#define GEDIT_SETTINGS_WINDOW_STATE "state"
|
||
#define GEDIT_SETTINGS_WINDOW_SIZE "size"
|
||
#define GEDIT_SETTINGS_SHOW_TABS_MODE "show-tabs-mode"
|
||
#define GEDIT_SETTINGS_SIDE_PANEL_SIZE "side-panel-size"
|
||
#define GEDIT_SETTINGS_SIDE_PANEL_ACTIVE_PAGE "side-panel-active-page"
|
||
#define GEDIT_SETTINGS_BOTTOM_PANEL_SIZE "bottom-panel-size"
|
||
#define GEDIT_SETTINGS_BOTTOM_PANEL_ACTIVE_PAGE "bottom-panel-active-page"
|
||
|
||
/* file chooser state keys */
|
||
#define GEDIT_SETTINGS_ACTIVE_FILE_FILTER "filter-id"
|
||
diff --git a/gedit/gedit-tab.c b/gedit/gedit-tab.c
|
||
index af72864e2..6bb38b160 100644
|
||
--- a/gedit/gedit-tab.c
|
||
+++ b/gedit/gedit-tab.c
|
||
@@ -1,65 +1,65 @@
|
||
/*
|
||
* gedit-tab.c
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 2005 - Paolo Maggi
|
||
* 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
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "gedit-tab.h"
|
||
#include "gedit-tab-private.h"
|
||
|
||
#include <stdlib.h>
|
||
#include <glib/gi18n.h>
|
||
-#include <tepl/tepl.h>
|
||
|
||
#include "gedit-app.h"
|
||
#include "gedit-app-private.h"
|
||
#include "gedit-recent.h"
|
||
#include "gedit-utils.h"
|
||
#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"
|
||
#include "gedit-enum-types.h"
|
||
#include "gedit-settings.h"
|
||
#include "gedit-view-frame.h"
|
||
|
||
#define GEDIT_TAB_KEY "GEDIT_TAB_KEY"
|
||
|
||
struct _GeditTab
|
||
{
|
||
GtkBox parent_instance;
|
||
|
||
GeditTabState state;
|
||
|
||
GSettings *editor_settings;
|
||
|
||
GeditViewFrame *frame;
|
||
|
||
GtkWidget *info_bar;
|
||
GtkWidget *info_bar_hidden;
|
||
|
||
GeditPrintJob *print_job;
|
||
GtkWidget *print_preview;
|
||
|
||
GtkSourceFileSaverFlags save_flags;
|
||
|
||
guint idle_scroll;
|
||
|
||
gint auto_save_interval;
|
||
@@ -547,63 +547,63 @@ gedit_tab_set_state (GeditTab *tab,
|
||
if (state == GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW)
|
||
{
|
||
gtk_widget_hide (GTK_WIDGET (tab->frame));
|
||
}
|
||
else if (state != GEDIT_TAB_STATE_LOADING_ERROR)
|
||
{
|
||
gtk_widget_show (GTK_WIDGET (tab->frame));
|
||
}
|
||
|
||
set_cursor_according_to_state (GTK_TEXT_VIEW (gedit_tab_get_view (tab)),
|
||
state);
|
||
|
||
update_auto_save_timeout (tab);
|
||
|
||
g_object_notify_by_pspec (G_OBJECT (tab), properties[PROP_STATE]);
|
||
g_object_notify_by_pspec (G_OBJECT (tab), properties[PROP_CAN_CLOSE]);
|
||
}
|
||
|
||
static void
|
||
document_location_notify_handler (GtkSourceFile *file,
|
||
GParamSpec *pspec,
|
||
GeditTab *tab)
|
||
{
|
||
gedit_debug (DEBUG_TAB);
|
||
|
||
/* Notify the change in the location */
|
||
g_object_notify_by_pspec (G_OBJECT (tab), properties[PROP_NAME]);
|
||
}
|
||
|
||
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);
|
||
|
||
/* Notify the change in the shortname */
|
||
g_object_notify_by_pspec (G_OBJECT (tab), properties[PROP_NAME]);
|
||
}
|
||
|
||
static void
|
||
document_modified_changed (GtkTextBuffer *document,
|
||
GeditTab *tab)
|
||
{
|
||
g_object_notify_by_pspec (G_OBJECT (tab), properties[PROP_NAME]);
|
||
g_object_notify_by_pspec (G_OBJECT (tab), properties[PROP_CAN_CLOSE]);
|
||
}
|
||
|
||
static void
|
||
set_info_bar (GeditTab *tab,
|
||
GtkWidget *info_bar,
|
||
GtkResponseType default_response)
|
||
{
|
||
gedit_debug (DEBUG_TAB);
|
||
|
||
if (tab->info_bar == info_bar)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (info_bar == NULL)
|
||
{
|
||
/* Don't destroy the old info_bar right away,
|
||
@@ -699,369 +699,369 @@ io_loading_error_info_bar_response (GtkWidget *info_bar,
|
||
g_task_return_boolean (loading_task, FALSE);
|
||
g_object_unref (loading_task);
|
||
break;
|
||
}
|
||
}
|
||
|
||
static void
|
||
file_already_open_warning_info_bar_response (GtkWidget *info_bar,
|
||
gint response_id,
|
||
GeditTab *tab)
|
||
{
|
||
GeditView *view = gedit_tab_get_view (tab);
|
||
|
||
if (response_id == GTK_RESPONSE_YES)
|
||
{
|
||
set_editable (tab, TRUE);
|
||
}
|
||
|
||
set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
|
||
|
||
gtk_widget_grab_focus (GTK_WIDGET (view));
|
||
}
|
||
|
||
static void
|
||
load_cancelled (GtkWidget *bar,
|
||
gint response_id,
|
||
GTask *loading_task)
|
||
{
|
||
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);
|
||
}
|
||
|
||
static void
|
||
unrecoverable_reverting_error_info_bar_response (GtkWidget *info_bar,
|
||
gint response_id,
|
||
GTask *loading_task)
|
||
{
|
||
LoaderData *data = g_task_get_task_data (loading_task);
|
||
GeditView *view;
|
||
|
||
gedit_tab_set_state (data->tab, GEDIT_TAB_STATE_NORMAL);
|
||
|
||
set_info_bar (data->tab, NULL, GTK_RESPONSE_NONE);
|
||
|
||
view = gedit_tab_get_view (data->tab);
|
||
gtk_widget_grab_focus (GTK_WIDGET (view));
|
||
|
||
g_task_return_boolean (loading_task, FALSE);
|
||
g_object_unref (loading_task);
|
||
}
|
||
|
||
#define MAX_MSG_LENGTH 100
|
||
|
||
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;
|
||
gchar *msg = NULL;
|
||
gchar *name_markup;
|
||
gchar *dirname_markup;
|
||
gint len;
|
||
|
||
if (data->tab->info_bar != NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
gedit_debug (DEBUG_TAB);
|
||
|
||
doc = gedit_tab_get_document (data->tab);
|
||
|
||
name = gedit_document_get_short_name_for_display (doc);
|
||
len = g_utf8_strlen (name, -1);
|
||
|
||
/* if the name is awfully long, truncate it and be done with it,
|
||
* otherwise also show the directory (ellipsized if needed)
|
||
*/
|
||
if (len > MAX_MSG_LENGTH)
|
||
{
|
||
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;
|
||
}
|
||
else
|
||
{
|
||
GtkSourceFile *file = gedit_document_get_file (doc);
|
||
GFile *location = gtk_source_file_get_location (file);
|
||
|
||
if (location != NULL)
|
||
{
|
||
gchar *str = gedit_utils_location_get_dirname_for_display (location);
|
||
|
||
/* use the remaining space for the dir, but use a min of 20 chars
|
||
* so that we do not end up with a dirname like "(a...b)".
|
||
* This means that in the worst case when the filename is long 99
|
||
* 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);
|
||
}
|
||
}
|
||
|
||
name_markup = g_markup_printf_escaped ("<b>%s</b>", name);
|
||
|
||
if (data->tab->state == GEDIT_TAB_STATE_REVERTING)
|
||
{
|
||
if (dirname != NULL)
|
||
{
|
||
dirname_markup = g_markup_printf_escaped ("<b>%s</b>", dirname);
|
||
|
||
/* Translators: the first %s is a file name (e.g. test.txt) the second one
|
||
is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
|
||
msg = g_strdup_printf (_("Reverting %s from %s"),
|
||
name_markup,
|
||
dirname_markup);
|
||
g_free (dirname_markup);
|
||
}
|
||
else
|
||
{
|
||
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
|
||
{
|
||
if (dirname != NULL)
|
||
{
|
||
dirname_markup = g_markup_printf_escaped ("<b>%s</b>", dirname);
|
||
|
||
/* Translators: the first %s is a file name (e.g. test.txt) the second one
|
||
is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
|
||
msg = g_strdup_printf (_("Loading %s from %s"),
|
||
name_markup,
|
||
dirname_markup);
|
||
g_free (dirname_markup);
|
||
}
|
||
else
|
||
{
|
||
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,
|
||
"response",
|
||
G_CALLBACK (load_cancelled),
|
||
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);
|
||
g_free (name_markup);
|
||
g_free (dirname);
|
||
}
|
||
|
||
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;
|
||
gchar *to = NULL;
|
||
gchar *from_markup;
|
||
gchar *to_markup;
|
||
gchar *msg = NULL;
|
||
gint len;
|
||
|
||
if (tab->info_bar != NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
gedit_debug (DEBUG_TAB);
|
||
|
||
doc = gedit_tab_get_document (tab);
|
||
|
||
short_name = gedit_document_get_short_name_for_display (doc);
|
||
|
||
len = g_utf8_strlen (short_name, -1);
|
||
|
||
/* if the name is awfully long, truncate it and be done with it,
|
||
* otherwise also show the directory (ellipsized if needed)
|
||
*/
|
||
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
|
||
{
|
||
gchar *str;
|
||
SaverData *data;
|
||
GFile *location;
|
||
|
||
data = g_task_get_task_data (saving_task);
|
||
location = gtk_source_file_saver_get_location (data->saver);
|
||
|
||
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;
|
||
}
|
||
|
||
from_markup = g_markup_printf_escaped ("<b>%s</b>", from);
|
||
|
||
if (to != NULL)
|
||
{
|
||
to_markup = g_markup_printf_escaped ("<b>%s</b>", to);
|
||
|
||
/* Translators: the first %s is a file name (e.g. test.txt) the second one
|
||
is a directory (e.g. ssh://master.gnome.org/home/users/paolo) */
|
||
msg = g_strdup_printf (_("Saving %s to %s"), from_markup, to_markup);
|
||
g_free (to_markup);
|
||
}
|
||
else
|
||
{
|
||
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);
|
||
g_free (from);
|
||
g_free (from_markup);
|
||
}
|
||
|
||
static void
|
||
info_bar_set_progress (GeditTab *tab,
|
||
goffset size,
|
||
goffset total_size)
|
||
{
|
||
- TeplProgressInfoBar *progress_info_bar;
|
||
+ GeditProgressInfoBar *progress_info_bar;
|
||
|
||
if (tab->info_bar == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
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);
|
||
}
|
||
}
|
||
|
||
/* Returns whether progress info should be shown. */
|
||
static gboolean
|
||
should_show_progress_info (GTimer **timer,
|
||
goffset size,
|
||
goffset total_size)
|
||
{
|
||
gdouble elapsed_time;
|
||
gdouble total_time;
|
||
gdouble remaining_time;
|
||
|
||
g_assert (timer != NULL);
|
||
|
||
if (*timer == NULL)
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
elapsed_time = g_timer_elapsed (*timer, NULL);
|
||
|
||
/* Wait a little, because at the very beginning it's maybe not very
|
||
* accurate (it takes initially more time for the first bytes, the
|
||
* following chunks should arrive more quickly, as a rough guess).
|
||
*/
|
||
if (elapsed_time < 0.5)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
/* elapsed_time / total_time = size / total_size */
|
||
total_time = (elapsed_time * total_size) / size;
|
||
|
||
remaining_time = total_time - elapsed_time;
|
||
|
||
/* Approximately more than 3 seconds remaining. */
|
||
if (remaining_time > 3.0)
|
||
{
|
||
/* Once the progress info bar is shown, it must remain
|
||
* shown until the end, so we don't need the timer
|
||
* anymore.
|
||
*/
|
||
g_timer_destroy (*timer);
|
||
*timer = NULL;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
return FALSE;
|
||
}
|
||
|
||
static gboolean
|
||
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;
|
||
}
|
||
|
||
static void
|
||
unrecoverable_saving_error_info_bar_response (GtkWidget *info_bar,
|
||
gint response_id,
|
||
GTask *saving_task)
|
||
{
|
||
GeditTab *tab = g_task_get_source_object (saving_task);
|
||
GeditView *view;
|
||
|
||
gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
|
||
|
||
set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
|
||
|
||
view = gedit_tab_get_view (tab);
|
||
gtk_widget_grab_focus (GTK_WIDGET (view));
|
||
|
||
g_task_return_boolean (saving_task, FALSE);
|
||
g_object_unref (saving_task);
|
||
}
|
||
|
||
/* Sets the save flags after an info bar response. */
|
||
static void
|
||
response_set_save_flags (GTask *saving_task,
|
||
GtkSourceFileSaverFlags save_flags)
|
||
{
|
||
GeditTab *tab = g_task_get_source_object (saving_task);
|
||
@@ -1091,63 +1091,63 @@ response_set_save_flags (GTask *saving_task,
|
||
static void
|
||
invalid_character_info_bar_response (GtkWidget *info_bar,
|
||
gint response_id,
|
||
GTask *saving_task)
|
||
{
|
||
if (response_id == GTK_RESPONSE_YES)
|
||
{
|
||
GeditTab *tab = g_task_get_source_object (saving_task);
|
||
SaverData *data = g_task_get_task_data (saving_task);
|
||
GtkSourceFileSaverFlags save_flags;
|
||
|
||
set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
|
||
|
||
/* Don't bug the user again with this... */
|
||
tab->save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS;
|
||
|
||
save_flags = gtk_source_file_saver_get_flags (data->saver);
|
||
save_flags |= GTK_SOURCE_FILE_SAVER_FLAGS_IGNORE_INVALID_CHARS;
|
||
response_set_save_flags (saving_task, save_flags);
|
||
|
||
/* Force saving */
|
||
launch_saver (saving_task);
|
||
}
|
||
else
|
||
{
|
||
unrecoverable_saving_error_info_bar_response (info_bar, response_id, saving_task);
|
||
}
|
||
}
|
||
|
||
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)
|
||
{
|
||
GeditTab *tab = g_task_get_source_object (saving_task);
|
||
SaverData *data = g_task_get_task_data (saving_task);
|
||
GtkSourceFileSaverFlags save_flags;
|
||
|
||
set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
|
||
|
||
data->force_no_backup = TRUE;
|
||
save_flags = gtk_source_file_saver_get_flags (data->saver);
|
||
response_set_save_flags (saving_task, save_flags);
|
||
|
||
/* Force saving */
|
||
launch_saver (saving_task);
|
||
}
|
||
else
|
||
{
|
||
unrecoverable_saving_error_info_bar_response (info_bar, response_id, saving_task);
|
||
}
|
||
}
|
||
|
||
static void
|
||
externally_modified_error_info_bar_response (GtkWidget *info_bar,
|
||
gint response_id,
|
||
GTask *saving_task)
|
||
{
|
||
if (response_id == GTK_RESPONSE_YES)
|
||
{
|
||
GeditTab *tab = g_task_get_source_object (saving_task);
|
||
@@ -1199,77 +1199,77 @@ recoverable_saving_error_info_bar_response (GtkWidget *info_bar,
|
||
|
||
static void
|
||
externally_modified_notification_info_bar_response (GtkWidget *info_bar,
|
||
gint response_id,
|
||
GeditTab *tab)
|
||
{
|
||
GeditView *view;
|
||
|
||
set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
|
||
|
||
view = gedit_tab_get_view (tab);
|
||
|
||
if (response_id == GTK_RESPONSE_OK)
|
||
{
|
||
_gedit_tab_revert (tab);
|
||
}
|
||
else
|
||
{
|
||
tab->ask_if_externally_modified = FALSE;
|
||
|
||
/* go back to normal state */
|
||
gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
|
||
}
|
||
|
||
gtk_widget_grab_focus (GTK_WIDGET (view));
|
||
}
|
||
|
||
static void
|
||
display_externally_modified_notification (GeditTab *tab)
|
||
{
|
||
- TeplInfoBar *info_bar;
|
||
+ GtkWidget *info_bar;
|
||
GeditDocument *doc;
|
||
GtkSourceFile *file;
|
||
GFile *location;
|
||
gboolean document_modified;
|
||
|
||
doc = gedit_tab_get_document (tab);
|
||
file = gedit_document_get_file (doc);
|
||
|
||
/* we're here because the file we're editing changed on disk */
|
||
location = gtk_source_file_get_location (file);
|
||
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",
|
||
G_CALLBACK (externally_modified_notification_info_bar_response),
|
||
tab);
|
||
}
|
||
|
||
static gboolean
|
||
view_focused_in (GtkWidget *widget,
|
||
GdkEventFocus *event,
|
||
GeditTab *tab)
|
||
{
|
||
GeditDocument *doc;
|
||
GtkSourceFile *file;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_TAB (tab), GDK_EVENT_PROPAGATE);
|
||
|
||
/* we try to detect file changes only in the normal state */
|
||
if (tab->state != GEDIT_TAB_STATE_NORMAL)
|
||
{
|
||
return GDK_EVENT_PROPAGATE;
|
||
}
|
||
|
||
/* we already asked, don't bug the user again */
|
||
if (!tab->ask_if_externally_modified)
|
||
{
|
||
return GDK_EVENT_PROPAGATE;
|
||
}
|
||
|
||
doc = gedit_tab_get_document (tab);
|
||
@@ -1280,104 +1280,101 @@ view_focused_in (GtkWidget *widget,
|
||
{
|
||
gtk_source_file_check_file_on_disk (file);
|
||
|
||
if (gtk_source_file_is_externally_modified (file))
|
||
{
|
||
gedit_tab_set_state (tab, GEDIT_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION);
|
||
|
||
display_externally_modified_notification (tab);
|
||
}
|
||
}
|
||
|
||
return GDK_EVENT_PROPAGATE;
|
||
}
|
||
|
||
static void
|
||
on_drop_uris (GeditView *view,
|
||
gchar **uri_list,
|
||
GeditTab *tab)
|
||
{
|
||
g_signal_emit (G_OBJECT (tab), signals[DROP_URIS], 0, uri_list);
|
||
}
|
||
|
||
static void
|
||
gedit_tab_init (GeditTab *tab)
|
||
{
|
||
gboolean auto_save;
|
||
gint auto_save_interval;
|
||
GeditDocument *doc;
|
||
GeditView *view;
|
||
GtkSourceFile *file;
|
||
- TeplFile *tepl_file;
|
||
|
||
tab->state = GEDIT_TAB_STATE_NORMAL;
|
||
|
||
tab->editor_settings = g_settings_new ("org.gnome.gedit.preferences.editor");
|
||
|
||
tab->editable = TRUE;
|
||
|
||
tab->ask_if_externally_modified = TRUE;
|
||
|
||
gtk_orientable_set_orientation (GTK_ORIENTABLE (tab),
|
||
GTK_ORIENTATION_VERTICAL);
|
||
|
||
/* Manage auto save data */
|
||
auto_save = g_settings_get_boolean (tab->editor_settings,
|
||
GEDIT_SETTINGS_AUTO_SAVE);
|
||
g_settings_get (tab->editor_settings, GEDIT_SETTINGS_AUTO_SAVE_INTERVAL,
|
||
"u", &auto_save_interval);
|
||
tab->auto_save = auto_save != FALSE;
|
||
tab->auto_save_interval = auto_save_interval;
|
||
|
||
/* Create the frame */
|
||
tab->frame = gedit_view_frame_new ();
|
||
gtk_widget_show (GTK_WIDGET (tab->frame));
|
||
|
||
gtk_box_pack_end (GTK_BOX (tab), GTK_WIDGET (tab->frame), TRUE, TRUE, 0);
|
||
|
||
doc = gedit_tab_get_document (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",
|
||
G_CALLBACK (document_location_notify_handler),
|
||
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",
|
||
G_CALLBACK (document_modified_changed),
|
||
tab);
|
||
|
||
view = gedit_tab_get_view (tab);
|
||
|
||
g_signal_connect_after (view,
|
||
"focus-in-event",
|
||
G_CALLBACK (view_focused_in),
|
||
tab);
|
||
|
||
g_signal_connect_after (view,
|
||
"realize",
|
||
G_CALLBACK (view_realized),
|
||
tab);
|
||
|
||
g_signal_connect (view,
|
||
"drop-uris",
|
||
G_CALLBACK (on_drop_uris),
|
||
tab);
|
||
}
|
||
|
||
GeditTab *
|
||
_gedit_tab_new (void)
|
||
{
|
||
return g_object_new (GEDIT_TYPE_TAB, NULL);
|
||
}
|
||
|
||
@@ -1407,94 +1404,94 @@ gedit_tab_get_view (GeditTab *tab)
|
||
*/
|
||
GeditDocument *
|
||
gedit_tab_get_document (GeditTab *tab)
|
||
{
|
||
GeditView *view;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_TAB (tab), NULL);
|
||
|
||
view = gedit_view_frame_get_view (tab->frame);
|
||
|
||
return GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||
}
|
||
|
||
#define MAX_DOC_NAME_LENGTH 40
|
||
|
||
gchar *
|
||
_gedit_tab_get_name (GeditTab *tab)
|
||
{
|
||
GeditDocument *doc;
|
||
gchar *name;
|
||
gchar *docname;
|
||
gchar *tab_name;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_TAB (tab), NULL);
|
||
|
||
doc = gedit_tab_get_document (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)))
|
||
{
|
||
tab_name = g_strdup_printf ("*%s", docname);
|
||
}
|
||
else
|
||
{
|
||
tab_name = g_strdup (docname);
|
||
}
|
||
|
||
g_free (docname);
|
||
g_free (name);
|
||
|
||
return tab_name;
|
||
}
|
||
|
||
gchar *
|
||
_gedit_tab_get_tooltip (GeditTab *tab)
|
||
{
|
||
GeditDocument *doc;
|
||
gchar *tip;
|
||
gchar *uri;
|
||
gchar *ruri;
|
||
gchar *ruri_markup;
|
||
|
||
g_return_val_if_fail (GEDIT_IS_TAB (tab), NULL);
|
||
|
||
doc = gedit_tab_get_document (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 ("<i>%s</i>", ruri);
|
||
|
||
switch (tab->state)
|
||
{
|
||
gchar *content_type;
|
||
gchar *mime_type;
|
||
gchar *content_description;
|
||
gchar *content_full_description;
|
||
gchar *encoding;
|
||
GtkSourceFile *file;
|
||
const GtkSourceEncoding *enc;
|
||
|
||
case GEDIT_TAB_STATE_LOADING_ERROR:
|
||
tip = g_strdup_printf (_("Error opening file %s"),
|
||
ruri_markup);
|
||
break;
|
||
|
||
case GEDIT_TAB_STATE_REVERTING_ERROR:
|
||
tip = g_strdup_printf (_("Error reverting file %s"),
|
||
ruri_markup);
|
||
break;
|
||
|
||
case GEDIT_TAB_STATE_SAVING_ERROR:
|
||
tip = g_strdup_printf (_("Error saving file %s"),
|
||
ruri_markup);
|
||
break;
|
||
default:
|
||
content_type = gedit_document_get_content_type (doc);
|
||
@@ -1606,65 +1603,63 @@ gedit_tab_get_from_document (GeditDocument *doc)
|
||
return g_object_get_data (G_OBJECT (doc), GEDIT_TAB_KEY);
|
||
}
|
||
|
||
static void
|
||
loader_progress_cb (goffset size,
|
||
goffset total_size,
|
||
GTask *loading_task)
|
||
{
|
||
LoaderData *data = g_task_get_task_data (loading_task);
|
||
|
||
g_return_if_fail (data->tab->state == GEDIT_TAB_STATE_LOADING ||
|
||
data->tab->state == GEDIT_TAB_STATE_REVERTING);
|
||
|
||
if (should_show_progress_info (&data->timer, size, total_size))
|
||
{
|
||
show_loading_info_bar (loading_task);
|
||
info_bar_set_progress (data->tab, size, total_size);
|
||
}
|
||
}
|
||
|
||
static void
|
||
goto_line (GTask *loading_task)
|
||
{
|
||
LoaderData *data = g_task_get_task_data (loading_task);
|
||
GeditDocument *doc = gedit_tab_get_document (data->tab);
|
||
GtkTextIter iter;
|
||
|
||
/* 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;
|
||
}
|
||
|
||
/* If enabled, move to the position stored in the metadata. */
|
||
if (g_settings_get_boolean (data->tab->editor_settings, GEDIT_SETTINGS_RESTORE_CURSOR_POSITION))
|
||
{
|
||
gchar *pos;
|
||
gint offset;
|
||
|
||
pos = gedit_document_get_metadata (doc, GEDIT_METADATA_ATTRIBUTE_POSITION);
|
||
|
||
offset = pos != NULL ? atoi (pos) : 0;
|
||
g_free (pos);
|
||
|
||
gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc),
|
||
&iter,
|
||
MAX (0, offset));
|
||
|
||
/* make sure it's a valid position, if the file
|
||
* changed we may have ended up in the middle of
|
||
* a utf8 character cluster */
|
||
if (!gtk_text_iter_is_cursor_position (&iter))
|
||
{
|
||
gtk_text_iter_set_line_offset (&iter, 0);
|
||
}
|
||
}
|
||
|
||
/* Otherwise to the top. */
|
||
else
|
||
{
|
||
@@ -1726,72 +1721,72 @@ successful_load (GTask *loading_task)
|
||
|
||
if (data->user_requested_encoding)
|
||
{
|
||
const GtkSourceEncoding *encoding = gtk_source_file_loader_get_encoding (data->loader);
|
||
const gchar *charset = gtk_source_encoding_get_charset (encoding);
|
||
|
||
gedit_document_set_metadata (doc,
|
||
GEDIT_METADATA_ATTRIBUTE_ENCODING, charset,
|
||
NULL);
|
||
}
|
||
|
||
goto_line (loading_task);
|
||
|
||
/* Scroll to the cursor when the document is loaded, we need to do it in
|
||
* an idle as after the document is loaded the textview is still
|
||
* redrawing and relocating its internals.
|
||
*/
|
||
if (data->tab->idle_scroll == 0)
|
||
{
|
||
data->tab->idle_scroll = g_idle_add ((GSourceFunc)scroll_to_cursor, data->tab);
|
||
}
|
||
|
||
location = gtk_source_file_loader_get_location (data->loader);
|
||
|
||
/* If the document is readonly we don't care how many times the file
|
||
* is opened.
|
||
*/
|
||
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
|
||
* buffer as modified.
|
||
*/
|
||
if (location == NULL)
|
||
{
|
||
gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (doc), TRUE);
|
||
}
|
||
|
||
data->tab->ask_if_externally_modified = TRUE;
|
||
|
||
g_signal_emit_by_name (doc, "loaded");
|
||
}
|
||
|
||
static void
|
||
load_cb (GtkSourceFileLoader *loader,
|
||
GAsyncResult *result,
|
||
GTask *loading_task)
|
||
{
|
||
LoaderData *data = g_task_get_task_data (loading_task);
|
||
GeditDocument *doc;
|
||
GFile *location = gtk_source_file_loader_get_location (loader);
|
||
gboolean create_named_new_doc;
|
||
GError *error = NULL;
|
||
|
||
g_clear_pointer (&data->timer, g_timer_destroy);
|
||
|
||
gtk_source_file_loader_load_finish (loader, result, &error);
|
||
|
||
@@ -2283,75 +2278,75 @@ save_cb (GtkSourceFileSaver *saver,
|
||
if (data->timer != NULL)
|
||
{
|
||
g_timer_destroy (data->timer);
|
||
data->timer = NULL;
|
||
}
|
||
|
||
set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
|
||
|
||
if (error != NULL)
|
||
{
|
||
GtkWidget *info_bar;
|
||
|
||
gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING_ERROR);
|
||
|
||
if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR &&
|
||
error->code == GTK_SOURCE_FILE_SAVER_ERROR_EXTERNALLY_MODIFIED)
|
||
{
|
||
/* This error is recoverable */
|
||
info_bar = gedit_externally_modified_saving_error_info_bar_new (location, error);
|
||
g_return_if_fail (info_bar != NULL);
|
||
|
||
g_signal_connect (info_bar,
|
||
"response",
|
||
G_CALLBACK (externally_modified_error_info_bar_response),
|
||
saving_task);
|
||
}
|
||
else if (error->domain == G_IO_ERROR &&
|
||
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 &&
|
||
error->code == GTK_SOURCE_FILE_SAVER_ERROR_INVALID_CHARS)
|
||
{
|
||
/* 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,
|
||
"response",
|
||
G_CALLBACK (invalid_character_info_bar_response),
|
||
saving_task);
|
||
}
|
||
else if (error->domain == GTK_SOURCE_FILE_SAVER_ERROR ||
|
||
(error->domain == G_IO_ERROR &&
|
||
error->code != G_IO_ERROR_INVALID_DATA &&
|
||
error->code != G_IO_ERROR_PARTIAL_INPUT))
|
||
{
|
||
/* These errors are _NOT_ recoverable */
|
||
gedit_recent_remove_if_local (location);
|
||
|
||
info_bar = gedit_unrecoverable_saving_error_info_bar_new (location, error);
|
||
g_return_if_fail (info_bar != NULL);
|
||
|
||
g_signal_connect (info_bar,
|
||
"response",
|
||
G_CALLBACK (unrecoverable_saving_error_info_bar_response),
|
||
saving_task);
|
||
}
|
||
else
|
||
{
|
||
const GtkSourceEncoding *encoding;
|
||
|
||
/* This error is recoverable */
|
||
g_return_if_fail (error->domain == G_CONVERT_ERROR ||
|
||
error->domain == G_IO_ERROR);
|
||
@@ -2679,69 +2674,69 @@ get_print_settings (GeditTab *tab)
|
||
GEDIT_PRINT_SETTINGS_KEY);
|
||
|
||
if (data == NULL)
|
||
{
|
||
settings = _gedit_app_get_default_print_settings (GEDIT_APP (g_application_get_default ()));
|
||
}
|
||
else
|
||
{
|
||
settings = gtk_print_settings_copy (GTK_PRINT_SETTINGS (data));
|
||
}
|
||
|
||
/* Be sure the OUTPUT_URI is unset, because otherwise the
|
||
* OUTPUT_BASENAME is not taken into account.
|
||
*/
|
||
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_URI, NULL);
|
||
|
||
name = gedit_document_get_short_name_for_display (doc);
|
||
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_BASENAME, name);
|
||
|
||
g_free (name);
|
||
|
||
return settings;
|
||
}
|
||
|
||
/* FIXME: show the info bar only if the operation will be "long" */
|
||
static void
|
||
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
|
||
store_print_settings (GeditTab *tab,
|
||
GeditPrintJob *job)
|
||
{
|
||
GeditDocument *doc;
|
||
GtkPrintSettings *settings;
|
||
GtkPageSetup *page_setup;
|
||
|
||
doc = gedit_tab_get_document (tab);
|
||
|
||
settings = gedit_print_job_get_print_settings (job);
|
||
|
||
/* clear n-copies settings since we do not want to
|
||
* persist that one */
|
||
gtk_print_settings_unset (settings,
|
||
GTK_PRINT_SETTINGS_N_COPIES);
|
||
|
||
/* remember settings for this document */
|
||
g_object_set_data_full (G_OBJECT (doc),
|
||
GEDIT_PRINT_SETTINGS_KEY,
|
||
g_object_ref (settings),
|
||
(GDestroyNotify)g_object_unref);
|
||
|
||
/* make them the default */
|
||
_gedit_app_set_default_print_settings (GEDIT_APP (g_application_get_default ()),
|
||
settings);
|
||
|
||
page_setup = gedit_print_job_get_page_setup (job);
|
||
@@ -2797,73 +2792,75 @@ show_preview_cb (GeditPrintJob *job,
|
||
/* destroy the info bar */
|
||
set_info_bar (tab, NULL, GTK_RESPONSE_NONE);
|
||
|
||
tab->print_preview = GTK_WIDGET (preview);
|
||
g_object_ref_sink (tab->print_preview);
|
||
|
||
gtk_box_pack_end (GTK_BOX (tab), tab->print_preview, TRUE, TRUE, 0);
|
||
|
||
gtk_widget_show (tab->print_preview);
|
||
gtk_widget_grab_focus (tab->print_preview);
|
||
|
||
gedit_tab_set_state (tab, GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
|
||
}
|
||
|
||
static void
|
||
print_cancelled (GtkWidget *bar,
|
||
gint response_id,
|
||
GeditTab *tab)
|
||
{
|
||
gedit_debug (DEBUG_TAB);
|
||
|
||
if (tab->print_job != NULL)
|
||
{
|
||
gedit_print_job_cancel (tab->print_job);
|
||
}
|
||
}
|
||
|
||
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
|
||
_gedit_tab_print (GeditTab *tab)
|
||
{
|
||
GeditView *view;
|
||
GtkPageSetup *setup;
|
||
GtkPrintSettings *settings;
|
||
GtkPrintOperationResult res;
|
||
GError *error = NULL;
|
||
|
||
g_return_if_fail (GEDIT_IS_TAB (tab));
|
||
|
||
/* FIXME: currently we can have just one printoperation going on at a
|
||
* given time, so before starting the print we close the preview.
|
||
* Would be nice to handle it properly though.
|
||
*/
|
||
if (tab->state == GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW)
|
||
{
|
||
close_printing (tab);
|
||
}
|
||
|
||
g_return_if_fail (tab->print_job == NULL);
|
||
g_return_if_fail (tab->state == GEDIT_TAB_STATE_NORMAL);
|
||
|
||
view = gedit_tab_get_view (tab);
|
||
|
||
tab->print_job = gedit_print_job_new (view);
|
||
|
||
add_printing_info_bar (tab);
|
||
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
|
||
@@ -1,56 +1,55 @@
|
||
/*
|
||
* gedit-utils.c
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
|
||
* Copyright (C) 2000, 2002 Chema Celorio, Paolo Maggi
|
||
* Copyright (C) 2003-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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "gedit-utils.h"
|
||
#include <string.h>
|
||
#include <glib/gi18n.h>
|
||
-#include <tepl/tepl.h>
|
||
#include "gedit-debug.h"
|
||
|
||
gboolean
|
||
gedit_utils_menu_position_under_tree_view (GtkTreeView *tree_view,
|
||
GdkRectangle *rect)
|
||
{
|
||
GtkTreeSelection *selection;
|
||
GtkTreeModel *model;
|
||
gint count_rows;
|
||
GList *rows;
|
||
gint widget_x, widget_y;
|
||
|
||
model = gtk_tree_view_get_model (tree_view);
|
||
g_return_val_if_fail (model != NULL, FALSE);
|
||
|
||
selection = gtk_tree_view_get_selection (tree_view);
|
||
g_return_val_if_fail (selection != NULL, FALSE);
|
||
|
||
count_rows = gtk_tree_selection_count_selected_rows (selection);
|
||
if (count_rows != 1)
|
||
return FALSE;
|
||
|
||
rows = gtk_tree_selection_get_selected_rows (selection, &model);
|
||
gtk_tree_view_get_cell_area (tree_view, (GtkTreePath *)(rows->data),
|
||
gtk_tree_view_get_column (tree_view, 0),
|
||
rect);
|
||
|
||
gtk_tree_view_convert_bin_window_to_widget_coords (tree_view, rect->x, rect->y, &widget_x, &widget_y);
|
||
rect->x = widget_x;
|
||
rect->y = widget_y;
|
||
@@ -60,160 +59,321 @@ gedit_utils_menu_position_under_tree_view (GtkTreeView *tree_view,
|
||
}
|
||
|
||
/**
|
||
* gedit_utils_set_atk_name_description:
|
||
* @widget: The Gtk widget for which name/description to be set
|
||
* @name: Atk name string
|
||
* @description: Atk description string
|
||
*
|
||
* This function sets up name and description
|
||
* for a specified gtk widget.
|
||
*/
|
||
void
|
||
gedit_utils_set_atk_name_description (GtkWidget *widget,
|
||
const gchar *name,
|
||
const gchar *description)
|
||
{
|
||
AtkObject *aobj;
|
||
|
||
aobj = gtk_widget_get_accessible (widget);
|
||
|
||
if (!(GTK_IS_ACCESSIBLE (aobj)))
|
||
return;
|
||
|
||
if (name)
|
||
atk_object_set_name (aobj, name);
|
||
|
||
if (description)
|
||
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)
|
||
{
|
||
gchar *res;
|
||
gchar *str;
|
||
|
||
g_return_val_if_fail (uri != NULL, NULL);
|
||
|
||
/* CHECK: does it work with uri chaining? - Paolo */
|
||
str = g_path_get_dirname (uri);
|
||
g_return_val_if_fail (str != NULL, g_strdup ("."));
|
||
|
||
if ((strlen (str) == 1) && (*str == '.'))
|
||
{
|
||
g_free (str);
|
||
|
||
return NULL;
|
||
}
|
||
|
||
- res = tepl_utils_replace_home_dir_with_tilde (str);
|
||
+ res = gedit_utils_replace_home_dir_with_tilde (str);
|
||
|
||
g_free (str);
|
||
|
||
return res;
|
||
}
|
||
|
||
/**
|
||
* gedit_utils_location_get_dirname_for_display:
|
||
* @location: the location
|
||
*
|
||
* Returns a string suitable to be displayed in the UI indicating
|
||
* the name of the directory where the file is located.
|
||
* For remote files it may also contain the hostname etc.
|
||
* For local files it tries to replace the home dir with ~.
|
||
*
|
||
* Returns: (transfer full): a string to display the dirname
|
||
*/
|
||
gchar *
|
||
gedit_utils_location_get_dirname_for_display (GFile *location)
|
||
{
|
||
gchar *uri;
|
||
gchar *res;
|
||
GMount *mount;
|
||
|
||
g_return_val_if_fail (location != NULL, NULL);
|
||
|
||
/* we use the parse name, that is either the local path
|
||
* or an uri but which is utf8 safe */
|
||
uri = g_file_get_parse_name (location);
|
||
|
||
/* FIXME: this is sync... is it a problem? */
|
||
mount = g_file_find_enclosing_mount (location, NULL, NULL);
|
||
if (mount != NULL)
|
||
{
|
||
gchar *mount_name;
|
||
gchar *path = NULL;
|
||
gchar *dirname;
|
||
|
||
mount_name = g_mount_get_name (mount);
|
||
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)
|
||
{
|
||
dirname = uri_get_dirname (uri);
|
||
}
|
||
else
|
||
{
|
||
dirname = uri_get_dirname (path);
|
||
}
|
||
|
||
if (dirname == NULL || strcmp (dirname, ".") == 0)
|
||
{
|
||
res = mount_name;
|
||
}
|
||
else
|
||
{
|
||
res = g_strdup_printf ("%s %s", mount_name, dirname);
|
||
g_free (mount_name);
|
||
}
|
||
|
||
g_free (path);
|
||
g_free (dirname);
|
||
}
|
||
else
|
||
{
|
||
/* fallback for local files or uris without mounts */
|
||
res = uri_get_dirname (uri);
|
||
}
|
||
|
||
g_free (uri);
|
||
|
||
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)
|
||
{
|
||
return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
|
||
}
|
||
|
||
static gboolean
|
||
has_valid_scheme (const gchar *uri)
|
||
{
|
||
const gchar *p;
|
||
|
||
p = uri;
|
||
|
||
if (!is_valid_scheme_character (*p))
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
do
|
||
{
|
||
p++;
|
||
} while (is_valid_scheme_character (*p));
|
||
|
||
return *p == ':';
|
||
}
|
||
|
||
gboolean
|
||
gedit_utils_is_valid_location (GFile *location)
|
||
{
|
||
const guchar *p;
|
||
@@ -326,61 +486,61 @@ gedit_utils_basename_for_display (GFile *location)
|
||
|
||
/* First, try to query the display name, but only on local files */
|
||
if (g_file_has_uri_scheme (location, "file"))
|
||
{
|
||
GFileInfo *info;
|
||
|
||
info = g_file_query_info (location,
|
||
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
|
||
G_FILE_QUERY_INFO_NONE,
|
||
NULL,
|
||
NULL);
|
||
|
||
if (info)
|
||
{
|
||
/* Simply get the display name to use as the basename */
|
||
name = g_strdup (g_file_info_get_display_name (info));
|
||
g_object_unref (info);
|
||
}
|
||
else
|
||
{
|
||
/* This is a local file, and therefore we will use
|
||
* g_filename_display_basename on the local path */
|
||
gchar *local_path;
|
||
|
||
local_path = g_file_get_path (location);
|
||
name = g_filename_display_basename (local_path);
|
||
g_free (local_path);
|
||
}
|
||
}
|
||
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,
|
||
use the _parse_name and take basename of that */
|
||
gchar *parse_name;
|
||
gchar *base;
|
||
|
||
parse_name = g_file_get_parse_name (location);
|
||
base = g_filename_display_basename (parse_name);
|
||
name = g_uri_unescape_string (base, NULL);
|
||
|
||
g_free (base);
|
||
g_free (parse_name);
|
||
}
|
||
else
|
||
{
|
||
/* display '/ on <host>' using the decoded host */
|
||
gchar *hn_utf8;
|
||
|
||
if (hn != NULL)
|
||
{
|
||
hn_utf8 = g_utf8_make_valid (hn, -1);
|
||
}
|
||
else
|
||
{
|
||
/* we should never get here */
|
||
hn_utf8 = g_strdup ("?");
|
||
}
|
||
|
||
/* Translators: '/ on <remote-share>' */
|
||
@@ -411,60 +571,219 @@ gedit_utils_drop_get_uris (GtkSelectionData *selection_data)
|
||
gchar **uris;
|
||
gint i;
|
||
gint p = 0;
|
||
gchar **uri_list;
|
||
|
||
uris = g_uri_list_extract_uris ((gchar *) gtk_selection_data_get_data (selection_data));
|
||
uri_list = g_new0(gchar *, g_strv_length (uris) + 1);
|
||
|
||
for (i = 0; uris[i] != NULL; i++)
|
||
{
|
||
gchar *uri;
|
||
|
||
uri = make_canonical_uri_from_shell_arg (uris[i]);
|
||
|
||
/* Silently ignore malformed URI/filename */
|
||
if (uri != NULL)
|
||
uri_list[p++] = uri;
|
||
}
|
||
|
||
if (*uri_list == NULL)
|
||
{
|
||
g_free(uri_list);
|
||
g_strfreev (uris);
|
||
return NULL;
|
||
}
|
||
|
||
g_strfreev (uris);
|
||
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)
|
||
{
|
||
if (content_type == NULL)
|
||
{
|
||
return GTK_SOURCE_COMPRESSION_TYPE_NONE;
|
||
}
|
||
|
||
if (g_content_type_is_a (content_type, "application/x-gzip"))
|
||
{
|
||
return GTK_SOURCE_COMPRESSION_TYPE_GZIP;
|
||
}
|
||
|
||
return GTK_SOURCE_COMPRESSION_TYPE_NONE;
|
||
}
|
||
|
||
/* Copied from nautilus */
|
||
static gchar *
|
||
get_direct_save_filename (GdkDragContext *context)
|
||
{
|
||
guchar *prop_text;
|
||
gint prop_len;
|
||
|
||
if (!gdk_property_get (gdk_drag_context_get_source_window (context), gdk_atom_intern ("XdndDirectSave0", FALSE),
|
||
gdk_atom_intern ("text/plain", FALSE), 0, 1024, FALSE, NULL, NULL,
|
||
&prop_len, &prop_text) && prop_text != NULL) {
|
||
return NULL;
|
||
}
|
||
|
||
/* Zero-terminate the string */
|
||
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
|
||
@@ -1,56 +1,75 @@
|
||
/*
|
||
* gedit-utils.h
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
|
||
* Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
|
||
* Copyright (C) 2002 - 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_UTILS_H
|
||
#define GEDIT_UTILS_H
|
||
|
||
#include <gtksourceview/gtksource.h>
|
||
|
||
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);
|
||
|
||
gchar *gedit_utils_set_direct_save_filename (GdkDragContext *context);
|
||
|
||
GtkSourceCompressionType gedit_utils_get_compression_type_from_content_type (const gchar *content_type);
|
||
|
||
const gchar *gedit_utils_newline_type_to_string (GtkSourceNewlineType newline_type);
|
||
|
||
G_END_DECLS
|
||
|
||
#endif /* GEDIT_UTILS_H */
|
||
|
||
/* ex:set ts=8 noet: */
|
||
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 <gtksourceview/gtksource.h>
|
||
+
|
||
+#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 <gtk/gtk.h>
|
||
+
|
||
+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
|
||
@@ -1,86 +1,91 @@
|
||
/*
|
||
* gedit-view-frame.c
|
||
* 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
|
||
* 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, write to the Free Software
|
||
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||
* Boston, MA 02110-1301 USA
|
||
*/
|
||
|
||
#include "gedit-view-frame.h"
|
||
|
||
#include <gtksourceview/gtksource.h>
|
||
#include <gdk/gdkkeysyms.h>
|
||
#include <glib/gi18n.h>
|
||
#include <stdlib.h>
|
||
|
||
+#include "gedit-view-centering.h"
|
||
#include "gedit-debug.h"
|
||
#include "gedit-utils.h"
|
||
#include "gedit-settings.h"
|
||
#include "libgd/gd.h"
|
||
|
||
#define FLUSH_TIMEOUT_DURATION 30 /* in seconds */
|
||
|
||
#define SEARCH_POPUP_MARGIN 12
|
||
|
||
typedef enum
|
||
{
|
||
GOTO_LINE,
|
||
SEARCH
|
||
} SearchMode;
|
||
|
||
typedef enum
|
||
{
|
||
SEARCH_STATE_NORMAL,
|
||
SEARCH_STATE_NOT_FOUND
|
||
} SearchState;
|
||
|
||
struct _GeditViewFrame
|
||
{
|
||
GtkOverlay parent_instance;
|
||
|
||
+ GSettings *editor_settings;
|
||
+
|
||
GeditView *view;
|
||
+ GeditViewCentering *view_centering;
|
||
+ GtkFrame *map_frame;
|
||
|
||
SearchMode search_mode;
|
||
|
||
/* Where the search has started. When the user presses escape in the
|
||
* search entry (to cancel the search), we return to the start_mark.
|
||
*/
|
||
GtkTextMark *start_mark;
|
||
|
||
GtkRevealer *revealer;
|
||
GdTaggedEntry *search_entry;
|
||
GdTaggedEntryTag *entry_tag;
|
||
GtkWidget *go_up_button;
|
||
GtkWidget *go_down_button;
|
||
|
||
guint flush_timeout_id;
|
||
guint idle_update_entry_tag_id;
|
||
guint remove_entry_tag_timeout_id;
|
||
gulong view_scroll_event_id;
|
||
gulong search_entry_focus_out_id;
|
||
gulong search_entry_changed_id;
|
||
|
||
GtkSourceSearchSettings *search_settings;
|
||
|
||
/* Used to restore the search state if an incremental search is
|
||
* cancelled.
|
||
*/
|
||
GtkSourceSearchSettings *old_search_settings;
|
||
|
||
/* The original search texts. In search_settings and
|
||
* old_search_settings, the search text is unescaped. Since the escape
|
||
@@ -132,115 +137,116 @@ gedit_view_frame_dispose (GObject *object)
|
||
if (frame->start_mark != NULL && buffer != NULL)
|
||
{
|
||
gtk_text_buffer_delete_mark (buffer, frame->start_mark);
|
||
frame->start_mark = NULL;
|
||
}
|
||
|
||
if (frame->flush_timeout_id != 0)
|
||
{
|
||
g_source_remove (frame->flush_timeout_id);
|
||
frame->flush_timeout_id = 0;
|
||
}
|
||
|
||
if (frame->idle_update_entry_tag_id != 0)
|
||
{
|
||
g_source_remove (frame->idle_update_entry_tag_id);
|
||
frame->idle_update_entry_tag_id = 0;
|
||
}
|
||
|
||
if (frame->remove_entry_tag_timeout_id != 0)
|
||
{
|
||
g_source_remove (frame->remove_entry_tag_timeout_id);
|
||
frame->remove_entry_tag_timeout_id = 0;
|
||
}
|
||
|
||
if (buffer != NULL)
|
||
{
|
||
GtkSourceFile *file = gedit_document_get_file (GEDIT_DOCUMENT (buffer));
|
||
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);
|
||
|
||
G_OBJECT_CLASS (gedit_view_frame_parent_class)->dispose (object);
|
||
}
|
||
|
||
static void
|
||
gedit_view_frame_finalize (GObject *object)
|
||
{
|
||
GeditViewFrame *frame = GEDIT_VIEW_FRAME (object);
|
||
|
||
g_free (frame->search_text);
|
||
g_free (frame->old_search_text);
|
||
|
||
G_OBJECT_CLASS (gedit_view_frame_parent_class)->finalize (object);
|
||
}
|
||
|
||
static void
|
||
hide_search_widget (GeditViewFrame *frame,
|
||
gboolean cancel)
|
||
{
|
||
GtkTextBuffer *buffer;
|
||
|
||
if (!gtk_revealer_get_reveal_child (frame->revealer))
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (frame->view_scroll_event_id != 0)
|
||
{
|
||
g_signal_handler_disconnect (frame->view,
|
||
frame->view_scroll_event_id);
|
||
frame->view_scroll_event_id = 0;
|
||
}
|
||
|
||
if (frame->flush_timeout_id != 0)
|
||
{
|
||
g_source_remove (frame->flush_timeout_id);
|
||
frame->flush_timeout_id = 0;
|
||
}
|
||
|
||
gtk_revealer_set_reveal_child (frame->revealer, FALSE);
|
||
|
||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (frame->view));
|
||
|
||
if (cancel && frame->start_mark != NULL)
|
||
{
|
||
GtkTextIter iter;
|
||
|
||
gtk_text_buffer_get_iter_at_mark (buffer, &iter,
|
||
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)
|
||
{
|
||
gtk_text_buffer_delete_mark (buffer, frame->start_mark);
|
||
frame->start_mark = NULL;
|
||
}
|
||
}
|
||
|
||
static gboolean
|
||
search_entry_flush_timeout (GeditViewFrame *frame)
|
||
{
|
||
frame->flush_timeout_id = 0;
|
||
hide_search_widget (frame, FALSE);
|
||
|
||
return G_SOURCE_REMOVE;
|
||
}
|
||
|
||
static void
|
||
renew_flush_timeout (GeditViewFrame *frame)
|
||
{
|
||
if (frame->flush_timeout_id != 0)
|
||
{
|
||
g_source_remove (frame->flush_timeout_id);
|
||
}
|
||
|
||
frame->flush_timeout_id =
|
||
g_timeout_add_seconds (FLUSH_TIMEOUT_DURATION,
|
||
(GSourceFunc)search_entry_flush_timeout,
|
||
frame);
|
||
@@ -270,61 +276,61 @@ get_search_context (GeditViewFrame *frame)
|
||
|
||
return NULL;
|
||
}
|
||
|
||
static void
|
||
set_search_state (GeditViewFrame *frame,
|
||
SearchState state)
|
||
{
|
||
GtkStyleContext *context;
|
||
|
||
context = gtk_widget_get_style_context (GTK_WIDGET (frame->search_entry));
|
||
|
||
if (state == SEARCH_STATE_NOT_FOUND)
|
||
{
|
||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_ERROR);
|
||
}
|
||
else
|
||
{
|
||
gtk_style_context_remove_class (context, GTK_STYLE_CLASS_ERROR);
|
||
}
|
||
}
|
||
|
||
static void
|
||
finish_search (GeditViewFrame *frame,
|
||
gboolean found)
|
||
{
|
||
const gchar *entry_text = gtk_entry_get_text (GTK_ENTRY (frame->search_entry));
|
||
|
||
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);
|
||
}
|
||
else
|
||
{
|
||
set_search_state (frame, SEARCH_STATE_NOT_FOUND);
|
||
}
|
||
}
|
||
|
||
static void
|
||
start_search_finished (GtkSourceSearchContext *search_context,
|
||
GAsyncResult *result,
|
||
GeditViewFrame *frame)
|
||
{
|
||
GtkTextIter match_start;
|
||
GtkTextIter match_end;
|
||
gboolean found;
|
||
GtkSourceBuffer *buffer;
|
||
|
||
found = gtk_source_search_context_forward_finish (search_context,
|
||
result,
|
||
&match_start,
|
||
&match_end,
|
||
NULL,
|
||
NULL);
|
||
|
||
buffer = gtk_source_search_context_get_buffer (search_context);
|
||
|
||
if (found)
|
||
{
|
||
@@ -1034,117 +1040,121 @@ customize_for_search_mode (GeditViewFrame *frame)
|
||
gtk_widget_set_tooltip_text (GTK_WIDGET (frame->search_entry),
|
||
_("Line you want to move the cursor to"));
|
||
|
||
gtk_widget_hide (frame->go_up_button);
|
||
gtk_widget_hide (frame->go_down_button);
|
||
}
|
||
|
||
gtk_entry_set_icon_from_gicon (GTK_ENTRY (frame->search_entry),
|
||
GTK_ENTRY_ICON_PRIMARY,
|
||
icon);
|
||
|
||
gtk_widget_set_size_request (GTK_WIDGET (frame->search_entry),
|
||
width_request,
|
||
-1);
|
||
|
||
g_object_unref (icon);
|
||
}
|
||
|
||
static void
|
||
update_goto_line (GeditViewFrame *frame)
|
||
{
|
||
const gchar *entry_text;
|
||
gboolean moved;
|
||
gboolean moved_offset;
|
||
gint line;
|
||
gint offset_line = 0;
|
||
gint line_offset = 0;
|
||
gchar **split_text = NULL;
|
||
const gchar *text;
|
||
GtkTextIter iter;
|
||
+ GeditDocument *doc;
|
||
|
||
entry_text = gtk_entry_get_text (GTK_ENTRY (frame->search_entry));
|
||
|
||
if (entry_text[0] == '\0')
|
||
{
|
||
return;
|
||
}
|
||
|
||
get_iter_at_start_mark (frame, &iter);
|
||
|
||
split_text = g_strsplit (entry_text, ":", -1);
|
||
|
||
if (g_strv_length (split_text) > 1)
|
||
{
|
||
text = split_text[0];
|
||
}
|
||
else
|
||
{
|
||
text = entry_text;
|
||
}
|
||
|
||
if (text[0] == '-')
|
||
{
|
||
gint cur_line = gtk_text_iter_get_line (&iter);
|
||
|
||
if (text[1] != '\0')
|
||
{
|
||
offset_line = MAX (atoi (text + 1), 0);
|
||
}
|
||
|
||
line = MAX (cur_line - offset_line, 0);
|
||
}
|
||
else if (entry_text[0] == '+')
|
||
{
|
||
gint cur_line = gtk_text_iter_get_line (&iter);
|
||
|
||
if (text[1] != '\0')
|
||
{
|
||
offset_line = MAX (atoi (text + 1), 0);
|
||
}
|
||
|
||
line = cur_line + offset_line;
|
||
}
|
||
else
|
||
{
|
||
line = MAX (atoi (text) - 1, 0);
|
||
}
|
||
|
||
if (split_text[1] != NULL)
|
||
{
|
||
line_offset = atoi (split_text[1]);
|
||
}
|
||
|
||
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)
|
||
{
|
||
set_search_state (frame, SEARCH_STATE_NOT_FOUND);
|
||
}
|
||
else
|
||
{
|
||
set_search_state (frame, SEARCH_STATE_NORMAL);
|
||
}
|
||
}
|
||
|
||
static void
|
||
search_entry_changed_cb (GtkEntry *entry,
|
||
GeditViewFrame *frame)
|
||
{
|
||
renew_flush_timeout (frame);
|
||
|
||
if (frame->search_mode == SEARCH)
|
||
{
|
||
update_search_text (frame);
|
||
start_search (frame);
|
||
}
|
||
else
|
||
{
|
||
update_goto_line (frame);
|
||
}
|
||
}
|
||
|
||
static gboolean
|
||
search_entry_focus_out_event (GtkWidget *widget,
|
||
@@ -1401,86 +1411,95 @@ start_interactive_search_real (GeditViewFrame *frame,
|
||
|
||
gtk_widget_grab_focus (GTK_WIDGET (frame->search_entry));
|
||
|
||
customize_for_search_mode (frame);
|
||
init_search_entry (frame);
|
||
|
||
/* Manage the scroll also for the view */
|
||
frame->view_scroll_event_id =
|
||
g_signal_connect (frame->view, "scroll-event",
|
||
G_CALLBACK (search_widget_scroll_event),
|
||
frame);
|
||
|
||
renew_flush_timeout (frame);
|
||
|
||
install_update_entry_tag_idle (frame);
|
||
}
|
||
|
||
static void
|
||
gedit_view_frame_class_init (GeditViewFrameClass *klass)
|
||
{
|
||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||
|
||
object_class->dispose = gedit_view_frame_dispose;
|
||
object_class->finalize = gedit_view_frame_finalize;
|
||
|
||
/* Bind class to template */
|
||
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);
|
||
gtk_widget_class_bind_template_child (widget_class, GeditViewFrame, go_down_button);
|
||
}
|
||
|
||
static GMountOperation *
|
||
view_frame_mount_operation_factory (GtkSourceFile *file,
|
||
gpointer user_data)
|
||
{
|
||
GtkWidget *view_frame = user_data;
|
||
GtkWidget *window = gtk_widget_get_toplevel (view_frame);
|
||
|
||
return gtk_mount_operation_new (GTK_WINDOW (window));
|
||
}
|
||
|
||
static void
|
||
gedit_view_frame_init (GeditViewFrame *frame)
|
||
{
|
||
GeditDocument *doc;
|
||
GtkSourceFile *file;
|
||
|
||
gedit_debug (DEBUG_WINDOW);
|
||
|
||
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);
|
||
|
||
gtk_source_file_set_mount_operation_factory (file,
|
||
view_frame_mount_operation_factory,
|
||
frame,
|
||
NULL);
|
||
|
||
frame->entry_tag = gd_tagged_entry_tag_new ("");
|
||
|
||
gd_tagged_entry_tag_set_style (frame->entry_tag,
|
||
"gedit-search-entry-occurrences-tag");
|
||
|
||
gd_tagged_entry_tag_set_has_close_button (frame->entry_tag, FALSE);
|
||
|
||
gtk_widget_set_margin_end (GTK_WIDGET (frame->revealer),
|
||
SEARCH_POPUP_MARGIN);
|
||
|
||
g_signal_connect (doc,
|
||
"mark-set",
|
||
G_CALLBACK (mark_set_cb),
|
||
frame);
|
||
|
||
g_signal_connect (frame->revealer,
|
||
"key-press-event",
|
||
G_CALLBACK (search_widget_key_press_event),
|
||
frame);
|
||
|
||
g_signal_connect (frame->revealer,
|
||
"scroll-event",
|
||
@@ -1524,60 +1543,68 @@ gedit_view_frame_init (GeditViewFrame *frame)
|
||
|
||
frame->search_entry_changed_id =
|
||
g_signal_connect (frame->search_entry,
|
||
"changed",
|
||
G_CALLBACK (search_entry_changed_cb),
|
||
frame);
|
||
|
||
frame->search_entry_focus_out_id =
|
||
g_signal_connect (frame->search_entry,
|
||
"focus-out-event",
|
||
G_CALLBACK (search_entry_focus_out_event),
|
||
frame);
|
||
|
||
g_signal_connect_swapped (frame->go_up_button,
|
||
"clicked",
|
||
G_CALLBACK (backward_search),
|
||
frame);
|
||
|
||
g_signal_connect_swapped (frame->go_down_button,
|
||
"clicked",
|
||
G_CALLBACK (forward_search),
|
||
frame);
|
||
}
|
||
|
||
GeditViewFrame *
|
||
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)
|
||
{
|
||
g_return_val_if_fail (GEDIT_IS_VIEW_FRAME (frame), NULL);
|
||
|
||
return frame->view;
|
||
}
|
||
|
||
void
|
||
gedit_view_frame_popup_search (GeditViewFrame *frame)
|
||
{
|
||
g_return_if_fail (GEDIT_IS_VIEW_FRAME (frame));
|
||
|
||
start_interactive_search_real (frame, SEARCH);
|
||
}
|
||
|
||
void
|
||
gedit_view_frame_popup_goto_line (GeditViewFrame *frame)
|
||
{
|
||
g_return_if_fail (GEDIT_IS_VIEW_FRAME (frame));
|
||
|
||
start_interactive_search_real (frame, GOTO_LINE);
|
||
}
|
||
|
||
void
|
||
gedit_view_frame_clear_search (GeditViewFrame *frame)
|
||
{
|
||
g_return_if_fail (GEDIT_IS_VIEW_FRAME (frame));
|
||
|
||
g_signal_handler_block (frame->search_entry,
|
||
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
|
||
@@ -1,45 +1,49 @@
|
||
/*
|
||
* gedit-view-frame.h
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 2010 - 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_VIEW_FRAME_H
|
||
#define GEDIT_VIEW_FRAME_H
|
||
|
||
#include <gtk/gtk.h>
|
||
#include "gedit-document.h"
|
||
#include "gedit-view.h"
|
||
+#include "gedit-view-centering.h"
|
||
|
||
G_BEGIN_DECLS
|
||
|
||
#define GEDIT_TYPE_VIEW_FRAME (gedit_view_frame_get_type ())
|
||
G_DECLARE_FINAL_TYPE (GeditViewFrame, gedit_view_frame, GEDIT, VIEW_FRAME, GtkOverlay)
|
||
|
||
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);
|
||
|
||
void gedit_view_frame_popup_goto_line (GeditViewFrame *frame);
|
||
|
||
void gedit_view_frame_clear_search (GeditViewFrame *frame);
|
||
|
||
G_END_DECLS
|
||
|
||
#endif /* GEDIT_VIEW_FRAME_H */
|
||
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
|
||
@@ -1,232 +1,259 @@
|
||
/*
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
|
||
* Copyright (C) 2000, 2002 Chema Celorio, Paolo Maggi
|
||
* Copyright (C) 2003-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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "gedit-view.h"
|
||
#include <libpeas/peas-extension-set.h>
|
||
#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
|
||
{
|
||
TARGET_URI_LIST = 100,
|
||
TARGET_XDNDDIRECTSAVE
|
||
};
|
||
|
||
enum
|
||
{
|
||
SIGNAL_DROP_URIS,
|
||
N_SIGNALS
|
||
};
|
||
|
||
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)
|
||
{
|
||
GeditDocument *doc;
|
||
GtkSourceFile *file;
|
||
|
||
doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
||
file = gedit_document_get_file (doc);
|
||
|
||
gtk_text_view_set_editable (GTK_TEXT_VIEW (view),
|
||
!gtk_source_file_is_readonly (file));
|
||
}
|
||
|
||
static void
|
||
file_read_only_notify_cb (GtkSourceFile *file,
|
||
GParamSpec *pspec,
|
||
GeditView *view)
|
||
{
|
||
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);
|
||
}
|
||
|
||
static void
|
||
buffer_notify_cb (GeditView *view,
|
||
GParamSpec *pspec,
|
||
gpointer user_data)
|
||
{
|
||
buffer_changed (view);
|
||
}
|
||
|
||
static void
|
||
gedit_view_init (GeditView *view)
|
||
{
|
||
GtkTargetList *target_list;
|
||
- GtkStyleContext *style_context;
|
||
+ GtkStyleContext *context;
|
||
|
||
gedit_debug (DEBUG_VIEW);
|
||
|
||
view->priv = gedit_view_get_instance_private (view);
|
||
|
||
/* Drag and drop support */
|
||
view->priv->direct_save_uri = NULL;
|
||
target_list = gtk_drag_dest_get_target_list (GTK_WIDGET (view));
|
||
|
||
if (target_list != NULL)
|
||
{
|
||
gtk_target_list_add (target_list,
|
||
gdk_atom_intern ("XdndDirectSave0", FALSE),
|
||
0,
|
||
TARGET_XDNDDIRECTSAVE);
|
||
gtk_target_list_add_uri_targets (target_list, TARGET_URI_LIST);
|
||
}
|
||
|
||
/* GeditViewActivatable */
|
||
view->priv->extensions =
|
||
peas_extension_set_new (PEAS_ENGINE (gedit_plugins_engine_get_default ()),
|
||
GEDIT_TYPE_VIEW_ACTIVATABLE,
|
||
"view", view,
|
||
NULL);
|
||
|
||
/* Act on buffer changes */
|
||
buffer_changed (view);
|
||
g_signal_connect (view,
|
||
"notify::buffer",
|
||
G_CALLBACK (buffer_notify_cb),
|
||
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
|
||
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
|
||
* reinstate a buffer which we don't want.
|
||
* There is no problem calling g_signal_handlers_disconnect_by_func()
|
||
* several times (if dispose() is called several times).
|
||
*/
|
||
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
|
||
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",
|
||
G_SETTINGS_BIND_GET);
|
||
|
||
g_settings_bind (editor_settings, GEDIT_SETTINGS_AUTO_INDENT,
|
||
view, "auto-indent",
|
||
G_SETTINGS_BIND_GET);
|
||
|
||
g_settings_bind (editor_settings, GEDIT_SETTINGS_TABS_SIZE,
|
||
view, "tab-width",
|
||
G_SETTINGS_BIND_GET);
|
||
|
||
g_settings_bind (editor_settings, GEDIT_SETTINGS_INSERT_SPACES,
|
||
view, "insert-spaces-instead-of-tabs",
|
||
G_SETTINGS_BIND_GET);
|
||
|
||
g_settings_bind (editor_settings, GEDIT_SETTINGS_DISPLAY_RIGHT_MARGIN,
|
||
view, "show-right-margin",
|
||
G_SETTINGS_BIND_GET);
|
||
|
||
g_settings_bind (editor_settings, GEDIT_SETTINGS_BACKGROUND_PATTERN,
|
||
view, "background-pattern",
|
||
G_SETTINGS_BIND_GET);
|
||
|
||
g_settings_bind (editor_settings, GEDIT_SETTINGS_RIGHT_MARGIN_POSITION,
|
||
view, "right-margin-position",
|
||
G_SETTINGS_BIND_GET);
|
||
|
||
g_settings_bind (editor_settings, GEDIT_SETTINGS_HIGHLIGHT_CURRENT_LINE,
|
||
@@ -693,31 +720,244 @@ gedit_view_class_init (GeditViewClass *klass)
|
||
GDK_CONTROL_MASK,
|
||
"change-case", 1,
|
||
G_TYPE_ENUM, GTK_SOURCE_CHANGE_CASE_LOWER);
|
||
|
||
gtk_binding_entry_add_signal (binding_set,
|
||
GDK_KEY_asciitilde,
|
||
GDK_CONTROL_MASK,
|
||
"change-case", 1,
|
||
G_TYPE_ENUM, GTK_SOURCE_CHANGE_CASE_TOGGLE);
|
||
}
|
||
|
||
/**
|
||
* gedit_view_new:
|
||
* @doc: a #GeditDocument
|
||
*
|
||
* Creates a new #GeditView object displaying the @doc document.
|
||
* @doc cannot be %NULL.
|
||
*
|
||
* Returns: a new #GeditView.
|
||
*/
|
||
GtkWidget *
|
||
gedit_view_new (GeditDocument *doc)
|
||
{
|
||
g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL);
|
||
|
||
return g_object_new (GEDIT_TYPE_VIEW,
|
||
"buffer", 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
|
||
@@ -1,67 +1,85 @@
|
||
/*
|
||
* This file is part of gedit
|
||
*
|
||
* Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
|
||
* Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
|
||
* Copyright (C) 2002-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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_VIEW_H
|
||
#define GEDIT_VIEW_H
|
||
|
||
+#include <gtk/gtk.h>
|
||
+
|
||
#include <gedit/gedit-document.h>
|
||
-#include <tepl/tepl.h>
|
||
+#include <gtksourceview/gtksource.h>
|
||
|
||
G_BEGIN_DECLS
|
||
|
||
#define GEDIT_TYPE_VIEW (gedit_view_get_type ())
|
||
#define GEDIT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GEDIT_TYPE_VIEW, GeditView))
|
||
#define GEDIT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GEDIT_TYPE_VIEW, GeditViewClass))
|
||
#define GEDIT_IS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GEDIT_TYPE_VIEW))
|
||
#define GEDIT_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_VIEW))
|
||
#define GEDIT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GEDIT_TYPE_VIEW, GeditViewClass))
|
||
|
||
typedef struct _GeditView GeditView;
|
||
typedef struct _GeditViewClass GeditViewClass;
|
||
typedef struct _GeditViewPrivate GeditViewPrivate;
|
||
|
||
struct _GeditView
|
||
{
|
||
- TeplView view;
|
||
+ GtkSourceView view;
|
||
|
||
/*< private >*/
|
||
GeditViewPrivate *priv;
|
||
};
|
||
|
||
struct _GeditViewClass
|
||
{
|
||
- TeplViewClass parent_class;
|
||
+ GtkSourceViewClass parent_class;
|
||
|
||
void (*drop_uris) (GeditView *view,
|
||
gchar **uri_list);
|
||
|
||
gpointer padding;
|
||
};
|
||
|
||
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 */
|
||
|
||
/* ex:set ts=8 noet: */
|
||
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
|
||
@@ -1,112 +1,119 @@
|
||
/*
|
||
* gedit-window-private.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
|
||
* 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef GEDIT_WINDOW_PRIVATE_H
|
||
#define GEDIT_WINDOW_PRIVATE_H
|
||
|
||
#include <libpeas/peas-extension-set.h>
|
||
|
||
#include "gedit/gedit-window.h"
|
||
#include "gedit-message-bus.h"
|
||
#include "gedit-settings.h"
|
||
#include "gedit-multi-notebook.h"
|
||
+#include "gedit-open-document-selector.h"
|
||
|
||
G_BEGIN_DECLS
|
||
|
||
/* WindowPrivate is in a separate .h so that we can access it from gedit-commands */
|
||
|
||
struct _GeditWindowPrivate
|
||
{
|
||
GSettings *editor_settings;
|
||
GSettings *ui_settings;
|
||
GSettings *window_settings;
|
||
|
||
GeditMultiNotebook *multi_notebook;
|
||
|
||
GtkWidget *side_panel;
|
||
GtkWidget *side_stack_switcher;
|
||
GtkWidget *side_panel_inline_stack_switcher;
|
||
GtkWidget *bottom_panel_box;
|
||
GtkWidget *bottom_panel;
|
||
|
||
GtkWidget *hpaned;
|
||
GtkWidget *vpaned;
|
||
|
||
GeditMessageBus *message_bus;
|
||
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;
|
||
GtkWidget *line_col_button;
|
||
GtkWidget *tab_width_button;
|
||
GtkWidget *language_button;
|
||
GtkWidget *language_button_label;
|
||
GtkWidget *language_popover;
|
||
guint generic_message_cid;
|
||
guint tip_message_cid;
|
||
guint bracket_match_message_cid;
|
||
guint tab_width_id;
|
||
guint language_changed_id;
|
||
guint wrap_mode_changed_id;
|
||
|
||
/* Headerbars */
|
||
GtkWidget *titlebar_paned;
|
||
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;
|
||
|
||
gint num_tabs_with_error;
|
||
|
||
gint width;
|
||
gint height;
|
||
GdkWindowState window_state;
|
||
|
||
gint side_panel_size;
|
||
gint bottom_panel_size;
|
||
|
||
GeditWindowState state;
|
||
|
||
guint inhibition_cookie;
|
||
|
||
gint bottom_panel_item_removed_handler_id;
|
||
|
||
GtkWindowGroup *window_group;
|
||
|
||
gchar *file_chooser_folder_uri;
|
||
|
||
gchar *direct_save_uri;
|
||
|
||
GSList *closed_docs_stack;
|
||
|
||
guint removing_tabs : 1;
|
||
guint dispose_has_run : 1;
|
||
|
||
guint in_fullscreen_eventbox : 1;
|
||
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
|
||
@@ -1,86 +1,92 @@
|
||
/*
|
||
* gedit-window.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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include "gedit-window.h"
|
||
|
||
#include <time.h>
|
||
#include <sys/types.h>
|
||
#include <string.h>
|
||
|
||
#include <glib/gi18n.h>
|
||
#include <libpeas/peas-extension-set.h>
|
||
-#include <tepl/tepl.h>
|
||
|
||
#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"
|
||
#include "gedit-statusbar.h"
|
||
#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"
|
||
#include "gedit-debug.h"
|
||
#include "gedit-document.h"
|
||
#include "gedit-document-private.h"
|
||
#include "gedit-documents-panel.h"
|
||
#include "gedit-plugins-engine.h"
|
||
#include "gedit-window-activatable.h"
|
||
#include "gedit-enum-types.h"
|
||
#include "gedit-dirs.h"
|
||
#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
|
||
{
|
||
PROP_0,
|
||
PROP_STATE,
|
||
LAST_PROP
|
||
};
|
||
|
||
static GParamSpec *properties[LAST_PROP];
|
||
|
||
enum
|
||
{
|
||
TAB_ADDED,
|
||
TAB_REMOVED,
|
||
TABS_REORDERED,
|
||
ACTIVE_TAB_CHANGED,
|
||
ACTIVE_TAB_STATE_CHANGED,
|
||
LAST_SIGNAL
|
||
};
|
||
|
||
static guint signals[LAST_SIGNAL];
|
||
|
||
enum
|
||
{
|
||
TARGET_URI_LIST = 100,
|
||
TARGET_XDNDDIRECTSAVE
|
||
};
|
||
|
||
static const GtkTargetEntry drop_types [] = {
|
||
{ "XdndDirectSave0", 0, TARGET_XDNDDIRECTSAVE }, /* XDS Protocol Type */
|
||
@@ -131,63 +137,63 @@ save_panels_state (GeditWindow *window)
|
||
{
|
||
g_settings_set_string (window->priv->window_settings,
|
||
GEDIT_SETTINGS_SIDE_PANEL_ACTIVE_PAGE,
|
||
panel_page);
|
||
}
|
||
|
||
if (window->priv->bottom_panel_size > 0)
|
||
{
|
||
g_settings_set_int (window->priv->window_settings,
|
||
GEDIT_SETTINGS_BOTTOM_PANEL_SIZE,
|
||
window->priv->bottom_panel_size);
|
||
}
|
||
|
||
panel_page = gtk_stack_get_visible_child_name (GTK_STACK (window->priv->bottom_panel));
|
||
if (panel_page != NULL)
|
||
{
|
||
g_settings_set_string (window->priv->window_settings,
|
||
GEDIT_SETTINGS_BOTTOM_PANEL_ACTIVE_PAGE,
|
||
panel_page);
|
||
}
|
||
|
||
g_settings_apply (window->priv->window_settings);
|
||
}
|
||
|
||
static void
|
||
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);
|
||
}
|
||
}
|
||
|
||
static void
|
||
gedit_window_dispose (GObject *object)
|
||
{
|
||
GeditWindow *window;
|
||
|
||
gedit_debug (DEBUG_WINDOW);
|
||
|
||
window = GEDIT_WINDOW (object);
|
||
|
||
/* Stop tracking removal of panels otherwise we always
|
||
* end up with thinking we had no panel active, since they
|
||
* should all be removed below */
|
||
if (window->priv->bottom_panel_item_removed_handler_id != 0)
|
||
{
|
||
g_signal_handler_disconnect (window->priv->bottom_panel,
|
||
window->priv->bottom_panel_item_removed_handler_id);
|
||
window->priv->bottom_panel_item_removed_handler_id = 0;
|
||
}
|
||
|
||
/* First of all, force collection so that plugins
|
||
* really drop some of the references.
|
||
*/
|
||
peas_engine_garbage_collect (PEAS_ENGINE (gedit_plugins_engine_get_default ()));
|
||
|
||
@@ -204,142 +210,160 @@ gedit_window_dispose (GObject *object)
|
||
|
||
peas_engine_garbage_collect (PEAS_ENGINE (gedit_plugins_engine_get_default ()));
|
||
|
||
window->priv->dispose_has_run = TRUE;
|
||
}
|
||
|
||
g_clear_object (&window->priv->message_bus);
|
||
g_clear_object (&window->priv->window_group);
|
||
|
||
/* We must free the settings after saving the panels */
|
||
g_clear_object (&window->priv->editor_settings);
|
||
g_clear_object (&window->priv->ui_settings);
|
||
g_clear_object (&window->priv->window_settings);
|
||
|
||
/* Now that there have broken some reference loops,
|
||
* force collection again.
|
||
*/
|
||
peas_engine_garbage_collect (PEAS_ENGINE (gedit_plugins_engine_get_default ()));
|
||
|
||
g_clear_object (&window->priv->side_stack_switcher);
|
||
|
||
/* GTK+/GIO unref the action map in an idle. For the last GeditWindow,
|
||
* the application quits before the idle, so the action map is not
|
||
* unreffed, and some objects are not finalized on application shutdown
|
||
* (GeditView for example).
|
||
* So this is just for making the debugging of object references a bit
|
||
* nicer.
|
||
*/
|
||
remove_actions (window);
|
||
|
||
- window->priv->fullscreen_open_recent_button = NULL;
|
||
-
|
||
G_OBJECT_CLASS (gedit_window_parent_class)->dispose (object);
|
||
}
|
||
|
||
static void
|
||
gedit_window_finalize (GObject *object)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (object);
|
||
|
||
g_free (window->priv->file_chooser_folder_uri);
|
||
g_slist_free_full (window->priv->closed_docs_stack, (GDestroyNotify)g_object_unref);
|
||
|
||
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)
|
||
{
|
||
GAction *fullscreen_action;
|
||
|
||
_gedit_multi_notebook_set_show_tabs (window->priv->multi_notebook, !is_fullscreen);
|
||
|
||
if (is_fullscreen)
|
||
{
|
||
gtk_widget_hide (window->priv->statusbar);
|
||
}
|
||
else
|
||
{
|
||
if (g_settings_get_boolean (window->priv->ui_settings, "statusbar-visible"))
|
||
{
|
||
gtk_widget_show (window->priv->statusbar);
|
||
}
|
||
}
|
||
|
||
+ gedit_multi_notebook_foreach_tab (window->priv->multi_notebook,
|
||
+ (GtkCallback)update_view_centering,
|
||
+ GBOOLEAN_TO_POINTER (is_fullscreen));
|
||
+
|
||
#ifndef OS_OSX
|
||
if (is_fullscreen)
|
||
{
|
||
gtk_widget_show_all (window->priv->fullscreen_eventbox);
|
||
}
|
||
else
|
||
{
|
||
gtk_widget_hide (window->priv->fullscreen_eventbox);
|
||
}
|
||
#endif
|
||
|
||
fullscreen_action = g_action_map_lookup_action (G_ACTION_MAP (window),
|
||
"fullscreen");
|
||
|
||
g_simple_action_set_state (G_SIMPLE_ACTION (fullscreen_action),
|
||
g_variant_new_boolean (is_fullscreen));
|
||
}
|
||
|
||
static gboolean
|
||
gedit_window_window_state_event (GtkWidget *widget,
|
||
GdkEventWindowState *event)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (widget);
|
||
|
||
window->priv->window_state = event->new_window_state;
|
||
|
||
g_settings_set_int (window->priv->window_settings, GEDIT_SETTINGS_WINDOW_STATE,
|
||
window->priv->window_state);
|
||
|
||
if ((event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) != 0)
|
||
{
|
||
update_fullscreen (window, (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) != 0);
|
||
}
|
||
|
||
return GTK_WIDGET_CLASS (gedit_window_parent_class)->window_state_event (widget, event);
|
||
}
|
||
|
||
static gboolean
|
||
gedit_window_configure_event (GtkWidget *widget,
|
||
GdkEventConfigure *event)
|
||
{
|
||
GeditWindow *window = GEDIT_WINDOW (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);
|
||
}
|
||
|
||
return GTK_WIDGET_CLASS (gedit_window_parent_class)->configure_event (widget, event);
|
||
}
|
||
|
||
/*
|
||
* GtkWindow catches keybindings for the menu items _before_ passing them to
|
||
* the focused widget. This is unfortunate and means that pressing ctrl+V
|
||
* in an entry on a panel ends up pasting text in the TextView.
|
||
* Here we override GtkWindow's handler to do the same things that it
|
||
* does, but in the opposite order and then we chain up to the grand
|
||
* parent handler, skipping gtk_window_key_press_event.
|
||
*/
|
||
static gboolean
|
||
gedit_window_key_press_event (GtkWidget *widget,
|
||
GdkEventKey *event)
|
||
{
|
||
static gpointer grand_parent_class = NULL;
|
||
|
||
GtkWindow *window = GTK_WINDOW (widget);
|
||
gboolean handled = FALSE;
|
||
|
||
if (grand_parent_class == NULL)
|
||
{
|
||
grand_parent_class = g_type_class_peek_parent (gedit_window_parent_class);
|
||
}
|
||
|
||
/* handle focus widget key events */
|
||
@@ -427,76 +451,78 @@ gedit_window_class_init (GeditWindowClass *klass)
|
||
G_SIGNAL_RUN_FIRST,
|
||
G_STRUCT_OFFSET (GeditWindowClass, tabs_reordered),
|
||
NULL, NULL, NULL,
|
||
G_TYPE_NONE,
|
||
0);
|
||
signals[ACTIVE_TAB_CHANGED] =
|
||
g_signal_new ("active-tab-changed",
|
||
G_OBJECT_CLASS_TYPE (object_class),
|
||
G_SIGNAL_RUN_FIRST,
|
||
G_STRUCT_OFFSET (GeditWindowClass, active_tab_changed),
|
||
NULL, NULL, NULL,
|
||
G_TYPE_NONE,
|
||
1,
|
||
GEDIT_TYPE_TAB);
|
||
signals[ACTIVE_TAB_STATE_CHANGED] =
|
||
g_signal_new ("active-tab-state-changed",
|
||
G_OBJECT_CLASS_TYPE (object_class),
|
||
G_SIGNAL_RUN_FIRST,
|
||
G_STRUCT_OFFSET (GeditWindowClass, active_tab_state_changed),
|
||
NULL, NULL, NULL,
|
||
G_TYPE_NONE,
|
||
0);
|
||
|
||
/* Bind class to template */
|
||
gtk_widget_class_set_template_from_resource (widget_class,
|
||
"/org/gnome/gedit/ui/gedit-window.ui");
|
||
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, titlebar_paned);
|
||
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);
|
||
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, side_panel_inline_stack_switcher);
|
||
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, vpaned);
|
||
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, multi_notebook);
|
||
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, bottom_panel_box);
|
||
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, bottom_panel);
|
||
gtk_widget_class_bind_template_child_private (widget_class, GeditWindow, statusbar);
|
||
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);
|
||
}
|
||
|
||
static void
|
||
received_clipboard_contents (GtkClipboard *clipboard,
|
||
GtkSelectionData *selection_data,
|
||
GeditWindow *window)
|
||
{
|
||
GeditTab *tab;
|
||
gboolean enabled;
|
||
GAction *action;
|
||
|
||
/* getting clipboard contents is async, so we need to
|
||
* get the current tab and its state */
|
||
|
||
tab = gedit_window_get_active_tab (window);
|
||
|
||
if (tab != NULL)
|
||
{
|
||
GeditTabState state;
|
||
gboolean state_normal;
|
||
|
||
state = gedit_tab_get_state (tab);
|
||
state_normal = (state == GEDIT_TAB_STATE_NORMAL);
|
||
|
||
enabled = state_normal &&
|
||
gtk_selection_data_targets_include_text (selection_data);
|
||
}
|
||
else
|
||
{
|
||
@@ -738,138 +764,178 @@ update_actions_sensitivity (GeditWindow *window)
|
||
|
||
/* We disable File->Quit/SaveAll/CloseAll while printing to avoid to have two
|
||
operations (save and print/print preview) that uses the message area at
|
||
the same time (may be we can remove this limitation in the future) */
|
||
/* We disable File->Quit/CloseAll if state is saving since saving cannot be
|
||
cancelled (may be we can remove this limitation in the future) */
|
||
action = g_action_map_lookup_action (G_ACTION_MAP (g_application_get_default ()),
|
||
"quit");
|
||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||
!(window->priv->state & GEDIT_WINDOW_STATE_SAVING) &&
|
||
!(window->priv->state & GEDIT_WINDOW_STATE_PRINTING));
|
||
|
||
action = g_action_map_lookup_action (G_ACTION_MAP (window), "save-all");
|
||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||
!(window->priv->state & GEDIT_WINDOW_STATE_PRINTING) &&
|
||
num_tabs > 0);
|
||
|
||
action = g_action_map_lookup_action (G_ACTION_MAP (window), "close-all");
|
||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||
num_tabs > 0 &&
|
||
!(window->priv->state & GEDIT_WINDOW_STATE_SAVING) &&
|
||
!(window->priv->state & GEDIT_WINDOW_STATE_PRINTING) &&
|
||
num_tabs > 0);
|
||
|
||
peas_extension_set_foreach (window->priv->extensions,
|
||
(PeasExtensionSetForeachFunc) extension_update_state,
|
||
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;
|
||
|
||
active_document = gedit_window_get_active_document (window);
|
||
if (active_document != NULL)
|
||
{
|
||
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;
|
||
|
||
active_document = gedit_window_get_active_document (window);
|
||
if (active_document != NULL)
|
||
{
|
||
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);
|
||
|
||
window->priv->generic_message_cid = gtk_statusbar_get_context_id
|
||
(GTK_STATUSBAR (window->priv->statusbar), "generic_message");
|
||
window->priv->tip_message_cid = gtk_statusbar_get_context_id
|
||
(GTK_STATUSBAR (window->priv->statusbar), "tip_message");
|
||
window->priv->bracket_match_message_cid = gtk_statusbar_get_context_id
|
||
(GTK_STATUSBAR (window->priv->statusbar), "bracket_match_message");
|
||
|
||
g_settings_bind (window->priv->ui_settings,
|
||
"statusbar-visible",
|
||
window->priv->statusbar,
|
||
"visible",
|
||
G_SETTINGS_BIND_GET);
|
||
|
||
/* Line Col button */
|
||
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (window->priv->line_col_button),
|
||
_gedit_app_get_line_col_menu (GEDIT_APP (g_application_get_default ())));
|
||
|
||
/* Tab Width button */
|
||
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (window->priv->tab_width_button),
|
||
_gedit_app_get_tab_width_menu (GEDIT_APP (g_application_get_default ())));
|
||
|
||
/* Language button */
|
||
window->priv->language_popover = gtk_popover_new (window->priv->language_button);
|
||
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 *
|
||
clone_window (GeditWindow *origin)
|
||
{
|
||
GeditWindow *window;
|
||
GdkScreen *screen;
|
||
GeditApp *app;
|
||
const gchar *panel_page;
|
||
|
||
gedit_debug (DEBUG_WINDOW);
|
||
|
||
app = GEDIT_APP (g_application_get_default ());
|
||
|
||
screen = gtk_window_get_screen (GTK_WINDOW (origin));
|
||
window = gedit_app_create_window (app, screen);
|
||
|
||
gtk_window_set_default_size (GTK_WINDOW (window),
|
||
origin->priv->width,
|
||
origin->priv->height);
|
||
|
||
if ((origin->priv->window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0)
|
||
gtk_window_maximize (GTK_WINDOW (window));
|
||
else
|
||
gtk_window_unmaximize (GTK_WINDOW (window));
|
||
|
||
if ((origin->priv->window_state & GDK_WINDOW_STATE_STICKY) != 0)
|
||
gtk_window_stick (GTK_WINDOW (window));
|
||
else
|
||
gtk_window_unstick (GTK_WINDOW (window));
|
||
@@ -1017,81 +1083,81 @@ set_title (GeditWindow *window)
|
||
gedit_app_set_window_title (GEDIT_APP (g_application_get_default ()),
|
||
window,
|
||
"gedit");
|
||
gtk_header_bar_set_title (GTK_HEADER_BAR (window->priv->headerbar),
|
||
"gedit");
|
||
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (window->priv->headerbar),
|
||
NULL);
|
||
gtk_header_bar_set_title (GTK_HEADER_BAR (window->priv->fullscreen_headerbar),
|
||
"gedit");
|
||
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (window->priv->fullscreen_headerbar),
|
||
NULL);
|
||
return;
|
||
}
|
||
|
||
doc = gedit_tab_get_document (tab);
|
||
g_return_if_fail (doc != NULL);
|
||
|
||
file = gedit_document_get_file (doc);
|
||
|
||
name = gedit_document_get_short_name_for_display (doc);
|
||
|
||
len = g_utf8_strlen (name, -1);
|
||
|
||
/* if the name is awfully long, truncate it and be done with it,
|
||
* otherwise also show the directory (ellipsized if needed)
|
||
*/
|
||
if (len > MAX_TITLE_LENGTH)
|
||
{
|
||
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;
|
||
}
|
||
else
|
||
{
|
||
GFile *location = gtk_source_file_get_location (file);
|
||
|
||
if (location != NULL)
|
||
{
|
||
gchar *str = gedit_utils_location_get_dirname_for_display (location);
|
||
|
||
/* use the remaining space for the dir, but use a min of 20 chars
|
||
* so that we do not end up with a dirname like "(a...b)".
|
||
* This means that in the worst case when the filename is long 99
|
||
* 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);
|
||
}
|
||
}
|
||
|
||
if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)))
|
||
{
|
||
gchar *tmp_name;
|
||
|
||
tmp_name = g_strdup_printf ("*%s", name);
|
||
g_free (name);
|
||
|
||
name = tmp_name;
|
||
}
|
||
|
||
if (gtk_source_file_is_readonly (file))
|
||
{
|
||
title = g_strdup_printf ("%s [%s]",
|
||
name, _("Read-Only"));
|
||
|
||
if (dirname != NULL)
|
||
{
|
||
main_title = g_strdup_printf ("%s [%s] (%s) - gedit",
|
||
name,
|
||
_("Read-Only"),
|
||
dirname);
|
||
subtitle = dirname;
|
||
}
|
||
else
|
||
{
|
||
main_title = g_strdup_printf ("%s [%s] - gedit",
|
||
@@ -1663,142 +1729,138 @@ drag_drop_cb (GtkWidget *widget,
|
||
|
||
found = gtk_target_list_find (target_list, target, &info);
|
||
g_assert (found);
|
||
|
||
if (info == TARGET_XDNDDIRECTSAVE)
|
||
{
|
||
gchar *uri;
|
||
uri = gedit_utils_set_direct_save_filename (context);
|
||
|
||
if (uri != NULL)
|
||
{
|
||
g_free (window->priv->direct_save_uri);
|
||
window->priv->direct_save_uri = uri;
|
||
}
|
||
}
|
||
|
||
gtk_drag_get_data (GTK_WIDGET (widget), context,
|
||
target, time);
|
||
}
|
||
}
|
||
|
||
/* Handle drops on the GeditView */
|
||
static void
|
||
drop_uris_cb (GtkWidget *widget,
|
||
gchar **uri_list,
|
||
GeditWindow *window)
|
||
{
|
||
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);
|
||
}
|
||
|
||
static void
|
||
empty_search_notify_cb (GeditDocument *doc,
|
||
GParamSpec *pspec,
|
||
GeditWindow *window)
|
||
{
|
||
if (doc == gedit_window_get_active_document (window))
|
||
{
|
||
update_actions_sensitivity (window);
|
||
}
|
||
}
|
||
|
||
static void
|
||
can_undo (GeditDocument *doc,
|
||
GParamSpec *pspec,
|
||
GeditWindow *window)
|
||
{
|
||
if (doc == gedit_window_get_active_document (window))
|
||
{
|
||
update_actions_sensitivity (window);
|
||
}
|
||
}
|
||
|
||
static void
|
||
can_redo (GeditDocument *doc,
|
||
GParamSpec *pspec,
|
||
GeditWindow *window)
|
||
{
|
||
@@ -1858,61 +1920,61 @@ on_tab_added (GeditMultiNotebook *multi,
|
||
update_actions_sensitivity (window);
|
||
|
||
view = gedit_tab_get_view (tab);
|
||
doc = gedit_tab_get_document (tab);
|
||
file = gedit_document_get_file (doc);
|
||
|
||
/* IMPORTANT: remember to disconnect the signal in notebook_tab_removed
|
||
* if a new signal is connected here */
|
||
|
||
g_signal_connect (tab,
|
||
"notify::name",
|
||
G_CALLBACK (sync_name),
|
||
window);
|
||
g_signal_connect (tab,
|
||
"notify::state",
|
||
G_CALLBACK (sync_state),
|
||
window);
|
||
g_signal_connect (tab,
|
||
"notify::can-close",
|
||
G_CALLBACK (sync_can_close),
|
||
window);
|
||
g_signal_connect (tab,
|
||
"drop_uris",
|
||
G_CALLBACK (drop_uris_cb),
|
||
window);
|
||
g_signal_connect (doc,
|
||
"bracket-matched",
|
||
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,
|
||
"notify::empty-search",
|
||
G_CALLBACK (empty_search_notify_cb),
|
||
window);
|
||
g_signal_connect (doc,
|
||
"notify::can-undo",
|
||
G_CALLBACK (can_undo),
|
||
window);
|
||
g_signal_connect (doc,
|
||
"notify::can-redo",
|
||
G_CALLBACK (can_redo),
|
||
window);
|
||
g_signal_connect (doc,
|
||
"notify::has-selection",
|
||
G_CALLBACK (selection_changed),
|
||
window);
|
||
g_signal_connect (view,
|
||
"notify::overwrite",
|
||
G_CALLBACK (overwrite_mode_changed),
|
||
window);
|
||
g_signal_connect (view,
|
||
"notify::editable",
|
||
G_CALLBACK (editable_changed),
|
||
window);
|
||
g_signal_connect (file,
|
||
"notify::read-only",
|
||
G_CALLBACK (readonly_changed),
|
||
window);
|
||
@@ -2117,64 +2179,77 @@ on_show_popup_menu (GeditMultiNotebook *multi,
|
||
}
|
||
|
||
menu = gedit_notebook_popup_menu_new (window, tab);
|
||
|
||
g_signal_connect (menu,
|
||
"selection-done",
|
||
G_CALLBACK (gtk_widget_destroy),
|
||
NULL);
|
||
|
||
gtk_widget_show (menu);
|
||
gtk_menu_popup_at_pointer (GTK_MENU (menu), (GdkEvent *)event);
|
||
}
|
||
|
||
static void
|
||
on_notebook_changed (GeditMultiNotebook *mnb,
|
||
GParamSpec *pspec,
|
||
GeditWindow *window)
|
||
{
|
||
update_actions_sensitivity (window);
|
||
}
|
||
|
||
static void
|
||
on_notebook_removed (GeditMultiNotebook *mnb,
|
||
GeditNotebook *notebook,
|
||
GeditWindow *window)
|
||
{
|
||
update_actions_sensitivity (window);
|
||
}
|
||
|
||
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
|
||
side_panel_size_allocate (GtkWidget *widget,
|
||
GtkAllocation *allocation,
|
||
GeditWindow *window)
|
||
{
|
||
window->priv->side_panel_size = allocation->width;
|
||
}
|
||
|
||
static void
|
||
bottom_panel_size_allocate (GtkWidget *widget,
|
||
GtkAllocation *allocation,
|
||
GeditWindow *window)
|
||
{
|
||
window->priv->bottom_panel_size = allocation->height;
|
||
}
|
||
|
||
static void
|
||
hpaned_restore_position (GtkWidget *widget,
|
||
GeditWindow *window)
|
||
{
|
||
gint pos;
|
||
|
||
gedit_debug_message (DEBUG_WINDOW,
|
||
"Restoring hpaned position: side panel size %d",
|
||
window->priv->side_panel_size);
|
||
|
||
pos = MAX (100, window->priv->side_panel_size);
|
||
gtk_paned_set_position (GTK_PANED (window->priv->hpaned), pos);
|
||
@@ -2510,60 +2585,72 @@ clipboard_owner_change (GtkClipboard *clipboard,
|
||
|
||
static void
|
||
window_realized (GtkWidget *window,
|
||
gpointer *data)
|
||
{
|
||
GtkClipboard *clipboard;
|
||
|
||
clipboard = gtk_widget_get_clipboard (window,
|
||
GDK_SELECTION_CLIPBOARD);
|
||
|
||
g_signal_connect (clipboard,
|
||
"owner_change",
|
||
G_CALLBACK (clipboard_owner_change),
|
||
window);
|
||
}
|
||
|
||
static void
|
||
window_unrealized (GtkWidget *window,
|
||
gpointer *data)
|
||
{
|
||
GtkClipboard *clipboard;
|
||
|
||
clipboard = gtk_widget_get_clipboard (window,
|
||
GDK_SELECTION_CLIPBOARD);
|
||
|
||
g_signal_handlers_disconnect_by_func (clipboard,
|
||
G_CALLBACK (clipboard_owner_change),
|
||
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,
|
||
PeasExtension *exten,
|
||
GeditWindow *window)
|
||
{
|
||
gedit_window_activatable_activate (GEDIT_WINDOW_ACTIVATABLE (exten));
|
||
}
|
||
|
||
static void
|
||
extension_removed (PeasExtensionSet *extensions,
|
||
PeasPluginInfo *info,
|
||
PeasExtension *exten,
|
||
GeditWindow *window)
|
||
{
|
||
gedit_window_activatable_deactivate (GEDIT_WINDOW_ACTIVATABLE (exten));
|
||
}
|
||
|
||
static GActionEntry win_entries[] = {
|
||
{ "new-tab", _gedit_cmd_file_new },
|
||
{ "open", _gedit_cmd_file_open },
|
||
{ "revert", _gedit_cmd_file_revert },
|
||
{ "reopen-closed-tab", _gedit_cmd_file_reopen_closed_tab },
|
||
{ "save", _gedit_cmd_file_save },
|
||
{ "save-as", _gedit_cmd_file_save_as },
|
||
{ "save-all", _gedit_cmd_file_save_all },
|
||
{ "close", _gedit_cmd_file_close },
|
||
{ "close-all", _gedit_cmd_file_close_all },
|
||
{ "print", _gedit_cmd_file_print },
|
||
{ "focus-active-view", NULL, NULL, "false", _gedit_cmd_view_focus_active },
|
||
@@ -2581,188 +2668,145 @@ static GActionEntry win_entries[] = {
|
||
{ "previous-tab-group", _gedit_cmd_documents_previous_tab_group },
|
||
{ "next-tab-group", _gedit_cmd_documents_next_tab_group },
|
||
{ "previous-document", _gedit_cmd_documents_previous_document },
|
||
{ "next-document", _gedit_cmd_documents_next_document },
|
||
{ "move-to-new-window", _gedit_cmd_documents_move_to_new_window },
|
||
{ "undo", _gedit_cmd_edit_undo },
|
||
{ "redo", _gedit_cmd_edit_redo },
|
||
{ "cut", _gedit_cmd_edit_cut },
|
||
{ "copy", _gedit_cmd_edit_copy },
|
||
{ "paste", _gedit_cmd_edit_paste },
|
||
{ "delete", _gedit_cmd_edit_delete },
|
||
{ "select-all", _gedit_cmd_edit_select_all },
|
||
{ "highlight-mode", _gedit_cmd_view_highlight_mode },
|
||
{ "overwrite-mode", NULL, NULL, "false", _gedit_cmd_edit_overwrite_mode }
|
||
};
|
||
|
||
static void
|
||
sync_fullscreen_actions (GeditWindow *window,
|
||
gboolean fullscreen)
|
||
{
|
||
GtkMenuButton *button;
|
||
GPropertyAction *action;
|
||
|
||
button = fullscreen ? window->priv->fullscreen_gear_button : window->priv->gear_button;
|
||
g_action_map_remove_action (G_ACTION_MAP (window), "hamburger-menu");
|
||
action = g_property_action_new ("hamburger-menu", button, "active");
|
||
g_action_map_add_action (G_ACTION_MAP (window), G_ACTION (action));
|
||
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)
|
||
{
|
||
GtkTargetList *tl;
|
||
GMenuModel *hamburger_menu;
|
||
|
||
gedit_debug (DEBUG_WINDOW);
|
||
|
||
window->priv = gedit_window_get_instance_private (window);
|
||
|
||
window->priv->removing_tabs = FALSE;
|
||
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");
|
||
window->priv->ui_settings = g_settings_new ("org.gnome.gedit.preferences.ui");
|
||
|
||
/* window settings are applied only once the window is closed. We do not
|
||
want to keep writing to disk when the window is dragged around */
|
||
window->priv->window_settings = g_settings_new ("org.gnome.gedit.state.window");
|
||
g_settings_delay (window->priv->window_settings);
|
||
|
||
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,
|
||
G_N_ELEMENTS (win_entries),
|
||
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)
|
||
{
|
||
gtk_menu_button_set_menu_model (window->priv->gear_button, hamburger_menu);
|
||
gtk_menu_button_set_menu_model (window->priv->fullscreen_gear_button, hamburger_menu);
|
||
}
|
||
else
|
||
{
|
||
gtk_widget_hide (GTK_WIDGET (window->priv->gear_button));
|
||
gtk_widget_hide (GTK_WIDGET (window->priv->fullscreen_gear_button));
|
||
gtk_widget_set_no_show_all (GTK_WIDGET (window->priv->gear_button), TRUE);
|
||
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 */
|
||
setup_statusbar (window);
|
||
|
||
/* Setup main area */
|
||
g_signal_connect (window->priv->multi_notebook,
|
||
"notebook-removed",
|
||
G_CALLBACK (on_notebook_removed),
|
||
window);
|
||
g_signal_connect (window->priv->multi_notebook,
|
||
"notify::active-notebook",
|
||
G_CALLBACK (on_notebook_changed),
|
||
window);
|
||
|
||
g_signal_connect (window->priv->multi_notebook,
|
||
"tab-added",
|
||
G_CALLBACK (on_tab_added),
|
||
window);
|
||
|
||
g_signal_connect (window->priv->multi_notebook,
|
||
"tab-removed",
|
||
G_CALLBACK (on_tab_removed),
|
||
window);
|
||
|
||
g_signal_connect (window->priv->multi_notebook,
|
||
"switch-tab",
|
||
G_CALLBACK (tab_switched),
|
||
window);
|
||
|
||
@@ -2822,60 +2866,66 @@ gedit_window_init (GeditWindow *window)
|
||
{
|
||
tl = gtk_target_list_new (drop_types, G_N_ELEMENTS (drop_types));
|
||
gtk_drag_dest_set_target_list (GTK_WIDGET (window), tl);
|
||
gtk_target_list_unref (tl);
|
||
}
|
||
|
||
gtk_target_list_add_uri_targets (tl, TARGET_URI_LIST);
|
||
|
||
/* connect instead of override, so that we can
|
||
* share the cb code with the view */
|
||
g_signal_connect (window,
|
||
"drag_data_received",
|
||
G_CALLBACK (drag_data_received_cb),
|
||
NULL);
|
||
g_signal_connect (window,
|
||
"drag_drop",
|
||
G_CALLBACK (drag_drop_cb),
|
||
NULL);
|
||
|
||
/* we can get the clipboard only after the widget
|
||
* is realized */
|
||
g_signal_connect (window,
|
||
"realize",
|
||
G_CALLBACK (window_realized),
|
||
NULL);
|
||
g_signal_connect (window,
|
||
"unrealize",
|
||
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 ()),
|
||
GEDIT_TYPE_WINDOW_ACTIVATABLE,
|
||
"window", window,
|
||
NULL);
|
||
g_signal_connect (window->priv->extensions,
|
||
"extension-added",
|
||
G_CALLBACK (extension_added),
|
||
window);
|
||
g_signal_connect (window->priv->extensions,
|
||
"extension-removed",
|
||
G_CALLBACK (extension_removed),
|
||
window);
|
||
peas_extension_set_foreach (window->priv->extensions,
|
||
(PeasExtensionSetForeachFunc) extension_added,
|
||
window);
|
||
|
||
/* set visibility of panels.
|
||
* This needs to be done after plugins activatation */
|
||
init_panels_visibility (window);
|
||
|
||
update_actions_sensitivity (window);
|
||
|
||
gedit_debug_message (DEBUG_WINDOW, "END");
|
||
}
|
||
|
||
/**
|
||
* gedit_window_get_active_view:
|
||
* @window: a #GeditWindow
|
||
diff --git a/gedit/gedit.c b/gedit/gedit.c
|
||
index fcffdaca6..ee3769537 100644
|
||
--- a/gedit/gedit.c
|
||
+++ b/gedit/gedit.c
|
||
@@ -1,67 +1,66 @@
|
||
/*
|
||
* gedit.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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "config.h"
|
||
|
||
#include "gedit-app.h"
|
||
|
||
#if defined OS_OSX
|
||
# include "gedit-app-osx.h"
|
||
#elif defined G_OS_WIN32
|
||
# include "gedit-app-win32.h"
|
||
#endif
|
||
|
||
+#include <glib.h>
|
||
#include <locale.h>
|
||
#include <libintl.h>
|
||
-#include <tepl/tepl.h>
|
||
|
||
#include "gedit-dirs.h"
|
||
#include "gedit-debug.h"
|
||
-#include "gedit-factory.h"
|
||
#include "gedit-settings.h"
|
||
|
||
#ifdef G_OS_WIN32
|
||
#include <gmodule.h>
|
||
static GModule *libgedit_dll = NULL;
|
||
|
||
/* This code must live in gedit.exe, not in libgedit.dll, since the whole
|
||
* point is to find and load libgedit.dll.
|
||
*/
|
||
static gboolean
|
||
gedit_w32_load_private_dll (void)
|
||
{
|
||
gchar *dllpath;
|
||
gchar *prefix;
|
||
|
||
prefix = g_win32_get_package_installation_directory_of_module (NULL);
|
||
|
||
if (prefix != NULL)
|
||
{
|
||
/* Instead of g_module_open () it may be possible to do any of the
|
||
* following:
|
||
* A) Change PATH to "${dllpath}/lib/gedit;$PATH"
|
||
* B) Call SetDllDirectory ("${dllpath}/lib/gedit")
|
||
* C) Call AddDllDirectory ("${dllpath}/lib/gedit")
|
||
* But since we only have one library, and its name is known, may as well
|
||
* use gmodule.
|
||
*/
|
||
dllpath = g_build_filename (prefix, "lib", "gedit", "lib" PACKAGE_STRING ".dll", NULL);
|
||
g_free (prefix);
|
||
|
||
@@ -90,91 +89,86 @@ gedit_w32_load_private_dll (void)
|
||
|
||
static void
|
||
gedit_w32_unload_private_dll (void)
|
||
{
|
||
if (libgedit_dll)
|
||
{
|
||
g_module_close (libgedit_dll);
|
||
libgedit_dll = NULL;
|
||
}
|
||
}
|
||
#endif /* G_OS_WIN32 */
|
||
|
||
static void
|
||
setup_i18n (void)
|
||
{
|
||
const gchar *dir;
|
||
|
||
setlocale (LC_ALL, "");
|
||
|
||
dir = gedit_dirs_get_gedit_locale_dir ();
|
||
bindtextdomain (GETTEXT_PACKAGE, dir);
|
||
|
||
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||
textdomain (GETTEXT_PACKAGE);
|
||
}
|
||
|
||
int
|
||
main (int argc, char *argv[])
|
||
{
|
||
GType type;
|
||
- GeditFactory *factory;
|
||
GeditApp *app;
|
||
gint status;
|
||
|
||
#if defined OS_OSX
|
||
type = GEDIT_TYPE_APP_OSX;
|
||
#elif defined G_OS_WIN32
|
||
if (!gedit_w32_load_private_dll ())
|
||
{
|
||
return 1;
|
||
}
|
||
|
||
type = GEDIT_TYPE_APP_WIN32;
|
||
#else
|
||
type = GEDIT_TYPE_APP;
|
||
#endif
|
||
|
||
/* NOTE: we should not make any calls to the gedit API before the
|
||
* private library is loaded.
|
||
*/
|
||
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",
|
||
"flags", G_APPLICATION_HANDLES_COMMAND_LINE | G_APPLICATION_HANDLES_OPEN,
|
||
NULL);
|
||
|
||
status = g_application_run (G_APPLICATION (app), argc, argv);
|
||
|
||
gedit_settings_unref_singleton ();
|
||
|
||
/* Break reference cycles caused by the PeasExtensionSet
|
||
* for GeditAppActivatable which holds a ref on the GeditApp
|
||
*/
|
||
g_object_run_dispose (G_OBJECT (app));
|
||
|
||
g_object_add_weak_pointer (G_OBJECT (app), (gpointer *) &app);
|
||
g_object_unref (app);
|
||
|
||
if (app != NULL)
|
||
{
|
||
gedit_debug_message (DEBUG_APP, "Leaking with %i refs",
|
||
G_OBJECT (app)->ref_count);
|
||
}
|
||
|
||
- tepl_finalize ();
|
||
gedit_dirs_shutdown ();
|
||
|
||
#ifdef G_OS_WIN32
|
||
gedit_w32_unload_private_dll ();
|
||
#endif
|
||
|
||
return status;
|
||
}
|
||
|
||
/* ex:set ts=8 noet: */
|
||
diff --git a/gedit/meson.build b/gedit/meson.build
|
||
index 214c2b9a5..51472f12d 100644
|
||
--- a/gedit/meson.build
|
||
+++ b/gedit/meson.build
|
||
@@ -1,149 +1,166 @@
|
||
libgedit_public_headers = [
|
||
'gedit-app-activatable.h',
|
||
'gedit-app.h',
|
||
'gedit-commands.h',
|
||
'gedit-debug.h',
|
||
'gedit-document.h',
|
||
'gedit-encodings-combo-box.h',
|
||
'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',
|
||
'gedit-view-activatable.h',
|
||
'gedit-view.h',
|
||
'gedit-window-activatable.h',
|
||
'gedit-window.h',
|
||
]
|
||
|
||
libgedit_public_sources = [
|
||
'gedit-app-activatable.c',
|
||
'gedit-app.c',
|
||
'gedit-commands-file.c',
|
||
'gedit-debug.c',
|
||
'gedit-document.c',
|
||
'gedit-encodings-combo-box.c',
|
||
'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',
|
||
]
|
||
|
||
libgedit_private_headers = [
|
||
'gedit-app-osx.h',
|
||
'gedit-app-win32.h',
|
||
'gedit-close-confirmation-dialog.h',
|
||
'gedit-dirs.h',
|
||
'gedit-document-private.h',
|
||
'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',
|
||
]
|
||
|
||
libgedit_private_sources = [
|
||
'gedit-close-confirmation-dialog.c',
|
||
'gedit-commands-documents.c',
|
||
'gedit-commands-edit.c',
|
||
'gedit-commands-file-print.c',
|
||
'gedit-commands-help.c',
|
||
'gedit-commands-search.c',
|
||
'gedit-commands-view.c',
|
||
'gedit-dirs.c',
|
||
'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',
|
||
'gedit-print-preview.c',
|
||
'gedit-recent.c',
|
||
'gedit-replace-dialog.c',
|
||
'gedit-settings.c',
|
||
'gedit-status-menu-button.c',
|
||
'gedit-tab-label.c',
|
||
'gedit-view-frame.c',
|
||
]
|
||
|
||
libgedit_c_args = []
|
||
libgedit_link_args = []
|
||
|
||
libgedit_deps = [
|
||
deps_basic_list,
|
||
libgd_dep,
|
||
+ libxml_dep,
|
||
]
|
||
|
||
if host_machine.system() == 'darwin'
|
||
libgedit_private_sources += [
|
||
'gedit-app-osx.m',
|
||
'gedit-recent-osx.c',
|
||
]
|
||
libgedit_c_args += [
|
||
'-DOS_OSX=1',
|
||
]
|
||
libgedit_link_args += [
|
||
'-Wl,-framework', '-Wl,Foundation',
|
||
'-Wl,-framework', '-Wl,AppKit',
|
||
]
|
||
libgedit_deps += [
|
||
dependency('gtk-mac-integration-gtk3'),
|
||
]
|
||
elif host_machine.system() == 'windows'
|
||
libgedit_private_sources += [
|
||
'gedit-app-win32.c',
|
||
]
|
||
endif
|
||
|
||
headers_install_dir = get_option('includedir') / 'gedit-@0@/gedit/'.format(api_version)
|
||
install_headers(
|
||
libgedit_public_headers,
|
||
install_dir: headers_install_dir,
|
||
)
|
||
|
||
libgedit_public_enum_types = gnome.mkenums_simple(
|
||
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
|
||
@@ -1,31 +1,43 @@
|
||
.gedit-side-panel-paned.pane-separator:dir(ltr),
|
||
.gedit-side-panel-paned.pane-separator:hover:dir(ltr) {
|
||
border-radius: 0;
|
||
border-width: 0 1px 0 0;
|
||
}
|
||
|
||
.gedit-side-panel-paned.pane-separator:dir(rtl),
|
||
.gedit-side-panel-paned.pane-separator:hover:dir(rtl) {
|
||
border-radius: 0;
|
||
border-width: 0 0 0 1px;
|
||
}
|
||
|
||
.gedit-menu-stack-switcher {
|
||
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;
|
||
padding-right: 6px;
|
||
}
|
||
|
||
statusbar button.flat {
|
||
border-radius: 0;
|
||
border-bottom: none;
|
||
}
|
||
|
||
GeditFileBrowserWidget .small-button {
|
||
padding: 2px 4px;
|
||
}
|
||
|
||
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,30 +1,55 @@
|
||
+.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;
|
||
}
|
||
|
||
.gedit-document-panel:backdrop {
|
||
color: #b0b2b2;
|
||
}
|
||
|
||
.gedit-document-panel row:selected:backdrop {
|
||
background-color: #8b8e8f;
|
||
}
|
||
|
||
.gedit-document-panel-group-row,
|
||
.gedit-document-panel-group-row:hover {
|
||
border-top: 1px solid alpha(currentColor, 0.3);
|
||
}
|
||
|
||
.gedit-document-panel-group-row:first-child,
|
||
.gedit-document-panel-group-row:first-child:hover {
|
||
border-top: 0px;
|
||
}
|
||
|
||
/* Try to look as the notebook tab close button */
|
||
.gedit-document-panel row button.flat {
|
||
padding: 0;
|
||
margin-top: 8px;
|
||
margin-bottom: 8px;
|
||
min-width: 18px;
|
||
min-height: 18px;
|
||
color: alpha(currentColor,0.3);
|
||
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
|
||
@@ -1,23 +1,27 @@
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<gresources>
|
||
<gresource prefix="/org/gnome/gedit">
|
||
<file preprocess="xml-stripblanks">gtk/menus.ui</file>
|
||
<file preprocess="xml-stripblanks">gtk/menus-common.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-encodings-dialog.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-preferences-dialog.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-replace-dialog.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-print-preview.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-print-preferences.ui</file>
|
||
+ <file preprocess="xml-stripblanks">ui/gedit-progress-info-bar.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-status-menu-button.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-tab-label.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-view-frame.ui</file>
|
||
+ <file preprocess="xml-stripblanks">ui/gedit-highlight-mode-dialog.ui</file>
|
||
+ <file preprocess="xml-stripblanks">ui/gedit-highlight-mode-selector.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-window.ui</file>
|
||
+ <file preprocess="xml-stripblanks">ui/gedit-open-document-selector.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-shortcuts.ui</file>
|
||
<file preprocess="xml-stripblanks">ui/gedit-statusbar.ui</file>
|
||
<file>css/gedit-style.css</file>
|
||
<file>css/gedit.adwaita.css</file>
|
||
<file>css/gedit.highcontrast.css</file>
|
||
|
||
@OS_DEPENDENT_RESOURCE_FILES@
|
||
</gresource>
|
||
</gresources>
|
||
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 @@
|
||
+<?xml version="1.0" encoding="UTF-8"?>
|
||
+<interface>
|
||
+ <!-- interface-requires gtk+ 3.8 -->
|
||
+ <template class="GeditHighlightModeDialog" parent="GtkDialog">
|
||
+ <property name="width_request">300</property>
|
||
+ <property name="height_request">400</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <property name="border_width">5</property>
|
||
+ <property name="title" translatable="yes">Highlight Mode</property>
|
||
+ <property name="type_hint">dialog</property>
|
||
+ <property name="modal">True</property>
|
||
+ <child internal-child="vbox">
|
||
+ <object class="GtkBox" id="dialog-vbox1">
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <property name="orientation">vertical</property>
|
||
+ <property name="spacing">2</property>
|
||
+ <child internal-child="action_area">
|
||
+ <object class="GtkButtonBox" id="dialog-action_area1">
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <property name="layout_style">end</property>
|
||
+ <property name="border_width">5</property>
|
||
+ <property name="spacing">6</property>
|
||
+ <child>
|
||
+ <object class="GtkButton" id="cancel_button">
|
||
+ <property name="label" translatable="yes">_Cancel</property>
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <property name="receives_default">True</property>
|
||
+ <property name="use_underline">True</property>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">0</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkButton" id="ok_button">
|
||
+ <property name="label" translatable="yes">_Select</property>
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <property name="receives_default">True</property>
|
||
+ <property name="can_default">True</property>
|
||
+ <property name="use_underline">True</property>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">1</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="pack_type">end</property>
|
||
+ <property name="position">0</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GeditHighlightModeSelector" id="selector">
|
||
+ <property name="visible">True</property>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">1</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ </object>
|
||
+ </child>
|
||
+ <action-widgets>
|
||
+ <action-widget response="-6">cancel_button</action-widget>
|
||
+ <action-widget response="-5">ok_button</action-widget>
|
||
+ </action-widgets>
|
||
+ </template>
|
||
+</interface>
|
||
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 @@
|
||
+<?xml version="1.0" encoding="UTF-8"?>
|
||
+<interface>
|
||
+ <!-- interface-requires gtk+ 3.8 -->
|
||
+ <object class="GtkListStore" id="liststore">
|
||
+ <columns>
|
||
+ <!-- column-name name -->
|
||
+ <column type="gchararray"/>
|
||
+ <!-- column-name lang -->
|
||
+ <column type="GtkSourceLanguage"/>
|
||
+ </columns>
|
||
+ </object>
|
||
+ <object class="GtkTreeModelFilter" id="treemodelfilter">
|
||
+ <property name="child_model">liststore</property>
|
||
+ </object>
|
||
+ <template class="GeditHighlightModeSelector" parent="GtkGrid">
|
||
+ <property name="width_request">300</property>
|
||
+ <property name="height_request">400</property>
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <property name="row_spacing">3</property>
|
||
+ <property name="border_width">6</property>
|
||
+ <child>
|
||
+ <object class="GtkSearchEntry" id="entry">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="has_focus">True</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <property name="activates_default">True</property>
|
||
+ <property name="placeholder_text" translatable="yes">Search highlight mode…</property>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="left_attach">0</property>
|
||
+ <property name="top_attach">0</property>
|
||
+ <property name="width">1</property>
|
||
+ <property name="height">1</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <property name="hexpand">True</property>
|
||
+ <property name="vexpand">True</property>
|
||
+ <property name="shadow_type">in</property>
|
||
+ <child>
|
||
+ <object class="GtkTreeView" id="treeview">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <property name="model">treemodelfilter</property>
|
||
+ <property name="headers_visible">False</property>
|
||
+ <property name="headers_clickable">False</property>
|
||
+ <property name="enable_search">False</property>
|
||
+ <child internal-child="selection">
|
||
+ <object class="GtkTreeSelection" id="treeview_selection"/>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkTreeViewColumn" id="treeviewcolumn">
|
||
+ <child>
|
||
+ <object class="GtkCellRendererText" id="cellrenderertext"/>
|
||
+ <attributes>
|
||
+ <attribute name="text">0</attribute>
|
||
+ </attributes>
|
||
+ </child>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="left_attach">0</property>
|
||
+ <property name="top_attach">1</property>
|
||
+ <property name="width">1</property>
|
||
+ <property name="height">1</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ </template>
|
||
+</interface>
|
||
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 @@
|
||
+<?xml version="1.0" encoding="UTF-8"?>
|
||
+<interface>
|
||
+ <requires lib="gtk+" version="3.10"/>
|
||
+ <template class="GeditOpenDocumentSelector" parent="GtkBox">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="border_width">9</property>
|
||
+ <property name="orientation">vertical</property>
|
||
+ <property name="spacing">6</property>
|
||
+ <child>
|
||
+ <object class="GtkSearchEntry" id="search_entry">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="primary_icon_name">edit-find-symbolic</property>
|
||
+ <property name="primary_icon_activatable">False</property>
|
||
+ <property name="primary_icon_sensitive">False</property>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">False</property>
|
||
+ <property name="position">0</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkFrame" id="placeholder_box">
|
||
+ <property name="visible">False</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="hexpand">True</property>
|
||
+ <property name="vexpand">True</property>
|
||
+ <property name="shadow_type">in</property>
|
||
+ <child>
|
||
+ <object class="GtkBox" id="placeholder_inner_box">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="orientation">vertical</property>
|
||
+ <property name="halign">center</property>
|
||
+ <property name="valign">center</property>
|
||
+ <child>
|
||
+ <object class="GtkImage" id="placeholder_image">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="icon_name">edit-find-symbolic</property>
|
||
+ <property name="pixel_size">64</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <style>
|
||
+ <class name="dim-label"/>
|
||
+ </style>
|
||
+ </object>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkLabel" id="placeholder_label">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="sensitive">False</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="label" translatable="yes">No results</property>
|
||
+ <style>
|
||
+ <class name="dim-label"/>
|
||
+ </style>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">True</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">1</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkScrolledWindow" id="scrolled_window">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="hexpand">True</property>
|
||
+ <property name="vexpand">True</property>
|
||
+ <property name="hscrollbar_policy">never</property>
|
||
+ <property name="shadow_type">in</property>
|
||
+ <child>
|
||
+ <object class="GtkTreeView" id="treeview">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="hexpand">True</property>
|
||
+ <property name="vexpand">True</property>
|
||
+ <property name="headers_visible">False</property>
|
||
+ <property name="fixed_height_mode">True</property>
|
||
+ <property name="enable_grid_lines">horizontal</property>
|
||
+ <property name="enable_search">False</property>
|
||
+ <property name="activate_on_single_click">True</property>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">True</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">2</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkButton" id="open_button">
|
||
+ <property name="label" translatable="yes">Other _Documents…</property>
|
||
+ <property name="use-underline">True</property>
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="tooltip_text" translatable="yes">Open another file</property>
|
||
+ <property name="margin-top">6</property>
|
||
+ <property name="action_name">win.open</property>
|
||
+ <style>
|
||
+ <class name="text-button"/>
|
||
+ </style>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">3</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ </template>
|
||
+</interface>
|
||
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
|
||
@@ -78,72 +78,87 @@
|
||
<property name="climb_rate">1</property>
|
||
<property name="snap_to_ticks">True</property>
|
||
<property name="numeric">True</property>
|
||
</object>
|
||
<packing>
|
||
<property name="left_attach">0</property>
|
||
<property name="top_attach">0</property>
|
||
</packing>
|
||
</child>
|
||
</object>
|
||
<packing>
|
||
<property name="left_attach">1</property>
|
||
<property name="top_attach">1</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
<object class="GtkCheckButton" id="display_statusbar_checkbutton">
|
||
<property name="label" translatable="yes">Display _statusbar</property>
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">True</property>
|
||
<property name="receives_default">False</property>
|
||
<property name="use_underline">True</property>
|
||
<property name="draw_indicator">True</property>
|
||
</object>
|
||
<packing>
|
||
<property name="left_attach">0</property>
|
||
<property name="top_attach">2</property>
|
||
<property name="width">2</property>
|
||
</packing>
|
||
</child>
|
||
+ <child>
|
||
+ <object class="GtkCheckButton" id="display_overview_map_checkbutton">
|
||
+ <property name="label" translatable="yes">Display _overview map</property>
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="receives_default">False</property>
|
||
+ <property name="use_underline">True</property>
|
||
+ <property name="draw_indicator">True</property>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="left_attach">0</property>
|
||
+ <property name="top_attach">3</property>
|
||
+ <property name="width">2</property>
|
||
+ </packing>
|
||
+ </child>
|
||
<child>
|
||
<object class="GtkCheckButton" id="display_grid_checkbutton">
|
||
<property name="label" translatable="yes">Display _grid pattern</property>
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">True</property>
|
||
<property name="receives_default">False</property>
|
||
<property name="use_underline">True</property>
|
||
<property name="draw_indicator">True</property>
|
||
</object>
|
||
<packing>
|
||
<property name="left_attach">0</property>
|
||
- <property name="top_attach">3</property>
|
||
+ <property name="top_attach">4</property>
|
||
<property name="width">2</property>
|
||
</packing>
|
||
</child>
|
||
</object>
|
||
<packing>
|
||
<property name="left_attach">0</property>
|
||
<property name="top_attach">0</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
<object class="GtkGrid" id="grid2">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="row_spacing">6</property>
|
||
<child>
|
||
<object class="GtkLabel" id="label848">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="xalign">0</property>
|
||
<property name="label" translatable="yes">Text Wrapping</property>
|
||
<attributes>
|
||
<attribute name="weight" value="bold"/>
|
||
</attributes>
|
||
</object>
|
||
<packing>
|
||
<property name="left_attach">0</property>
|
||
<property name="top_attach">0</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
@@ -603,62 +618,73 @@
|
||
</child>
|
||
<child>
|
||
<object class="GtkGrid" id="grid14">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="hexpand">True</property>
|
||
<property name="vexpand">True</property>
|
||
<property name="row_spacing">6</property>
|
||
<child>
|
||
<object class="GtkLabel" id="label798">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="xalign">0</property>
|
||
<property name="label" translatable="yes">Color Scheme</property>
|
||
<attributes>
|
||
<attribute name="weight" value="bold"/>
|
||
</attributes>
|
||
</object>
|
||
<packing>
|
||
<property name="left_attach">0</property>
|
||
<property name="top_attach">0</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
<object class="GtkGrid" id="grid15">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="hexpand">True</property>
|
||
<property name="vexpand">True</property>
|
||
<child>
|
||
- <object class="TeplStyleSchemeChooserWidget" id="schemes_list">
|
||
+ <object class="GtkScrolledWindow" id="schemes_scrolled_window">
|
||
<property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ <property name="hexpand">True</property>
|
||
+ <property name="vexpand">True</property>
|
||
+ <property name="shadow_type">etched-in</property>
|
||
+ <property name="min_content_height">200</property>
|
||
+ <child>
|
||
+ <object class="GtkSourceStyleSchemeChooserWidget" id="schemes_list">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ </object>
|
||
+ </child>
|
||
</object>
|
||
<packing>
|
||
<property name="left_attach">0</property>
|
||
<property name="top_attach">0</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
<object class="GtkToolbar" id="schemes_toolbar">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="toolbar_style">icons</property>
|
||
<property name="icon_size">1</property>
|
||
<child>
|
||
<object class="GtkToolButton" id="install_scheme_button">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="has_tooltip">True</property>
|
||
<property name="tooltip_markup" translatable="yes">Install scheme</property>
|
||
<property name="tooltip_text" translatable="yes">Install scheme</property>
|
||
<property name="label" translatable="yes">Install Scheme</property>
|
||
<property name="use_underline">True</property>
|
||
<property name="icon_name">list-add-symbolic</property>
|
||
</object>
|
||
<packing>
|
||
<property name="expand">False</property>
|
||
<property name="homogeneous">True</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
<object class="GtkToolButton" id="uninstall_scheme_button">
|
||
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 @@
|
||
+<?xml version="1.0" encoding="UTF-8"?>
|
||
+<interface>
|
||
+ <!-- interface-requires gtk+ 3.6 -->
|
||
+ <template class="GeditProgressInfoBar" parent="GtkInfoBar">
|
||
+ <property name="app_paintable">True</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="message_type">other</property>
|
||
+ <child internal-child="content_area">
|
||
+ <object class="GtkBox" id="infobar-content_area1">
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="orientation">vertical</property>
|
||
+ <property name="spacing">6</property>
|
||
+ <child>
|
||
+ <object class="GtkBox" id="box1">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="spacing">4</property>
|
||
+ <child>
|
||
+ <object class="GtkImage" id="image">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="icon-size">2</property>
|
||
+ <property name="icon_name">image-missing</property>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="padding">4</property>
|
||
+ <property name="position">0</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkLabel" id="label">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="halign">start</property>
|
||
+ <property name="label">label</property>
|
||
+ <property name="use_markup">True</property>
|
||
+ <property name="ellipsize">end</property>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">1</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">0</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkProgressBar" id="progress">
|
||
+ <property name="height_request">15</property>
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="hexpand">True</property>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">1</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">True</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">0</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ <child internal-child="action_area">
|
||
+ <object class="GtkButtonBox" id="infobar-action_area1">
|
||
+ <property name="can_focus">False</property>
|
||
+ <child>
|
||
+ <placeholder/>
|
||
+ </child>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="expand">False</property>
|
||
+ <property name="fill">True</property>
|
||
+ <property name="position">1</property>
|
||
+ </packing>
|
||
+ </child>
|
||
+ </template>
|
||
+</interface>
|
||
diff --git a/gedit/resources/ui/gedit-view-frame.ui b/gedit/resources/ui/gedit-view-frame.ui
|
||
index 4c783c711..779802db3 100644
|
||
--- a/gedit/resources/ui/gedit-view-frame.ui
|
||
+++ b/gedit/resources/ui/gedit-view-frame.ui
|
||
@@ -1,47 +1,68 @@
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<interface>
|
||
<!-- interface-requires gtk+ 3.8 -->
|
||
<template class="GeditViewFrame" parent="GtkOverlay">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="has_focus">False</property>
|
||
<property name="is_focus">False</property>
|
||
<child>
|
||
- <object class="GtkScrolledWindow" id="scrolled_window">
|
||
+ <object class="GtkGrid" id="grid">
|
||
<property name="visible">True</property>
|
||
<property name="hexpand">True</property>
|
||
<property name="vexpand">True</property>
|
||
<child>
|
||
- <object class="GeditView" id="view">
|
||
+ <object class="GeditViewCentering" id="view_centering">
|
||
<property name="visible">True</property>
|
||
- <property name="can_focus">True</property>
|
||
+ <property name="hexpand">True</property>
|
||
+ <property name="vexpand">True</property>
|
||
+ <child>
|
||
+ <object class="GeditView" id="view">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">True</property>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkFrame" id="map_frame">
|
||
+ <property name="visible">True</property>
|
||
+ <style>
|
||
+ <class name="gedit-map-frame"/>
|
||
+ </style>
|
||
+ <child>
|
||
+ <object class="GtkSourceMap" id="map">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="view">view</property>
|
||
+ </object>
|
||
+ </child>
|
||
</object>
|
||
</child>
|
||
</object>
|
||
</child>
|
||
<child type="overlay">
|
||
<object class="GtkRevealer" id="revealer">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="halign">end</property>
|
||
<property name="valign">start</property>
|
||
<child>
|
||
<object class="GtkFrame" id="frame">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="shadow_type">none</property>
|
||
<style>
|
||
<class name="gedit-search-slider"/>
|
||
</style>
|
||
<child>
|
||
<object class="GtkBox" id="hbox">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="orientation">horizontal</property>
|
||
<style>
|
||
<class name="linked"/>
|
||
</style>
|
||
<child>
|
||
<object class="GdTaggedEntry" id="search_entry">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">True</property>
|
||
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
|
||
@@ -1,59 +1,103 @@
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<interface>
|
||
<!-- interface-requires gtk+ 3.10 -->
|
||
<template class="GeditWindow" parent="GtkApplicationWindow">
|
||
<property name="can_focus">False</property>
|
||
<property name="has_focus">False</property>
|
||
<property name="is_focus">False</property>
|
||
<style>
|
||
<class name="org-gnome-gedit"/>
|
||
</style>
|
||
<child type="titlebar">
|
||
<object class="GtkPaned" id="titlebar_paned">
|
||
<property name="visible">True</property>
|
||
<property name="position" bind-source="hpaned" bind-property="position" bind-flags="bidirectional|sync-create"/>
|
||
<child>
|
||
<object class="GtkHeaderBar" id="side_headerbar">
|
||
<property name="visible" bind-source="side_panel" bind-property="visible" bind-flags="sync-create"/>
|
||
<property name="show_close_button">True</property>
|
||
<property name="title" translatable="yes">Documents</property>
|
||
</object>
|
||
<packing>
|
||
<property name="resize">False</property>
|
||
<property name="shrink">False</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
<object class="GtkHeaderBar" id="headerbar">
|
||
<property name="visible">True</property>
|
||
<property name="show_close_button">True</property>
|
||
+ <child>
|
||
+ <object class="GtkMenuButton" id="open_button">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="tooltip_text" translatable="yes">Open a file</property>
|
||
+ <property name="valign">center</property>
|
||
+ <property name="use_popover">True</property>
|
||
+ <style>
|
||
+ <class name="text-button"/>
|
||
+ <class name="image-button"/>
|
||
+ </style>
|
||
+ <child>
|
||
+ <object class="GtkBox" id="open_button_box">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <child>
|
||
+ <object class="GtkLabel" id="open_button_name">
|
||
+ <property name="label" translatable="yes">_Open</property>
|
||
+ <property name="use-underline">True</property>
|
||
+ <property name="visible">True</property>
|
||
+ <property name="valign">baseline</property>
|
||
+ </object>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkImage" id="open_button_arrow">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="valign">baseline</property>
|
||
+ <property name="icon_name">pan-down-symbolic</property>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ </child>
|
||
+ <child internal-child="accessible">
|
||
+ <object class="AtkObject" id="open_button_a11y">
|
||
+ <property name="accessible-name" translatable="yes">Open</property>
|
||
+ <property name="accessible-description" translatable="yes">Open a file</property>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="pack_type">start</property>
|
||
+ </packing>
|
||
+ </child>
|
||
<child>
|
||
<object class="GtkButton" id="new_button">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">True</property>
|
||
<property name="can_default">True</property>
|
||
<property name="receives_default">False</property>
|
||
<property name="tooltip_text" translatable="yes">Create a new document</property>
|
||
<property name="action_name">win.new-tab</property>
|
||
<property name="image">new_tab_image</property>
|
||
<child internal-child="accessible">
|
||
<object class="AtkObject" id="new_button_a11y">
|
||
<property name="accessible-name" translatable="yes">New</property>
|
||
<property name="accessible-description" translatable="yes">Create a new document</property>
|
||
</object>
|
||
</child>
|
||
</object>
|
||
</child>
|
||
<child>
|
||
<object class="GtkMenuButton" id="gear_button">
|
||
<property name="visible">True</property>
|
||
<property name="use_popover">True</property>
|
||
<property name="image">menu_image</property>
|
||
</object>
|
||
<packing>
|
||
<property name="pack_type">end</property>
|
||
</packing>
|
||
</child>
|
||
<child>
|
||
<object class="GtkButton" id="save_button">
|
||
<property name="label" translatable="yes">_Save</property>
|
||
@@ -283,68 +327,109 @@
|
||
</packing>
|
||
</child>
|
||
</object>
|
||
<packing>
|
||
<property name="expand">False</property>
|
||
<property name="fill">True</property>
|
||
<property name="position">1</property>
|
||
</packing>
|
||
</child>
|
||
</object>
|
||
<packing>
|
||
<property name="resize">True</property>
|
||
<property name="shrink">True</property>
|
||
</packing>
|
||
</child>
|
||
</object>
|
||
<packing>
|
||
<property name="expand">True</property>
|
||
<property name="fill">True</property>
|
||
<property name="position">1</property>
|
||
</packing>
|
||
</child>
|
||
</object>
|
||
</child>
|
||
<child type="overlay">
|
||
<object class="GtkEventBox" id="fullscreen_eventbox">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="valign">start</property>
|
||
<child>
|
||
- <object class="GtkRevealer" id="fullscreen_revealer">
|
||
+ <object class="GtkRevealer" id="fullscreen_controls">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">False</property>
|
||
<property name="reveal_child">False</property>
|
||
<property name="valign">start</property>
|
||
<child>
|
||
<object class="GtkHeaderBar" id="fullscreen_headerbar">
|
||
<property name="visible">True</property>
|
||
+ <child>
|
||
+ <object class="GtkMenuButton" id="fullscreen_open_button">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="tooltip_text" translatable="yes">Open a file dialog</property>
|
||
+ <property name="valign">center</property>
|
||
+ <property name="use_popover">True</property>
|
||
+ <style>
|
||
+ <class name="text-button"/>
|
||
+ <class name="image-button"/>
|
||
+ </style>
|
||
+ <child>
|
||
+ <object class="GtkBox" id="fullscreen_open_button_box">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="can_focus">False</property>
|
||
+ <property name="has_focus">False</property>
|
||
+ <property name="is_focus">False</property>
|
||
+ <child>
|
||
+ <object class="GtkLabel" id="fullscreen_open_button_name">
|
||
+ <property name="label" translatable="yes">Open</property>
|
||
+ <property name="visible">True</property>
|
||
+ </object>
|
||
+ </child>
|
||
+ <child>
|
||
+ <object class="GtkImage" id="fullscreen_open_button_arrow">
|
||
+ <property name="visible">True</property>
|
||
+ <property name="icon_name">pan-down-symbolic</property>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ </child>
|
||
+ <child internal-child="accessible">
|
||
+ <object class="AtkObject" id="fullscreen_open_button_a11y">
|
||
+ <property name="accessible-name" translatable="yes">Open</property>
|
||
+ <property name="accessible-description" translatable="yes">Open a file</property>
|
||
+ </object>
|
||
+ </child>
|
||
+ </object>
|
||
+ <packing>
|
||
+ <property name="pack_type">start</property>
|
||
+ </packing>
|
||
+ </child>
|
||
<child>
|
||
<object class="GtkButton" id="fullscreen_new_button">
|
||
<property name="visible">True</property>
|
||
<property name="can_focus">True</property>
|
||
<property name="can_default">True</property>
|
||
<property name="receives_default">False</property>
|
||
<property name="tooltip_text" translatable="yes">Create a new document</property>
|
||
<property name="action_name">win.new-tab</property>
|
||
<property name="image">fullscreen_new_tab_image</property>
|
||
<child internal-child="accessible">
|
||
<object class="AtkObject" id="fullscreen_new_button_a11y">
|
||
<property name="accessible-name" translatable="yes">New</property>
|
||
<property name="accessible-description" translatable="yes">Create a new document</property>
|
||
</object>
|
||
</child>
|
||
</object>
|
||
</child>
|
||
<child>
|
||
<object class="GtkButton" id="leave_fullscreen_button">
|
||
<property name="visible">True</property>
|
||
<property name="tooltip_text" translatable="yes">Leave Fullscreen</property>
|
||
<property name="action_name">win.leave-fullscreen</property>
|
||
<property name="image">leave_fullscreen_image</property>
|
||
<child internal-child="accessible">
|
||
<object class="AtkObject" id="leave_fullscreen_button_a11y">
|
||
<property name="accessible-name" translatable="yes">Leave Fullscreen</property>
|
||
<property name="accessible-description" translatable="yes">Leave Fullscreen</property>
|
||
</object>
|
||
</child>
|
||
</object>
|
||
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
|
||
@@ -1,58 +1,58 @@
|
||
<page xmlns="http://projectmallard.org/1.0/"
|
||
xmlns:its="http://www.w3.org/2005/11/its"
|
||
type="topic" style="task"
|
||
id="gedit-tab-groups">
|
||
|
||
<info>
|
||
<link type="guide" xref="index#gedit-working-with-files" group="last"/>
|
||
<link type="seealso" xref="gedit-tabs"/>
|
||
<link type="seealso" xref="gedit-tabs-moving"/>
|
||
<desc>Group similar tabs together.</desc>
|
||
<revision pkgversion="3.8" date="2013-06-19" status="draft"/>
|
||
|
||
<credit type="author copyright">
|
||
<name>Radina Matic</name>
|
||
<email its:translate="no">radina.matic@gmail.com</email>
|
||
<years>2013</years>
|
||
</credit>
|
||
|
||
<include href="legal.xml" xmlns="http://www.w3.org/2001/XInclude"/>
|
||
</info>
|
||
|
||
<title>Organize files in grouped tabs</title>
|
||
|
||
<p>If you are working with multiple tabs in <app>gedit</app> you can group
|
||
them, making it easier to keep your opened files organized. Adding a new tab
|
||
group will divide the <app>gedit</app> 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.</p>
|
||
+ “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.</p>
|
||
|
||
<section id="open-new-tab-group">
|
||
<title>Open a new tab group in the gedit window</title>
|
||
|
||
<p>To open a new tab group you can:</p>
|
||
|
||
<list>
|
||
<item>
|
||
<p>Right click on a tab and select <gui>Move to New Tab Group</gui>.</p>
|
||
</item>
|
||
<item>
|
||
<p>Use the <keyseq><key>Ctrl</key><key>Alt</key><key>N</key></keyseq>
|
||
shortcut.</p>
|
||
</item>
|
||
</list>
|
||
|
||
<p>This action will divide the <app>gedit</app> window in two panes, and the
|
||
pane with the new tab group will be placed on the right of the active tab.
|
||
You can move the handle right or left assigning more or less space of the
|
||
<app>gedit</app> window between panes according to your needs.</p>
|
||
|
||
<p>You can open as much tab groups in a <app>gedit</app> window as your screen
|
||
allows, but you will have to move the handle in order to see them
|
||
correctly.</p>
|
||
|
||
<p>To close a tab group pane just close all the tabs that are opened inside
|
||
it.</p>
|
||
</section>
|
||
|
||
<!--
|
||
diff --git a/meson.build b/meson.build
|
||
index be77a885f..ef77bc8a8 100644
|
||
--- a/meson.build
|
||
+++ b/meson.build
|
||
@@ -13,84 +13,104 @@ i18n = import('i18n')
|
||
pkg_config = import('pkgconfig')
|
||
python = import('python')
|
||
|
||
api_version = '40.0'
|
||
|
||
# Paths
|
||
root_include_dir = include_directories('.')
|
||
|
||
srcdir = meson.current_source_dir()
|
||
|
||
pkglibdir = get_option('prefix') / get_option('libdir') / 'gedit'
|
||
pkgdatadir = get_option('prefix') / get_option('datadir') / 'gedit'
|
||
glibdir = get_option('prefix') / get_option('datadir') / 'glib-2.0'
|
||
|
||
# Subprojects
|
||
if not get_option('buildtype').contains('plain')
|
||
run_command('git', '-C', meson.source_root(), 'submodule', 'update', '--init', '--recursive')
|
||
endif
|
||
|
||
libgd_subproject = subproject(
|
||
'libgd',
|
||
default_options: [
|
||
'with-tagged-entry=true',
|
||
'static=true',
|
||
]
|
||
)
|
||
|
||
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 = [
|
||
libgedit_public_deps,
|
||
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))
|
||
config_h.set_quoted('GETTEXT_PACKAGE', meson.project_name())
|
||
config_h.set_quoted('LIBDIR', join_paths(get_option('prefix'), get_option('libdir')))
|
||
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
|
||
)
|
||
|
||
subdir('data')
|
||
subdir('po')
|
||
subdir('gedit')
|
||
subdir('plugins')
|
||
|
||
if get_option('gtk_doc')
|
||
subdir('docs/reference')
|
||
endif
|
||
|
||
if get_option('user_documentation')
|
||
subdir('help')
|
||
endif
|
||
|
||
meson.add_install_script(
|
||
'build-aux/meson/post_install.py',
|
||
get_option('prefix') / get_option('libdir'),
|
||
get_option('prefix') / get_option('datadir')
|
||
)
|
||
|
||
summary('API version', api_version)
|
||
summary('Prefix', get_option('prefix'))
|
||
summary('API documentation', get_option('gtk_doc'))
|
||
summary('User documentation', get_option('user_documentation'))
|
||
summary('Require all tests', get_option('require_all_tests'))
|
||
diff --git a/meson_options.txt b/meson_options.txt
|
||
index 4e842d1ea..33d03cb14 100644
|
||
--- a/meson_options.txt
|
||
+++ b/meson_options.txt
|
||
@@ -1,24 +1,31 @@
|
||
option(
|
||
'gtk_doc',
|
||
type: 'boolean', value: false,
|
||
description: 'Build API reference for plugins (requires gtk-doc)'
|
||
)
|
||
|
||
# If this option is kept to false, then it's an automatic behavior: if the
|
||
# third party program is found, then the test is defined.
|
||
# Setting this option to true will stop the configure phase with a hard error
|
||
# if a third party program is not found and is required to define a test.
|
||
option(
|
||
'require_all_tests',
|
||
type: 'boolean', value: false,
|
||
description: 'Require that all tests can be run, even those that depend on third party programs'
|
||
)
|
||
|
||
# This option exists for the developers, to speed up the install.
|
||
option(
|
||
'user_documentation',
|
||
type: 'boolean', value: true,
|
||
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
|
||
@@ -135,67 +135,67 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
|
||
self.provider.language_id = self.language_id
|
||
|
||
SharedData().update_state(self.view.get_toplevel())
|
||
|
||
def accelerator_activate(self, keyval, mod):
|
||
if not self.view or not self.view.get_editable():
|
||
return False
|
||
|
||
accelerator = Gtk.accelerator_name(keyval, mod)
|
||
snippets = Library().from_accelerator(accelerator, \
|
||
self.language_id)
|
||
|
||
if len(snippets) == 0:
|
||
return False
|
||
elif len(snippets) == 1:
|
||
self.apply_snippet(snippets[0])
|
||
else:
|
||
# Do the fancy completion dialog
|
||
provider = completion.Provider(_('Snippets'), self.language_id, self.on_proposal_activated)
|
||
provider.set_proposals(snippets)
|
||
|
||
cm = self.view.get_completion()
|
||
cm.show([provider], cm.create_context(None))
|
||
|
||
return True
|
||
|
||
def first_snippet_inserted(self):
|
||
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):
|
||
buf = self.view.get_buffer()
|
||
|
||
piter = buf.get_iter_at_mark(buf.get_insert())
|
||
found = []
|
||
|
||
for placeholder in self.placeholders:
|
||
begin = placeholder.begin_iter()
|
||
end = placeholder.end_iter()
|
||
|
||
if piter.compare(begin) >= 0 and piter.compare(end) <= 0:
|
||
found.append(placeholder)
|
||
|
||
if self.active_placeholder in found:
|
||
return self.active_placeholder
|
||
elif len(found) > 0:
|
||
return found[0]
|
||
else:
|
||
return None
|
||
|
||
def advance_placeholder(self, direction):
|
||
# Returns (CurrentPlaceholder, NextPlaceholder), depending on direction
|
||
buf = self.view.get_buffer()
|
||
|
||
piter = buf.get_iter_at_mark(buf.get_insert())
|
||
found = current = next = None
|
||
length = len(self.placeholders)
|
||
|
||
@@ -532,87 +532,87 @@ class Document(GObject.Object, Gedit.ViewActivatable, Signals):
|
||
|
||
for k in environ['noenc']:
|
||
env['noenc'][k] = environ['noenc'][k]
|
||
|
||
buf = self.view.get_buffer()
|
||
s = Snippet(snippet, env)
|
||
|
||
if not start:
|
||
start = buf.get_iter_at_mark(buf.get_insert())
|
||
|
||
if not end:
|
||
end = buf.get_iter_at_mark(buf.get_selection_bound())
|
||
|
||
if start.equal(end) and self.uses_current_word(s):
|
||
# There is no tab trigger and no selection and the snippet uses
|
||
# the current word. Set start and end to the word boundary so that
|
||
# it will be removed
|
||
start, end = helper.buffer_word_boundary(buf)
|
||
elif start.equal(end) and self.uses_current_line(s):
|
||
# There is no tab trigger and no selection and the snippet uses
|
||
# the current line. Set start and end to the line boundary so that
|
||
# it will be removed
|
||
start, end = helper.buffer_line_boundary(buf)
|
||
|
||
# You know, we could be in an end placeholder
|
||
(current, next) = self.next_placeholder()
|
||
if current and current.__class__ == PlaceholderEnd:
|
||
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()
|
||
|
||
# Remove the tag, selection or current word
|
||
buf.delete(start, end)
|
||
|
||
# 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)
|
||
|
||
# Put cursor at first tab placeholder
|
||
keys = [x for x in sn.placeholders.keys() if x > 0]
|
||
|
||
if len(keys) == 0:
|
||
if 0 in sn.placeholders:
|
||
self.goto_placeholder(self.active_placeholder, sn.placeholders[0])
|
||
else:
|
||
buf.place_cursor(sn.begin_iter())
|
||
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
|
||
# current cursor position out of view
|
||
cur = buf.get_iter_at_mark(buf.get_insert())
|
||
last = sn.end_iter()
|
||
|
||
curloc = self.view.get_iter_location(cur)
|
||
lastloc = self.view.get_iter_location(last)
|
||
|
||
if (lastloc.y + lastloc.height) - curloc.y <= \
|
||
self.view.get_visible_rect().height:
|
||
self.view.scroll_mark_onscreen(sn.end_mark)
|
||
|
||
buf.end_user_action()
|
||
self.view.grab_focus()
|
||
|
||
return True
|
||
|
||
def get_tab_tag(self, buf, end = None):
|
||
if not end:
|
||
end = buf.get_iter_at_mark(buf.get_insert())
|
||
|
||
start = end.copy()
|
||
word = None
|
||
first = True
|
||
|
||
# Move start backward as long as there is a valid character
|
||
while start.backward_char():
|
||
c = start.get_char()
|
||
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
|
||
@@ -3,62 +3,67 @@
|
||
*
|
||
* Copyright (C) 2002-2005 Paolo Maggi
|
||
* Copyright (C) 2015-2016 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, 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 <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#include "gedit-spell-plugin.h"
|
||
|
||
#include <glib/gi18n.h>
|
||
#include <gedit/gedit-debug.h>
|
||
#include <gedit/gedit-app.h>
|
||
#include <gedit/gedit-window.h>
|
||
#include <gedit/gedit-window-activatable.h>
|
||
#include <gspell/gspell.h>
|
||
#include <libpeas-gtk/peas-gtk-configurable.h>
|
||
|
||
#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"
|
||
#define SETTINGS_KEY_HIGHLIGHT_MISSPELLED "highlight-misspelled"
|
||
|
||
static void gedit_window_activatable_iface_init (GeditWindowActivatableInterface *iface);
|
||
static void peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface);
|
||
|
||
struct _GeditSpellPluginPrivate
|
||
{
|
||
GeditWindow *window;
|
||
GSettings *settings;
|
||
};
|
||
|
||
enum
|
||
{
|
||
PROP_0,
|
||
PROP_WINDOW
|
||
};
|
||
|
||
typedef struct _SpellConfigureWidget SpellConfigureWidget;
|
||
|
||
struct _SpellConfigureWidget
|
||
{
|
||
GtkWidget *content;
|
||
GtkWidget *highlight_button;
|
||
|
||
GSettings *settings;
|
||
};
|
||
|
||
diff --git a/po/POTFILES.in b/po/POTFILES.in
|
||
index 2383549f4..dc6b1f9d7 100644
|
||
--- a/po/POTFILES.in
|
||
+++ b/po/POTFILES.in
|
||
@@ -1,73 +1,79 @@
|
||
# List of source files containing translatable strings.
|
||
# Please keep this file sorted alphabetically.
|
||
data/org.gnome.gedit.appdata.xml.in
|
||
data/org.gnome.gedit.desktop.in
|
||
data/org.gnome.gedit.gschema.xml.in
|
||
gedit/gedit-app.c
|
||
gedit/gedit-app-osx.m
|
||
gedit/gedit.c
|
||
gedit/gedit-close-confirmation-dialog.c
|
||
gedit/gedit-commands-file.c
|
||
gedit/gedit-commands-help.c
|
||
gedit/gedit-commands-search.c
|
||
gedit/gedit-debug.c
|
||
gedit/gedit-document.c
|
||
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
|
||
gedit/gedit-tab-label.c
|
||
gedit/gedit-utils.c
|
||
gedit/gedit-view.c
|
||
gedit/gedit-view-frame.c
|
||
gedit/gedit-window.c
|
||
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
|
||
gedit/resources/ui/gedit-replace-dialog.ui
|
||
gedit/resources/ui/gedit-shortcuts.ui
|
||
gedit/resources/ui/gedit-tab-label.ui
|
||
gedit/resources/ui/gedit-window.ui
|
||
plugins/docinfo/docinfo.plugin.desktop.in
|
||
plugins/docinfo/gedit-docinfo-plugin.c
|
||
plugins/docinfo/resources/ui/gedit-docinfo-plugin.ui
|
||
plugins/externaltools/data/build.desktop.in
|
||
plugins/externaltools/data/open-terminal-here.desktop.in
|
||
plugins/externaltools/data/open-terminal-here-osx.desktop.in
|
||
plugins/externaltools/data/remove-trailing-spaces.desktop.in
|
||
plugins/externaltools/data/run-command.desktop.in
|
||
plugins/externaltools/data/send-to-fpaste.desktop.in
|
||
plugins/externaltools/externaltools.plugin.desktop.in
|
||
plugins/externaltools/org.gnome.gedit.plugins.externaltools.gschema.xml
|
||
plugins/externaltools/tools/appactivatable.py
|
||
plugins/externaltools/tools/capture.py
|
||
plugins/externaltools/tools/functions.py
|
||
plugins/externaltools/tools/__init__.py
|
||
plugins/externaltools/tools/manager.py
|
||
plugins/externaltools/tools/outputpanel.py
|
||
plugins/externaltools/tools/outputpanel.ui
|
||
plugins/externaltools/tools/tools.ui
|
||
plugins/externaltools/tools/windowactivatable.py
|
||
plugins/filebrowser/filebrowser.plugin.desktop.in
|
||
plugins/filebrowser/gedit-file-bookmarks-store.c
|
||
plugins/filebrowser/gedit-file-browser-plugin.c
|
||
--
|
||
2.31.1
|
||
|