[gnome-builder] wip
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] wip
- Date: Tue, 24 Mar 2015 00:23:48 +0000 (UTC)
commit 8be3f3b44a8d7b50e499941ed3d890fba3b1c1bc
Author: Christian Hergert <christian hergert me>
Date: Wed Mar 18 15:20:55 2015 -0700
wip
configure.ac | 6 +-
{libide/trie => cut-n-paste}/trie.c | 0
{libide/trie => cut-n-paste}/trie.h | 0
data/data.mk | 5 +-
data/gsettings.mk | 6 +-
.../org.gnome.builder.editor.gschema.xml.in | 23 +-
...rg.gnome.builder.editor.language.gschema.xml.in | 0
.../org.gnome.builder.editor.vim.gschema.xml.in | 0
data/keybindings/default.css | 13 +
data/keybindings/emacs.css | 4 +-
data/keybindings/vim.css | 13 +-
data/{styles => style-schemes}/builder-dark.xml | 0
data/{styles => style-schemes}/builder.xml | 0
{src/resources => data}/ui/gb-command-bar.ui | 0
data/ui/gb-editor-frame.ui | 112 +
.../ui/gb-editor-settings-widget.ui | 0
.../ui/gb-editor-tweak-widget.ui | 8 +
data/ui/gb-editor-view.ui | 56 +
data/ui/gb-editor-workspace.ui | 12 +
data/ui/gb-view-stack.ui | 301 +
data/ui/gb-workbench.ui | 63 +
libide/Makefile.am | 5 +-
libide/devhelp/ide-devhelp-search-provider.c | 141 +-
libide/git/ide-git-search-index.c | 8 +-
libide/git/ide-git-search-provider.c | 7 +
libide/gsettings/ide-language-defaults.c | 34 +-
libide/ide-back-forward-item.c | 71 +-
libide/ide-back-forward-list.c | 5 +-
libide/ide-buffer-manager.c | 72 +-
libide/ide-file.c | 5 +
libide/ide-log.c | 2 +-
libide/ide-search-context.c | 18 +-
libide/ide-search-context.h | 3 +-
libide/ide-search-reducer.c | 3 +-
libide/ide.h | 1 +
src/animation/gb-animation.c | 1133 ----
src/animation/gb-animation.h | 89 -
src/animation/gb-frame-source.c | 134 -
src/animation/gb-frame-source.h | 32 -
src/app/gb-application-actions.c | 230 +
.../gb-application-actions.h} | 25 +-
.../gb-application-private.h} | 33 +-
src/app/gb-application.c | 675 +--
src/app/gb-application.h | 27 +-
src/auto-indent/c-parse-helper.c | 255 -
src/auto-indent/gb-source-auto-indenter-c.c | 1486 -----
src/auto-indent/gb-source-auto-indenter-c.h | 56 -
src/auto-indent/gb-source-auto-indenter-python.c | 727 ---
src/auto-indent/gb-source-auto-indenter-python.h | 56 -
src/auto-indent/gb-source-auto-indenter-xml.c | 430 --
src/auto-indent/gb-source-auto-indenter-xml.h | 56 -
src/auto-indent/gb-source-auto-indenter.c | 98 -
src/auto-indent/gb-source-auto-indenter.h | 78 -
.../gb-source-code-assistant-renderer.c | 332 --
.../gb-source-code-assistant-renderer.h | 55 -
src/code-assistant/gb-source-code-assistant.c | 829 ---
src/code-assistant/gb-source-code-assistant.h | 60 -
src/commands/gb-command-bar.c | 14 +-
src/commands/gb-command-gaction-provider.c | 12 +-
src/commands/gb-command-provider.c | 34 +-
src/commands/gb-command-provider.h | 4 +-
src/commands/gb-command-vim-provider.c | 4 +
src/commands/gb-command-vim.c | 18 +-
src/commands/gb-command.c | 2 +-
src/credits/gb-credits-widget.c | 315 -
src/credits/gb-credits-widget.h | 65 -
src/dialogs/gb-close-confirmation-dialog.c | 688 ---
src/dialogs/gb-close-confirmation-dialog.h | 64 -
src/documents/gb-document-grid.c | 1001 ----
src/documents/gb-document-grid.h | 77 -
src/documents/gb-document-manager.c | 352 --
src/documents/gb-document-manager.h | 76 -
src/documents/gb-document-menu-button.c | 698 ---
src/documents/gb-document-menu-button.h | 68 -
src/documents/gb-document-stack.c | 1127 ----
src/documents/gb-document-stack.h | 83 -
src/documents/gb-document-view.c | 303 -
src/documents/gb-document-view.h | 72 -
src/documents/gb-document.c | 14 +-
src/documents/gb-document.h | 14 +-
src/editor/gb-editor-document.c | 1477 +-----
src/editor/gb-editor-document.h | 62 +-
src/editor/gb-editor-file-mark.c | 239 -
src/editor/gb-editor-file-mark.h | 67 -
src/editor/gb-editor-file-marks.c | 388 --
src/editor/gb-editor-file-marks.h | 71 -
src/editor/gb-editor-frame-actions.c | 52 +
.../gb-editor-frame-actions.h} | 25 +-
src/editor/gb-editor-frame-private.h | 44 +-
src/editor/gb-editor-frame.c | 1627 +-----
src/editor/gb-editor-frame.h | 36 +-
src/editor/gb-editor-navigation-item.c | 257 -
src/editor/gb-editor-navigation-item.h | 63 -
src/editor/gb-editor-settings-widget.c | 16 +-
src/editor/gb-editor-tweak-widget.c | 57 +-
src/editor/gb-editor-tweak-widget.h | 29 +-
src/editor/gb-editor-view-actions.c | 271 +
.../gb-editor-view-actions.h} | 25 +-
.../gb-editor-view-private.h} | 37 +-
src/editor/gb-editor-view.c | 1120 +----
src/editor/gb-editor-view.h | 47 +-
.../gb-editor-workspace-actions.c} | 29 +-
.../gb-editor-workspace-actions.h} | 25 +-
.../gb-editor-workspace-private.h} | 27 +-
src/editor/gb-editor-workspace.c | 470 +--
src/editor/gb-editor-workspace.h | 32 +-
src/editor/gb-source-change-gutter-renderer.c | 210 -
src/editor/gb-source-change-gutter-renderer.h | 55 -
src/editor/gb-source-change-monitor.c | 905 ---
src/editor/gb-source-change-monitor.h | 71 -
src/editor/gb-source-formatter.c | 8 +-
src/editor/gb-source-search-highlighter.c | 369 --
src/editor/gb-source-search-highlighter.h | 64 -
src/editor/gb-source-view.c | 2496 --------
src/editor/gb-source-view.h | 99 -
src/emacs/gb-source-emacs.c | 1365 -----
src/emacs/gb-source-emacs.h | 65 -
src/fuzzy/fuzzy.c | 548 --
src/fuzzy/fuzzy.h | 55 -
src/gca/gca-diagnostics.c | 1039 ----
src/gca/gca-diagnostics.h | 170 -
src/gca/gca-diagnostics.xml | 9 -
src/gca/gca-service.c | 1291 ----
src/gca/gca-service.h | 209 -
src/gca/gca-service.xml | 16 -
src/gca/gca-structs.c | 107 -
src/gca/gca-structs.h | 67 -
src/git/gb-git-search-provider.c | 539 --
src/git/gb-git-search-provider.h | 61 -
src/gnome-builder.mk | 222 +-
src/html/gb-html-view.c | 6 +-
src/keybindings/gb-keybindings.c | 311 +-
src/keybindings/gb-keybindings.h | 45 +-
src/log/gb-log.c | 206 -
src/log/gb-log.h | 77 -
src/main.c | 5 +-
src/navigation/gb-navigation-item.c | 236 -
src/navigation/gb-navigation-item.h | 65 -
src/navigation/gb-navigation-list.c | 315 -
src/navigation/gb-navigation-list.h | 68 -
src/preferences/gb-preferences-page-editor.c | 53 +-
src/preferences/gb-preferences-page-emacs.c | 11 +-
src/preferences/gb-preferences-page-vim.c | 20 +-
src/preferences/gb-preferences-page.c | 2 +-
src/preferences/gb-preferences-window.c | 8 +-
src/resources/css/builder.Adwaita.css | 13 +-
src/resources/gnome-builder.gresource.xml | 25 +-
src/resources/gtk/menus.ui | 6 +-
src/resources/keybindings/default.ini | 42 -
src/resources/keybindings/vim.ini | 41 -
src/resources/language/defaults.ini | 74 -
src/resources/ui/gb-editor-frame.ui | 112 -
src/resources/ui/gb-editor-view.ui | 224 -
src/resources/ui/gb-editor-workspace.ui | 55 -
src/resources/ui/gb-preferences-page-editor.ui | 59 +-
src/resources/ui/gb-preferences-page-emacs.ui | 2 +
src/resources/ui/gb-preferences-page-vim.ui | 2 +
src/search/gb-search-box.c | 258 +-
src/search/gb-search-box.h | 35 +-
src/search/gb-search-context.c | 207 -
src/search/gb-search-context.h | 75 -
src/search/gb-search-display-group.c | 193 +-
src/search/gb-search-display-group.h | 51 +-
src/search/gb-search-display-row.c | 64 +-
src/search/gb-search-display-row.h | 33 +-
src/search/gb-search-display.c | 369 +-
src/search/gb-search-display.h | 39 +-
src/search/gb-search-manager.c | 130 -
src/search/gb-search-manager.h | 59 -
src/search/gb-search-provider.c | 93 -
src/search/gb-search-provider.h | 68 -
src/search/gb-search-reducer.c | 98 -
src/search/gb-search-reducer.h | 49 -
src/search/gb-search-result.c | 266 -
src/search/gb-search-result.h | 62 -
src/search/gb-search-types.h | 72 -
src/snippets/gb-source-snippet-chunk.c | 355 --
src/snippets/gb-source-snippet-chunk.h | 74 -
src/snippets/gb-source-snippet-completion-item.c | 182 -
src/snippets/gb-source-snippet-completion-item.h | 61 -
.../gb-source-snippet-completion-provider.c | 377 --
.../gb-source-snippet-completion-provider.h | 60 -
src/snippets/gb-source-snippet-context.c | 725 ---
src/snippets/gb-source-snippet-context.h | 72 -
src/snippets/gb-source-snippet-parser.c | 618 --
src/snippets/gb-source-snippet-parser.h | 60 -
src/snippets/gb-source-snippet-private.h | 57 -
src/snippets/gb-source-snippet.c | 1099 ----
src/snippets/gb-source-snippet.h | 83 -
src/snippets/gb-source-snippets-manager.c | 231 -
src/snippets/gb-source-snippets-manager.h | 62 -
src/snippets/gb-source-snippets.c | 171 -
src/snippets/gb-source-snippets.h | 67 -
src/theatrics/gb-box-theatric.c | 336 --
src/theatrics/gb-box-theatric.h | 55 -
src/tree/gb-tree.c | 34 +-
src/trie/trie.c | 812 ---
src/trie/trie.h | 52 -
src/util/gb-widget.c | 104 +-
src/util/gb-widget.h | 43 +-
src/views/gb-view-grid.c | 631 ++
src/views/gb-view-grid.h | 48 +
src/views/gb-view-stack-actions.c | 125 +
src/views/gb-view-stack-actions.h | 30 +
src/views/gb-view-stack-private.h | 49 +
src/views/gb-view-stack.c | 409 ++
src/views/gb-view-stack.h | 43 +
src/views/gb-view.c | 240 +
src/views/gb-view.h | 50 +
src/vim/gb-source-vim.c | 6152 --------------------
src/vim/gb-source-vim.h | 116 -
src/workbench/gb-workbench-actions.c | 81 +
.../gb-workbench-actions.h} | 25 +-
src/workbench/gb-workbench-private.h | 60 +
src/workbench/gb-workbench-types.h | 9 +-
src/workbench/gb-workbench.c | 1100 +---
src/workbench/gb-workbench.h | 43 +-
src/workbench/gb-workspace.c | 76 +-
src/workbench/gb-workspace.h | 25 +-
tests/test-navigation-list.c | 58 -
tests/tests.mk | 13 +-
tools/ide-search.c | 2 +-
222 files changed, 4978 insertions(+), 44132 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index bf364b1..d7d22cb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,9 +71,9 @@ AC_CONFIG_FILES([
src/util/gb-version.h
data/icons/Makefile
data/libide-1.0.pc
- data/org.gnome.builder.editor.gschema.xml
- data/org.gnome.builder.editor.language.gschema.xml
- data/org.gnome.builder.editor.vim.gschema.xml
+ data/gsettings/org.gnome.builder.editor.gschema.xml
+ data/gsettings/org.gnome.builder.editor.language.gschema.xml
+ data/gsettings/org.gnome.builder.editor.vim.gschema.xml
po/Makefile.in
])
diff --git a/libide/trie/trie.c b/cut-n-paste/trie.c
similarity index 100%
rename from libide/trie/trie.c
rename to cut-n-paste/trie.c
diff --git a/libide/trie/trie.h b/cut-n-paste/trie.h
similarity index 100%
rename from libide/trie/trie.h
rename to cut-n-paste/trie.h
diff --git a/data/data.mk b/data/data.mk
index ac6d9ee..5c0816f 100644
--- a/data/data.mk
+++ b/data/data.mk
@@ -16,7 +16,10 @@ CLEANFILES += $(service_DATA)
# GtkSourceView Style Scheme
styledir = $(datadir)/gtksourceview-3.0/styles/
-style_DATA = data/styles/builder.xml data/styles/builder-dark.xml
+style_DATA = \
+ data/style-schemes/builder.xml \
+ data/style-schemes/builder-dark.xml \
+ $(NULL)
EXTRA_DIST += $(style_DATA)
data/org.gnome.Builder.service: data/org.gnome.Builder.service.in
diff --git a/data/gsettings.mk b/data/gsettings.mk
index fbd3e0b..f8c7dda 100644
--- a/data/gsettings.mk
+++ b/data/gsettings.mk
@@ -1,7 +1,7 @@
gsettingsschema_in_files = \
- data/org.gnome.builder.editor.gschema.xml.in \
- data/org.gnome.builder.editor.vim.gschema.xml.in \
- data/org.gnome.builder.editor.language.gschema.xml.in
+ data/gsettings/org.gnome.builder.editor.gschema.xml.in \
+ data/gsettings/org.gnome.builder.editor.vim.gschema.xml.in \
+ data/gsettings/org.gnome.builder.editor.language.gschema.xml.in
gsettings_SCHEMAS = $(gsettingsschema_in_files:.xml.in=.xml)
.PRECIOUS: $(gsettings_SCHEMAS)
diff --git a/data/org.gnome.builder.editor.gschema.xml.in
b/data/gsettings/org.gnome.builder.editor.gschema.xml.in
similarity index 82%
rename from data/org.gnome.builder.editor.gschema.xml.in
rename to data/gsettings/org.gnome.builder.editor.gschema.xml.in
index 55cdcbc..2730295 100644
--- a/data/org.gnome.builder.editor.gschema.xml.in
+++ b/data/gsettings/org.gnome.builder.editor.gschema.xml.in
@@ -1,14 +1,12 @@
<schemalist>
<schema id="org.gnome.builder.editor" path="/org/gnome/builder/editor/" gettext-domain="gnome-builder">
- <key name="vim-mode" type="b">
- <default>false</default>
- <summary>Enable VIM keybindings</summary>
- <description>Whether or not VIM style keybindings should be used in the source code
editor.</description>
- </key>
- <key name="emacs-mode" type="b">
- <default>false</default>
- <summary>Enable EMACS keybindings</summary>
- <description>Whether or not EMACS style keybindings should be used in the source code
editor.</description>
+ <key name="keybindings" type="s">
+ <choices>
+ <choice value="default"/>
+ <choice value="emacs"/>
+ <choice value="vim"/>
+ </choices>
+ <default>'default'</default>
</key>
<key name="restore-insert-mark" type="b">
<default>true</default>
@@ -21,7 +19,7 @@
<summary>Enable auto-completion of words in document.</summary>
<description>If enabled, words within the current document will be available for
auto-completion.</description>
</key>
- <key name="show-diff" type="b">
+ <key name="show-line-changes" type="b">
<default>true</default>
<summary>Show modified lines.</summary>
<description>If enabled, the editor will show line additions and changes next to the source
code.</description>
@@ -41,6 +39,11 @@
<summary>Show line numbers.</summary>
<description>If enabled, the editor will show line numbers.</description>
</key>
+ <key name="smart-backspace" type="b">
+ <default>true</default>
+ <summary>Smart backspace.</summary>
+ <description>Backspace will remove additional spaces to keep you aligned to the indentation
size.</description>
+ </key>
<key name="smart-home-end" type="b">
<default>true</default>
<summary>Smart home end.</summary>
diff --git a/data/org.gnome.builder.editor.language.gschema.xml.in
b/data/gsettings/org.gnome.builder.editor.language.gschema.xml.in
similarity index 100%
rename from data/org.gnome.builder.editor.language.gschema.xml.in
rename to data/gsettings/org.gnome.builder.editor.language.gschema.xml.in
diff --git a/data/org.gnome.builder.editor.vim.gschema.xml.in
b/data/gsettings/org.gnome.builder.editor.vim.gschema.xml.in
similarity index 100%
rename from data/org.gnome.builder.editor.vim.gschema.xml.in
rename to data/gsettings/org.gnome.builder.editor.vim.gschema.xml.in
diff --git a/data/keybindings/default.css b/data/keybindings/default.css
new file mode 100644
index 0000000..ad33511
--- /dev/null
+++ b/data/keybindings/default.css
@@ -0,0 +1,13 @@
+
+ binding-set default-ide-source-view
+{
+ bind "<ctrl>comma" { "action" ("app", "preferences", "") };
+ bind "<ctrl>f" { "action" ("frame", "find", "") };
+ bind "<ctrl>period" { "action" ("workbench", "global-search", "") };
+ bind "<ctrl>s" { "action" ("editor-view", "save", "") };
+}
+
+IdeSourceViewMode.default {
+ gtk-key-bindings: default-ide-source-view;
+}
+
diff --git a/data/keybindings/emacs.css b/data/keybindings/emacs.css
index 27cb9ef..6c8b0e4 100644
--- a/data/keybindings/emacs.css
+++ b/data/keybindings/emacs.css
@@ -50,7 +50,7 @@
bind "<ctrl>underscore" { "undo" () };
bind "<alt>x" { "action" ("win", "show-command-bar", "") };
bind "<ctrl>s" { "action" ("editor-frame", "find", "") };
- bind "<ctrl>period" { "action" ("win", "global-search", "") };
+ bind "<ctrl>period" { "action" ("workbench", "global-search", "") };
bind "<ctrl>comma" { "action" ("app", "preferences", "") };
bind "<alt>n" { "move-error" (down) };
bind "<alt>p" { "move-error" (up) };
@@ -77,7 +77,7 @@
bind "0" { "action" ("stack", "close", "") };
bind "k" { "action" ("stack", "close", "") };
bind "<ctrl>f" { "action" ("workspace", "open", "") };
- bind "<ctrl>s" { "action" ("stack", "save", "") };
+ bind "<ctrl>s" { "action" ("editor-view", "save", "") };
bind "s" { "action" ("win", "save-all", "") };
bind "b" { "action" ("workspace", "new-document", "") };
bind "<ctrl>w" { "action" ("stack", "save-as", "") };
diff --git a/data/keybindings/vim.css b/data/keybindings/vim.css
index 5cbaf93..a40dcf7 100644
--- a/data/keybindings/vim.css
+++ b/data/keybindings/vim.css
@@ -88,6 +88,10 @@
"clear-selection" ()
"clear-snippets" ()
"set-mode" ("vim-normal", permanent) };
+
+ bind "<ctrl>comma" { "action" ("app", "preferences", "") };
+ bind "<ctrl>period" { "action" ("workbench", "global-search", "") };
+ bind "<ctrl>s" { "action" ("editor-view", "save", "") };
}
@binding-set builder-vim-source-view-normal-with-count
@@ -124,6 +128,9 @@
/* replay the last recording */
bind "period" { "replay-macro" (1) };
+ /* start search */
+ bind "slash" { "action" ("frame", "find", "") };
+
/* insert at cursor */
bind "i" { "begin-macro" ()
"set-mode" ("vim-insert", permanent) };
@@ -323,9 +330,13 @@
"clear-selection" () };
bind "p" { "begin-macro" ()
+ "save-insert-mark" ()
"paste-clipboard-extended" (1, 1, 1)
"clear-count" ()
- "end-macro" () };
+ "restore-insert-mark" ()
+ "end-macro" ()
+ "movement" (next-line, 0, 0, 0)
+ "movement" (first-nonspace-char, 0, 1, 0) };
bind "<shift>p" { "begin-macro" ()
"paste-clipboard-extended" (1, 0, 1)
"clear-count" ()
diff --git a/data/styles/builder-dark.xml b/data/style-schemes/builder-dark.xml
similarity index 100%
rename from data/styles/builder-dark.xml
rename to data/style-schemes/builder-dark.xml
diff --git a/data/styles/builder.xml b/data/style-schemes/builder.xml
similarity index 100%
rename from data/styles/builder.xml
rename to data/style-schemes/builder.xml
diff --git a/src/resources/ui/gb-command-bar.ui b/data/ui/gb-command-bar.ui
similarity index 100%
rename from src/resources/ui/gb-command-bar.ui
rename to data/ui/gb-command-bar.ui
diff --git a/data/ui/gb-editor-frame.ui b/data/ui/gb-editor-frame.ui
new file mode 100644
index 0000000..288a0ff
--- /dev/null
+++ b/data/ui/gb-editor-frame.ui
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.15 -->
+ <template class="GbEditorFrame" parent="GtkBin">
+ <child>
+ <object class="GtkOverlay">
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <child type="overlay">
+ <object class="NautilusFloatingBar" id="floating_bar">
+ <property name="halign">end</property>
+ <property name="primary_label"></property>
+ <property name="valign">end</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child type="overlay">
+ <object class="GtkRevealer" id="search_revealer">
+ <property name="halign">end</property>
+ <property name="valign">start</property>
+ <property name="visible">true</property>
+ <property name="width-request">300</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">true</property>
+ <property name="margin-end">12</property>
+ <style>
+ <class name="gb-search-slider"/>
+ </style>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GdTaggedEntry" id="search_entry">
+ <property name="visible">true</property>
+ <property name="tag-close-visible">false</property>
+ <property name="can-focus">true</property>
+ <property name="width-request">260</property>
+ <property name="primary-icon-activatable">true</property>
+ <property name="primary-icon-sensitive">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">true</property>
+ <property name="can-focus">false</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-up-symbolic</property>
+ <property name="icon-size">1</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">true</property>
+ <property name="can-focus">false</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-down-symbolic</property>
+ <property name="icon-size">1</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolled_window">
+ <property name="visible">true</property>
+ <child>
+ <object class="IdeSourceView" id="source_view">
+ <property name="auto-indent">true</property>
+ <property name="enable-word-completion">true</property>
+ <property name="highlight-current-line">true</property>
+ <property name="insert-matching-brace">true</property>
+ <property name="overwrite-braces">true</property>
+ <property name="scroll-offset">0</property>
+ <property name="show-grid-lines">true</property>
+ <property name="show-line-changes">true</property>
+ <property name="show-line-numbers">true</property>
+ <property name="show-right-margin">true</property>
+ <property name="show-search-bubbles">true</property>
+ <property name="show-search-shadow">true</property>
+ <property name="smart-backspace">true</property>
+ <property name="snippet-completion">true</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/src/resources/ui/gb-editor-settings-widget.ui b/data/ui/gb-editor-settings-widget.ui
similarity index 100%
rename from src/resources/ui/gb-editor-settings-widget.ui
rename to data/ui/gb-editor-settings-widget.ui
diff --git a/src/resources/ui/gb-editor-tweak-widget.ui b/data/ui/gb-editor-tweak-widget.ui
similarity index 95%
rename from src/resources/ui/gb-editor-tweak-widget.ui
rename to data/ui/gb-editor-tweak-widget.ui
index f08e201..0e5ee49 100644
--- a/src/resources/ui/gb-editor-tweak-widget.ui
+++ b/data/ui/gb-editor-tweak-widget.ui
@@ -84,6 +84,14 @@
</object>
</child>
<child>
+ <object class="GtkModelButton">
+ <property name="visible">true</property>
+ <property name="text" translatable="yes">Smart Backspace</property>
+ <property name="halign">fill</property>
+ <property name="action-name">editor-view.smart-backspace</property>
+ </object>
+ </child>
+ <child>
<object class="GtkLabel">
<property name="visible">true</property>
<property name="label" translatable="yes">Indentation</property>
diff --git a/data/ui/gb-editor-view.ui b/data/ui/gb-editor-view.ui
new file mode 100644
index 0000000..d62ab1b
--- /dev/null
+++ b/data/ui/gb-editor-view.ui
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.15 -->
+ <template class="GbEditorView" parent="GbView">
+ <child>
+ <object class="GtkOverlay">
+ <property name="visible">true</property>
+ <child type="overlay">
+ <object class="GtkProgressBar" id="progress_bar">
+ <property name="halign">fill</property>
+ <property name="orientation">horizontal</property>
+ <property name="valign">start</property>
+ <property name="visible">false</property>
+ <style>
+ <class name="osd"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkPaned" id="paned">
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GbEditorFrame" id="frame1">
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child internal-child="controls">
+ <object class="GtkBox">
+ <child>
+ <object class="GtkMenuButton" id="tweak_button">
+ <property name="popover">popover</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="dim-label"/>
+ <class name="text-button"/>
+ <class name="flat"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkPopover" id="popover">
+ <child>
+ <object class="GbEditorTweakWidget" id="tweak_widget">
+ <property name="border-width">12</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/data/ui/gb-editor-workspace.ui b/data/ui/gb-editor-workspace.ui
new file mode 100644
index 0000000..2fa83b4
--- /dev/null
+++ b/data/ui/gb-editor-workspace.ui
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.15 -->
+ <template class="GbEditorWorkspace" parent="GbWorkspace">
+ <child>
+ <object class="GbViewGrid" id="view_grid">
+ <property name="expand">true</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/ui/gb-view-stack.ui b/data/ui/gb-view-stack.ui
new file mode 100644
index 0000000..f78ee10
--- /dev/null
+++ b/data/ui/gb-view-stack.ui
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.15 -->
+ <template class="GbViewStack" parent="GtkBin">
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="notebook"/>
+ <class name="header"/>
+ </style>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">true</property>
+ <property name="margin-bottom">3</property>
+ <property name="margin-end">6</property>
+ <property name="margin-start">6</property>
+ <property name="margin-top">3</property>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkButton" id="go_backward">
+ <property name="visible">true</property>
+ <property name="action-name">navigation.go-backward</property>
+ <style>
+ <class name="flat"/>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-previous-symbolic</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="go_forward">
+ <property name="visible">true</property>
+ <property name="action-name">navigation.go-forkward</property>
+ <style>
+ <class name="flat"/>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="icon-name">go-next-symbolic</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="center">
+ <object class="GtkMenuButton">
+ <property name="hexpand">true</property>
+ <property name="popover">popover</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="dim-label"/>
+ <class name="flat"/>
+ <class name="text-button"/>
+ </style>
+ <child>
+ <object class="GtkLabel" id="title_label">
+ <property name="visible">true</property>
+ <property name="width-chars">40</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">true</property>
+ <style>
+ <class name="dim-label"/>
+ <class name="image-button"/>
+ <class name="flat"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon-name">window-close-symbolic</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkStack" id="controls_stack">
+ <property name="visible">true</property>
+ </object>
+ <packing>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="hexpand">true</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkPopover" id="popover">
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <property name="visible">true</property>
+ <property name="margin-start">6</property>
+ <property name="margin-end">6</property>
+ <property name="margin-top">12</property>
+ <property name="margin-bottom">12</property>
+ <child>
+ <object class="GtkBox">
+ <property name="margin-end">12</property>
+ <property name="margin-start">12</property>
+ <property name="spacing">6</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkLabel" id="split_label">
+ <property name="label" translatable="yes">Split</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">true</property>
+ <property name="margin-start">6</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">true</property>
+ <property name="action-name">view.split-left</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon-name">builder-split-left-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">true</property>
+ <property name="action-name">view.split-right</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon-name">builder-split-right-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">true</property>
+ <property name="action-name">view.split-down</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon-name">builder-split-tab-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="margin-end">12</property>
+ <property name="margin-start">12</property>
+ <property name="spacing">6</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkLabel" id="move_label">
+ <property name="visible">true</property>
+ <property name="label" translatable="yes">Move</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="hexpand">true</property>
+ <property name="margin-start">6</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="linked"/>
+ </style>
+ <child>
+ <object class="GtkButton">
+ <property name="action-name">view.move-left</property>
+ <property name="hexpand">true</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon-name">builder-move-left-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="action-name">view.move-right</property>
+ <property name="hexpand">true</property>
+ <property name="visible">true</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">true</property>
+ <property name="icon-name">builder-move-right-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkModelButton">
+ <property name="action-name">view.save</property>
+ <property name="halign">fill</property>
+ <property name="hexpand">true</property>
+ <property name="text" translatable="yes">Save</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkModelButton">
+ <property name="action-name">view.save-as</property>
+ <property name="halign">fill</property>
+ <property name="hexpand">true</property>
+ <property name="text" translatable="yes">Save As</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkModelButton">
+ <property name="halign">fill</property>
+ <property name="hexpand">true</property>
+ <property name="action-name">view.close</property>
+ <property name="text" translatable="yes">Close</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkSizeGroup">
+ <property name="mode">horizontal</property>
+ <widgets>
+ <widget name="split_label"/>
+ <widget name="move_label"/>
+ </widgets>
+ </object>
+</interface>
diff --git a/data/ui/gb-workbench.ui b/data/ui/gb-workbench.ui
new file mode 100644
index 0000000..fe76192
--- /dev/null
+++ b/data/ui/gb-workbench.ui
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.15 -->
+ <template class="GbWorkbench" parent="GtkApplicationWindow">
+ <property name="icon-name">builder</property>
+ <child type="titlebar">
+ <object class="GtkHeaderBar">
+ <property name="visible">true</property>
+ <property name="show_close_button">true</property>
+ <child type="title">
+ <object class="GbSearchBox" id="search_box">
+ <property name="margin-end">6</property>
+ <property name="margin-start">6</property>
+ <property name="visible">true</property>
+ <property name="width_request">540</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkMenuButton" id="gear_menu_button">
+ <property name="visible">true</property>
+ <style>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="icon_name">open-menu-symbolic</property>
+ <property name="valign">baseline</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="expand">true</property>
+ <property name="transition_type">slide-up-down</property>
+ <property name="visible">true</property>
+ <child>
+ <object class="GbEditorWorkspace" id="editor_workspace">
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GbCommandBar" id="command_bar">
+ <property name="transition-type">slide-up</property>
+ <property name="visible">true</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 7e4fcce..fb95204 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -180,6 +180,8 @@ libide_1_0_la_public_sources = \
libide_1_0_la_SOURCES = \
$(libide_1_0_la_public_sources) \
+ cut-n-paste/trie.c \
+ cut-n-paste/trie.h \
libide/autotools/ide-makecache.c \
libide/autotools/ide-makecache.h \
libide/c/c-parse-helper.c \
@@ -249,8 +251,6 @@ libide_1_0_la_SOURCES = \
libide/theatrics/ide-box-theatric.h \
libide/theatrics/ide-frame-source.c \
libide/theatrics/ide-frame-source.h \
- libide/trie/trie.c \
- libide/trie/trie.h \
libide/util/ide-cairo.c \
libide/util/ide-cairo.h \
libide/util/ide-pango.c \
@@ -260,6 +260,7 @@ libide_1_0_la_SOURCES = \
$(NULL)
libide_1_0_la_includes = \
+ -I$(top_srcdir)/cut-n-paste \
-I$(top_srcdir)/libide \
-I$(top_srcdir)/libide/autotools \
-I$(top_srcdir)/libide/c \
diff --git a/libide/devhelp/ide-devhelp-search-provider.c b/libide/devhelp/ide-devhelp-search-provider.c
index 084213c..af9ec9d 100644
--- a/libide/devhelp/ide-devhelp-search-provider.c
+++ b/libide/devhelp/ide-devhelp-search-provider.c
@@ -28,93 +28,72 @@
#include "ide-search-result.h"
#include "ide-search-context.h"
-typedef struct
-{
- DhBookManager *book_manager;
- DhKeywordModel *keywords_model;
-} IdeDevhelpSearchProviderPrivate;
-
struct _IdeDevhelpSearchProvider
{
- IdeSearchProvider parent;
+ IdeSearchProvider parent;
- /*< private >*/
- IdeDevhelpSearchProviderPrivate *priv;
+ DhBookManager *book_manager;
+ DhKeywordModel *keywords_model;
};
-typedef struct
-{
- IdeSearchContext *context;
- gchar *search_terms;
- gsize max_results;
-} PopulateState;
-
-G_DEFINE_TYPE_WITH_PRIVATE (IdeDevhelpSearchProvider,
- ide_devhelp_search_provider,
- IDE_TYPE_SEARCH_PROVIDER)
+G_DEFINE_TYPE (IdeDevhelpSearchProvider, ide_devhelp_search_provider, IDE_TYPE_SEARCH_PROVIDER)
-static GQuark gQuarkLink;
+static GQuark gQuarkLink;
static void
-populate_get_matches_cb (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
+ide_devhelp_search_provider_populate (IdeSearchProvider *provider,
+ IdeSearchContext *context,
+ const gchar *search_terms,
+ gsize max_results,
+ GCancellable *cancellable)
{
- IdeDevhelpSearchProviderPrivate *priv;
- IdeContext* context;
- PopulateState *state;
+ IdeDevhelpSearchProvider *self = (IdeDevhelpSearchProvider *)provider;
g_auto(IdeSearchReducer) reducer = { 0 };
+ IdeContext *idecontext;
GtkTreeIter iter;
gboolean valid;
- gint count = 0;
+ gint count = 0;;
gint total;
- priv = IDE_DEVHELP_SEARCH_PROVIDER (source_object)->priv;
- state = (PopulateState*) user_data;
- context = ide_object_get_context (IDE_OBJECT (state->context));
+ g_assert (IDE_IS_DEVHELP_SEARCH_PROVIDER (self));
+ g_assert (IDE_IS_SEARCH_CONTEXT (context));
+ g_assert (search_terms);
+ g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
- dh_keyword_model_filter (priv->keywords_model, state->search_terms, NULL, NULL);
+ if (search_terms [0] == '\0')
+ {
+ ide_search_context_provider_completed (context, provider);
+ return;
+ }
- total = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (priv->keywords_model),
- NULL);
- if (state->max_results != 0)
- total = MIN (total, state->max_results);
+ idecontext = ide_object_get_context (IDE_OBJECT (provider));
- /* initialize our reducer, which helps us prevent creating unnecessary
- * objects that will simply be discarded */
- ide_search_reducer_init (&reducer,
- state->context,
- IDE_SEARCH_PROVIDER (source_object),
- state->max_results);
+ dh_keyword_model_filter (self->keywords_model, search_terms, NULL, NULL);
+
+ ide_search_reducer_init (&reducer, context, provider, max_results);
+
+ valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self->keywords_model), &iter);
+ total = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (self->keywords_model), NULL);
- valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->keywords_model),
- &iter);
while (valid)
{
g_autoptr(IdeSearchResult) result = NULL;
- DhLink *link = NULL;
g_autofree gchar *name = NULL;
- gfloat score = .0;
+ DhLink *link = NULL;
+ gfloat score = (total - count) / (gfloat)total;
- gtk_tree_model_get (GTK_TREE_MODEL (priv->keywords_model), &iter,
+ gtk_tree_model_get (GTK_TREE_MODEL (self->keywords_model), &iter,
DH_KEYWORD_MODEL_COL_NAME, &name,
DH_KEYWORD_MODEL_COL_LINK, &link,
-1);
- valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->keywords_model),
- &iter);
+ valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (self->keywords_model), &iter);
- count++;
- score = (total - count) / (gfloat) (total + 1);
+ /* we traverse from best to worst, so just break */
if (!ide_search_reducer_accepts (&reducer, score))
- continue;
+ break;
- if (!g_str_is_ascii (name))
- {
- gchar *ascii_name = g_str_to_ascii (name, NULL);
- g_free (name);
- name = ascii_name;
- }
+ count++;
if ((dh_link_get_flags (link) & DH_LINK_FLAGS_DEPRECATED) != 0)
{
@@ -123,44 +102,20 @@ populate_get_matches_cb (GObject *source_object,
name = italic_name;
}
- result = ide_search_result_new (context,
- name,
- dh_link_get_book_name (link),
- score);
- g_object_set_qdata_full (G_OBJECT (result),
- gQuarkLink,
- dh_link_get_uri (link),
- g_free);
+ result = ide_search_result_new (idecontext, name, dh_link_get_book_name (link), score);
+ g_object_set_qdata_full (G_OBJECT (result), gQuarkLink, dh_link_get_uri (link), g_free);
/* push the result through the search reducer */
ide_search_reducer_push (&reducer, result);
}
- ide_search_context_provider_completed (state->context,
- IDE_SEARCH_PROVIDER (source_object));
-
- g_free (state->search_terms);
- g_object_unref (state->context);
- g_slice_free (PopulateState, state);
+ ide_search_context_provider_completed (context, provider);
}
-void
-ide_devhelp_search_provider_populate (IdeSearchProvider *provider,
- IdeSearchContext *context,
- const gchar *search_terms,
- gsize max_results,
- GCancellable *cancellable)
+static const gchar *
+ide_devhelp_search_provider_get_verb (IdeSearchProvider *provider)
{
- PopulateState *state;
- g_autoptr(GTask) task = NULL;
-
- state = g_new0 (PopulateState, 1);
- state->context = g_object_ref (context);
- state->search_terms = g_strdup (search_terms);
- state->max_results = max_results;
-
- task = g_task_new (provider, cancellable, populate_get_matches_cb, state);
- g_task_return_pointer (task, NULL, NULL);
+ return _("Documentation");
}
static void
@@ -168,8 +123,8 @@ ide_devhelp_search_provider_constructed (GObject *object)
{
IdeDevhelpSearchProvider *self = IDE_DEVHELP_SEARCH_PROVIDER (object);
- dh_book_manager_populate (self->priv->book_manager);
- dh_keyword_model_set_words (self->priv->keywords_model, self->priv->book_manager);
+ dh_book_manager_populate (self->book_manager);
+ dh_keyword_model_set_words (self->keywords_model, self->book_manager);
}
static void
@@ -177,7 +132,7 @@ ide_devhelp_search_provider_finalize (GObject *object)
{
IdeDevhelpSearchProvider *self = IDE_DEVHELP_SEARCH_PROVIDER (object);
- g_clear_object (&self->priv->book_manager);
+ g_clear_object (&self->book_manager);
G_OBJECT_CLASS (ide_devhelp_search_provider_parent_class)->finalize (object);
}
@@ -191,6 +146,7 @@ ide_devhelp_search_provider_class_init (IdeDevhelpSearchProviderClass *klass)
object_class->constructed = ide_devhelp_search_provider_constructed;
object_class->finalize = ide_devhelp_search_provider_finalize;
+ provider_class->get_verb = ide_devhelp_search_provider_get_verb;
provider_class->populate = ide_devhelp_search_provider_populate;
gQuarkLink = g_quark_from_static_string ("LINK");
@@ -199,7 +155,6 @@ ide_devhelp_search_provider_class_init (IdeDevhelpSearchProviderClass *klass)
static void
ide_devhelp_search_provider_init (IdeDevhelpSearchProvider *self)
{
- self->priv = ide_devhelp_search_provider_get_instance_private (self);
- self->priv->book_manager = dh_book_manager_new ();
- self->priv->keywords_model = dh_keyword_model_new ();
+ self->book_manager = dh_book_manager_new ();
+ self->keywords_model = dh_keyword_model_new ();
}
diff --git a/libide/git/ide-git-search-index.c b/libide/git/ide-git-search-index.c
index 01f98d7..76a50c5 100644
--- a/libide/git/ide-git-search-index.c
+++ b/libide/git/ide-git-search-index.c
@@ -227,12 +227,8 @@ ide_git_search_index_populate (IdeGitSearchIndex *self,
markup = str_highlight (shortname, search_terms);
/* create our search result and connect to signals */
- result = ide_search_result_new (context,
- markup,
- str->str,
- match->score);
- g_object_set_qdata_full (G_OBJECT (result), gPathQuark,
- g_strdup (match->value), g_free);
+ result = ide_search_result_new (context, markup, str->str, match->score);
+ g_object_set_qdata_full (G_OBJECT (result), gPathQuark, g_strdup (match->value), g_free);
#if 0
/* I think we might want to leave this signal on the provider */
g_signal_connect (result, "activate", G_CALLBACK (activate_cb), NULL);
diff --git a/libide/git/ide-git-search-provider.c b/libide/git/ide-git-search-provider.c
index 634f37c..9e7a4c4 100644
--- a/libide/git/ide-git-search-provider.c
+++ b/libide/git/ide-git-search-provider.c
@@ -190,6 +190,12 @@ ide_git_search_provider_populate (IdeSearchProvider *provider,
state);
}
+static const gchar *
+ide_git_search_provider_get_verb (IdeSearchProvider *provider)
+{
+ return _("Switch To");
+}
+
static void
ide_git_search_provider_finalize (GObject *object)
{
@@ -208,6 +214,7 @@ ide_git_search_provider_class_init (IdeGitSearchProviderClass *klass)
object_class->finalize = ide_git_search_provider_finalize;
+ provider_class->get_verb = ide_git_search_provider_get_verb;
provider_class->populate = ide_git_search_provider_populate;
}
diff --git a/libide/gsettings/ide-language-defaults.c b/libide/gsettings/ide-language-defaults.c
index 3d0bde2..7797295 100644
--- a/libide/gsettings/ide-language-defaults.c
+++ b/libide/gsettings/ide-language-defaults.c
@@ -286,30 +286,30 @@ ide_language_defaults_init_worker (GTask *task,
g_task_return_error (task, error);
goto failure;
}
- }
- version_contents = g_strdup_printf ("%d", global_version);
+ version_contents = g_strdup_printf ("%d", global_version);
- version_dir = g_path_get_dirname (version_path);
+ version_dir = g_path_get_dirname (version_path);
- if (!g_file_test (version_dir, G_FILE_TEST_IS_DIR))
- {
- if (g_mkdir_with_parents (version_dir, 0750) == -1)
+ if (!g_file_test (version_dir, G_FILE_TEST_IS_DIR))
{
- g_task_return_new_error (task,
- G_IO_ERROR,
- g_io_error_from_errno (errno),
- "%s", g_strerror (errno));
- goto failure;
+ if (g_mkdir_with_parents (version_dir, 0750) == -1)
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "%s", g_strerror (errno));
+ goto failure;
+ }
}
- }
- IDE_TRACE_MSG ("Writing new language defaults version to \"%s\"", version_path);
+ IDE_TRACE_MSG ("Writing new language defaults version to \"%s\"", version_path);
- if (!g_file_set_contents (version_path, version_contents, -1, &error))
- {
- g_task_return_error (task, error);
- goto failure;
+ if (!g_file_set_contents (version_path, version_contents, -1, &error))
+ {
+ g_task_return_error (task, error);
+ goto failure;
+ }
}
g_task_return_boolean (task, TRUE);
diff --git a/libide/ide-back-forward-item.c b/libide/ide-back-forward-item.c
index 9524e91..44ed77c 100644
--- a/libide/ide-back-forward-item.c
+++ b/libide/ide-back-forward-item.c
@@ -50,42 +50,6 @@ ide_back_forward_item_new (IdeContext *context,
NULL);
}
-gboolean
-ide_back_forward_item_chain (IdeBackForwardItem *self,
- IdeBackForwardItem *other)
-{
- IdeSourceLocation *loc1;
- IdeSourceLocation *loc2;
- IdeFile *file1;
- IdeFile *file2;
- gint line1;
- gint line2;
-
- g_return_val_if_fail (IDE_IS_BACK_FORWARD_ITEM (self), FALSE);
- g_return_val_if_fail (IDE_IS_BACK_FORWARD_ITEM (other), FALSE);
-
- loc1 = ide_back_forward_item_get_location (self);
- loc2 = ide_back_forward_item_get_location (other);
-
- file1 = ide_source_location_get_file (loc1);
- file2 = ide_source_location_get_file (loc2);
-
- if (!ide_file_equal (file1, file2))
- return FALSE;
-
- line1 = ide_source_location_get_line (loc1);
- line2 = ide_source_location_get_line (loc2);
-
- if (ABS (line1 - line2) <= NUM_LINES_CHAIN_MAX)
- {
- self->location = ide_source_location_ref (loc2);
- ide_source_location_unref (loc1);
- return TRUE;
- }
-
- return FALSE;
-}
-
IdeSourceLocation *
ide_back_forward_item_get_location (IdeBackForwardItem *self)
{
@@ -186,3 +150,38 @@ static void
ide_back_forward_item_init (IdeBackForwardItem *self)
{
}
+
+gboolean
+ide_back_forward_item_chain (IdeBackForwardItem *self,
+ IdeBackForwardItem *other)
+{
+ IdeSourceLocation *loc1;
+ IdeSourceLocation *loc2;
+ IdeFile *file1;
+ IdeFile *file2;
+ gint line1;
+ gint line2;
+
+ g_return_val_if_fail (IDE_IS_BACK_FORWARD_ITEM (self), FALSE);
+ g_return_val_if_fail (IDE_IS_BACK_FORWARD_ITEM (other), FALSE);
+
+ loc1 = ide_back_forward_item_get_location (self);
+ loc2 = ide_back_forward_item_get_location (other);
+
+ file1 = ide_source_location_get_file (loc1);
+ file2 = ide_source_location_get_file (loc2);
+
+ if (!ide_file_equal (file1, file2))
+ return FALSE;
+
+ line1 = ide_source_location_get_line (loc1);
+ line2 = ide_source_location_get_line (loc2);
+
+ if (ABS (line1 - line2) <= NUM_LINES_CHAIN_MAX)
+ {
+ ide_back_forward_item_set_location (self, other->location);
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/libide/ide-back-forward-list.c b/libide/ide-back-forward-list.c
index f4aa566..8cf7a50 100644
--- a/libide/ide-back-forward-list.c
+++ b/libide/ide-back-forward-list.c
@@ -640,6 +640,7 @@ create_source_location (IdeBackForwardList *self,
IdeContext *context;
IdeProject *project;
g_autoptr(IdeFile) file = NULL;
+ IdeSourceLocation *ret;
g_assert (IDE_IS_BACK_FORWARD_LIST (self));
g_assert (G_IS_FILE (gfile));
@@ -648,7 +649,9 @@ create_source_location (IdeBackForwardList *self,
project = ide_context_get_project (context);
file = ide_project_get_project_file (project, gfile);
- return ide_source_location_new (file, line, line_offset, 0);
+ ret = ide_source_location_new (file, line, line_offset, 0);
+
+ return ret;
}
static void
diff --git a/libide/ide-buffer-manager.c b/libide/ide-buffer-manager.c
index 2c932d3..39bdbcf 100644
--- a/libide/ide-buffer-manager.c
+++ b/libide/ide-buffer-manager.c
@@ -86,6 +86,8 @@ enum {
};
enum {
+ CREATE_BUFFER,
+
SAVE_BUFFER,
BUFFER_SAVED,
@@ -661,12 +663,29 @@ ide_buffer_manager_load_file_async (IdeBufferManager *self,
"context", context,
NULL);
if (buffer)
- state->buffer = g_object_ref (buffer);
+ {
+ state->buffer = g_object_ref (buffer);
+ }
else
- state->buffer = g_object_new (IDE_TYPE_BUFFER,
- "context", context,
- "file", file,
- NULL);
+ {
+ /*
+ * Allow application to specify the buffer instance which may be a
+ * decendent of IdeBuffer.
+ */
+ g_signal_emit (self, gSignals [CREATE_BUFFER], 0, file, &state->buffer);
+
+ if ((state->buffer != NULL) && !IDE_IS_BUFFER (state->buffer))
+ {
+ g_warning ("Invalid buffer type retrieved from create-buffer signal.");
+ state->buffer = NULL;
+ }
+
+ if (state->buffer == NULL)
+ state->buffer = g_object_new (IDE_TYPE_BUFFER,
+ "context", context,
+ "file", file,
+ NULL);
+ }
_ide_buffer_set_loading (state->buffer, TRUE);
@@ -717,6 +736,7 @@ ide_buffer_manager_save_file__save_cb (GObject *object,
g_autoptr(GTask) task = user_data;
GtkSourceFileSaver *saver = (GtkSourceFileSaver *)object;
IdeBufferManager *self;
+ IdeFile *file;
SaveState *state;
GError *error = NULL;
@@ -739,6 +759,11 @@ ide_buffer_manager_save_file__save_cb (GObject *object,
return;
}
+ /* Make the buffer as not modified if we saved it to the backing file */
+ file = ide_buffer_get_file (state->buffer);
+ if (ide_file_equal (file, state->file))
+ gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (state->buffer), FALSE);
+
/* Notify signal handlers that the file is saved */
g_signal_emit (self, gSignals [BUFFER_SAVED], 0, state->buffer);
@@ -1034,6 +1059,31 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
gParamSpecs [PROP_AUTO_SAVE_TIMEOUT]);
/**
+ * IdeBufferManager::create-buffer:
+ * @self: An #IdeBufferManager
+ * @file: An #IdeFile
+ *
+ * This signal is emitted when there is a request to create a new buffer
+ * object. This allows subclasses of #IdeBuffer to be instantiated by the
+ * buffer manager.
+ *
+ * The first handler of this signal is responsible for returning an
+ * #IdeBuffer or %NULL, for which one will be created.
+ *
+ * Returns: (transfer full) (nullable): An #IdeBuffer or %NULL.
+ */
+ gSignals [CREATE_BUFFER] = g_signal_new ("create-buffer",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ g_signal_accumulator_first_wins,
+ NULL,
+ g_cclosure_marshal_generic,
+ IDE_TYPE_BUFFER,
+ 1,
+ IDE_TYPE_FILE);
+
+ /**
* IdeBufferManager::save-buffer:
* @self: An #IdeBufferManager.
* @buffer: an #IdeBuffer.
@@ -1042,7 +1092,7 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
* if you'd like to perform mutation of the buffer before it is persisted to storage.
*/
gSignals [SAVE_BUFFER] = g_signal_new ("save-buffer",
- G_TYPE_FROM_CLASS (object_class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
@@ -1061,7 +1111,7 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
* storage.
*/
gSignals [BUFFER_SAVED] = g_signal_new ("buffer-saved",
- G_TYPE_FROM_CLASS (object_class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
@@ -1079,7 +1129,7 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
* connect to this signal to be notified when loading of a buffer has begun.
*/
gSignals [LOAD_BUFFER] = g_signal_new ("load-buffer",
- G_TYPE_FROM_CLASS (object_class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
@@ -1097,7 +1147,7 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
* signal to be notified when a buffer has completed loading.
*/
gSignals [BUFFER_LOADED] = g_signal_new ("buffer-loaded",
- G_TYPE_FROM_CLASS (object_class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
@@ -1115,7 +1165,7 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
* signal when you want to perform an operation while a buffer is in focus.
*/
gSignals [BUFFER_FOCUS_ENTER] = g_signal_new ("buffer-focus-enter",
- G_TYPE_FROM_CLASS (object_class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
@@ -1133,7 +1183,7 @@ ide_buffer_manager_class_init (IdeBufferManagerClass *klass)
* to this signal to stop any work you were performing while the buffer was focused.
*/
gSignals [BUFFER_FOCUS_LEAVE] = g_signal_new ("buffer-focus-leave",
- G_TYPE_FROM_CLASS (object_class),
+ G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
diff --git a/libide/ide-file.c b/libide/ide-file.c
index c9df629..ff62de4 100644
--- a/libide/ide-file.c
+++ b/libide/ide-file.c
@@ -19,6 +19,7 @@
#include <glib/gi18n.h>
#include <gtksourceview/gtksource.h>
+#include "ide-debug.h"
#include "ide-file.h"
#include "ide-file-settings.h"
#include "ide-language.h"
@@ -333,6 +334,8 @@ ide_file_finalize (GObject *object)
{
IdeFile *self = (IdeFile *)object;
+ IDE_ENTRY;
+
g_clear_object (&self->file);
g_clear_object (&self->source_file);
g_clear_object (&self->language);
@@ -340,6 +343,8 @@ ide_file_finalize (GObject *object)
g_clear_pointer (&self->content_type, g_free);
G_OBJECT_CLASS (ide_file_parent_class)->finalize (object);
+
+ IDE_EXIT;
}
static void
diff --git a/libide/ide-log.c b/libide/ide-log.c
index ae9abc8..f172f13 100644
--- a/libide/ide-log.c
+++ b/libide/ide-log.c
@@ -99,7 +99,7 @@ ide_log_level_str (GLogLevelFlags log_level)
*/
static void
ide_log_write_to_channel (GIOChannel *channel,
- const gchar *message)
+ const gchar *message)
{
g_io_channel_write_chars (channel, message, -1, NULL, NULL);
g_io_channel_flush (channel, NULL);
diff --git a/libide/ide-search-context.c b/libide/ide-search-context.c
index d7c2172..80798db 100644
--- a/libide/ide-search-context.c
+++ b/libide/ide-search-context.c
@@ -16,6 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define G_LOG_DOMAIN "ide-search-context"
+
+#include "ide-debug.h"
#include "ide-search-context.h"
#include "ide-search-provider.h"
#include "ide-search-result.h"
@@ -26,6 +29,7 @@ struct _IdeSearchContext
GCancellable *cancellable;
GList *providers;
+ gsize max_results;
guint in_progress;
guint executed : 1;
};
@@ -115,35 +119,37 @@ ide_search_context_set_provider_count (IdeSearchContext *self,
void
ide_search_context_execute (IdeSearchContext *self,
- const gchar *search_terms)
+ const gchar *search_terms,
+ gsize max_results)
{
GList *iter;
+ IDE_ENTRY;
+
g_return_if_fail (IDE_IS_SEARCH_CONTEXT (self));
g_return_if_fail (!self->executed);
g_return_if_fail (search_terms);
self->executed = TRUE;
self->in_progress = g_list_length (self->providers);
+ self->max_results = max_results;
if (!self->in_progress)
{
g_signal_emit (self, gSignals [COMPLETED], 0);
- return;
+ IDE_EXIT;
}
for (iter = self->providers; iter; iter = iter->next)
{
- gsize max_results = 0;
-
- /* TODO: Get the max results for this provider */
-
ide_search_provider_populate (iter->data,
self,
search_terms,
max_results,
self->cancellable);
}
+
+ IDE_EXIT;
}
void
diff --git a/libide/ide-search-context.h b/libide/ide-search-context.h
index 55fec02..5de1ea4 100644
--- a/libide/ide-search-context.h
+++ b/libide/ide-search-context.h
@@ -38,7 +38,8 @@ void ide_search_context_remove_result (IdeSearchContext *self,
IdeSearchResult *result);
void ide_search_context_cancel (IdeSearchContext *self);
void ide_search_context_execute (IdeSearchContext *self,
- const gchar *search_terms);
+ const gchar *search_terms,
+ gsize max_results);
void ide_search_context_set_provider_count (IdeSearchContext *self,
IdeSearchProvider *provider,
guint64 count);
diff --git a/libide/ide-search-reducer.c b/libide/ide-search-reducer.c
index 4753b7c..5d765de 100644
--- a/libide/ide-search-reducer.c
+++ b/libide/ide-search-reducer.c
@@ -62,8 +62,7 @@ ide_search_reducer_push (IdeSearchReducer *reducer,
/* Remove lowest score */
iter = g_sequence_get_begin_iter (reducer->sequence);
lowest = g_sequence_get (iter);
- ide_search_context_remove_result (reducer->context, reducer->provider,
- lowest);
+ ide_search_context_remove_result (reducer->context, reducer->provider, lowest);
g_sequence_remove (iter);
}
diff --git a/libide/ide.h b/libide/ide.h
index e637050..c5080a9 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -33,6 +33,7 @@ G_BEGIN_DECLS
#include "ide-buffer.h"
#include "ide-buffer-manager.h"
#include "ide-context.h"
+#include "ide-debug.h"
#include "ide-debugger.h"
#include "ide-deployer.h"
#include "ide-device.h"
diff --git a/src/app/gb-application-actions.c b/src/app/gb-application-actions.c
new file mode 100644
index 0000000..edb69a0
--- /dev/null
+++ b/src/app/gb-application-actions.c
@@ -0,0 +1,230 @@
+/* gb-application-actions.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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 3 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 "gb-application"
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <glib/gi18n.h>
+
+#include "gb-application-actions.h"
+#include "gb-application-private.h"
+#include "gb-support.h"
+#include "gb-workbench.h"
+
+static void
+gb_application_actions_preferences (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GbApplication *self = user_data;
+ GbPreferencesWindow *window;
+ GbWorkbench *workbench = NULL;
+ GList *list;
+
+ IDE_ENTRY;
+
+ g_assert (GB_IS_APPLICATION (self));
+
+ if (self->preferences_window)
+ {
+ gtk_window_present (GTK_WINDOW (self->preferences_window));
+ return;
+ }
+
+ list = gtk_application_get_windows (GTK_APPLICATION (self));
+
+ for (; list; list = list->next)
+ if (GB_IS_WORKBENCH (list->data))
+ workbench = GB_WORKBENCH (list->data);
+
+ window = g_object_new (GB_TYPE_PREFERENCES_WINDOW,
+ "transient-for", workbench,
+ NULL);
+ ide_set_weak_pointer (&self->preferences_window, window);
+
+ gtk_window_present (GTK_WINDOW (window));
+
+ IDE_EXIT;
+}
+
+static void
+gb_application_actions_support (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GbApplication *self = user_data;
+ GtkWidget *dialog;
+ gchar *text = NULL;
+ GList *windows;
+ GError *error = NULL;
+ gchar *str = NULL;
+ gchar *log_path = NULL;
+ gchar *name = NULL;
+
+ name = g_strdup_printf ("gnome-builder-%u.log", (int)getpid ());
+ log_path = g_build_filename (g_get_home_dir (), name, NULL);
+ g_free (name);
+
+ windows = gtk_application_get_windows (GTK_APPLICATION (self));
+
+ str = gb_get_support_log ();
+
+ if (!g_file_set_contents (log_path, str, -1, &error))
+ {
+ g_printerr ("%s\n", error->message);
+ goto cleanup;
+ }
+
+ text = g_strdup_printf (_("The support log file has been written to '%s'. "
+ "Please provide this file as an attachment on "
+ "your bug report or support request."),
+ log_path);
+
+ g_message ("%s", text);
+
+ dialog = gtk_message_dialog_new (windows ? windows->data : NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE,
+ "%s", text);
+ gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
+
+cleanup:
+ g_free (text);
+ g_clear_error (&error);
+ g_free (str);
+ g_free (log_path);
+}
+
+static void
+gb_application_actions_quit (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbApplication *self = user_data;
+
+ IDE_ENTRY;
+
+ g_assert (GB_IS_APPLICATION (self));
+
+ g_application_quit (G_APPLICATION (self));
+
+ IDE_EXIT;
+}
+
+static void
+gb_application_actions_about (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbApplication *self = user_data;
+ const gchar *artists[] = {
+ "Allan Day",
+ "Hylke Bons",
+ "Jakub Steiner",
+ NULL };
+ const gchar *authors[] = {
+ "Alexander Larsson",
+ "Alexandre Franke",
+ "Carlos Soriano",
+ "Christian Hergert",
+ "Cosimo Cecchi",
+ "Dimitris Zenios",
+ "Fabiano Fidêncio",
+ "Florian Bäuerle",
+ "Florian Müllner",
+ "Hashem Nasarat",
+ "Hylke Bons",
+ "Igor Gnatenko",
+ "Jakub Steiner",
+ "Jasper St. Pierre",
+ "Jonathon Jongsma",
+ "Mathieu Bridon",
+ "Megh Parikh",
+ "Michael Catanzaro",
+ "Pete Travis",
+ "Ray Strode",
+ "Roberto Majadas",
+ "Ting-Wei Lan",
+ "Trinh Anh Ngoc",
+ "Yosef Or Boczko",
+ NULL };
+ const gchar *funders[] = {
+ "Aaron Hergert",
+ "Christian Hergert",
+ /* todo: load from crowdfunding */
+ NULL };
+ const gchar *documenters[] = {
+ NULL };
+ GtkDialog *dialog;
+ GtkWindow *parent = NULL;
+ GList *iter;
+ GList *windows;
+
+ g_assert (GB_IS_APPLICATION (self));
+
+ windows = gtk_application_get_windows (GTK_APPLICATION (self));
+
+ for (iter = windows; iter; iter = iter->next)
+ {
+ if (GB_IS_WORKBENCH (iter->data))
+ {
+ parent = iter->data;
+ break;
+ }
+ }
+
+ dialog = g_object_new (GTK_TYPE_ABOUT_DIALOG,
+ "artists", artists,
+ "authors", authors,
+ "comments", _("An IDE for GNOME"),
+ "documenters", documenters,
+ "license-type", GTK_LICENSE_GPL_3_0,
+ "logo-icon-name", "builder",
+ "modal", FALSE,
+ "program-name", _("GNOME Builder"),
+ "transient-for", parent,
+ "translator-credits", _("translator-credits"),
+ "version", PACKAGE_VERSION,
+ "website", "https://wiki.gnome.org/Apps/Builder",
+ "website-label", _("Learn more about GNOME Builder"),
+ NULL);
+ gtk_about_dialog_add_credit_section (GTK_ABOUT_DIALOG (dialog), _("Funded By"), funders);
+
+ g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+ gtk_window_present (GTK_WINDOW (dialog));
+}
+
+static const GActionEntry GbApplicationActions[] = {
+ { "about", gb_application_actions_about },
+ { "preferences", gb_application_actions_preferences },
+ { "quit", gb_application_actions_quit },
+ { "support", gb_application_actions_support },
+};
+
+void
+gb_application_actions_init (GbApplication *self)
+{
+ g_action_map_add_action_entries (G_ACTION_MAP (self), GbApplicationActions,
+ G_N_ELEMENTS (GbApplicationActions), self);
+}
diff --git a/src/auto-indent/c-parse-helper.h b/src/app/gb-application-actions.h
similarity index 57%
copy from src/auto-indent/c-parse-helper.h
copy to src/app/gb-application-actions.h
index 418f518..c4e660e 100644
--- a/src/auto-indent/c-parse-helper.h
+++ b/src/app/gb-application-actions.h
@@ -1,6 +1,6 @@
-/* c-parse-helper.h
+/* gb-application-actions.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,26 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef C_PARSE_HELPER_H
-#define C_PARSE_HELPER_H
+#ifndef GB_APPLICATION_ACTIONS_H
+#define GB_APPLICATION_ACTIONS_H
-#include <glib.h>
+#include "gb-application.h"
G_BEGIN_DECLS
-typedef struct
-{
- gchar *type;
- gchar *name;
- guint ellipsis : 1;
- guint n_star : 4;
-} Parameter;
-
-gboolean parameter_validate (Parameter *param);
-void parameter_free (Parameter *p);
-Parameter *parameter_copy (const Parameter *src);
-GSList *parse_parameters (const gchar *text);
+void gb_application_actions_init (GbApplication *self);
G_END_DECLS
-#endif /* C_PARSE_HELPER_H */
+#endif /* GB_APPLICATION_ACTIONS_H */
diff --git a/src/auto-indent/c-parse-helper.h b/src/app/gb-application-private.h
similarity index 57%
copy from src/auto-indent/c-parse-helper.h
copy to src/app/gb-application-private.h
index 418f518..24c01f6 100644
--- a/src/auto-indent/c-parse-helper.h
+++ b/src/app/gb-application-private.h
@@ -1,6 +1,6 @@
-/* c-parse-helper.h
+/* gb-application-private.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,26 +16,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef C_PARSE_HELPER_H
-#define C_PARSE_HELPER_H
+#ifndef GB_APPLICATION_PRIVATE_H
+#define GB_APPLICATION_PRIVATE_H
-#include <glib.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+#include "gb-keybindings.h"
+#include "gb-preferences-window.h"
G_BEGIN_DECLS
-typedef struct
+struct _GbApplication
{
- gchar *type;
- gchar *name;
- guint ellipsis : 1;
- guint n_star : 4;
-} Parameter;
+ GtkApplication parent_instance;
+
+ GSettings *editor_settings;
+ GbKeybindings *keybindings;
+ GbPreferencesWindow *preferences_window;
+};
-gboolean parameter_validate (Parameter *param);
-void parameter_free (Parameter *p);
-Parameter *parameter_copy (const Parameter *src);
-GSList *parse_parameters (const gchar *text);
G_END_DECLS
-#endif /* C_PARSE_HELPER_H */
+#endif /* GB_APPLICATION_PRIVATE_H */
diff --git a/src/app/gb-application.c b/src/app/gb-application.c
index d1ce037..fc19763 100644
--- a/src/app/gb-application.c
+++ b/src/app/gb-application.c
@@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "app"
+#define G_LOG_DOMAIN "gb-application"
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -27,128 +27,56 @@
#include <ide.h>
#include "gb-application.h"
-#include "gb-editor-file-marks.h"
+#include "gb-application-actions.h"
+#include "gb-application-private.h"
+#include "gb-editor-document.h"
#include "gb-editor-workspace.h"
#include "gb-glib.h"
-#include "gb-log.h"
-#include "gb-keybindings.h"
-#include "gb-preferences-window.h"
-#include "gb-support.h"
#include "gb-resources.h"
#include "gb-workbench.h"
-#define ADWAITA_CSS "resource:///org/gnome/builder/css/builder.Adwaita.css"
-#define LANGUAGE_SCHEMA "org.gnome.builder.editor.language"
-#define LANGUAGE_PATH "/org/gnome/builder/editor/language/"
-#define GSV_PATH "resource:///org/gnome/builder/styles/"
+#define ADWAITA_CSS "resource:///org/gnome/builder/css/builder.Adwaita.css"
+#define GSV_PATH "resource:///org/gnome/builder/styles/"
-struct _GbApplicationPrivate
-{
- GbKeybindings *keybindings;
- GSettings *editor_settings;
- GbPreferencesWindow *preferences_window;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (GbApplication, gb_application, GTK_TYPE_APPLICATION)
+G_DEFINE_TYPE (GbApplication, gb_application, GTK_TYPE_APPLICATION)
static void
-gb_application_setup_search_paths (void)
+get_default_size (GtkRequisition *req)
{
- GtkSourceStyleSchemeManager *mgr;
+ GdkScreen *screen;
+ GdkRectangle rect;
+ gint primary;
+
+ screen = gdk_screen_get_default ();
+ primary = gdk_screen_get_primary_monitor (screen);
+ gdk_screen_get_monitor_geometry (screen, primary, &rect);
- mgr = gtk_source_style_scheme_manager_get_default ();
- gtk_source_style_scheme_manager_append_search_path (
- mgr, PACKAGE_DATADIR"/gtksourceview-3.0/styles/");
+ req->width = rect.width * 0.75;
+ req->height = rect.height * 0.75;
}
static void
-gb_application_install_language_defaults (GbApplication *self)
+gb_application_setup_search_paths (void)
{
- gchar *defaults_installed_path;
- gboolean exists;
-
- g_return_if_fail (GB_IS_APPLICATION (self));
-
- defaults_installed_path = g_build_filename (g_get_user_data_dir (),
- "gnome-builder",
- ".defaults-installed",
- NULL);
- exists = g_file_test (defaults_installed_path, G_FILE_TEST_EXISTS);
+ GtkSourceStyleSchemeManager *style_scheme_manager;
+ static gboolean initialized;
- if (!exists)
- {
- GKeyFile *key_file;
- GBytes *bytes;
-
- key_file = g_key_file_new ();
-
- bytes =
- g_resources_lookup_data ("/org/gnome/builder/language/defaults.ini",
- 0, NULL);
-
- if (bytes)
- {
- if (g_key_file_load_from_data (key_file,
- g_bytes_get_data (bytes, NULL),
- g_bytes_get_size (bytes),
- 0, NULL))
- {
- gchar **groups;
- guint i;
-
- groups = g_key_file_get_groups (key_file, NULL);
-
- for (i = 0; groups [i]; i++)
- {
- GSettings *settings;
- gchar *settings_path;
- gchar **keys;
- guint j;
-
- settings_path = g_strdup_printf (
- "/org/gnome/builder/editor/language/%s/", groups [i]);
- settings = g_settings_new_with_path (
- "org.gnome.builder.editor.language",
- settings_path);
- g_free (settings_path);
-
- keys = g_key_file_get_keys (key_file, groups [i], NULL, NULL);
-
- for (j = 0; keys [j]; j++)
- {
- GVariant *param;
- gchar *value;
-
- value = g_key_file_get_value (key_file, groups [i],
- keys [j], NULL);
- param = g_variant_parse (NULL, value, NULL, NULL, NULL);
-
- if (param)
- {
- g_settings_set_value (settings, keys [j], param);
- g_variant_unref (param);
- }
-
- g_free (value);
- }
-
- g_object_unref (settings);
- g_strfreev (keys);
- }
-
- g_strfreev (groups);
- }
-
- g_bytes_unref (bytes);
- }
+ if (initialized)
+ return;
- g_key_file_free (key_file);
- g_file_set_contents (defaults_installed_path, "", 0, NULL);
- }
-
- g_free (defaults_installed_path);
+ style_scheme_manager = gtk_source_style_scheme_manager_get_default ();
+ gtk_source_style_scheme_manager_append_search_path (style_scheme_manager,
+ PACKAGE_DATADIR"/gtksourceview-3.0/styles/");
+ initialized = TRUE;
}
+/**
+ * gb_application_make_skeleton_dirs:
+ * @self: A #GbApplication.
+ *
+ * Creates all the directories we might need later. Simpler to just ensure they
+ * are created during startup.
+ */
static void
gb_application_make_skeleton_dirs (GbApplication *self)
{
@@ -177,39 +105,36 @@ gb_application_make_skeleton_dirs (GbApplication *self)
path = g_build_filename (g_get_user_config_dir (),
"gnome-builder",
- "uncrustify",
+ "syntax",
NULL);
g_mkdir_with_parents (path, 0750);
g_free (path);
-}
-static void
-gb_application_load_file_marks (GbApplication *application)
-{
- GbEditorFileMarks *marks;
- GError *error = NULL;
-
- g_return_if_fail (GB_IS_APPLICATION (application));
-
- marks = gb_editor_file_marks_get_default ();
-
- if (!gb_editor_file_marks_load (marks, &error))
- {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- }
+ path = g_build_filename (g_get_user_config_dir (),
+ "gnome-builder",
+ "uncrustify",
+ NULL);
+ g_mkdir_with_parents (path, 0750);
+ g_free (path);
}
+/**
+ * gb_application_on_theme_changed:
+ * @self: A #GbApplication.
+ *
+ * Update the theme overrides when the theme changes. This includes our custom
+ * CSS for Adwaita, etc.
+ */
static void
gb_application_on_theme_changed (GbApplication *self,
GParamSpec *pspec,
GtkSettings *settings)
{
- static GtkCssProvider *provider = NULL;
+ static GtkCssProvider *provider;
GdkScreen *screen;
gchar *theme;
- ENTRY;
+ IDE_ENTRY;
g_assert (GB_IS_APPLICATION (self));
g_assert (GTK_IS_SETTINGS (settings));
@@ -242,7 +167,7 @@ gb_application_on_theme_changed (GbApplication *self,
g_free (theme);
- EXIT;
+ IDE_EXIT;
}
static void
@@ -250,7 +175,7 @@ gb_application_register_theme_overrides (GbApplication *application)
{
GtkSettings *settings;
- ENTRY;
+ IDE_ENTRY;
gtk_icon_theme_add_resource_path (gtk_icon_theme_get_default (),
"/org/gnome/builder/icons/");
@@ -267,190 +192,149 @@ gb_application_register_theme_overrides (GbApplication *application)
G_CONNECT_SWAPPED);
gb_application_on_theme_changed (application, NULL, settings);
- EXIT;
+ IDE_EXIT;
}
static void
-gb_application_load_keybindings (GbApplication *application,
- const gchar *name)
+gb_application_load_keybindings (GbApplication *self)
{
- GbKeybindings *keybindings = NULL;
- GError *error = NULL;
- GBytes *bytes = NULL;
- gchar *path;
+ g_autoptr(GSettings) settings = NULL;
+ g_autofree gchar *name = NULL;
- g_return_if_fail (GB_IS_APPLICATION (application));
+ g_assert (GB_IS_APPLICATION (self));
- if (application->priv->keybindings)
- {
- gb_keybindings_unregister (application->priv->keybindings,
- GTK_APPLICATION (application));
- g_clear_object (&application->priv->keybindings);
- }
+ settings = g_settings_new ("org.gnome.builder.editor");
+ name = g_settings_get_string (settings, "keybindings");
+ self->keybindings = gb_keybindings_new (GTK_APPLICATION (self), name);
+ g_settings_bind (settings, "keybindings", self->keybindings, "mode", G_SETTINGS_BIND_GET);
+}
- path = g_strdup_printf ("/org/gnome/builder/keybindings/%s.ini", name);
- bytes = g_resources_lookup_data (path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
- g_free (path);
+static GbWorkbench *
+gb_application_find_workbench_for_file (GbApplication *self,
+ GFile *file)
+{
+ GList *iter;
+ GList *workbenches;
- if (!bytes)
- {
- g_warning (_("Failed to load keybindings."));
- return;
- }
+ g_assert (GB_IS_APPLICATION (self));
+ g_assert (G_IS_FILE (file));
- keybindings = gb_keybindings_new ();
+ workbenches = gtk_application_get_windows (GTK_APPLICATION (self));
- if (!gb_keybindings_load_bytes (keybindings, bytes, &error))
+ /*
+ * Find the a project that contains this file in its working directory.
+ */
+ for (iter = workbenches; iter; iter = iter->next)
{
- g_warning (_("Failed to load keybindings: %s"), error->message);
- goto cleanup;
- }
-
- path = g_build_filename (g_get_user_config_dir (),
- "gnome-builder",
- "keybindings.ini",
- NULL);
+ if (GB_IS_WORKBENCH (iter->data))
+ {
+ GbWorkbench *workbench = iter->data;
+ g_autofree gchar *relpath = NULL;
+ IdeContext *context;
+ IdeVcs *vcs;
+ GFile *workdir;
- if (g_file_test (path, G_FILE_TEST_EXISTS) &&
- !gb_keybindings_load_path (keybindings, path, &error))
- {
- g_warning (_("Failed to load local keybindings: %s"), error->message);
- goto cleanup;
- }
+ context = gb_workbench_get_context (workbench);
+ vcs = ide_context_get_vcs (context);
+ workdir = ide_vcs_get_working_directory (vcs);
- g_free (path);
+ relpath = g_file_get_relative_path (workdir, file);
- gb_keybindings_register (keybindings, GTK_APPLICATION (application));
+ if (relpath != NULL)
+ return workbench;
+ }
+ }
- application->priv->keybindings = g_object_ref (keybindings);
+ /*
+ * No matches found, take the first workbench we find.
+ */
+ for (iter = workbenches; iter; iter = iter->next)
+ if (GB_IS_WORKBENCH (iter->data))
+ return iter->data;
-cleanup:
- g_clear_object (&keybindings);
- g_clear_error (&error);
- g_clear_pointer (&bytes, g_bytes_unref);
+ return NULL;
}
static void
-gb_application_vim_mode_changed (GbApplication *self,
- const gchar *key,
- GSettings *settings)
+gb_application_activate (GApplication *application)
{
- g_return_if_fail (GB_IS_APPLICATION (self));
- g_return_if_fail (G_IS_SETTINGS (settings));
-
- if (g_settings_get_boolean (settings, "vim-mode"))
- {
- g_settings_set_boolean (settings, "emacs-mode", FALSE);
- gb_application_load_keybindings (self, "vim");
- }
- else
- gb_application_load_keybindings (self, "default");
+ g_warning ("TODO: Show project selection window");
}
-static void
-gb_application_emacs_mode_changed (GbApplication *self,
- const gchar *key,
- GSettings *settings)
+static IdeBuffer *
+on_create_buffer (IdeBufferManager *buffer_manager,
+ IdeFile *file,
+ gpointer user_data)
{
- g_return_if_fail (GB_IS_APPLICATION (self));
- g_return_if_fail (G_IS_SETTINGS (settings));
-
- if (g_settings_get_boolean (settings, "emacs-mode"))
- {
- g_settings_set_boolean (settings, "vim-mode", FALSE);
- gb_application_load_keybindings (self, "emacs");
- }
- else
- gb_application_load_keybindings (self, "default");
+ return g_object_new (GB_TYPE_EDITOR_DOCUMENT,
+ "context", ide_object_get_context (IDE_OBJECT (buffer_manager)),
+ "file", file,
+ "highlight-diagnostics", TRUE,
+ NULL);
}
static void
-gb_application_register_keybindings (GbApplication *self)
+gb_application__context_new_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- g_return_if_fail (GB_IS_APPLICATION (self));
- g_return_if_fail (!self->priv->editor_settings);
-
- self->priv->editor_settings = g_settings_new ("org.gnome.builder.editor");
- g_signal_connect_object (self->priv->editor_settings,
- "changed::vim-mode",
- G_CALLBACK (gb_application_vim_mode_changed),
- self,
- G_CONNECT_SWAPPED);
- g_signal_connect_object (self->priv->editor_settings,
- "changed::emacs-mode",
- G_CALLBACK (gb_application_emacs_mode_changed),
- self,
- G_CONNECT_SWAPPED);
- if (g_settings_get_boolean(self->priv->editor_settings, "vim-mode") == TRUE)
- gb_application_vim_mode_changed (self, NULL, self->priv->editor_settings);
- else if (g_settings_get_boolean(self->priv->editor_settings, "emacs-mode") == TRUE)
- gb_application_emacs_mode_changed (self, NULL, self->priv->editor_settings);
- else
- gb_application_vim_mode_changed (self, NULL, self->priv->editor_settings);
-
-}
+ g_autoptr(GTask) task = user_data;
+ g_autoptr(IdeContext) context = NULL;
+ IdeBufferManager *bufmgr;
+ GbApplication *self;
+ GbWorkbench *workbench;
+ GtkRequisition req;
+ GPtrArray *ar;
+ GError *error = NULL;
+ gsize i;
-static GbWorkbench *
-gb_application_create_workbench (GApplication *application)
-{
- GtkWindow *window;
- GdkScreen *screen;
- GdkRectangle geom;
- gint primary;
- gint default_width;
- gint default_height;
+ g_assert (G_IS_TASK (task));
- ENTRY;
+ self = g_task_get_source_object (task);
+ ar = g_task_get_task_data (task);
- /*
- * Determine 3/4's the screen width for the default size. We will maximize
- * the window anyway, but handy when unmaximizing.
- */
- screen = gdk_screen_get_default ();
- primary = gdk_screen_get_primary_monitor (screen);
- gdk_screen_get_monitor_geometry (screen, primary, &geom);
- default_width = (geom.width / 4) * 3;
- default_height = (geom.height / 4) * 3;
+ g_assert (GB_IS_APPLICATION (self));
+ g_assert (ar);
+ g_assert (ar->len);
- window = g_object_new (GB_TYPE_WORKBENCH,
- "title", _ ("Builder"),
- "default-width", default_width,
- "default-height", default_height,
- "window-position", GTK_WIN_POS_CENTER,
- NULL);
+ context = ide_context_new_finish (result, &error);
- gtk_window_maximize (window);
+ if (!context)
+ {
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ goto cleanup;
+ }
- gtk_application_add_window (GTK_APPLICATION (application), window);
+ bufmgr = ide_context_get_buffer_manager (context);
+ g_signal_connect (bufmgr, "create-buffer", G_CALLBACK (on_create_buffer), NULL);
- RETURN (GB_WORKBENCH (window));
-}
+ get_default_size (&req);
-static void
-gb_application_activate (GApplication *application)
-{
- GbWorkbench *workbench;
- GbWorkspace *workspace;
- GList *list;
+ workbench = g_object_new (GB_TYPE_WORKBENCH,
+ "application", self,
+ "context", context,
+ "default-width", req.width,
+ "default-height", req.height,
+ "title", _("Builder"),
+ NULL);
- g_return_if_fail (GB_IS_APPLICATION (application));
+ for (i = 0; i < ar->len; i++)
+ {
+ GFile *file;
- list = gtk_application_get_windows (GTK_APPLICATION (application));
+ file = g_ptr_array_index (ar, i);
+ g_assert (G_IS_FILE (file));
- for (; list; list = list->next)
- {
- if (GB_IS_WORKBENCH (list->data))
- {
- gtk_window_present (GTK_WINDOW (list->data));
- return;
- }
+ gb_workbench_open (workbench, file);
}
- workbench = gb_application_create_workbench (application);
- workspace = gb_workbench_get_workspace (workbench, GB_TYPE_EDITOR_WORKSPACE);
- gb_editor_workspace_new_document (GB_EDITOR_WORKSPACE (workspace));
-
+ gtk_window_maximize (GTK_WINDOW (workbench));
gtk_window_present (GTK_WINDOW (workbench));
+
+cleanup:
+ g_task_return_boolean (task, FALSE);
+ g_application_release (G_APPLICATION (self));
}
static void
@@ -459,153 +343,65 @@ gb_application_open (GApplication *application,
gint n_files,
const gchar *hint)
{
- GbWorkbench *workbench = NULL;
- GbWorkspace *workspace;
- GList *list;
+ GbApplication *self = (GbApplication *)application;
+ GbWorkbench *workbench;
+ g_autoptr(GPtrArray) ar = NULL;
guint i;
- ENTRY;
-
- g_assert (GB_IS_APPLICATION (application));
-
- list = gtk_application_get_windows (GTK_APPLICATION (application));
-
- for (; list; list = list->next)
- {
- if (GB_IS_WORKBENCH (list->data))
- {
- workbench = GB_WORKBENCH (list->data);
- break;
- }
- }
-
- if (!workbench)
- workbench = GB_WORKBENCH (gb_application_create_workbench (application));
-
- gtk_window_present (GTK_WINDOW (workbench));
-
- workspace = gb_workbench_get_workspace (workbench,
- GB_TYPE_EDITOR_WORKSPACE);
+ IDE_ENTRY;
- g_assert (GB_IS_EDITOR_WORKSPACE (workspace));
+ g_assert (GB_IS_APPLICATION (self));
+ /*
+ * Try to open the files using an existing workbench.
+ */
for (i = 0; i < n_files; i++)
{
- g_return_if_fail (G_IS_FILE (files [i]));
- gb_editor_workspace_open (GB_EDITOR_WORKSPACE (workspace), files [i]);
- }
+ GFile *file = files [i];
- EXIT;
-}
-
-static void
-gb_application_activate_quit_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- g_return_if_fail (GB_IS_APPLICATION (user_data));
-
- g_application_quit (G_APPLICATION (user_data));
-}
+ g_assert (G_IS_FILE (file));
-static void
-gb_application_activate_preferences_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbApplication *application = user_data;
- GbPreferencesWindow *window;
- GbWorkbench *workbench = NULL;
- GList *list;
+ workbench = gb_application_find_workbench_for_file (self, file);
- g_return_if_fail (GB_IS_APPLICATION (application));
+ if (workbench != NULL)
+ {
+ gb_workbench_open (workbench, file);
+ gtk_window_present (GTK_WINDOW (workbench));
+ continue;
+ }
- if (application->priv->preferences_window)
- {
- gtk_window_present (GTK_WINDOW (application->priv->preferences_window));
- return;
+ if (!ar)
+ ar = g_ptr_array_new_with_free_func (g_object_unref);
+ g_ptr_array_add (ar, g_object_ref (file));
}
- list = gtk_application_get_windows (GTK_APPLICATION (application));
-
- for (; list; list = list->next)
- if (GB_IS_WORKBENCH (list->data))
- workbench = GB_WORKBENCH (list->data);
-
- window = g_object_new (GB_TYPE_PREFERENCES_WINDOW,
- "transient-for", workbench,
- NULL);
- gb_set_weak_pointer (window, &application->priv->preferences_window);
-
- gtk_window_present (GTK_WINDOW (window));
-}
-
-static void
-gb_application_activate_support_action (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbApplication *application = user_data;
- GtkWidget *dialog;
- gchar *text = NULL;
- GList *windows;
- GError *error = NULL;
- gchar *str = NULL;
- gchar *log_path = NULL;
- gchar *name = NULL;
-
- name = g_strdup_printf ("gnome-builder-%u.log", (int)getpid ());
- log_path = g_build_filename (g_get_home_dir (), name, NULL);
- g_free (name);
-
- windows = gtk_application_get_windows (GTK_APPLICATION (application));
-
- str = gb_get_support_log ();
-
- if (!g_file_set_contents (log_path, str, -1, &error))
+ /*
+ * No workbench found for these files, let's create one!
+ */
+ if (ar && ar->len)
{
- g_printerr ("%s\n", error->message);
- goto cleanup;
- }
+ g_autoptr(GFile) directory = NULL;
+ g_autoptr(GTask) task = NULL;
+ GFile *file;
- text = g_strdup_printf (_("The support log file has been written to '%s'. "
- "Please provide this file as an attachment on "
- "your bug report or support request."),
- log_path);
+ task = g_task_new (self, NULL, NULL, NULL);
+ g_task_set_task_data (task, g_ptr_array_ref (ar), (GDestroyNotify)g_ptr_array_unref);
- g_message ("%s", text);
-
- dialog = gtk_message_dialog_new (windows ? windows->data : NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_INFO,
- GTK_BUTTONS_CLOSE,
- "%s", text);
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
- gtk_window_present (GTK_WINDOW (dialog));
-
-cleanup:
- g_free (text);
- g_clear_error (&error);
- g_free (str);
- g_free (log_path);
-}
+ file = g_ptr_array_index (ar, 0);
-static void
-gb_application_register_actions (GbApplication *self)
-{
- static const GActionEntry action_entries[] = {
- { "preferences", gb_application_activate_preferences_action },
- { "support", gb_application_activate_support_action },
- { "quit", gb_application_activate_quit_action },
- };
+ if (g_file_query_file_type (file, 0, NULL) == G_FILE_TYPE_DIRECTORY)
+ directory = g_object_ref (file);
+ else
+ directory = g_file_get_parent (file);
- g_return_if_fail (GB_IS_APPLICATION (self));
+ ide_context_new_async (directory,
+ NULL,
+ gb_application__context_new_cb,
+ g_object_ref (task));
+ g_application_hold (G_APPLICATION (self));
+ }
- g_action_map_add_action_entries (G_ACTION_MAP (self),
- action_entries,
- G_N_ELEMENTS (action_entries),
- self);
+ IDE_EXIT;
}
static void
@@ -613,7 +409,7 @@ gb_application_startup (GApplication *app)
{
GbApplication *self = (GbApplication *)app;
- ENTRY;
+ IDE_ENTRY;
g_assert (GB_IS_APPLICATION (self));
@@ -623,42 +419,16 @@ gb_application_startup (GApplication *app)
G_APPLICATION_CLASS (gb_application_parent_class)->startup (app);
gb_application_make_skeleton_dirs (self);
- gb_application_install_language_defaults (self);
- gb_application_register_actions (self);
- gb_application_register_keybindings (self);
+ gb_application_actions_init (self);
gb_application_register_theme_overrides (self);
- gb_application_load_file_marks (self);
gb_application_setup_search_paths ();
+ gb_application_load_keybindings (self);
- EXIT;
-}
-
-static void
-gb_application_shutdown (GApplication *app)
-{
- GbApplication *self = (GbApplication *)app;
- GbEditorFileMarks *marks;
- GError *error = NULL;
-
- ENTRY;
-
- g_assert (GB_IS_APPLICATION (self));
-
- marks = gb_editor_file_marks_get_default ();
-
- if (!gb_editor_file_marks_save (marks, NULL, &error))
- {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- }
-
- G_APPLICATION_CLASS (gb_application_parent_class)->shutdown (app);
-
- EXIT;
+ IDE_EXIT;
}
static gboolean
-verbose_cb (void)
+gb_application_increase_verbosity (void)
{
ide_log_increase_verbosity ();
return TRUE;
@@ -671,8 +441,12 @@ gb_application_local_command_line (GApplication *app,
{
g_autoptr(GOptionContext) context = NULL;
GOptionEntry entries[] = {
- { "verbose", 'v', G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_CALLBACK,
- verbose_cb, N_("Increase verbosity. May be specified multiple times.") },
+ { "verbose",
+ 'v',
+ G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_IN_MAIN,
+ G_OPTION_ARG_CALLBACK,
+ gb_application_increase_verbosity,
+ N_("Increase verbosity. May be specified multiple times.") },
{ NULL }
};
@@ -682,36 +456,24 @@ gb_application_local_command_line (GApplication *app,
g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
g_option_context_parse_strv (context, argv, NULL);
- return G_APPLICATION_CLASS (gb_application_parent_class)->
- local_command_line (app, argv, exit_status);
-}
-
-static void
-gb_application_constructed (GObject *object)
-{
- ENTRY;
-
- if (G_OBJECT_CLASS (gb_application_parent_class)->constructed)
- G_OBJECT_CLASS (gb_application_parent_class)->constructed (object);
-
- EXIT;
+ return G_APPLICATION_CLASS (gb_application_parent_class)->local_command_line (app,
+ argv,
+ exit_status);
}
static void
gb_application_finalize (GObject *object)
{
- GbApplicationPrivate *priv;
-
- ENTRY;
+ GbApplication *self = (GbApplication *)object;
- priv = GB_APPLICATION (object)->priv;
+ IDE_ENTRY;
- g_clear_object (&priv->editor_settings);
- g_clear_object (&priv->keybindings);
+ g_clear_object (&self->keybindings);
+ g_clear_object (&self->editor_settings);
G_OBJECT_CLASS (gb_application_parent_class)->finalize (object);
- EXIT;
+ IDE_EXIT;
}
static void
@@ -720,24 +482,21 @@ gb_application_class_init (GbApplicationClass *klass)
GApplicationClass *app_class = G_APPLICATION_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- ENTRY;
+ IDE_ENTRY;
- object_class->constructed = gb_application_constructed;
object_class->finalize = gb_application_finalize;
app_class->activate = gb_application_activate;
app_class->startup = gb_application_startup;
- app_class->shutdown = gb_application_shutdown;
app_class->open = gb_application_open;
app_class->local_command_line = gb_application_local_command_line;
- EXIT;
+ IDE_EXIT;
}
static void
gb_application_init (GbApplication *application)
{
- ENTRY;
- application->priv = gb_application_get_instance_private (application);
- EXIT;
+ IDE_ENTRY;
+ IDE_EXIT;
}
diff --git a/src/app/gb-application.h b/src/app/gb-application.h
index 24adbed..43d2666 100644
--- a/src/app/gb-application.h
+++ b/src/app/gb-application.h
@@ -23,32 +23,9 @@
G_BEGIN_DECLS
-#define GB_TYPE_APPLICATION (gb_application_get_type())
-#define GB_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_APPLICATION,
GbApplication))
-#define GB_APPLICATION_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_APPLICATION,
GbApplication const))
-#define GB_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_APPLICATION,
GbApplicationClass))
-#define GB_IS_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_APPLICATION))
-#define GB_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_APPLICATION))
-#define GB_APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_APPLICATION,
GbApplicationClass))
+#define GB_TYPE_APPLICATION (gb_application_get_type())
-typedef struct _GbApplication GbApplication;
-typedef struct _GbApplicationClass GbApplicationClass;
-typedef struct _GbApplicationPrivate GbApplicationPrivate;
-
-struct _GbApplication
-{
- GtkApplication parent;
-
- /*< private >*/
- GbApplicationPrivate *priv;
-};
-
-struct _GbApplicationClass
-{
- GtkApplicationClass parent_class;
-};
-
-GType gb_application_get_type (void);
+G_DECLARE_FINAL_TYPE (GbApplication, gb_application, GB, APPLICATION, GtkApplication)
G_END_DECLS
diff --git a/src/commands/gb-command-bar.c b/src/commands/gb-command-bar.c
index de21055..f2d3d5c 100644
--- a/src/commands/gb-command-bar.c
+++ b/src/commands/gb-command-bar.c
@@ -17,8 +17,8 @@
*/
#include <glib/gi18n.h>
+#include <ide.h>
-#include "gb-animation.h"
#include "gb-command.h"
#include "gb-command-bar.h"
#include "gb-command-bar-item.h"
@@ -165,12 +165,12 @@ gb_command_bar_push_result (GbCommandBar *bar,
upper = gtk_adjustment_get_upper (vadj);
frame_clock = gtk_widget_get_frame_clock (GTK_WIDGET (bar->priv->list_box));
- gb_object_animate (vadj,
- GB_ANIMATION_EASE_IN_CUBIC,
- 250,
- frame_clock,
- "value", upper,
- NULL);
+ ide_object_animate (vadj,
+ IDE_ANIMATION_EASE_IN_CUBIC,
+ 250,
+ frame_clock,
+ "value", upper,
+ NULL);
}
static void
diff --git a/src/commands/gb-command-gaction-provider.c b/src/commands/gb-command-gaction-provider.c
index 50ce087..6a50102 100644
--- a/src/commands/gb-command-gaction-provider.c
+++ b/src/commands/gb-command-gaction-provider.c
@@ -18,11 +18,11 @@
#define G_LOG_DOMAIN "gaction-commands"
+#include <ide.h>
#include <string.h>
#include "gb-command-gaction-provider.h"
#include "gb-command-gaction.h"
-#include "gb-log.h"
G_DEFINE_TYPE (GbCommandGactionProvider, gb_command_gaction_provider,
GB_TYPE_COMMAND_PROVIDER)
@@ -152,13 +152,13 @@ gb_command_gaction_provider_lookup (GbCommandProvider *provider,
GList *iter;
gchar *action_name = NULL;
- ENTRY;
+ IDE_ENTRY;
g_return_val_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (self), NULL);
g_return_val_if_fail (command_text, NULL);
if (!parse_command_text (command_text, &action_name, ¶ms))
- RETURN (NULL);
+ IDE_RETURN (NULL);
groups = discover_groups (self);
@@ -181,7 +181,7 @@ gb_command_gaction_provider_lookup (GbCommandProvider *provider,
g_list_free (groups);
g_free (action_name);
- RETURN (command);
+ IDE_RETURN (command);
}
static void
@@ -193,7 +193,7 @@ gb_command_gaction_provider_complete (GbCommandProvider *provider,
GList *groups;
GList *iter;
- ENTRY;
+ IDE_ENTRY;
g_return_if_fail (GB_IS_COMMAND_GACTION_PROVIDER (self));
g_return_if_fail (initial_command_text);
@@ -221,7 +221,7 @@ gb_command_gaction_provider_complete (GbCommandProvider *provider,
g_list_free (groups);
- EXIT;
+ IDE_EXIT;
}
static void
diff --git a/src/commands/gb-command-provider.c b/src/commands/gb-command-provider.c
index 6b05ed2..6602a64 100644
--- a/src/commands/gb-command-provider.c
+++ b/src/commands/gb-command-provider.c
@@ -24,12 +24,11 @@
struct _GbCommandProviderPrivate
{
GbWorkbench *workbench;
- GbDocumentView *active_view;
+ GbView *active_view;
gint priority;
};
-G_DEFINE_TYPE_WITH_PRIVATE (GbCommandProvider, gb_command_provider,
- G_TYPE_OBJECT)
+G_DEFINE_TYPE_WITH_PRIVATE (GbCommandProvider, gb_command_provider, G_TYPE_OBJECT)
enum {
PROP_0,
@@ -62,9 +61,9 @@ gb_command_provider_new (GbWorkbench *workbench)
* Returns the "active-tab" property. The active-tab is the last tab that
* was focused in the workbench.
*
- * Returns: (transfer none): A #GbDocumentView or %NULL.
+ * Returns: (transfer none): A #GbView or %NULL.
*/
-GbDocumentView *
+GbView *
gb_command_provider_get_active_view (GbCommandProvider *provider)
{
g_return_val_if_fail (GB_IS_COMMAND_PROVIDER (provider), NULL);
@@ -74,12 +73,12 @@ gb_command_provider_get_active_view (GbCommandProvider *provider)
static void
gb_command_provider_set_active_view (GbCommandProvider *provider,
- GbDocumentView *tab)
+ GbView *tab)
{
GbCommandProviderPrivate *priv;
g_return_if_fail (GB_IS_COMMAND_PROVIDER (provider));
- g_return_if_fail (!tab || GB_IS_DOCUMENT_VIEW (tab));
+ g_return_if_fail (!tab || GB_IS_VIEW (tab));
priv = provider->priv;
@@ -112,13 +111,13 @@ on_workbench_set_focus (GbCommandProvider *provider,
/* walk the hierarchy to find a tab */
if (widget)
- while (!GB_IS_DOCUMENT_VIEW (widget))
+ while (!GB_IS_VIEW (widget))
if (!(widget = gtk_widget_get_parent (widget)))
break;
- if (GB_IS_DOCUMENT_VIEW (widget))
+ if (GB_IS_VIEW (widget))
gb_command_provider_set_active_view (provider,
- GB_DOCUMENT_VIEW (widget));
+ GB_VIEW (widget));
}
static void
@@ -313,13 +312,11 @@ gb_command_provider_class_init (GbCommandProviderClass *klass)
gParamSpecs [PROP_ACTIVE_VIEW] =
g_param_spec_object ("active-tab",
- _("Active DocumentView"),
- _("The last focused GbDocumentView widget."),
- GB_TYPE_DOCUMENT_VIEW,
- (G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_ACTIVE_VIEW,
- gParamSpecs [PROP_ACTIVE_VIEW]);
+ _("Active View"),
+ _("The last focused GbView widget."),
+ GB_TYPE_VIEW,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_ACTIVE_VIEW, gParamSpecs [PROP_ACTIVE_VIEW]);
/**
* GbCommandProvider:priority:
@@ -341,8 +338,7 @@ gb_command_provider_class_init (GbCommandProviderClass *klass)
G_MAXINT,
0,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_PRIORITY,
- gParamSpecs [PROP_PRIORITY]);
+ g_object_class_install_property (object_class, PROP_PRIORITY, gParamSpecs [PROP_PRIORITY]);
/**
* GbCommandProvider:workbench:
diff --git a/src/commands/gb-command-provider.h b/src/commands/gb-command-provider.h
index fd0ad91..5cce3ac 100644
--- a/src/commands/gb-command-provider.h
+++ b/src/commands/gb-command-provider.h
@@ -22,7 +22,7 @@
#include <gio/gio.h>
#include "gb-command.h"
-#include "gb-document-view.h"
+#include "gb-view.h"
#include "gb-workbench-types.h"
G_BEGIN_DECLS
@@ -61,7 +61,7 @@ struct _GbCommandProviderClass
GType gb_command_provider_get_type (void);
GbCommandProvider *gb_command_provider_new (GbWorkbench *workbench);
GbWorkbench *gb_command_provider_get_workbench (GbCommandProvider *provider);
-GbDocumentView *gb_command_provider_get_active_view (GbCommandProvider *provider);
+GbView *gb_command_provider_get_active_view (GbCommandProvider *provider);
gint gb_command_provider_get_priority (GbCommandProvider *provider);
void gb_command_provider_set_priority (GbCommandProvider *provider,
gint priority);
diff --git a/src/commands/gb-command-vim-provider.c b/src/commands/gb-command-vim-provider.c
index d6ecbbf..67d0a4f 100644
--- a/src/commands/gb-command-vim-provider.c
+++ b/src/commands/gb-command-vim-provider.c
@@ -18,6 +18,8 @@
#define G_LOG_DOMAIN "vim-command-provider"
+#if 0
+
#include "gb-editor-view.h"
#include "gb-editor-frame-private.h"
#include "gb-command-vim.h"
@@ -170,3 +172,5 @@ gb_command_vim_provider_init (GbCommandVimProvider *self)
g_object_set_data_full (G_OBJECT (self), "editor-settings", settings,
g_object_unref);
}
+
+#endif
diff --git a/src/commands/gb-command-vim.c b/src/commands/gb-command-vim.c
index daee4a5..11c8d36 100644
--- a/src/commands/gb-command-vim.c
+++ b/src/commands/gb-command-vim.c
@@ -17,14 +17,14 @@
*/
#include <glib/gi18n.h>
+#include <ide.h>
#include "gb-command-vim.h"
-#include "gb-source-view.h"
struct _GbCommandVimPrivate
{
- GbSourceView *source_view;
- gchar *command_text;
+ IdeSourceView *source_view;
+ gchar *command_text;
};
G_DEFINE_TYPE_WITH_PRIVATE (GbCommandVim, gb_command_vim, GB_TYPE_COMMAND)
@@ -38,7 +38,7 @@ enum {
static GParamSpec *gParamSpecs [LAST_PROP];
-GbSourceView *
+IdeSourceView *
gb_command_vim_get_source_view (GbCommandVim *vim)
{
g_return_val_if_fail (GB_IS_COMMAND_VIM (vim), NULL);
@@ -47,11 +47,11 @@ gb_command_vim_get_source_view (GbCommandVim *vim)
}
static void
-gb_command_vim_set_source_view (GbCommandVim *vim,
- GbSourceView *source_view)
+gb_command_vim_set_source_view (GbCommandVim *vim,
+ IdeSourceView *source_view)
{
g_return_if_fail (GB_IS_COMMAND_VIM (vim));
- g_return_if_fail (!source_view || GB_IS_SOURCE_VIEW (source_view));
+ g_return_if_fail (!source_view || IDE_IS_SOURCE_VIEW (source_view));
if (source_view != vim->priv->source_view)
{
@@ -106,10 +106,12 @@ gb_command_vim_execute (GbCommand *command)
if (self->priv->source_view)
{
+#if 0
GbSourceVim *vim;
vim = gb_source_view_get_vim (self->priv->source_view);
gb_source_vim_execute_command (vim, self->priv->command_text);
+#endif
}
return NULL;
@@ -198,7 +200,7 @@ gb_command_vim_class_init (GbCommandVimClass *klass)
g_param_spec_object ("source-view",
_("Source View"),
_("The source view to modify."),
- GB_TYPE_SOURCE_VIEW,
+ IDE_TYPE_SOURCE_VIEW,
(G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_SOURCE_VIEW,
diff --git a/src/commands/gb-command.c b/src/commands/gb-command.c
index aaa8b45..c04ad30 100644
--- a/src/commands/gb-command.c
+++ b/src/commands/gb-command.c
@@ -60,7 +60,7 @@ gb_command_class_init (GbCommandClass *klass)
G_STRUCT_OFFSET (GbCommandClass, execute),
g_signal_accumulator_first_wins,
NULL,
- NULL,
+ g_cclosure_marshal_generic,
GB_TYPE_COMMAND_RESULT,
0);
}
diff --git a/src/documents/gb-document.c b/src/documents/gb-document.c
index 4bd74dd..4abccda 100644
--- a/src/documents/gb-document.c
+++ b/src/documents/gb-document.c
@@ -16,10 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define G_LOG_DOMAIN "gb-document"
+
#include <glib/gi18n.h>
#include "gb-document.h"
-#include "gb-document-view.h"
+#include "gb-view.h"
G_DEFINE_INTERFACE (GbDocument, gb_document, G_TYPE_OBJECT)
@@ -207,6 +209,14 @@ gb_document_default_init (GbDocumentInterface *iface)
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_interface_install_property (iface, gParamSpecs [PROP_READ_ONLY]);
+ /**
+ * GbDocument::create-view:
+ * @self: A #GbDocument.
+ *
+ * Creates a new view for the document.
+ *
+ * Returns: (ctype GbView*) (transfer full): A #GbView.
+ */
gSignals [CREATE_VIEW] =
g_signal_new ("create-view",
GB_TYPE_DOCUMENT,
@@ -215,6 +225,6 @@ gb_document_default_init (GbDocumentInterface *iface)
g_signal_accumulator_first_wins,
NULL,
g_cclosure_marshal_generic,
- GB_TYPE_DOCUMENT_VIEW,
+ GTK_TYPE_WIDGET,
0);
}
diff --git a/src/documents/gb-document.h b/src/documents/gb-document.h
index 590d345..d6b0294 100644
--- a/src/documents/gb-document.h
+++ b/src/documents/gb-document.h
@@ -35,13 +35,13 @@ struct _GbDocumentInterface
{
GTypeInterface parent;
- GtkWidget *(*create_view) (GbDocument *document);
- gboolean (*get_modified) (GbDocument *document);
- gboolean (*get_mtime) (GbDocument *document,
- GTimeVal *mtime);
- gboolean (*get_read_only) (GbDocument *document);
- const gchar *(*get_title) (GbDocument *document);
- gboolean (*is_untitled) (GbDocument *document);
+ GtkWidget *(*create_view) (GbDocument *document);
+ gboolean (*get_modified) (GbDocument *document);
+ gboolean (*get_mtime) (GbDocument *document,
+ GTimeVal *mtime);
+ gboolean (*get_read_only) (GbDocument *document);
+ const gchar *(*get_title) (GbDocument *document);
+ gboolean (*is_untitled) (GbDocument *document);
void (*save_async) (GbDocument *document,
GtkWidget *toplevel,
GCancellable *cancellable,
diff --git a/src/editor/gb-editor-document.c b/src/editor/gb-editor-document.c
index e0653b0..180f0e7 100644
--- a/src/editor/gb-editor-document.c
+++ b/src/editor/gb-editor-document.c
@@ -1,6 +1,6 @@
/* gb-editor-document.c
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,1321 +16,94 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "editor-document"
+#define G_LOG_DOMAIN "gb-editor-document"
#include <glib/gi18n.h>
-#include <gtksourceview/gtksource.h>
+#include <ide.h>
#include "gb-document.h"
-#include "gb-doc-seq.h"
#include "gb-editor-document.h"
-#include "gb-editor-file-marks.h"
#include "gb-editor-view.h"
-#include "gb-log.h"
-#include "gb-gtk.h"
-#include "gca-structs.h"
-struct _GbEditorDocumentPrivate
+struct _GbEditorDocument
{
- GtkSourceFile *file;
- GbSourceChangeMonitor *change_monitor;
- GbSourceCodeAssistant *code_assistant;
- gchar *title;
- GCancellable *cancellable;
- GError *error;
-
- gdouble progress;
- guint doc_seq_id;
- GTimeVal mtime;
- GTimeVal unsaved_ctime;
-
- guint file_changed_on_volume : 1;
- guint mtime_set : 1;
- guint read_only : 1;
- guint trim_trailing_whitespace : 1;
+ IdeBuffer parent_instance;
};
enum {
PROP_0,
- PROP_CHANGE_MONITOR,
- PROP_ERROR,
- PROP_FILE,
- PROP_FILE_CHANGED_ON_VOLUME,
PROP_MODIFIED,
- PROP_PROGRESS,
PROP_READ_ONLY,
- PROP_STYLE_SCHEME_NAME,
- PROP_TITLE,
- PROP_TRIM_TRAILING_WHITESPACE,
LAST_PROP
};
enum {
- CURSOR_MOVED,
- FILE_MARK_SET,
- SAVED,
LAST_SIGNAL
};
-static void gb_editor_document_init_document (GbDocumentInterface *iface);
-static void gb_editor_document_update_title (GbEditorDocument *document);
-
-G_DEFINE_TYPE_EXTENDED (GbEditorDocument,
- gb_editor_document,
- GTK_SOURCE_TYPE_BUFFER,
- 0,
- G_ADD_PRIVATE (GbEditorDocument)
- G_IMPLEMENT_INTERFACE (GB_TYPE_DOCUMENT,
- gb_editor_document_init_document))
-
-static GParamSpec *gParamSpecs [LAST_PROP];
-static guint gSignals [LAST_SIGNAL];
-
-GbEditorDocument *
-gb_editor_document_new (void)
-{
- return g_object_new (GB_TYPE_EDITOR_DOCUMENT, NULL);
-}
-
-static gboolean
-gb_editor_document_is_untitled (GbDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
-
- return (GB_EDITOR_DOCUMENT (document)->priv->doc_seq_id > 0);
-}
-
-/**
- * gb_editor_document_get_error:
- *
- * Fetches the most recent error for the #GbEditorDocument instance. If no
- * error has been registered, %NULL is returned.
- *
- * Returns: (transfer none): A #GError or %NULL.
- */
-const GError *
-gb_editor_document_get_error (GbEditorDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), NULL);
-
- return document->priv->error;
-}
-
-static void
-gb_editor_document_set_error (GbEditorDocument *document,
- const GError *error)
-{
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- if (error != document->priv->error)
- {
- g_clear_error (&document->priv->error);
- document->priv->error = g_error_copy (error);
- g_object_notify_by_pspec (G_OBJECT (document), gParamSpecs [PROP_ERROR]);
- }
-}
-
-static gboolean
-gb_editor_document_get_read_only (GbDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
-
- return GB_EDITOR_DOCUMENT (document)->priv->read_only;
-}
-
-static void
-gb_editor_document_set_read_only (GbEditorDocument *document,
- gboolean read_only)
-{
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- if (document->priv->read_only != read_only)
- {
- document->priv->read_only = !!read_only;
- g_object_notify (G_OBJECT (document), "read-only");
- gb_editor_document_update_title (document);
- }
-
- EXIT;
-}
-
-gboolean
-gb_editor_document_get_file_changed_on_volume (GbEditorDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
-
- return document->priv->file_changed_on_volume;
-}
-
-static void
-gb_editor_document_set_file_changed_on_volume (GbEditorDocument *document,
- gboolean file_changed_on_volume)
-{
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- if (file_changed_on_volume != document->priv->file_changed_on_volume)
- {
- document->priv->file_changed_on_volume = !!file_changed_on_volume;
- g_object_notify_by_pspec (G_OBJECT (document),
- gParamSpecs [PROP_FILE_CHANGED_ON_VOLUME]);
- }
-}
-
-static void
-gb_editor_document_check_modified_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GbEditorDocument *document = user_data;
- GFileInfo *info;
- GError *error = NULL;
- GFile *file = (GFile *)object;
-
- g_return_if_fail (G_IS_FILE (file));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- info = g_file_query_info_finish (file, result, &error);
-
- if (info)
- {
- if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
- {
- gboolean read_only;
-
- read_only = !g_file_info_get_attribute_boolean (info,
- G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
- if (gb_editor_document_get_read_only (GB_DOCUMENT (document)) != read_only)
- gb_editor_document_set_read_only (document, read_only);
- }
-
- if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED) && document->priv->mtime_set)
- {
- GTimeVal tv;
-
- g_file_info_get_modification_time (info, &tv);
-
- if (memcmp (&tv, &document->priv->mtime, sizeof tv) != 0)
- gb_editor_document_set_file_changed_on_volume (document, TRUE);
- }
- }
-
- g_clear_object (&document);
- g_clear_object (&info);
-}
-
-void
-gb_editor_document_check_externally_modified (GbEditorDocument *document)
-{
- GFile *location;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- if (document->priv->file_changed_on_volume)
- return;
-
- location = gtk_source_file_get_location (document->priv->file);
- if (!location)
- return;
-
- g_file_query_info_async (location,
- G_FILE_ATTRIBUTE_TIME_MODIFIED ","
- G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE,
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- document->priv->cancellable,
- gb_editor_document_check_modified_cb,
- g_object_ref (document));
-}
-
-gdouble
-gb_editor_document_get_progress (GbEditorDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), 0.0);
-
- return document->priv->progress;
-}
-
-static void
-gb_editor_document_set_progress (GbEditorDocument *document,
- gdouble progress)
-{
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- g_return_if_fail (progress >= 0.0);
- g_return_if_fail (progress <= 1.0);
-
- document->priv->progress = progress;
- g_object_notify_by_pspec (G_OBJECT (document), gParamSpecs [PROP_PROGRESS]);
-}
-
-gboolean
-gb_editor_document_get_trim_trailing_whitespace (GbEditorDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
-
- return document->priv->trim_trailing_whitespace;
-}
-
-void
-gb_editor_document_set_trim_trailing_whitespace (GbEditorDocument *document,
- gboolean trim_trailing_whitespace)
-{
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- if (trim_trailing_whitespace != document->priv->trim_trailing_whitespace)
- {
- document->priv->trim_trailing_whitespace = !!trim_trailing_whitespace;
- g_object_notify_by_pspec (G_OBJECT (document),
- gParamSpecs [PROP_TRIM_TRAILING_WHITESPACE]);
- }
-}
-
-GbSourceChangeMonitor *
-gb_editor_document_get_change_monitor (GbEditorDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), NULL);
-
- return document->priv->change_monitor;
-}
-
-GbSourceCodeAssistant *
-gb_editor_document_get_code_assistant (GbEditorDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), NULL);
-
- return document->priv->code_assistant;
-}
-
-GtkSourceFile *
-gb_editor_document_get_file (GbEditorDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), NULL);
-
- return document->priv->file;
-}
-
-static void
-gb_editor_document_set_style_scheme_name (GbEditorDocument *document,
- const gchar *style_scheme_name)
-{
- GtkSourceStyleSchemeManager *manager;
- GtkSourceStyleScheme *scheme;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- manager = gtk_source_style_scheme_manager_get_default ();
- scheme = gtk_source_style_scheme_manager_get_scheme (manager,
- style_scheme_name);
- gtk_source_buffer_set_style_scheme (GTK_SOURCE_BUFFER (document), scheme);
-}
-
-static void
-gb_editor_document_mark_set (GtkTextBuffer *buffer,
- const GtkTextIter *iter,
- GtkTextMark *mark)
-{
- if (GTK_TEXT_BUFFER_CLASS (gb_editor_document_parent_class)->mark_set)
- GTK_TEXT_BUFFER_CLASS (gb_editor_document_parent_class)->mark_set (buffer, iter, mark);
-
- if (mark == gtk_text_buffer_get_insert (buffer))
- g_signal_emit (buffer, gSignals [CURSOR_MOVED], 0);
-}
-
-static void
-gb_editor_document_changed (GtkTextBuffer *buffer)
-{
- g_assert (GB_IS_EDITOR_DOCUMENT (buffer));
-
- g_signal_emit (buffer, gSignals [CURSOR_MOVED], 0);
-
- GTK_TEXT_BUFFER_CLASS (gb_editor_document_parent_class)->changed (buffer);
-}
-
-static void
-gb_editor_document_add_diagnostic (GbEditorDocument *document,
- GcaDiagnostic *diag,
- GcaSourceRange *range)
-{
- GtkTextBuffer *buffer;
- GtkTextIter begin;
- GtkTextIter end;
- guint column;
-
- g_assert (GB_IS_EDITOR_DOCUMENT (document));
- g_assert (diag);
- g_assert (range);
-
- if (range->begin.line == -1 || range->end.line == -1)
- return;
-
- buffer = GTK_TEXT_BUFFER (document);
-
- gtk_text_buffer_get_iter_at_line (buffer, &begin, range->begin.line);
- for (column = range->begin.column; column; column--)
- if (gtk_text_iter_ends_line (&begin) || !gtk_text_iter_forward_char (&begin))
- break;
-
- gtk_text_buffer_get_iter_at_line (buffer, &end, range->end.line);
- for (column = range->end.column; column; column--)
- if (gtk_text_iter_ends_line (&end) || !gtk_text_iter_forward_char (&end))
- break;
-
- if (gtk_text_iter_equal (&begin, &end))
- gtk_text_iter_forward_to_line_end (&end);
-
- gtk_text_buffer_apply_tag_by_name (buffer, "ErrorTag", &begin, &end);
-}
-
-static void
-apply_tag_style (GbEditorDocument *document,
- GtkTextTag *tag,
- const gchar *style_id)
-{
- GtkSourceStyleScheme *scheme;
- GtkSourceStyle *style;
- gboolean background_set;
- gboolean bold_set;
- gboolean foreground_set;
- gboolean line_background_set;
- gchar *str;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- scheme = gtk_source_buffer_get_style_scheme (GTK_SOURCE_BUFFER (document));
- if (!scheme)
- return;
-
- style = gtk_source_style_scheme_get_style (scheme, style_id);
- if (!style)
- return;
-
- g_object_get (style,
- "background-set", &background_set,
- "bold-set", &bold_set,
- "foreground-set", &foreground_set,
- "line-background-set", &line_background_set,
- NULL);
-
- if (background_set)
- {
- g_object_get (style, "background", &str, NULL);
- g_object_set (tag, "background", str, NULL);
- g_free (str);
- }
- else
- g_object_set (tag, "background-set", FALSE, NULL);
-
- if (bold_set)
- {
- PangoWeight weight;
- gboolean bold;
-
- g_object_get (style, "bold", &bold, NULL);
- weight = bold ? PANGO_WEIGHT_NORMAL : PANGO_WEIGHT_BOLD;
- g_object_set (tag, "weight", weight, NULL);
- }
- else
- g_object_set (tag, "weight-set", FALSE, NULL);
-
- if (foreground_set)
- {
- g_object_get (style, "foreground", &str, NULL);
- g_object_set (tag, "foreground", str, NULL);
- g_free (str);
- }
- else
- g_object_set (tag, "foreground-set", FALSE, NULL);
-
- if (line_background_set)
- {
- g_object_get (style, "line-background", &str, NULL);
- g_object_set (tag, "paragraph-background", str, NULL);
- g_free (str);
- }
- else
- g_object_set (tag, "paragraph-background-set", FALSE, NULL);
-}
-
-static GtkTextTag *
-gb_editor_document_get_error_tag (GbEditorDocument *document)
-{
- GtkTextBuffer *buffer;
- GtkTextTagTable *tag_table;
- GtkTextTag *tag;
-
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), NULL);
-
- buffer = GTK_TEXT_BUFFER (document);
- tag_table = gtk_text_buffer_get_tag_table (buffer);
- tag = gtk_text_tag_table_lookup (tag_table, "ErrorTag");
-
- if (!tag)
- {
- tag = gtk_text_buffer_create_tag (buffer, "ErrorTag",
- "underline", PANGO_UNDERLINE_ERROR,
- NULL);
- apply_tag_style (document, tag, "def:error");
- }
-
- return tag;
-}
-
-static void
-gb_editor_document_notify_style_scheme (GbEditorDocument *document,
- GParamSpec *pspec,
- gpointer unused)
-{
- GtkTextTag *tag;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- tag = gb_editor_document_get_error_tag (document);
- apply_tag_style (document, tag, "def:error");
-}
-
-static void
-gb_editor_document_code_assistant_changed (GbEditorDocument *document,
- GbSourceCodeAssistant *code_assistant)
-{
- GtkTextIter begin;
- GtkTextIter end;
- GtkTextTag *tag;
- GArray *ar;
- guint i;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- g_return_if_fail (GB_IS_SOURCE_CODE_ASSISTANT (code_assistant));
-
- /*
- * Update all of the error tags in the buffer based on the diagnostics
- * returned from code assistance. We might want to find a way to do this
- * iteratively in the background based interactivity.
- */
-
- tag = gb_editor_document_get_error_tag (document);
-
- gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (document), &begin, &end);
- gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (document), tag, &begin, &end);
-
- ar = gb_source_code_assistant_get_diagnostics (code_assistant);
-
- for (i = 0; i < ar->len; i++)
- {
- GcaDiagnostic *diag;
- guint j;
-
- diag = &g_array_index (ar, GcaDiagnostic, i);
-
- for (j = 0; j < diag->locations->len; j++)
- {
- GcaSourceRange *range;
-
- range = &g_array_index (diag->locations, GcaSourceRange, j);
- gb_editor_document_add_diagnostic (document, diag, range);
- }
- }
-
- g_array_unref (ar);
-}
-
-static gboolean
-gb_editor_document_should_trim_line (GbEditorDocument *document,
- guint line)
-{
- GbSourceChangeFlags flags;
-
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
-
- flags = gb_source_change_monitor_get_line (document->priv->change_monitor,
- line);
-
- return !!flags;
-}
-
-static gboolean
-text_iter_is_space (const GtkTextIter *iter)
-{
- return g_unichar_isspace (gtk_text_iter_get_char (iter));
-}
-
-static void
-gb_editor_document_trim (GbEditorDocument *document)
-{
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- gint line;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- buffer = GTK_TEXT_BUFFER (document);
-
- gtk_text_buffer_get_end_iter (buffer, &iter);
-
- for (line = gtk_text_iter_get_line (&iter); line >= 0; line--)
- {
- if (gb_editor_document_should_trim_line (document, line))
- {
- gtk_text_buffer_get_iter_at_line (buffer, &iter, line);
-
- if (gtk_text_iter_forward_to_line_end (&iter) &&
- text_iter_is_space (&iter))
- {
- GtkTextIter begin = iter;
-
- while (text_iter_is_space (&begin))
- {
- if (gtk_text_iter_starts_line (&begin))
- break;
-
- if (!gtk_text_iter_backward_char (&begin))
- break;
- }
-
- if (!text_iter_is_space (&begin) &&
- !gtk_text_iter_ends_line (&begin))
- gtk_text_iter_forward_char (&begin);
-
- if (!gtk_text_iter_equal (&begin, &iter))
- gtk_text_buffer_delete (buffer, &begin, &iter);
- }
- }
- }
-
- EXIT;
-}
-
-static void
-gb_editor_document_guess_language (GbEditorDocument *document)
-{
- GtkSourceLanguageManager *manager;
- GtkSourceLanguage *lang;
- GtkTextIter begin;
- GtkTextIter end;
- gboolean result_uncertain = TRUE;
- GFile *location;
- gchar *name = NULL;
- gchar *text = NULL;
- gchar *content_type = NULL;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- location = gtk_source_file_get_location (document->priv->file);
- if (location)
- name = g_file_get_basename (location);
-
- gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (document), &begin, &end);
- text = gtk_text_iter_get_slice (&begin, &end);
-
- content_type = g_content_type_guess (name,
- (const guint8 *)text, strlen (text),
- &result_uncertain);
- if (result_uncertain)
- g_clear_pointer (&content_type, g_free);
-
- manager = gtk_source_language_manager_get_default ();
- lang = gtk_source_language_manager_guess_language (manager, name, content_type);
-
- gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (document), lang);
-
- g_free (content_type);
- g_free (name);
- g_free (text);
-}
-
-static void
-gb_editor_document_update_title (GbEditorDocument *document)
-{
- GbEditorDocumentPrivate *priv;
- GFile *location;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- priv = document->priv;
-
- g_clear_pointer (&priv->title, g_free);
-
- location = gtk_source_file_get_location (priv->file);
-
- if (location)
- {
- priv->title = g_file_get_basename (location);
-
- if (document->priv->read_only)
- {
- gchar *tmp = priv->title;
- priv->title = g_strdup_printf (_("%s (Read Only)"), tmp);
- g_free (tmp);
- }
- }
- else
- priv->title = g_strdup_printf (_("untitled document %u"), priv->doc_seq_id);
-
- g_object_notify (G_OBJECT (document), "title");
-}
-
-static void
-gb_editor_document_notify_file_location (GbEditorDocument *document,
- GParamSpec *pspec,
- GtkSourceFile *file)
-{
- GbEditorDocumentPrivate *priv;
- GFile *location;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- g_return_if_fail (GTK_SOURCE_IS_FILE (file));
-
- priv = document->priv;
-
- location = gtk_source_file_get_location (file);
-
- if (!location)
- {
- if (!priv->doc_seq_id)
- {
- priv->doc_seq_id = gb_doc_seq_acquire ();
- g_get_current_time (&priv->unsaved_ctime);
- }
- }
- else
- {
- if (priv->doc_seq_id)
- {
- gb_doc_seq_release (priv->doc_seq_id);
- priv->doc_seq_id = 0;
- }
- }
+static void document_interface_init (GbDocumentInterface *iface);
- gb_editor_document_update_title (document);
+G_DEFINE_TYPE_WITH_CODE (GbEditorDocument, gb_editor_document, IDE_TYPE_BUFFER,
+ G_IMPLEMENT_INTERFACE (GB_TYPE_DOCUMENT,
+ document_interface_init))
- gb_source_change_monitor_set_file (priv->change_monitor, location);
-
- gb_editor_document_guess_language (document);
-}
-
-static void
-gb_editor_document_progress_cb (goffset current_num_bytes,
- goffset total_num_bytes,
- gpointer user_data)
-{
- GbEditorDocument *document = user_data;
- gdouble fraction;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- fraction = total_num_bytes
- ? ((gdouble)current_num_bytes / (gdouble)total_num_bytes)
- : 1.0;
-
- gb_editor_document_set_progress (document, fraction);
-}
-
-static void
-gb_editor_document_load_info_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GbEditorDocument *document = user_data;
- GFileInfo *info;
- GError *error = NULL;
- GFile *file = (GFile *)object;
-
- g_return_if_fail (G_IS_FILE (file));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- info = g_file_query_info_finish (file, result, &error);
-
- if (info)
- {
- if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE))
- {
- gboolean read_only;
-
- read_only = !g_file_info_get_attribute_boolean (info,
- G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE);
- gb_editor_document_set_read_only (document, read_only);
- }
-
- if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED))
- {
- GTimeVal tv;
-
- g_file_info_get_modification_time (info, &tv);
-
- document->priv->mtime = tv;
- document->priv->mtime_set = TRUE;
- }
- }
-
- g_clear_object (&document);
- g_clear_object (&info);
-}
-
-static GFile *
-gb_editor_document_prompt_save (GbEditorDocument *document,
- GtkWidget *toplevel)
-{
- const gchar *title;
- GtkDialog *dialog;
- GtkWidget *suggested;
- gint response;
- GFile *chosen_file = NULL;
-
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), NULL);
- g_return_val_if_fail (!toplevel || GTK_IS_WIDGET (toplevel), NULL);
-
- dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
- "action", GTK_FILE_CHOOSER_ACTION_SAVE,
- "do-overwrite-confirmation", TRUE,
- "local-only", FALSE,
- "select-multiple", FALSE,
- "show-hidden", FALSE,
- "transient-for", toplevel,
- "title", _("Save Document As"),
- NULL);
-
- title = gb_document_get_title (GB_DOCUMENT (document));
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), title);
-
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- _("Cancel"), GTK_RESPONSE_CANCEL,
- _("Save"), GTK_RESPONSE_OK,
- NULL);
-
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-
- suggested = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog),
- GTK_RESPONSE_OK);
- gtk_style_context_add_class (gtk_widget_get_style_context (suggested),
- GTK_STYLE_CLASS_SUGGESTED_ACTION);
-
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_hide (GTK_WIDGET (dialog));
-
- if (response == GTK_RESPONSE_OK)
- {
- chosen_file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
- gtk_source_file_set_location (document->priv->file, chosen_file);
- }
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
-
- return chosen_file;
-}
-
-static void
-gb_editor_document_save_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GtkSourceFileSaver *saver = (GtkSourceFileSaver *)object;
- GbSourceChangeMonitor *change_monitor;
- GbEditorDocument *document;
- GError *error = NULL;
- GTask *task = user_data;
- GFile *location;
-
- ENTRY;
-
- g_return_if_fail (GTK_SOURCE_IS_FILE_SAVER (saver));
- g_return_if_fail (G_IS_ASYNC_RESULT (result));
- g_return_if_fail (G_IS_TASK (task));
-
- document = g_task_get_source_object (task);
-
- if (!gtk_source_file_saver_save_finish (saver, result, &error))
- {
- gb_editor_document_set_error (document, error);
- g_task_return_error (task, error);
- GOTO (cleanup);
- }
-
- /*
- * FIXME:
- *
- * Technically this can race. We need to either disable the editing
- * for the buffer during the process or keep a sequence number to
- * ensure it hasn't changed since we started the request to save.
- */
- gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (document), FALSE);
-
- location = gtk_source_file_saver_get_location (saver);
- g_file_query_info_async (location,
- G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE","
- G_FILE_ATTRIBUTE_TIME_MODIFIED,
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- document->priv->cancellable,
- gb_editor_document_load_info_cb,
- g_object_ref (document));
-
- change_monitor = gb_editor_document_get_change_monitor (document);
- gb_source_change_monitor_reload (change_monitor);
-
- g_task_return_boolean (task, TRUE);
-
- g_signal_emit (document, gSignals [SAVED], 0);
-
-cleanup:
- g_object_unref (task);
-
- EXIT;
-}
-
-static void
-gb_editor_document_save_async (GbDocument *doc,
- GtkWidget *toplevel,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+static GtkWidget *
+gb_editor_document_create_view (GbDocument *self)
{
- GtkSourceFileSaver *saver;
- GbEditorDocument *document = (GbEditorDocument *)doc;
- GbEditorFileMarks *marks;
- GbEditorFileMark *mark;
- GFile *location;
- GTask *task;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-
- if (!(location = gtk_source_file_get_location (document->priv->file)))
- {
- GFile *chosen_file;
+ GtkWidget *ret;
- chosen_file = gb_editor_document_prompt_save (document, toplevel);
+ IDE_ENTRY;
- if (!chosen_file)
- {
- g_task_report_new_error (document, callback, user_data,
- gb_editor_document_save_async,
- G_IO_ERROR,
- G_IO_ERROR_NOT_FOUND,
- _("No file was selected."));
- EXIT;
- }
+ g_assert (GB_IS_EDITOR_DOCUMENT (self));
- location = gtk_source_file_get_location (document->priv->file);
- g_assert (location == chosen_file);
+ ret = g_object_new (GB_TYPE_EDITOR_VIEW,
+ "document", self,
+ "visible", TRUE,
+ NULL);
- g_clear_object (&chosen_file);
- }
-
- task = g_task_new (document, cancellable, callback, user_data);
-
- if (document->priv->trim_trailing_whitespace)
- gb_editor_document_trim (document);
-
- saver = gtk_source_file_saver_new (GTK_SOURCE_BUFFER (document),
- document->priv->file);
-
- location = gtk_source_file_get_location (document->priv->file);
-
- if (location)
- {
- GtkTextMark *insert;
- GtkTextIter iter;
- guint line;
- guint column;
-
- marks = gb_editor_file_marks_get_default ();
- mark = gb_editor_file_marks_get_for_file (marks, location);
-
- insert = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (document));
- gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (document), &iter,
- insert);
- line = gtk_text_iter_get_line (&iter);
- column = gtk_text_iter_get_line_offset (&iter);
-
- gb_editor_file_mark_set_line (mark, line);
- gb_editor_file_mark_set_column (mark, column);
- }
-
- gb_editor_document_set_progress (document, 0.0);
-
- document->priv->mtime_set = FALSE;
-
- gtk_source_file_saver_save_async (saver,
- G_PRIORITY_DEFAULT,
- cancellable,
- gb_editor_document_progress_cb,
- g_object_ref (document),
- g_object_unref,
- gb_editor_document_save_cb,
- task);
-
- g_object_unref (saver);
-
- EXIT;
+ IDE_RETURN (ret);
}
static gboolean
-gb_editor_document_save_finish (GbDocument *document,
- GAsyncResult *result,
- GError **error)
-{
- GTask *task = (GTask *)result;
-
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
- g_return_val_if_fail (G_IS_TASK (task), FALSE);
-
- return g_task_propagate_boolean (task, error);
-}
-
-static void
-gb_editor_document_save_as_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GbDocument *document;
- GTask *task = user_data;
- GError *error = NULL;
-
- g_return_if_fail (G_IS_ASYNC_RESULT (result));
- g_return_if_fail (G_IS_TASK (task));
-
- document = g_task_get_source_object (task);
-
- if (!gb_editor_document_save_finish (document, result, &error))
- g_task_return_error (task, error);
- else
- g_task_return_boolean (task, TRUE);
-
- g_object_unref (task);
-}
-
-static void
-gb_editor_document_save_as_async (GbDocument *document,
- GtkWidget *toplevel,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+gb_editor_document_get_modified (GbDocument *document)
{
- GbEditorDocument *self = (GbEditorDocument *)document;
- GTask *task;
- GFile *chosen_file;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (self));
-
- task = g_task_new (self, cancellable, callback, user_data);
-
- chosen_file = gb_editor_document_prompt_save (self, toplevel);
-
- if (chosen_file)
- {
- gb_editor_document_save_async (GB_DOCUMENT (self),
- toplevel,
- cancellable,
- gb_editor_document_save_as_cb,
- task);
- g_clear_object (&chosen_file);
- }
- else
- {
- g_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_NOT_FOUND,
- _("No file was selected for saving."));
- }
-
- EXIT;
+ return gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (document));
}
static gboolean
-gb_editor_document_save_as_finish (GbDocument *document,
- GAsyncResult *result,
- GError **error)
-{
- GTask *task = (GTask *)result;
-
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
- g_return_val_if_fail (G_IS_TASK (task), FALSE);
-
- return g_task_propagate_boolean (task, error);
-}
-
-static void
-gb_editor_document_restore_insert (GbEditorDocument *document)
-{
- GbEditorFileMarks *marks;
- GbEditorFileMark *mark;
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- GSettings *settings;
- gboolean load_mark;
- GFile *file;
- guint line;
- guint column;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- settings = g_settings_new ("org.gnome.builder.editor");
- load_mark = g_settings_get_boolean (settings, "restore-insert-mark");
- g_clear_object (&settings);
-
- buffer = GTK_TEXT_BUFFER (document);
-
- if (!load_mark)
- {
- gtk_text_buffer_get_start_iter (buffer, &iter);
- gtk_text_buffer_select_range (buffer, &iter, &iter);
- return;
- }
-
- file = gtk_source_file_get_location (document->priv->file);
- if (!file)
- return;
-
- marks = gb_editor_file_marks_get_default ();
- mark = gb_editor_file_marks_get_for_file (marks, file);
-
- line = gb_editor_file_mark_get_line (mark);
- column = gb_editor_file_mark_get_column (mark);
-
- gb_gtk_text_buffer_get_iter_at_line_and_offset (buffer, &iter, line, column);
- gtk_text_buffer_select_range (buffer, &iter, &iter);
-
- g_signal_emit (document, gSignals [FILE_MARK_SET], 0, &iter);
-}
-
-static void
-gb_editor_document_load_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GtkSourceFileLoader *loader = (GtkSourceFileLoader *)object;
- GbEditorDocument *document;
- GFile *location;
- GError *error = NULL;
- GTask *task = user_data;
-
- ENTRY;
-
- g_return_if_fail (GTK_SOURCE_IS_FILE_LOADER (loader));
- g_return_if_fail (G_IS_ASYNC_RESULT (result));
- g_return_if_fail (G_IS_TASK (task));
-
- document = g_task_get_source_object (task);
-
- if (!gtk_source_file_loader_load_finish (loader, result, &error))
- {
- gb_editor_document_set_error (document, error);
- g_task_return_error (task, error);
- GOTO (cleanup);
- }
-
- document->priv->mtime_set = FALSE;
- document->priv->file_changed_on_volume = FALSE;
-
- location = gtk_source_file_loader_get_location (loader);
- g_file_query_info_async (location,
- G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE","
- G_FILE_ATTRIBUTE_TIME_MODIFIED,
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- document->priv->cancellable,
- gb_editor_document_load_info_cb,
- g_object_ref (document));
-
- gb_editor_document_restore_insert (document);
- gb_editor_document_guess_language (document);
-
- g_task_return_boolean (task, TRUE);
-
-cleanup:
- g_object_unref (task);
-
- EXIT;
-}
-
-void
-gb_editor_document_load_async (GbEditorDocument *document,
- GFile *file,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GtkSourceFileLoader *loader;
- GTask *task;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-
- if (file)
- gtk_source_file_set_location (document->priv->file, file);
-
- task = g_task_new (document, cancellable, callback, user_data);
-
- loader = gtk_source_file_loader_new (GTK_SOURCE_BUFFER (document),
- document->priv->file);
-
- gb_editor_document_set_file_changed_on_volume (document, FALSE);
- gb_editor_document_set_progress (document, 0.0);
-
- gtk_source_file_loader_load_async (loader,
- G_PRIORITY_DEFAULT,
- cancellable,
- gb_editor_document_progress_cb,
- g_object_ref (document),
- g_object_unref,
- gb_editor_document_load_cb,
- task);
-
- g_object_unref (loader);
-
- EXIT;
-}
-
-gboolean
-gb_editor_document_load_finish (GbEditorDocument *document,
- GAsyncResult *result,
- GError **error)
-{
- GTask *task = (GTask *)result;
-
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
- g_return_val_if_fail (G_IS_TASK (task), FALSE);
-
- return g_task_propagate_boolean (task, error);
-}
-
-void
-gb_editor_document_reload (GbEditorDocument *document)
-{
- GFile *location;
-
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- location = gtk_source_file_get_location (document->priv->file);
-
- if (!location)
- {
- g_warning ("Cannot reload document as it has not been saved to disk.");
- return;
- }
-
- gb_editor_document_load_async (document, location, NULL, NULL, NULL);
-}
-
-static void
-gb_editor_document_modified_changed (GtkTextBuffer *buffer)
-{
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (buffer));
-
- if (GTK_TEXT_BUFFER_CLASS (gb_editor_document_parent_class)->modified_changed)
- GTK_TEXT_BUFFER_CLASS (gb_editor_document_parent_class)->
- modified_changed (buffer);
-
- g_object_notify (G_OBJECT (buffer), "modified");
-}
-
-gboolean
-gb_editor_document_get_mtime (GbDocument *document,
- GTimeVal *mtime)
+gb_editor_document_get_read_only (GbDocument *document)
{
- GbEditorDocument *self = (GbEditorDocument *)document;
-
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (self), FALSE);
-
- if (self->priv->doc_seq_id)
- {
- memcpy (mtime, &self->priv->unsaved_ctime, sizeof *mtime);
- return TRUE;
- }
-
- if (self->priv->mtime_set)
- {
- memcpy (mtime, &self->priv->mtime, sizeof *mtime);
- return TRUE;
- }
-
return FALSE;
}
-gboolean
-gb_editor_document_get_modified (GbDocument *document)
-{
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), FALSE);
-
- return gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (document));
-}
-
-const gchar *
+static const gchar *
gb_editor_document_get_title (GbDocument *document)
{
- GbEditorDocument *self = (GbEditorDocument *)document;
-
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (self), NULL);
-
- return self->priv->title;
-}
-
-static GtkWidget *
-gb_editor_document_create_view (GbDocument *document)
-{
- GbEditorView *view;
-
- g_return_val_if_fail (GB_IS_EDITOR_DOCUMENT (document), NULL);
-
- view = g_object_new (GB_TYPE_EDITOR_VIEW,
- "document", document,
- "visible", TRUE,
- NULL);
-
- return GTK_WIDGET (view);
+ return ide_buffer_get_title (IDE_BUFFER (document));
}
static void
gb_editor_document_constructed (GObject *object)
{
- GbEditorDocument *self = (GbEditorDocument *)object;
-
+ IDE_ENTRY;
G_OBJECT_CLASS (gb_editor_document_parent_class)->constructed (object);
-
- gb_editor_document_notify_file_location (self, NULL, self->priv->file);
+ IDE_EXIT;
}
static void
gb_editor_document_dispose (GObject *object)
{
- GbEditorDocument *document = (GbEditorDocument *)object;
-
- if (!g_cancellable_is_cancelled (document->priv->cancellable))
- g_cancellable_cancel (document->priv->cancellable);
-
+ IDE_ENTRY;
G_OBJECT_CLASS (gb_editor_document_parent_class)->dispose (object);
+ IDE_EXIT;
}
static void
gb_editor_document_finalize (GObject *object)
{
- GbEditorDocumentPrivate *priv = GB_EDITOR_DOCUMENT (object)->priv;
-
- ENTRY;
-
- if (priv->doc_seq_id)
- {
- gb_doc_seq_release (priv->doc_seq_id);
- priv->doc_seq_id = 0;
- }
-
- g_clear_object (&priv->file);
- g_clear_object (&priv->change_monitor);
- g_clear_object (&priv->code_assistant);
- g_clear_object (&priv->cancellable);
- g_clear_pointer (&priv->title, g_free);
-
+ IDE_ENTRY;
G_OBJECT_CLASS(gb_editor_document_parent_class)->finalize (object);
-
- EXIT;
+ IDE_EXIT;
}
static void
@@ -1343,45 +116,12 @@ gb_editor_document_get_property (GObject *object,
switch (prop_id)
{
- case PROP_MODIFIED:
- g_value_set_boolean (value,
- gb_editor_document_get_modified (GB_DOCUMENT (self)));
- break;
-
- case PROP_CHANGE_MONITOR:
- g_value_set_object (value, gb_editor_document_get_change_monitor (self));
- break;
-
- case PROP_ERROR:
- g_value_set_boxed (value, gb_editor_document_get_error (self));
- break;
-
- case PROP_FILE:
- g_value_set_object (value, gb_editor_document_get_file (self));
- break;
-
- case PROP_FILE_CHANGED_ON_VOLUME:
- g_value_set_boolean (value,
- gb_editor_document_get_file_changed_on_volume (self));
- break;
-
case PROP_READ_ONLY:
- g_value_set_boolean (value,
- gb_editor_document_get_read_only (GB_DOCUMENT (self)));
- break;
-
- case PROP_PROGRESS:
- g_value_set_double (value, gb_editor_document_get_progress (self));
+ g_value_set_boolean (value, gb_editor_document_get_read_only (GB_DOCUMENT (self)));
break;
- case PROP_TITLE:
- g_value_set_string (value,
- gb_editor_document_get_title (GB_DOCUMENT (self)));
- break;
-
- case PROP_TRIM_TRAILING_WHITESPACE:
- g_value_set_boolean (value,
- gb_editor_document_get_trim_trailing_whitespace (self));
+ case PROP_MODIFIED:
+ g_value_set_boolean (value, gb_editor_document_get_modified (GB_DOCUMENT (self)));
break;
default:
@@ -1395,20 +135,10 @@ gb_editor_document_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- GbEditorDocument *self = (GbEditorDocument *)object;
+ //GbEditorDocument *self = (GbEditorDocument *)object;
switch (prop_id)
{
- case PROP_STYLE_SCHEME_NAME:
- gb_editor_document_set_style_scheme_name (self,
- g_value_get_string (value));
- break;
-
- case PROP_TRIM_TRAILING_WHITESPACE:
- gb_editor_document_set_trim_trailing_whitespace (self,
- g_value_get_boolean (value));
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -1419,7 +149,6 @@ static void
gb_editor_document_class_init (GbEditorDocumentClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkTextBufferClass *text_buffer_class = GTK_TEXT_BUFFER_CLASS (klass);
object_class->constructed = gb_editor_document_constructed;
object_class->dispose = gb_editor_document_dispose;
@@ -1427,152 +156,20 @@ gb_editor_document_class_init (GbEditorDocumentClass *klass)
object_class->get_property = gb_editor_document_get_property;
object_class->set_property = gb_editor_document_set_property;
- text_buffer_class->mark_set = gb_editor_document_mark_set;
- text_buffer_class->changed = gb_editor_document_changed;
- text_buffer_class->modified_changed = gb_editor_document_modified_changed;
-
- g_object_class_override_property (object_class, PROP_MODIFIED, "modified");
g_object_class_override_property (object_class, PROP_READ_ONLY, "read-only");
- g_object_class_override_property (object_class, PROP_TITLE, "title");
-
- gParamSpecs [PROP_CHANGE_MONITOR] =
- g_param_spec_object ("change-monitor",
- _("Change Monitor"),
- _("The change monitor for the backing file."),
- GB_TYPE_SOURCE_CHANGE_MONITOR,
- (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_CHANGE_MONITOR,
- gParamSpecs [PROP_CHANGE_MONITOR]);
-
- gParamSpecs [PROP_ERROR] =
- g_param_spec_boxed ("error",
- _("Error"),
- _("An error that may have been loaded."),
- G_TYPE_ERROR,
- (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_ERROR,
- gParamSpecs [PROP_ERROR]);
-
- gParamSpecs [PROP_FILE] =
- g_param_spec_object ("file",
- _("File"),
- _("The backing file for the document."),
- GTK_SOURCE_TYPE_FILE,
- (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_FILE,
- gParamSpecs [PROP_FILE]);
-
- gParamSpecs [PROP_FILE_CHANGED_ON_VOLUME] =
- g_param_spec_boolean ("file-changed-on-volume",
- _("File Changed on Volume"),
- _("If the file has changed underneath the buffer."),
- FALSE,
- (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_FILE_CHANGED_ON_VOLUME,
- gParamSpecs [PROP_FILE_CHANGED_ON_VOLUME]);
-
- gParamSpecs [PROP_PROGRESS] =
- g_param_spec_double ("progress",
- _("Progress"),
- _("Loading or saving progress."),
- 0.0,
- 1.0,
- 0.0,
- (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_PROGRESS,
- gParamSpecs [PROP_PROGRESS]);
-
- gParamSpecs [PROP_STYLE_SCHEME_NAME] =
- g_param_spec_string ("style-scheme-name",
- _("Style Scheme Name"),
- _("The style scheme name."),
- NULL,
- (G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_STYLE_SCHEME_NAME,
- gParamSpecs [PROP_STYLE_SCHEME_NAME]);
-
- gParamSpecs [PROP_TRIM_TRAILING_WHITESPACE] =
- g_param_spec_boolean ("trim-trailing-whitespace",
- _("Trim Trailing Whitespace"),
- _("If whitespace should be trimmed before saving."),
- TRUE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_TRIM_TRAILING_WHITESPACE,
- gParamSpecs [PROP_TRIM_TRAILING_WHITESPACE]);
-
- gSignals [CURSOR_MOVED] =
- g_signal_new ("cursor-moved",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GbEditorDocumentClass, cursor_moved),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- gSignals [FILE_MARK_SET] =
- g_signal_new ("file-mark-set",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GbEditorDocumentClass, file_mark_set),
- NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 1,
- GTK_TYPE_TEXT_ITER);
-
- gSignals [SAVED] =
- g_signal_new ("saved",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GbEditorDocumentClass, saved),
- NULL, NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 0);
+ g_object_class_override_property (object_class, PROP_MODIFIED, "modified");
}
static void
gb_editor_document_init (GbEditorDocument *document)
{
- document->priv = gb_editor_document_get_instance_private (document);
-
- document->priv->cancellable = g_cancellable_new ();
- document->priv->trim_trailing_whitespace = TRUE;
- document->priv->file = gtk_source_file_new ();
- document->priv->change_monitor = gb_source_change_monitor_new (GTK_TEXT_BUFFER (document));
- document->priv->code_assistant = gb_source_code_assistant_new (GTK_TEXT_BUFFER (document));
-
- g_signal_connect_object (document->priv->file,
- "notify::location",
- G_CALLBACK (gb_editor_document_notify_file_location),
- document,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (document->priv->code_assistant,
- "changed",
- G_CALLBACK (gb_editor_document_code_assistant_changed),
- document,
- G_CONNECT_SWAPPED);
-
- g_signal_connect (document,
- "notify::style-scheme",
- G_CALLBACK (gb_editor_document_notify_style_scheme),
- NULL);
}
static void
-gb_editor_document_init_document (GbDocumentInterface *iface)
+document_interface_init (GbDocumentInterface *iface)
{
+ iface->create_view = gb_editor_document_create_view;
iface->get_modified = gb_editor_document_get_modified;
- iface->get_mtime = gb_editor_document_get_mtime;
iface->get_read_only = gb_editor_document_get_read_only;
iface->get_title = gb_editor_document_get_title;
- iface->is_untitled = gb_editor_document_is_untitled;
- iface->create_view = gb_editor_document_create_view;
- iface->save_async = gb_editor_document_save_async;
- iface->save_finish = gb_editor_document_save_finish;
- iface->save_as_async = gb_editor_document_save_as_async;
- iface->save_as_finish = gb_editor_document_save_as_finish;
}
diff --git a/src/editor/gb-editor-document.h b/src/editor/gb-editor-document.h
index b86f3ac..ada3ea5 100644
--- a/src/editor/gb-editor-document.h
+++ b/src/editor/gb-editor-document.h
@@ -1,6 +1,6 @@
/* gb-editor-document.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
*
* 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
@@ -19,67 +19,13 @@
#ifndef GB_EDITOR_DOCUMENT_H
#define GB_EDITOR_DOCUMENT_H
-#include <gtksourceview/gtksourcebuffer.h>
-
-#include "gb-source-change-monitor.h"
-#include "gb-source-code-assistant.h"
+#include <ide.h>
G_BEGIN_DECLS
-#define GB_TYPE_EDITOR_DOCUMENT (gb_editor_document_get_type())
-#define GB_EDITOR_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_EDITOR_DOCUMENT,
GbEditorDocument))
-#define GB_EDITOR_DOCUMENT_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_EDITOR_DOCUMENT,
GbEditorDocument const))
-#define GB_EDITOR_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_EDITOR_DOCUMENT,
GbEditorDocumentClass))
-#define GB_IS_EDITOR_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_EDITOR_DOCUMENT))
-#define GB_IS_EDITOR_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_EDITOR_DOCUMENT))
-#define GB_EDITOR_DOCUMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_EDITOR_DOCUMENT,
GbEditorDocumentClass))
-
-typedef struct _GbEditorDocument GbEditorDocument;
-typedef struct _GbEditorDocumentClass GbEditorDocumentClass;
-typedef struct _GbEditorDocumentPrivate GbEditorDocumentPrivate;
-
-struct _GbEditorDocument
-{
- GtkSourceBuffer parent;
-
- /*< private >*/
- GbEditorDocumentPrivate *priv;
-};
-
-struct _GbEditorDocumentClass
-{
- GtkSourceBufferClass parent_class;
-
- void (*cursor_moved) (GbEditorDocument *document);
- void (*file_mark_set) (GbEditorDocument *document,
- GtkTextIter *location);
- void (*saved) (GbEditorDocument *document);
-};
+#define GB_TYPE_EDITOR_DOCUMENT (gb_editor_document_get_type())
-GbEditorDocument *gb_editor_document_new (void);
-GType gb_editor_document_get_type (void);
-GtkSourceFile *gb_editor_document_get_file (GbEditorDocument *document);
-void gb_editor_document_set_file (GbEditorDocument *document,
- GtkSourceFile *file);
-gdouble gb_editor_document_get_progress (GbEditorDocument *document);
-GbSourceChangeMonitor *gb_editor_document_get_change_monitor (GbEditorDocument *document);
-GbSourceCodeAssistant *gb_editor_document_get_code_assistant (GbEditorDocument *document);
-gboolean gb_editor_document_get_file_changed_on_volume (GbEditorDocument *document);
-gboolean gb_editor_document_get_trim_trailing_whitespace (GbEditorDocument *document);
-void gb_editor_document_set_trim_trailing_whitespace (GbEditorDocument *document,
- gboolean
trim_trailing_whitespace);
-void gb_editor_document_load_async (GbEditorDocument *document,
- GFile *file,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean gb_editor_document_load_finish (GbEditorDocument *document,
- GAsyncResult *result,
- GError **error);
-void gb_editor_document_reformat (GbEditorDocument *document);
-void gb_editor_document_check_externally_modified (GbEditorDocument *document);
-void gb_editor_document_reload (GbEditorDocument *document);
-const GError *gb_editor_document_get_error (GbEditorDocument *document);
+G_DECLARE_FINAL_TYPE (GbEditorDocument, gb_editor_document, GB, EDITOR_DOCUMENT, IdeBuffer)
G_END_DECLS
diff --git a/src/editor/gb-editor-frame-actions.c b/src/editor/gb-editor-frame-actions.c
new file mode 100644
index 0000000..25cd256
--- /dev/null
+++ b/src/editor/gb-editor-frame-actions.c
@@ -0,0 +1,52 @@
+/* gb-editor-frame-actions.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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 3 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 <gtksourceview/gtksource.h>
+
+#include "gb-editor-frame-actions.h"
+#include "gb-editor-frame-private.h"
+
+static void
+gb_editor_frame_actions_find (GSimpleAction *action,
+ GVariant *variant,
+ gpointer user_data)
+{
+ GbEditorFrame *self = user_data;
+
+ g_assert (GB_IS_EDITOR_FRAME (self));
+
+ gtk_revealer_set_reveal_child (self->search_revealer, TRUE);
+ gtk_widget_grab_focus (GTK_WIDGET (self->search_entry));
+}
+
+static const GActionEntry GbEditorFrameActions[] = {
+ { "find", gb_editor_frame_actions_find },
+};
+
+void
+gb_editor_frame_actions_init (GbEditorFrame *self)
+{
+ g_autoptr(GSimpleActionGroup) group = NULL;
+
+ g_assert (GB_IS_EDITOR_FRAME (self));
+
+ group = g_simple_action_group_new ();
+ g_action_map_add_action_entries (G_ACTION_MAP (group), GbEditorFrameActions,
+ G_N_ELEMENTS (GbEditorFrameActions), self);
+ gtk_widget_insert_action_group (GTK_WIDGET (self), "frame", G_ACTION_GROUP (group));
+}
diff --git a/src/auto-indent/c-parse-helper.h b/src/editor/gb-editor-frame-actions.h
similarity index 57%
copy from src/auto-indent/c-parse-helper.h
copy to src/editor/gb-editor-frame-actions.h
index 418f518..f841ebd 100644
--- a/src/auto-indent/c-parse-helper.h
+++ b/src/editor/gb-editor-frame-actions.h
@@ -1,6 +1,6 @@
-/* c-parse-helper.h
+/* gb-editor-frame-actions.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,26 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef C_PARSE_HELPER_H
-#define C_PARSE_HELPER_H
+#ifndef GB_EDITOR_FRAME_ACTIONS_H
+#define GB_EDITOR_FRAME_ACTIONS_H
-#include <glib.h>
+#include "gb-editor-frame.h"
G_BEGIN_DECLS
-typedef struct
-{
- gchar *type;
- gchar *name;
- guint ellipsis : 1;
- guint n_star : 4;
-} Parameter;
-
-gboolean parameter_validate (Parameter *param);
-void parameter_free (Parameter *p);
-Parameter *parameter_copy (const Parameter *src);
-GSList *parse_parameters (const gchar *text);
+void gb_editor_frame_actions_init (GbEditorFrame *self);
G_END_DECLS
-#endif /* C_PARSE_HELPER_H */
+#endif /* GB_EDITOR_FRAME_ACTIONS_H */
diff --git a/src/editor/gb-editor-frame-private.h b/src/editor/gb-editor-frame-private.h
index 46e5bae..41957d6 100644
--- a/src/editor/gb-editor-frame-private.h
+++ b/src/editor/gb-editor-frame-private.h
@@ -1,6 +1,6 @@
/* gb-editor-frame-private.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -19,45 +19,23 @@
#ifndef GB_EDITOR_FRAME_PRIVATE_H
#define GB_EDITOR_FRAME_PRIVATE_H
-#include "gb-editor-frame.h"
-#include "gb-source-change-gutter-renderer.h"
-#include "gb-source-code-assistant-renderer.h"
-#include "gb-source-search-highlighter.h"
-#include "gb-source-view.h"
+#include <gtk/gtk.h>
+#include <ide.h>
+
#include "gd-tagged-entry.h"
-#include "gca-structs.h"
#include "nautilus-floating-bar.h"
G_BEGIN_DECLS
-struct _GbEditorFramePrivate
+struct _GbEditorFrame
{
- /* Widgets owned by GtkBuilder */
- GtkSpinner *busy_spinner;
- GbSourceChangeGutterRenderer *diff_renderer;
- GbSourceCodeAssistantRenderer *code_assistant_renderer;
- NautilusFloatingBar *floating_bar;
- GtkButton *forward_search;
- GtkButton *backward_search;
- GtkScrolledWindow *scrolled_window;
- GtkRevealer *search_revealer;
- GdTaggedEntry *search_entry;
- GdTaggedEntryTag *search_entry_tag;
- GbSourceView *source_view;
-
- /* Objects owned by GbEditorFrame */
- GbEditorDocument *document;
- GtkSourceSearchContext *search_context;
- GtkSourceSearchSettings *search_settings;
- GbSourceSearchHighlighter *search_highlighter;
- GtkDirectionType search_direction;
-
- /* Signal handler identifiers */
- gulong cursor_moved_handler;
+ GtkBin parent_instance;
- /* Tracking last cursor position when jumping */
- guint saved_line;
- guint saved_line_offset;
+ NautilusFloatingBar *floating_bar;
+ GtkScrolledWindow *scrolled_window;
+ GtkRevealer *search_revealer;
+ GdTaggedEntry *search_entry;
+ IdeSourceView *source_view;
};
G_END_DECLS
diff --git a/src/editor/gb-editor-frame.c b/src/editor/gb-editor-frame.c
index 13f7c3e..e8d2219 100644
--- a/src/editor/gb-editor-frame.c
+++ b/src/editor/gb-editor-frame.c
@@ -1,6 +1,6 @@
/* gb-editor-frame.c
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,433 +16,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "editor-frame"
-
#include <glib/gi18n.h>
-#include <gio/gio.h>
+#include <ide.h>
+#include "gb-editor-document.h"
#include "gb-editor-frame.h"
+#include "gb-editor-frame-actions.h"
#include "gb-editor-frame-private.h"
-#include "gb-editor-workspace.h"
-#include "gb-gtk.h"
-#include "gb-log.h"
-#include "gb-source-formatter.h"
-#include "gb-string.h"
#include "gb-widget.h"
-#include "gb-workbench.h"
-G_DEFINE_TYPE_WITH_PRIVATE (GbEditorFrame, gb_editor_frame, GTK_TYPE_OVERLAY)
+G_DEFINE_TYPE (GbEditorFrame, gb_editor_frame, GTK_TYPE_BIN)
enum {
PROP_0,
PROP_DOCUMENT,
- PROP_SEARCH_DIRECTION,
LAST_PROP
};
-enum {
- FOCUSED,
- LAST_SIGNAL
-};
-
static GParamSpec *gParamSpecs [LAST_PROP];
-static guint gSignals [LAST_SIGNAL];
-
-static void gb_editor_frame_set_search_direction (GbEditorFrame *self,
- GtkDirectionType search_direction);
-GtkWidget *
-gb_editor_frame_new (void)
-{
- return g_object_new (GB_TYPE_EDITOR_FRAME, NULL);
-}
-
-/**
- * gb_editor_frame_link:
- * @src: (in): The source frame.
- * @dst: (in): The destination frame.
- *
- * This function is intended to link two #GbEditorFrame instances to use the
- * same backend buffer. This is useful when you want two separate views of the
- * same content.
- */
-void
-gb_editor_frame_link (GbEditorFrame *src,
- GbEditorFrame *dst)
-{
- g_return_if_fail (GB_IS_EDITOR_FRAME (src));
- g_return_if_fail (GB_IS_EDITOR_FRAME (dst));
-
- g_object_bind_property (src, "document", dst, "document",
- G_BINDING_SYNC_CREATE);
-}
-
-static void
-gb_editor_frame_restore_position (GbEditorFrame *self)
-{
- GtkTextView *text_view;
- GtkTextIter iter;
- GtkTextBuffer *buffer;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- text_view = GTK_TEXT_VIEW (self->priv->source_view);
- buffer = gtk_text_view_get_buffer (text_view);
-
- gb_gtk_text_buffer_get_iter_at_line_and_offset (buffer, &iter,
- self->priv->saved_line,
- self->priv->saved_line_offset);
- gtk_text_buffer_select_range (buffer, &iter, &iter);
- if (!gb_gtk_text_view_get_iter_visible (text_view, &iter))
- gb_gtk_text_view_scroll_to_iter (text_view, &iter, 0.25, TRUE, 0.0, 0.5);
-}
-
-static void
-gb_editor_frame_save_position (GbEditorFrame *self)
-{
- GtkTextBuffer *buffer;
- GtkTextMark *insert;
- GtkTextIter iter;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- buffer = GTK_TEXT_BUFFER (self->priv->document);
- insert = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
-
- self->priv->saved_line = gtk_text_iter_get_line (&iter);
- self->priv->saved_line_offset = gtk_text_iter_get_line_offset (&iter);
-}
-
-/**
- * gb_editor_frame_match:
- * @self: the #GbEditorFrame
- * @direction: the direction to search through the document
- * @rubberbanding: if %TRUE then use the match closest to the
- * position of cursor at the time gb_editor_frame_save_position()
- * was last called, if %FALSE then use the match closest to
- * the current cursor position.
- *
- * Move to a search match in the direction of @direction and/or
- * select the match.
- */
-static void
-gb_editor_frame_match (GbEditorFrame *self,
- GtkDirectionType direction,
- gboolean rubberbanding)
-{
- GbEditorFramePrivate *priv;
- GtkTextBuffer *buffer;
- GtkTextIter select_begin;
- GtkTextIter select_end;
- GtkTextIter match_begin;
- GtkTextIter match_end;
- gboolean has_selection;
- gboolean search_backward;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (direction == GTK_DIR_UP || direction == GTK_DIR_DOWN);
-
- priv = self->priv;
-
- if (direction == GTK_DIR_UP)
- search_backward = TRUE;
- else if (direction == GTK_DIR_DOWN)
- search_backward = FALSE;
- else
- g_assert_not_reached ();
-
- gb_editor_frame_set_search_direction (self, direction);
-
- buffer = GTK_TEXT_BUFFER (priv->document);
-
- /*
- * Start by trying from our current location unless we are rubberbanding, then
- * start from our saved position.
- */
- if (rubberbanding)
- {
- gb_gtk_text_buffer_get_iter_at_line_and_offset (buffer, &select_begin,
- priv->saved_line,
- priv->saved_line_offset);
- select_end = select_begin;
- }
- else
- {
- has_selection = gtk_text_buffer_get_selection_bounds (buffer,
- &select_begin,
- &select_end);
-
- if (!has_selection)
- {
- if (!search_backward)
- {
- if (!gtk_text_iter_forward_char (&select_end))
- gtk_text_buffer_get_end_iter (buffer, &select_end);
- }
- else
- {
- if (!gtk_text_iter_backward_char (&select_begin))
- gtk_text_buffer_get_start_iter (buffer, &select_begin);
- }
- }
- }
-
- if (!search_backward)
- {
- if (gtk_source_search_context_forward (priv->search_context, &select_end,
- &match_begin, &match_end))
- GOTO (found_match);
- }
- else
- {
- if (gtk_source_search_context_backward (priv->search_context, &select_begin,
- &match_begin, &match_end))
- GOTO (found_match);
- }
-
- gb_editor_frame_restore_position (self);
-
- EXIT;
-
-found_match:
- gb_source_view_jump_notify (priv->source_view);
- gb_source_view_clear_saved_cursor (priv->source_view);
- gtk_text_buffer_select_range (GTK_TEXT_BUFFER (priv->document),
- &match_begin, &match_end);
-
- if (!gb_gtk_text_view_get_iter_visible (GTK_TEXT_VIEW (priv->source_view),
- &match_end))
- gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->source_view),
- &match_end, 0.0, TRUE, 1.0, 0.5);
-
- EXIT;
-}
-
-/**
- * gb_editor_frame_move_next_match:
- *
- * Move to the next search match after the cursor position.
- */
-static void
-gb_editor_frame_move_next_match (GbEditorFrame *self,
- gboolean rubberbanding)
-{
- gb_editor_frame_match (self, GTK_DIR_DOWN, rubberbanding);
-}
-
-/**
- * gb_editor_frame_move_previous_match:
- *
- * Move to the first match before the cursor position.
- */
-static void
-gb_editor_frame_move_previous_match (GbEditorFrame *self,
- gboolean rubberbanding)
-{
- gb_editor_frame_match (self, GTK_DIR_UP, rubberbanding);
-}
-
-static void
-gb_editor_frame_set_position_label (GbEditorFrame *self,
- const gchar *text)
-{
- GbEditorFramePrivate *priv;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- priv = self->priv;
-
- if (!text || !*text)
- {
- if (priv->search_entry_tag)
- {
- gd_tagged_entry_remove_tag (priv->search_entry,
- priv->search_entry_tag);
- g_clear_object (&priv->search_entry_tag);
- }
- return;
- }
-
- if (!priv->search_entry_tag)
- {
- priv->search_entry_tag = gd_tagged_entry_tag_new ("");
- gd_tagged_entry_tag_set_style (priv->search_entry_tag,
- "gb-search-entry-occurrences-tag");
- gd_tagged_entry_add_tag (priv->search_entry,
- priv->search_entry_tag);
- }
-
- gd_tagged_entry_tag_set_label (priv->search_entry_tag, text);
-}
-
-static void
-gb_editor_frame_update_search_position_label (GbEditorFrame *self)
-{
- GbEditorFramePrivate *priv;
- GtkStyleContext *context;
- GtkTextIter begin;
- GtkTextIter end;
- const gchar *search_text;
- gchar *text;
- gint count;
- gint pos;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- priv = self->priv;
-
- gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (priv->document),
- &begin, &end);
- pos = gtk_source_search_context_get_occurrence_position (
- priv->search_context, &begin, &end);
- count = gtk_source_search_context_get_occurrences_count (
- priv->search_context);
-
- if ((pos == -1) || (count == -1))
- {
- /*
- * We are not yet done scanning the buffer.
- * We will be updated when we know more, so just hide it for now.
- */
- gb_editor_frame_set_position_label (self, NULL);
- return;
- }
-
- context = gtk_widget_get_style_context (GTK_WIDGET (priv->search_entry));
- search_text = gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
-
- if ((count == 0) && !gb_str_empty0 (search_text))
- gtk_style_context_add_class (context, GTK_STYLE_CLASS_ERROR);
- else
- gtk_style_context_remove_class (context, GTK_STYLE_CLASS_ERROR);
-
- text = g_strdup_printf (_("%u of %u"), pos, count);
- gb_editor_frame_set_position_label (self, text);
- g_free (text);
-}
-
-static void
-gb_editor_frame_on_search_occurrences_notify (GbEditorFrame *self,
- GParamSpec *pspec,
- GtkSourceSearchContext *search_context)
-{
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GTK_SOURCE_IS_SEARCH_CONTEXT (search_context));
-
- gb_editor_frame_update_search_position_label (self);
-}
-
-void
-gb_editor_frame_reformat (GbEditorFrame *self)
-{
- GbEditorFramePrivate *priv;
- GbSourceFormatter *formatter;
- GtkSourceLanguage *language;
- GtkTextBuffer *buffer;
- GtkTextIter begin;
- GtkTextIter end;
- GtkTextIter iter;
- GtkTextMark *insert;
- gboolean fragment = TRUE;
- GError *error = NULL;
- gchar *input = NULL;
- gchar *output = NULL;
- guint line_number;
- guint char_offset;
-
- ENTRY;
-
- /*
- * TODO: Do this asynchronously, add tab state, propagate errors.
- */
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- priv = self->priv;
-
- buffer = GTK_TEXT_BUFFER (priv->document);
-
- gtk_text_buffer_get_selection_bounds (buffer, &begin, &end);
-
- if (gtk_text_iter_compare (&begin, &end) == 0)
- {
- gtk_text_buffer_get_bounds (buffer, &begin, &end);
- fragment = FALSE;
- }
-
- input = gtk_text_buffer_get_text (buffer, &begin, &end, TRUE);
-
- insert = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
- char_offset = gtk_text_iter_get_line_offset (&iter);
- line_number = gtk_text_iter_get_line (&iter);
-
- language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (buffer));
- formatter = gb_source_formatter_new_from_language (language);
-
- if (!gb_source_formatter_format (formatter, input, fragment, NULL, &output,
- &error))
- {
- g_warning ("%s", error->message);
- g_clear_error (&error);
- GOTO (cleanup);
- }
-
- gtk_text_buffer_begin_user_action (buffer);
- /* TODO: Keep the cursor on same CXCursor from Clang instead of the
- * same character offset within the buffer. We probably want
- * to defer this to the formatter API since it will be language
- * specific.
- */
-
- gtk_text_buffer_delete (buffer, &begin, &end);
- gtk_text_buffer_insert (buffer, &begin, output, -1);
-
- if (line_number >= gtk_text_buffer_get_line_count (buffer))
- {
- gtk_text_buffer_get_bounds (buffer, &begin, &iter);
- goto select_range;
- }
-
- gtk_text_buffer_get_iter_at_line (buffer, &iter, line_number);
- gtk_text_iter_forward_to_line_end (&iter);
-
- if (gtk_text_iter_get_line (&iter) != line_number)
- gtk_text_iter_backward_char (&iter);
- else if (gtk_text_iter_get_line_offset (&iter) > char_offset)
- gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, line_number, char_offset);
-
-select_range:
- gtk_text_buffer_select_range (buffer, &iter, &iter);
- gtk_text_buffer_end_user_action (buffer);
-
- gb_gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->source_view), &iter,
- 0.25, TRUE, 0.5, 0.5);
-
-cleanup:
- g_free (input);
- g_free (output);
- g_clear_object (&formatter);
-
- EXIT;
-}
-
-/**
- * gb_editor_frame_on_cursor_moved:
- *
- * Update cursor ruler in the floating bar upon changing of insert text mark.
- */
static void
-gb_editor_frame_on_cursor_moved (GbEditorFrame *self,
- GbEditorDocument *document)
+on_cursor_moved (GbEditorDocument *document,
+ const GtkTextIter *location,
+ GbEditorFrame *self)
{
GtkSourceView *source_view;
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- GtkTextMark *mark;
gchar *text;
guint ln;
guint col;
@@ -450,1149 +48,82 @@ gb_editor_frame_on_cursor_moved (GbEditorFrame *self,
g_return_if_fail (GB_IS_EDITOR_FRAME (self));
g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- source_view = GTK_SOURCE_VIEW (self->priv->source_view);
- buffer = GTK_TEXT_BUFFER (document);
-
- mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, mark);
-
- ln = gtk_text_iter_get_line (&iter);
- col = gtk_source_view_get_visual_column (source_view, &iter);
+ source_view = GTK_SOURCE_VIEW (self->source_view);
+ ln = gtk_text_iter_get_line (location);
+ col = gtk_source_view_get_visual_column (source_view, location);
text = g_strdup_printf (_("Line %u, Column %u"), ln + 1, col + 1);
- nautilus_floating_bar_set_primary_label (self->priv->floating_bar, text);
+ nautilus_floating_bar_set_primary_label (self->floating_bar, text);
g_free (text);
- gb_editor_frame_update_search_position_label (self);
-}
-
-static void
-gb_editor_frame_on_file_mark_set (GbEditorFrame *self,
- GtkTextIter *location,
- GtkTextBuffer *buffer)
-{
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
-
- if (!gtk_widget_has_focus (GTK_WIDGET (self->priv->source_view)))
- return;
-
- gb_gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (self->priv->source_view),
- location, 0.0, TRUE, 0.5, 0.5);
-}
-
-static void
-gb_editor_frame_document_saved (GbEditorFrame *self,
- GbEditorDocument *document)
-{
- GdkWindow *window;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- window = gtk_text_view_get_window (GTK_TEXT_VIEW (self->priv->source_view),
- GTK_TEXT_WINDOW_WIDGET);
- gdk_window_invalidate_rect (window, NULL, TRUE);
-}
-
-/**
- * gb_editor_frame_connect:
- *
- * Attach to dynamic signals for the #GtkTextBuffer. Create any objects that
- * are dependent on the buffer.
- */
-static void
-gb_editor_frame_connect (GbEditorFrame *self,
- GbEditorDocument *document)
-{
- GbEditorFramePrivate *priv;
- GbSourceChangeMonitor *monitor;
- GbSourceCodeAssistant *code_assistant;
- GtkTextIter iter;
- GtkTextMark *insert;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- g_return_if_fail (!self->priv->document);
-
- priv = self->priv;
-
- /*
- * Save the document for later.
- */
- priv->document = g_object_ref (document);
- gtk_text_view_set_buffer (GTK_TEXT_VIEW (priv->source_view),
- GTK_TEXT_BUFFER (priv->document));
-
- /*
- * Look the saved signal so that we can invalidate the window afterwards.
- * This could happen since gutter content could change (like if it is a
- * new file in a git repo).
- */
- g_signal_connect_object (priv->document,
- "saved",
- G_CALLBACK (gb_editor_frame_document_saved),
- self,
- G_CONNECT_SWAPPED);
-
- /*
- * Connect change monitor to gutter.
- */
- monitor = gb_editor_document_get_change_monitor (document);
- g_object_set (priv->diff_renderer,
- "change-monitor", monitor,
- NULL);
-
- /*
- * Connect code assistance to gutter and spinner.
- */
- code_assistant = gb_editor_document_get_code_assistant (document);
- g_object_set (priv->code_assistant_renderer,
- "code-assistant", code_assistant,
- NULL);
- g_object_bind_property (code_assistant, "active",
- priv->busy_spinner, "active",
- G_BINDING_SYNC_CREATE);
- g_object_bind_property (code_assistant, "active",
- priv->busy_spinner, "visible",
- G_BINDING_SYNC_CREATE);
-
- /*
- * Don't allow editing if the buffer is read-only.
- */
- g_object_bind_property (priv->document, "read-only",
- priv->source_view, "editable",
- G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
-
- /*
- * Create search defaults for this frame.
- */
- priv->search_context = g_object_new (GTK_SOURCE_TYPE_SEARCH_CONTEXT,
- "buffer", priv->document,
- "settings", priv->search_settings,
- "highlight", TRUE,
- NULL);
- g_object_set (priv->search_highlighter,
- "search-context", priv->search_context,
- NULL);
-
- g_signal_connect_object (priv->search_context,
- "notify::occurrences-count",
- G_CALLBACK (gb_editor_frame_on_search_occurrences_notify),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->document,
- "file-mark-set",
- G_CALLBACK (gb_editor_frame_on_file_mark_set),
- self,
- G_CONNECT_SWAPPED);
-
- /*
- * Connect to cursor-moved signal to update cursor position label.
- */
- if (GB_IS_EDITOR_DOCUMENT (priv->document))
- {
- priv->cursor_moved_handler =
- g_signal_connect_swapped (priv->document,
- "cursor-moved",
- G_CALLBACK (gb_editor_frame_on_cursor_moved),
- self);
- }
-
- insert = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (document));
- gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (document), &iter, insert);
- gb_gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (self->priv->source_view),
- &iter, 0.0, TRUE, 0.5, 0.0);
-
- EXIT;
-}
-
-/**
- * gb_editor_frame_disconnect:
- *
- * Cleanup any signals or objects that are related to the #GtkTextBuffer.
- */
-static void
-gb_editor_frame_disconnect (GbEditorFrame *self)
-{
- GbEditorFramePrivate *priv;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- priv = self->priv;
-
- if (priv->document)
- {
- g_signal_handler_disconnect (priv->document, priv->cursor_moved_handler);
- priv->cursor_moved_handler = 0;
- }
-
- g_object_set (priv->diff_renderer,
- "change-monitor", NULL,
- NULL);
-
- g_object_set (priv->code_assistant_renderer,
- "code-assistant", NULL,
- NULL);
-
- g_object_set (priv->search_highlighter,
- "search-context", NULL,
- NULL);
-
- g_clear_object (&priv->document);
- g_clear_object (&priv->search_context);
-
- EXIT;
+ //gb_editor_frame_update_search_position_label (self);
}
/**
* gb_editor_frame_get_document:
*
- * Gets the #GbEditorDocument associated with the #GbEditorFrame.
+ * Gets the #GbEditorFrame:document property.
*
- * Returns: (transfer none): A #GbEditorDocument.
+ * Returns: (transfer none) (nullable): A #GbEditorDocument or %NULL.
*/
GbEditorDocument *
gb_editor_frame_get_document (GbEditorFrame *self)
{
- g_return_val_if_fail (GB_IS_EDITOR_FRAME (self), NULL);
-
- return self->priv->document;
-}
-
-/**
- * gb_editor_frame_set_document:
- *
- * Set the #GbEditorDocument to be displayed by the #GbEditorFrame.
- */
-void
-gb_editor_frame_set_document (GbEditorFrame *self,
- GbEditorDocument *document)
-{
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (!document || GB_IS_EDITOR_DOCUMENT (document));
-
- if (document != self->priv->document)
- {
- gb_editor_frame_disconnect (self);
- if (document)
- gb_editor_frame_connect (self, document);
- g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_DOCUMENT]);
- }
-}
-
-/**
- * gb_editor_frame_get_search_direction:
- * @self: a #GbEditorFrame
- *
- * Gets the #GtkDirectionType associated with the last search.
- * Will only be %GTK_DIR_DOWN or %GTK_DIR_UP
- *
- * Returns: A #GtkDirectionType.
- */
-GtkDirectionType
-gb_editor_frame_get_search_direction (GbEditorFrame *self)
-{
- g_return_val_if_fail (GB_IS_EDITOR_FRAME (self), GTK_DIR_DOWN);
-
- return self->priv->search_direction;
-}
-
-static void
-gb_editor_frame_set_search_direction (GbEditorFrame *self,
- GtkDirectionType search_direction)
-{
- if (self->priv->search_direction == search_direction)
- return;
-
- self->priv->search_direction = search_direction;
-
- g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_SEARCH_DIRECTION]);
-}
-
-/**
- * gb_editor_frame_on_focus_in_event:
- *
- * Handle the "focus-in-event" on the #GbSourceView. Ensure the search entry
- * is hidden and we are no longer highlighting search results.
- */
-static gboolean
-gb_editor_frame_on_focus_in_event (GbEditorFrame *self,
- GdkEvent *event,
- GbSourceView *source_view)
-{
- g_return_val_if_fail (GB_IS_EDITOR_FRAME (self), FALSE);
- g_return_val_if_fail (GB_IS_SOURCE_VIEW (source_view), FALSE);
-
- if (gtk_revealer_get_reveal_child (self->priv->search_revealer))
- gtk_revealer_set_reveal_child (self->priv->search_revealer, FALSE);
-
- if (gtk_source_search_context_get_highlight (self->priv->search_context))
- gtk_source_search_context_set_highlight (self->priv->search_context, FALSE);
-
- gb_editor_document_check_externally_modified (self->priv->document);
-
- g_signal_emit (self, gSignals [FOCUSED], 0);
-
- return GDK_EVENT_PROPAGATE;
-}
-
-/**
- * gb_editor_frame_on_populate_popup:
- *
- * Update the popup menu to include choices for language highlight.
- */
-static void
-gb_editor_frame_on_populate_popup (GbEditorFrame *self,
- GtkWidget *popup,
- GtkTextView *text_view)
-{
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
- g_return_if_fail (GTK_IS_WIDGET (popup));
-
- /* TODO: Highlight Language Widget */
-}
-
-/**
- * gb_editor_frame_on_push_snippet:
- *
- * Update snippet context with the filename of the current document.
- */
-static void
-gb_editor_frame_on_push_snippet (GbEditorFrame *self,
- GbSourceSnippet *snippet,
- GbSourceSnippetContext *context,
- GtkTextIter *iter,
- GbSourceView *source_view)
-{
- GtkSourceFile *source_file;
- GFile *file;
-
- g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
- g_return_if_fail (GB_IS_SOURCE_SNIPPET (snippet));
- g_return_if_fail (GB_IS_SOURCE_SNIPPET_CONTEXT (context));
- g_return_if_fail (iter);
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- source_file = gb_editor_document_get_file (self->priv->document);
- file = gtk_source_file_get_location (source_file);
- g_assert (!file || G_IS_FILE (file));
-
- if (file)
- {
- gchar *name;
-
- name = g_file_get_basename (file);
- gb_source_snippet_context_add_variable (context, "filename", name);
- g_free (name);
- }
-}
-
-static gboolean
-gb_editor_frame_on_search_entry_key_press (GbEditorFrame *self,
- GdkEventKey *event,
- GdTaggedEntry *entry)
-{
- gint begin;
- gint end;
-
- ENTRY;
-
- g_assert (GD_IS_TAGGED_ENTRY (entry));
- g_assert (GB_IS_EDITOR_FRAME (self));
-
- /*
- * WORKAROUND:
- *
- * There is some weird stuff going on with key-press when we have a selection.
- * We want to overwrite the text, but sometimes it doesn't. So we can just
- * force it if the string field is set.
- */
- if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &begin, &end) &&
- g_unichar_isprint (gdk_keyval_to_unicode (event->keyval)))
- {
- gtk_editable_delete_selection (GTK_EDITABLE (entry));
- }
-
- switch (event->keyval)
- {
- case GDK_KEY_Escape:
- gtk_revealer_set_reveal_child (self->priv->search_revealer, FALSE);
- gb_source_view_set_show_shadow (self->priv->source_view, FALSE);
- gb_editor_frame_restore_position (self);
- gtk_widget_grab_focus (GTK_WIDGET (self->priv->source_view));
- RETURN (GDK_EVENT_STOP);
-
- case GDK_KEY_Down:
- gb_editor_frame_move_next_match (self, FALSE);
- gb_editor_frame_save_position (self);
- RETURN (GDK_EVENT_STOP);
-
- case GDK_KEY_Up:
- gb_editor_frame_move_previous_match (self, FALSE);
- gb_editor_frame_save_position (self);
- RETURN (GDK_EVENT_STOP);
-
- default:
- break;
- }
-
- RETURN (GDK_EVENT_PROPAGATE);
-}
-
-static void
-gb_editor_frame_on_search_entry_changed (GbEditorFrame *self,
- GtkEntry *entry)
-{
- const gchar *search_text;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GD_IS_TAGGED_ENTRY (entry));
-
- search_text = gtk_entry_get_text (entry);
-
- if (!gb_str_empty0 (search_text))
- {
- if (self->priv->search_direction == GTK_DIR_DOWN)
- gb_editor_frame_move_next_match (self, TRUE);
- else if (self->priv->search_direction == GTK_DIR_UP)
- gb_editor_frame_move_previous_match (self, TRUE);
- else
- g_assert_not_reached ();
- }
-}
-
-static void
-gb_editor_frame_on_search_entry_activate (GbEditorFrame *self,
- GdTaggedEntry *entry)
-{
GtkTextBuffer *buffer;
- GtkTextIter begin;
- GtkTextIter end;
- ENTRY;
-
- g_assert (GD_IS_TAGGED_ENTRY (entry));
- g_assert (GB_IS_EDITOR_FRAME (self));
-
- if (self->priv->search_direction == GTK_DIR_DOWN)
- gb_editor_frame_move_next_match (self, TRUE);
- else if (self->priv->search_direction == GTK_DIR_UP)
- gb_editor_frame_move_previous_match (self, TRUE);
- else
- g_assert_not_reached ();
-
- buffer = GTK_TEXT_BUFFER (self->priv->document);
-
- if (gtk_text_buffer_get_has_selection (buffer))
- {
- gtk_text_buffer_get_selection_bounds (buffer, &begin, &end);
-
- if (gtk_text_iter_compare (&begin, &end) <= 0)
- gtk_text_buffer_select_range (buffer, &begin, &begin);
- else
- gtk_text_buffer_select_range (buffer, &end, &end);
- }
-
- gtk_widget_grab_focus (GTK_WIDGET (self->priv->source_view));
-
- EXIT;
-}
-
-static void
-gb_editor_frame_on_forward_search_clicked (GbEditorFrame *self,
- GtkButton *button)
-{
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GTK_IS_BUTTON (button));
-
- gb_editor_frame_move_next_match (self, FALSE);
-}
-
-static void
-gb_editor_frame_on_backward_search_clicked (GbEditorFrame *self,
- GtkButton *button)
-{
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GTK_IS_BUTTON (button));
-
- gb_editor_frame_move_previous_match (self, FALSE);
-}
-
-/**
- * gb_editor_frame_on_begin_search:
- *
- * Show the search machinery when a request to begin a search has occurred.
- */
-static void
-gb_editor_frame_on_begin_search (GbEditorFrame *self,
- GtkDirectionType direction,
- const gchar *search_text,
- GbSourceView *source_view)
-{
- GbEditorFramePrivate *priv;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
-
- priv = self->priv;
-
- gb_editor_frame_save_position (self);
-
- if (search_text)
- gtk_entry_set_text (GTK_ENTRY (priv->search_entry), search_text);
-
- gtk_revealer_set_reveal_child (priv->search_revealer, TRUE);
- gtk_source_search_context_set_highlight (priv->search_context, TRUE);
- gtk_widget_grab_focus (GTK_WIDGET (priv->search_entry));
- if (search_text)
- {
- if (direction == GTK_DIR_DOWN)
- gb_editor_frame_move_next_match (self, TRUE);
- else if (direction == GTK_DIR_UP)
- gb_editor_frame_move_previous_match (self, TRUE);
- }
- else
- {
- const gchar *text;
- guint len;
+ g_return_val_if_fail (GB_IS_EDITOR_FRAME (self), NULL);
- if (direction == GTK_DIR_DOWN)
- gb_editor_frame_move_next_match (self, TRUE);
- else if (direction == GTK_DIR_UP)
- gb_editor_frame_move_previous_match (self, TRUE);
- else
- g_assert_not_reached ();
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->source_view));
- /*
- * We manually get the string length instead of passing -1 for length
- * because -1 doesn't seem to work as documented.
- */
- text = gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
- len = g_utf8_strlen (text, -1);
- gtk_editable_select_region (GTK_EDITABLE (priv->search_entry), 0, len);
- }
+ if (GB_IS_EDITOR_DOCUMENT (buffer))
+ return GB_EDITOR_DOCUMENT (buffer);
- EXIT;
+ return NULL;
}
void
-gb_editor_frame_find (GbEditorFrame *self,
- const gchar *search_text)
-{
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- gb_editor_frame_on_begin_search (self, GTK_DIR_DOWN, search_text,
- self->priv->source_view);
-}
-
-static void
-gb_editor_frame_find_activate (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
+gb_editor_frame_set_document (GbEditorFrame *self,
+ GbEditorDocument *document)
{
- GbEditorFrame *self = user_data;
-
g_return_if_fail (GB_IS_EDITOR_FRAME (self));
+ g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- gb_editor_frame_find (self, NULL);
+ gtk_text_view_set_buffer (GTK_TEXT_VIEW (self->source_view), GTK_TEXT_BUFFER (document));
+ g_signal_connect (document, "cursor-moved", G_CALLBACK (on_cursor_moved), self);
+ g_object_bind_property (document, "busy", self->floating_bar, "show-spinner", G_BINDING_SYNC_CREATE);
}
static gboolean
-gb_editor_frame_on_query_tooltip (GbEditorFrame *self,
- gint x,
- gint y,
- gboolean keyboard_mode,
- GtkTooltip *tooltip,
- GbSourceView *source_view)
-{
- GbEditorFramePrivate *priv;
- GbSourceCodeAssistant *code_assistant;
- GtkTextIter iter;
- GArray *ar;
- gboolean ret = FALSE;
- guint line;
- guint i;
-
- g_assert (GB_IS_SOURCE_VIEW (source_view));
- g_assert (GB_IS_EDITOR_FRAME (self));
-
- priv = self->priv;
-
- code_assistant = gb_editor_document_get_code_assistant (priv->document);
- if (!code_assistant)
- return FALSE;
-
- ar = gb_source_code_assistant_get_diagnostics (code_assistant);
- if (!ar)
- return FALSE;
-
- gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (source_view),
- GTK_TEXT_WINDOW_WIDGET,
- x, y, &x, &y);
-
- gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (source_view),
- &iter, x, y);
-
- line = gtk_text_iter_get_line (&iter);
-
- for (i = 0; i < ar->len; i++)
- {
- GcaDiagnostic *diag;
- guint j;
-
- diag = &g_array_index (ar, GcaDiagnostic, i);
-
- for (j = 0; j < diag->locations->len; j++)
- {
- GcaSourceRange *loc;
-
- loc = &g_array_index (diag->locations, GcaSourceRange, j);
-
- if ((loc->begin.line <= line) && (loc->end.line >= line))
- {
- gtk_tooltip_set_text (tooltip, diag->message);
- ret = TRUE;
- goto cleanup;
- }
- }
- }
-
-cleanup:
- g_array_unref (ar);
-
- return ret;
-}
-
-static void
-gb_editor_frame_on_switch_to_file (GbEditorFrame *self,
- GFile *file,
- GbSourceVim *vim)
-{
- GbWorkspace *workspace;
- GbWorkbench *workbench;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (G_IS_FILE (file));
- g_return_if_fail (GB_IS_SOURCE_VIM (vim));
-
- workbench = gb_widget_get_workbench (GTK_WIDGET (self));
- workspace = gb_workbench_get_workspace (workbench, GB_TYPE_EDITOR_WORKSPACE);
- gb_editor_workspace_open (GB_EDITOR_WORKSPACE (workspace), file);
-}
-
-static void
-gb_editor_frame_on_command_toggled (GbEditorFrame *self,
- gboolean visible,
- GbSourceVim *vim)
-{
- GbWorkbench *workbench;
- GAction *action;
- GVariant *params;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GB_IS_SOURCE_VIM (vim));
-
- workbench = gb_widget_get_workbench (GTK_WIDGET (self));
- if (!workbench)
- EXIT;
-
- action = g_action_map_lookup_action (G_ACTION_MAP (workbench),
- "toggle-command-bar");
- if (!action)
- EXIT;
-
- params = g_variant_new_boolean (visible);
- g_action_activate (action, params);
-
- EXIT;
-}
-
-static void
-gb_editor_frame_on_jump_to_doc (GbEditorFrame *self,
- const gchar *search_text,
- GbSourceView *source_view)
-{
- GActionGroup *action_group;
- GbWorkbench *workbench;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
- g_return_if_fail (search_text);
-
- workbench = gb_widget_get_workbench (GTK_WIDGET (self));
- action_group = gtk_widget_get_action_group (GTK_WIDGET (workbench),
- "workspace");
- g_action_group_activate_action (action_group, "jump-to-doc",
- g_variant_new_string (search_text));
-
- EXIT;
-}
-
-static void
-gb_editor_frame_on_drop_uris (GbEditorFrame *self,
- const gchar **uri_list,
- GbSourceView *source_view)
-{
- GVariantBuilder *builder;
- GVariant *variant;
- guint i;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- g_return_if_fail (GB_IS_SOURCE_VIEW (source_view));
- g_return_if_fail (uri_list);
-
- builder = g_variant_builder_new (G_VARIANT_TYPE_STRING_ARRAY);
- for (i = 0; uri_list [i]; i++)
- g_variant_builder_add (builder, "s", uri_list[i]);
- variant = g_variant_builder_end (builder);
- g_variant_builder_unref (builder);
-
- gb_widget_activate_action (GTK_WIDGET (self),
- "workspace", "open-uri-list",
- variant);
-
- EXIT;
-}
-
-static void
-gb_editor_frame_grab_focus (GtkWidget *widget)
-{
- GbEditorFrame *self = (GbEditorFrame *)widget;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- gtk_widget_grab_focus (GTK_WIDGET (self->priv->source_view));
-
- EXIT;
-}
-
-static void
-gb_editor_frame_scroll_to_line (GbEditorFrame *self,
- guint line,
- guint offset)
-{
- GtkTextBuffer *buffer;
- GtkTextView *text_view;
- GtkTextIter iter;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- buffer = GTK_TEXT_BUFFER (self->priv->document);
- text_view = GTK_TEXT_VIEW (self->priv->source_view);
-
- gb_gtk_text_buffer_get_iter_at_line_and_offset (buffer, &iter, line, offset);
- gtk_text_buffer_select_range (buffer, &iter, &iter);
- gb_gtk_text_view_scroll_to_iter (text_view, &iter, 0.0, TRUE, 0.0, 0.5);
-}
-
-static void
-gb_editor_frame_next_diagnostic (GbEditorFrame *self)
-{
- GbSourceCodeAssistant *assistant;
- GtkTextMark *mark;
- GtkTextIter iter;
- guint current_line;
- GArray *ar;
- guint i;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- assistant = gb_editor_document_get_code_assistant (self->priv->document);
- ar = gb_source_code_assistant_get_diagnostics (assistant);
- mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (self->priv->document));
- gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (self->priv->document),
- &iter, mark);
- current_line = gtk_text_iter_get_line (&iter);
-
- if (ar)
- {
- for (i = 0; i < ar->len; i++)
- {
- GcaDiagnostic *diag;
- guint j;
-
- diag = &g_array_index (ar, GcaDiagnostic, i);
-
- for (j = 0; j < diag->locations->len; j++)
- {
- GcaSourceRange *range;
-
- range = &g_array_index (diag->locations, GcaSourceRange, j);
-
- if (range->begin.line > current_line)
- {
- gb_editor_frame_scroll_to_line (self,
- range->begin.line,
- range->begin.column);
- goto cleanup;
- }
- }
- }
-
- /* wrap around to first diagnostic */
- if (ar->len > 0)
- {
- GcaDiagnostic *diag;
-
- diag = &g_array_index (ar, GcaDiagnostic, 0);
-
- if (diag->locations->len > 0)
- {
- GcaSourceRange *range;
-
- range = &g_array_index (diag->locations, GcaSourceRange, 0);
- gb_editor_frame_scroll_to_line (self, range->begin.line,
- range->begin.column);
- }
- }
-
-cleanup:
- g_array_unref (ar);
- }
-}
-
-static void
-gb_editor_frame_previous_diagnostic (GbEditorFrame *self)
+get_smart_home_end (GValue *value,
+ GVariant *variant,
+ gpointer user_data)
{
- GbSourceCodeAssistant *assistant;
- GtkTextMark *mark;
- GtkTextIter iter;
- guint current_line;
- GArray *ar;
- gint i;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- assistant = gb_editor_document_get_code_assistant (self->priv->document);
- ar = gb_source_code_assistant_get_diagnostics (assistant);
- mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (self->priv->document));
- gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (self->priv->document),
- &iter, mark);
- current_line = gtk_text_iter_get_line (&iter);
-
- if (ar)
- {
- for (i = 0; i < ar->len; i++)
- {
- GcaDiagnostic *diag;
- guint j;
-
- diag = &g_array_index (ar, GcaDiagnostic, ar->len-i-1);
-
- for (j = 0; j < diag->locations->len; j++)
- {
- GcaSourceRange *range;
-
- range = &g_array_index (diag->locations, GcaSourceRange, j);
-
- if (range->begin.line < current_line)
- {
- gb_editor_frame_scroll_to_line (self,
- range->begin.line,
- range->begin.column);
- goto cleanup;
- }
- }
- }
-
- /* wrap around to last diagnostic */
- if (ar->len > 0)
- {
- GcaDiagnostic *diag;
-
- diag = &g_array_index (ar, GcaDiagnostic, ar->len-1);
-
- if (diag->locations->len > 0)
- {
- GcaSourceRange *range;
-
- range = &g_array_index (diag->locations, GcaSourceRange, 0);
- gb_editor_frame_scroll_to_line (self, range->begin.line,
- range->begin.column);
- }
- }
- }
-
-cleanup:
- g_clear_pointer (&ar, g_array_unref);
-}
-
-static void
-gb_editor_frame_reformat_activate (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbEditorFrame *self = user_data;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- gb_editor_frame_reformat (self);
-}
-
-static void
-gb_editor_frame_next_diagnostic_activate (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbEditorFrame *self = user_data;
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- gb_editor_frame_next_diagnostic (self);
-}
-
-static void
-gb_editor_frame_previous_diagnostic_activate (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbEditorFrame *self = user_data;
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
- gb_editor_frame_previous_diagnostic (self);
-}
-
-static void
-gb_editor_frame_scroll (GbEditorFrame *self,
- GtkDirectionType dir)
-{
- GtkAdjustment *vadj;
- GtkScrolledWindow *scroller;
- GtkTextMark *insert;
- GtkTextView *view;
- GtkTextBuffer *buffer;
- GdkRectangle rect;
- GtkTextIter iter;
- gdouble amount;
- gdouble value;
- gdouble upper;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- scroller = self->priv->scrolled_window;
- view = GTK_TEXT_VIEW (self->priv->source_view);
- buffer = GTK_TEXT_BUFFER (self->priv->document);
-
- insert = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert);
- gtk_text_view_get_iter_location (view, &iter, &rect);
-
- amount = (dir == GTK_DIR_UP) ? -rect.height : rect.height;
-
- vadj = gtk_scrolled_window_get_vadjustment (scroller);
- value = gtk_adjustment_get_value (vadj);
- upper = gtk_adjustment_get_upper (vadj);
- gtk_adjustment_set_value (vadj, CLAMP (value + amount, 0, upper));
-}
-
-static void
-gb_editor_frame_scroll_down (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbEditorFrame *self = user_data;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
+ if (g_variant_get_boolean (variant))
+ g_value_set_enum (value, GTK_SOURCE_SMART_HOME_END_BEFORE);
+ else
+ g_value_set_enum (value, GTK_SOURCE_SMART_HOME_END_DISABLED);
- gb_editor_frame_scroll (self, GTK_DIR_DOWN);
- gtk_text_view_place_cursor_onscreen (GTK_TEXT_VIEW (self->priv->source_view));
+ return TRUE;
}
static void
-gb_editor_frame_scroll_up (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
+keybindings_changed (GSettings *settings,
+ const gchar *key,
+ GbEditorFrame *self)
{
- GbEditorFrame *self = user_data;
-
- g_return_if_fail (GB_IS_EDITOR_FRAME (self));
-
- gb_editor_frame_scroll (self, GTK_DIR_UP);
- gtk_text_view_place_cursor_onscreen (GTK_TEXT_VIEW (self->priv->source_view));
+ g_signal_emit_by_name (self->source_view,
+ "set-mode",
+ NULL,
+ IDE_SOURCE_VIEW_MODE_TYPE_PERMANENT);
}
static void
gb_editor_frame_finalize (GObject *object)
{
- GbEditorFrame *self = GB_EDITOR_FRAME (object);
-
- gb_editor_frame_disconnect (self);
-
- g_clear_object (&self->priv->code_assistant_renderer);
- g_clear_object (&self->priv->diff_renderer);
- g_clear_object (&self->priv->search_settings);
- g_clear_object (&self->priv->search_highlighter);
-
G_OBJECT_CLASS (gb_editor_frame_parent_class)->finalize (object);
}
static void
-gb_editor_frame_constructed (GObject *object)
-{
- GbSourceChangeMonitor *monitor = NULL;
- GbEditorFramePrivate *priv;
- GtkSourceGutter *gutter;
- GbEditorFrame *self = (GbEditorFrame *)object;
- GbSourceVim *vim;
- GSettings *settings;
-
- G_OBJECT_CLASS (gb_editor_frame_parent_class)->constructed (object);
-
- priv = self->priv;
-
- settings = g_settings_new ("org.gnome.builder.editor");
-
- if (priv->document)
- monitor = gb_editor_document_get_change_monitor (priv->document);
-
- gutter = gtk_source_view_get_gutter (GTK_SOURCE_VIEW (priv->source_view),
- GTK_TEXT_WINDOW_LEFT);
-
- priv->diff_renderer = g_object_new (GB_TYPE_SOURCE_CHANGE_GUTTER_RENDERER,
- "change-monitor", monitor,
- "size", 2,
- "visible", TRUE,
- "xpad", 1,
- NULL);
- priv->diff_renderer = g_object_ref (priv->diff_renderer);
- gtk_source_gutter_insert (gutter,
- GTK_SOURCE_GUTTER_RENDERER (priv->diff_renderer),
- 0);
- g_settings_bind (settings, "show-diff",
- priv->diff_renderer, "visible",
- G_SETTINGS_BIND_GET);
-
- priv->code_assistant_renderer =
- g_object_new (GB_TYPE_SOURCE_CODE_ASSISTANT_RENDERER,
- "code-assistant", NULL,
- "size", 16,
- "visible", TRUE,
- NULL);
- priv->code_assistant_renderer = g_object_ref (priv->code_assistant_renderer);
- gtk_source_gutter_insert (gutter,
- GTK_SOURCE_GUTTER_RENDERER (priv->code_assistant_renderer),
- -50);
-
- priv->search_settings = g_object_new (GTK_SOURCE_TYPE_SEARCH_SETTINGS,
- "wrap-around", TRUE,
- NULL);
- g_object_bind_property (priv->search_entry, "text",
- priv->search_settings, "search-text",
- G_BINDING_SYNC_CREATE);
-
- priv->search_highlighter =
- g_object_new (GB_TYPE_SOURCE_SEARCH_HIGHLIGHTER,
- "search-settings", priv->search_settings,
- NULL);
- g_object_set (priv->source_view,
- "search-highlighter", priv->search_highlighter,
- NULL);
- g_object_bind_property (priv->search_revealer, "reveal-child",
- priv->source_view, "show-shadow",
- G_BINDING_SYNC_CREATE);
-
- vim = gb_source_view_get_vim (priv->source_view);
- g_signal_connect_object (vim,
- "command-visibility-toggled",
- G_CALLBACK (gb_editor_frame_on_command_toggled),
- self,
- G_CONNECT_SWAPPED);
- g_signal_connect_object (vim,
- "switch-to-file",
- G_CALLBACK (gb_editor_frame_on_switch_to_file),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->source_view,
- "display-documentation",
- G_CALLBACK (gb_editor_frame_on_jump_to_doc),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->source_view,
- "drop-uris",
- G_CALLBACK (gb_editor_frame_on_drop_uris),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->source_view,
- "focus-in-event",
- G_CALLBACK (gb_editor_frame_on_focus_in_event),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->source_view,
- "populate-popup",
- G_CALLBACK (gb_editor_frame_on_populate_popup),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->source_view,
- "push-snippet",
- G_CALLBACK (gb_editor_frame_on_push_snippet),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->source_view,
- "begin-search",
- G_CALLBACK (gb_editor_frame_on_begin_search),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->source_view,
- "query-tooltip",
- G_CALLBACK (gb_editor_frame_on_query_tooltip),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->search_entry,
- "key-press-event",
- G_CALLBACK (gb_editor_frame_on_search_entry_key_press),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->search_entry,
- "changed",
- G_CALLBACK (gb_editor_frame_on_search_entry_changed),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->search_entry,
- "activate",
- G_CALLBACK (gb_editor_frame_on_search_entry_activate),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->forward_search,
- "clicked",
- G_CALLBACK (gb_editor_frame_on_forward_search_clicked),
- self,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (priv->backward_search,
- "clicked",
- G_CALLBACK (gb_editor_frame_on_backward_search_clicked),
- self,
- G_CONNECT_SWAPPED);
-
- g_object_unref (settings);
-}
-
-static void
gb_editor_frame_get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -1606,10 +137,6 @@ gb_editor_frame_get_property (GObject *object,
g_value_set_object (value, gb_editor_frame_get_document (self));
break;
- case PROP_SEARCH_DIRECTION:
- g_value_set_enum (value, gb_editor_frame_get_search_direction (self));
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -1638,86 +165,48 @@ static void
gb_editor_frame_class_init (GbEditorFrameClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- object_class->constructed = gb_editor_frame_constructed;
object_class->finalize = gb_editor_frame_finalize;
object_class->get_property = gb_editor_frame_get_property;
object_class->set_property = gb_editor_frame_set_property;
- widget_class->grab_focus = gb_editor_frame_grab_focus;
-
gParamSpecs [PROP_DOCUMENT] =
g_param_spec_object ("document",
_("Document"),
- _("The document for the editor."),
+ _("The editor document."),
GB_TYPE_EDITOR_DOCUMENT,
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_DOCUMENT,
- gParamSpecs [PROP_DOCUMENT]);
-
- gParamSpecs [PROP_SEARCH_DIRECTION] =
- g_param_spec_enum ("search-direction",
- _("Search Direction"),
- _("The direction of the last text searched for."),
- GTK_TYPE_DIRECTION_TYPE,
- GTK_DIR_DOWN,
- (G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_SEARCH_DIRECTION,
- gParamSpecs [PROP_SEARCH_DIRECTION]);
-
-
- gSignals [FOCUSED] =
- g_signal_new ("focused",
- GB_TYPE_EDITOR_FRAME,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+ g_object_class_install_property (object_class, PROP_DOCUMENT, gParamSpecs [PROP_DOCUMENT]);
GB_WIDGET_CLASS_TEMPLATE (klass, "gb-editor-frame.ui");
- GB_WIDGET_CLASS_BIND (klass, GbEditorFrame, busy_spinner);
+
GB_WIDGET_CLASS_BIND (klass, GbEditorFrame, floating_bar);
- GB_WIDGET_CLASS_BIND (klass, GbEditorFrame, forward_search);
- GB_WIDGET_CLASS_BIND (klass, GbEditorFrame, backward_search);
GB_WIDGET_CLASS_BIND (klass, GbEditorFrame, scrolled_window);
- GB_WIDGET_CLASS_BIND (klass, GbEditorFrame, search_revealer);
GB_WIDGET_CLASS_BIND (klass, GbEditorFrame, search_entry);
+ GB_WIDGET_CLASS_BIND (klass, GbEditorFrame, search_revealer);
GB_WIDGET_CLASS_BIND (klass, GbEditorFrame, source_view);
- g_type_ensure (GB_TYPE_SOURCE_VIEW);
- g_type_ensure (GD_TYPE_TAGGED_ENTRY);
g_type_ensure (NAUTILUS_TYPE_FLOATING_BAR);
+ g_type_ensure (GD_TYPE_TAGGED_ENTRY);
}
static void
gb_editor_frame_init (GbEditorFrame *self)
{
- const GActionEntry entries[] = {
- { "find", gb_editor_frame_find_activate },
- { "reformat", gb_editor_frame_reformat_activate },
- { "scroll-up", gb_editor_frame_scroll_up },
- { "scroll-down", gb_editor_frame_scroll_down },
- { "next-diagnostic", gb_editor_frame_next_diagnostic_activate },
- { "previous-diagnostic", gb_editor_frame_previous_diagnostic_activate },
- };
- GSimpleActionGroup *actions;
-
- self->priv = gb_editor_frame_get_instance_private (self);
+ g_autoptr(GSettings) settings = NULL;
gtk_widget_init_template (GTK_WIDGET (self));
- actions = g_simple_action_group_new ();
- g_action_map_add_action_entries (G_ACTION_MAP (actions),
- entries, G_N_ELEMENTS (entries),
- self);
- gtk_widget_insert_action_group (GTK_WIDGET (self), "editor-frame",
- G_ACTION_GROUP (actions));
- g_object_unref (actions);
+ gb_editor_frame_actions_init (self);
- self->priv->search_direction = GTK_DIR_DOWN;
+ settings = g_settings_new ("org.gnome.builder.editor");
+ g_settings_bind (settings, "font-name", self->source_view, "font-name", G_SETTINGS_BIND_GET);
+ g_settings_bind (settings, "highlight-current-line", self->source_view, "highlight-current-line",
G_SETTINGS_BIND_GET);
+ g_settings_bind (settings, "show-grid-lines", self->source_view, "show-grid-lines", G_SETTINGS_BIND_GET);
+ g_settings_bind (settings, "show-line-changes", self->source_view, "show-line-changes",
G_SETTINGS_BIND_GET);
+ g_settings_bind (settings, "show-line-numbers", self->source_view, "show-line-numbers",
G_SETTINGS_BIND_GET);
+ g_settings_bind (settings, "smart-backspace", self->source_view, "smart-backspace", G_SETTINGS_BIND_GET);
+ g_settings_bind_with_mapping (settings, "smart-home-end", self->source_view, "smart-home-end",
G_SETTINGS_BIND_GET, get_smart_home_end, NULL, NULL, NULL);
+ g_settings_bind (settings, "word-completion", self->source_view, "enable-word-completion",
G_SETTINGS_BIND_GET);
+ g_signal_connect (settings, "changed::keybindings", G_CALLBACK (keybindings_changed), self);
}
diff --git a/src/editor/gb-editor-frame.h b/src/editor/gb-editor-frame.h
index 7d10478..ed6b1fb 100644
--- a/src/editor/gb-editor-frame.h
+++ b/src/editor/gb-editor-frame.h
@@ -1,6 +1,6 @@
/* gb-editor-frame.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -25,43 +25,13 @@
G_BEGIN_DECLS
-#define GB_TYPE_EDITOR_FRAME (gb_editor_frame_get_type())
-#define GB_EDITOR_FRAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_EDITOR_FRAME,
GbEditorFrame))
-#define GB_EDITOR_FRAME_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_EDITOR_FRAME,
GbEditorFrame const))
-#define GB_EDITOR_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_EDITOR_FRAME,
GbEditorFrameClass))
-#define GB_IS_EDITOR_FRAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_EDITOR_FRAME))
-#define GB_IS_EDITOR_FRAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_EDITOR_FRAME))
-#define GB_EDITOR_FRAME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_EDITOR_FRAME,
GbEditorFrameClass))
+#define GB_TYPE_EDITOR_FRAME (gb_editor_frame_get_type())
-typedef struct _GbEditorFrame GbEditorFrame;
-typedef struct _GbEditorFrameClass GbEditorFrameClass;
-typedef struct _GbEditorFramePrivate GbEditorFramePrivate;
+G_DECLARE_FINAL_TYPE (GbEditorFrame, gb_editor_frame, GB, EDITOR_FRAME, GtkBin)
-struct _GbEditorFrame
-{
- GtkOverlay parent;
-
- /*< private >*/
- GbEditorFramePrivate *priv;
-};
-
-struct _GbEditorFrameClass
-{
- GtkOverlayClass parent;
-};
-
-GType gb_editor_frame_get_type (void);
-GtkWidget *gb_editor_frame_new (void);
-void gb_editor_frame_link (GbEditorFrame *src,
- GbEditorFrame *dst);
GbEditorDocument *gb_editor_frame_get_document (GbEditorFrame *self);
void gb_editor_frame_set_document (GbEditorFrame *self,
GbEditorDocument *document);
-void gb_editor_frame_find (GbEditorFrame *self,
- const gchar *search_text);
-void gb_editor_frame_reformat (GbEditorFrame *self);
-
-GtkDirectionType gb_editor_frame_get_search_direction (GbEditorFrame *self);
G_END_DECLS
diff --git a/src/editor/gb-editor-settings-widget.c b/src/editor/gb-editor-settings-widget.c
index e10ad02..26c2527 100644
--- a/src/editor/gb-editor-settings-widget.c
+++ b/src/editor/gb-editor-settings-widget.c
@@ -168,14 +168,14 @@ gb_editor_settings_widget_class_init (GbEditorSettingsWidgetClass *klass)
object_class->set_property = gb_editor_settings_widget_set_property;
GB_WIDGET_CLASS_TEMPLATE (klass, "gb-editor-settings-widget.ui");
- GB_WIDGET_CLASS_BIND (klass, GbEditorSettingsWidget, auto_indent);
- GB_WIDGET_CLASS_BIND (klass, GbEditorSettingsWidget, insert_matching_brace);
- GB_WIDGET_CLASS_BIND (klass, GbEditorSettingsWidget, insert_spaces_instead_of_tabs);
- GB_WIDGET_CLASS_BIND (klass, GbEditorSettingsWidget, right_margin_position);
- GB_WIDGET_CLASS_BIND (klass, GbEditorSettingsWidget, overwrite_braces);
- GB_WIDGET_CLASS_BIND (klass, GbEditorSettingsWidget, show_right_margin);
- GB_WIDGET_CLASS_BIND (klass, GbEditorSettingsWidget, tab_width);
- GB_WIDGET_CLASS_BIND (klass, GbEditorSettingsWidget, trim_trailing_whitespace);
+ GB_WIDGET_CLASS_BIND_PRIVATE (klass, GbEditorSettingsWidget, auto_indent);
+ GB_WIDGET_CLASS_BIND_PRIVATE (klass, GbEditorSettingsWidget, insert_matching_brace);
+ GB_WIDGET_CLASS_BIND_PRIVATE (klass, GbEditorSettingsWidget, insert_spaces_instead_of_tabs);
+ GB_WIDGET_CLASS_BIND_PRIVATE (klass, GbEditorSettingsWidget, right_margin_position);
+ GB_WIDGET_CLASS_BIND_PRIVATE (klass, GbEditorSettingsWidget, overwrite_braces);
+ GB_WIDGET_CLASS_BIND_PRIVATE (klass, GbEditorSettingsWidget, show_right_margin);
+ GB_WIDGET_CLASS_BIND_PRIVATE (klass, GbEditorSettingsWidget, tab_width);
+ GB_WIDGET_CLASS_BIND_PRIVATE (klass, GbEditorSettingsWidget, trim_trailing_whitespace);
gParamSpecs [PROP_LANGUAGE] =
g_param_spec_string ("language",
diff --git a/src/editor/gb-editor-tweak-widget.c b/src/editor/gb-editor-tweak-widget.c
index 3cf3c69..b94a87d 100644
--- a/src/editor/gb-editor-tweak-widget.c
+++ b/src/editor/gb-editor-tweak-widget.c
@@ -25,14 +25,15 @@
#include "gb-string.h"
#include "gb-widget.h"
-struct _GbEditorTweakWidgetPrivate
+struct _GbEditorTweakWidget
{
+ GtkBin parent_instance;
+
GtkSearchEntry *entry;
GtkListBox *list_box;
};
-G_DEFINE_TYPE_WITH_PRIVATE (GbEditorTweakWidget, gb_editor_tweak_widget,
- GTK_TYPE_BIN)
+G_DEFINE_TYPE (GbEditorTweakWidget, gb_editor_tweak_widget, GTK_TYPE_BIN)
static GQuark gLangQuark;
@@ -67,55 +68,36 @@ gb_editor_tweak_widget_filter_func (GtkListBoxRow *row,
}
static void
-gb_editor_tweak_widget_entry_changed (GbEditorTweakWidget *widget,
+gb_editor_tweak_widget_entry_changed (GbEditorTweakWidget *self,
GtkEntry *entry)
{
const gchar *text;
- g_return_if_fail (GB_IS_EDITOR_TWEAK_WIDGET (widget));
+ g_return_if_fail (GB_IS_EDITOR_TWEAK_WIDGET (self));
g_return_if_fail (GTK_IS_ENTRY (entry));
text = gtk_entry_get_text (entry);
if (gb_str_empty0 (text))
- gtk_list_box_set_filter_func (widget->priv->list_box, NULL, NULL, NULL);
+ gtk_list_box_set_filter_func (self->list_box, NULL, NULL, NULL);
else
- gtk_list_box_set_filter_func (widget->priv->list_box,
+ gtk_list_box_set_filter_func (self->list_box,
gb_editor_tweak_widget_filter_func,
g_strdup (text),
g_free);
}
-static GActionGroup *
-find_action_group (GtkWidget *widget,
- const gchar *name)
-{
- GActionGroup *group = NULL;
-
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- g_return_val_if_fail (name, NULL);
-
- while (!group && widget)
- {
- group = gtk_widget_get_action_group (widget, name);
- widget = gtk_widget_get_parent (widget);
- }
-
- return group;
-}
-
static void
-gb_editor_tweak_widget_row_activated (GbEditorTweakWidget *widget,
+gb_editor_tweak_widget_row_activated (GbEditorTweakWidget *self,
GtkListBoxRow *row,
GtkListBox *list_box)
{
GtkSourceLanguage *lang;
- GActionGroup *group;
const gchar *lang_id;
GtkWidget *child;
GVariant *param;
- g_return_if_fail (GB_IS_EDITOR_TWEAK_WIDGET (widget));
+ g_return_if_fail (GB_IS_EDITOR_TWEAK_WIDGET (self));
g_return_if_fail (GTK_IS_LIST_BOX_ROW (row));
g_return_if_fail (GTK_IS_LIST_BOX (list_box));
@@ -124,23 +106,22 @@ gb_editor_tweak_widget_row_activated (GbEditorTweakWidget *widget,
if (lang)
{
- group = find_action_group (GTK_WIDGET (widget), "editor-view");
lang_id = gtk_source_language_get_id (lang);
param = g_variant_new_string (lang_id);
- g_action_group_activate_action (group, "language", param);
+ gb_widget_activate_action (GTK_WIDGET (self), "editor-view", "language", param);
}
}
static void
gb_editor_tweak_widget_constructed (GObject *object)
{
- GbEditorTweakWidget *widget = (GbEditorTweakWidget *)object;
+ GbEditorTweakWidget *self = (GbEditorTweakWidget *)object;
GtkSourceLanguageManager *manager;
GtkSourceLanguage *lang;
const gchar * const *lang_ids;
guint i;
- g_return_if_fail (GB_IS_EDITOR_TWEAK_WIDGET (widget));
+ g_return_if_fail (GB_IS_EDITOR_TWEAK_WIDGET (self));
G_OBJECT_CLASS (gb_editor_tweak_widget_parent_class)->constructed (object);
@@ -162,19 +143,19 @@ gb_editor_tweak_widget_constructed (GObject *object)
"margin-bottom", 3,
NULL);
g_object_set_qdata (G_OBJECT (row), gLangQuark, lang);
- gtk_list_box_insert (widget->priv->list_box, row, -1);
+ gtk_list_box_insert (self->list_box, row, -1);
}
- g_signal_connect_object (widget->priv->entry,
+ g_signal_connect_object (self->entry,
"changed",
G_CALLBACK (gb_editor_tweak_widget_entry_changed),
- widget,
+ self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (widget->priv->list_box,
+ g_signal_connect_object (self->list_box,
"row-activated",
G_CALLBACK (gb_editor_tweak_widget_row_activated),
- widget,
+ self,
G_CONNECT_SWAPPED);
}
@@ -195,7 +176,5 @@ gb_editor_tweak_widget_class_init (GbEditorTweakWidgetClass *klass)
static void
gb_editor_tweak_widget_init (GbEditorTweakWidget *self)
{
- self->priv = gb_editor_tweak_widget_get_instance_private (self);
-
gtk_widget_init_template (GTK_WIDGET (self));
}
diff --git a/src/editor/gb-editor-tweak-widget.h b/src/editor/gb-editor-tweak-widget.h
index d1f1bf4..6394dfa 100644
--- a/src/editor/gb-editor-tweak-widget.h
+++ b/src/editor/gb-editor-tweak-widget.h
@@ -20,36 +20,13 @@
#define GB_EDITOR_TWEAK_WIDGET_H
#include <gtk/gtk.h>
+#include <ide.h>
G_BEGIN_DECLS
-#define GB_TYPE_EDITOR_TWEAK_WIDGET (gb_editor_tweak_widget_get_type())
-#define GB_EDITOR_TWEAK_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_EDITOR_TWEAK_WIDGET, GbEditorTweakWidget))
-#define GB_EDITOR_TWEAK_WIDGET_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_EDITOR_TWEAK_WIDGET, GbEditorTweakWidget const))
-#define GB_EDITOR_TWEAK_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GB_TYPE_EDITOR_TWEAK_WIDGET, GbEditorTweakWidgetClass))
-#define GB_IS_EDITOR_TWEAK_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GB_TYPE_EDITOR_TWEAK_WIDGET))
-#define GB_IS_EDITOR_TWEAK_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GB_TYPE_EDITOR_TWEAK_WIDGET))
-#define GB_EDITOR_TWEAK_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GB_TYPE_EDITOR_TWEAK_WIDGET, GbEditorTweakWidgetClass))
+#define GB_TYPE_EDITOR_TWEAK_WIDGET (gb_editor_tweak_widget_get_type())
-typedef struct _GbEditorTweakWidget GbEditorTweakWidget;
-typedef struct _GbEditorTweakWidgetClass GbEditorTweakWidgetClass;
-typedef struct _GbEditorTweakWidgetPrivate GbEditorTweakWidgetPrivate;
-
-struct _GbEditorTweakWidget
-{
- GtkBin parent;
-
- /*< private >*/
- GbEditorTweakWidgetPrivate *priv;
-};
-
-struct _GbEditorTweakWidgetClass
-{
- GtkBinClass parent;
-};
-
-GType gb_editor_tweak_widget_get_type (void);
-GtkWidget *gb_editor_tweak_widget_new (void);
+G_DECLARE_FINAL_TYPE (GbEditorTweakWidget, gb_editor_tweak_widget, GB, EDITOR_TWEAK_WIDGET, GtkBin)
G_END_DECLS
diff --git a/src/editor/gb-editor-view-actions.c b/src/editor/gb-editor-view-actions.c
new file mode 100644
index 0000000..a271898
--- /dev/null
+++ b/src/editor/gb-editor-view-actions.c
@@ -0,0 +1,271 @@
+/* gb-editor-view-actions.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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 3 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 "gb-editor-view"
+
+#include <ide.h>
+
+#include "gb-editor-frame-private.h"
+#include "gb-editor-view-actions.h"
+#include "gb-editor-view-private.h"
+#include "gb-widget.h"
+
+static void
+gb_editor_view_actions_source_view_notify (IdeSourceView *source_view,
+ GParamSpec *pspec,
+ GActionMap *actions)
+{
+ g_autoptr(GVariant) param = NULL;
+ GtkSourceView *gsv;
+ GAction *action = NULL;
+
+ g_assert (IDE_IS_SOURCE_VIEW (source_view));
+ g_assert (pspec != NULL);
+ g_assert (G_IS_ACTION_MAP (actions));
+
+ gsv = GTK_SOURCE_VIEW (source_view);
+
+ if (g_str_equal (pspec->name, "show-line-numbers"))
+ {
+ gboolean show_line_numbers;
+
+ action = g_action_map_lookup_action (actions, "show-line-numbers");
+ show_line_numbers = gtk_source_view_get_show_line_numbers (gsv);
+ param = g_variant_new_boolean (show_line_numbers);
+ }
+ else if (g_str_equal (pspec->name, "show-right-margin"))
+ {
+ gboolean show_right_margin;
+
+ action = g_action_map_lookup_action (actions, "show-right-margin");
+ show_right_margin = gtk_source_view_get_show_right_margin (gsv);
+ param = g_variant_new_boolean (show_right_margin);
+ }
+ else if (g_str_equal (pspec->name, "highlight-current-line"))
+ {
+ gboolean highlight_current_line;
+
+ action = g_action_map_lookup_action (actions, "highlight-current-line");
+ highlight_current_line = gtk_source_view_get_highlight_current_line (gsv);
+ param = g_variant_new_boolean (highlight_current_line);
+ }
+ else if (g_str_equal (pspec->name, "auto-indent"))
+ {
+ gboolean auto_indent;
+
+ action = g_action_map_lookup_action (actions, "auto-indent");
+ g_object_get (source_view, "auto-indent", &auto_indent, NULL);
+ param = g_variant_new_boolean (auto_indent);
+ }
+ else if (g_str_equal (pspec->name, "tab-width"))
+ {
+ guint tab_width;
+
+ action = g_action_map_lookup_action (actions, "tab-width");
+ g_object_get (source_view, "tab-width", &tab_width, NULL);
+ param = g_variant_new_int32 (tab_width);
+ }
+ else if (g_str_equal (pspec->name, "insert-spaces-instead-of-tabs"))
+ {
+ gboolean use_spaces;
+
+ action = g_action_map_lookup_action (actions, "use-spaces");
+ g_object_get (source_view, "insert-spaces-instead-of-tabs", &use_spaces, NULL);
+ param = g_variant_new_boolean (use_spaces);
+ }
+ else if (g_str_equal (pspec->name, "smart-backspace"))
+ {
+ gboolean smart_backspace;
+
+ action = g_action_map_lookup_action (actions, "smart-backspace");
+ g_object_get (source_view, "smart-backspace", &smart_backspace, NULL);
+ param = g_variant_new_boolean (smart_backspace);
+ }
+
+ if (action && param)
+ {
+ g_simple_action_set_state (G_SIMPLE_ACTION (action), param);
+ param = NULL;
+ }
+}
+
+static void
+gb_editor_view_actions_language (GSimpleAction *action,
+ GVariant *variant,
+ gpointer user_data)
+{
+ GbEditorView *self = user_data;
+ GtkSourceLanguageManager *manager;
+ GtkSourceLanguage *language;
+ GtkSourceBuffer *buffer;
+ const gchar *name;
+
+ g_assert (GB_IS_EDITOR_VIEW (self));
+
+ manager = gtk_source_language_manager_get_default ();
+ name = g_variant_get_string (variant, NULL);
+ buffer = GTK_SOURCE_BUFFER (self->document);
+
+ if (name != NULL)
+ {
+ language = gtk_source_language_manager_get_language (manager, name);
+ gtk_source_buffer_set_language (buffer, language);
+ }
+}
+
+#define STATE_HANDLER_BOOLEAN(name,propname) \
+static void \
+gb_editor_view_actions_##name (GSimpleAction *action, \
+ GVariant *variant, \
+ gpointer user_data) \
+{ \
+ GbEditorView *self = user_data; \
+ gboolean val; \
+ \
+ g_assert (GB_IS_EDITOR_VIEW (self)); \
+ \
+ val = g_variant_get_boolean (variant); \
+ g_object_set (self->frame1->source_view, propname, val, NULL); \
+ if (self->frame2) \
+ g_object_set (self->frame2->source_view, propname, val, NULL); \
+}
+
+#define STATE_HANDLER_INT(name,propname) \
+static void \
+gb_editor_view_actions_##name (GSimpleAction *action, \
+ GVariant *variant, \
+ gpointer user_data) \
+{ \
+ GbEditorView *self = user_data; \
+ gint val; \
+ \
+ g_assert (GB_IS_EDITOR_VIEW (self)); \
+ \
+ val = g_variant_get_int32 (variant); \
+ g_object_set (self->frame1->source_view, propname, val, NULL); \
+ if (self->frame2) \
+ g_object_set (self->frame2->source_view, propname, val, NULL); \
+}
+
+STATE_HANDLER_BOOLEAN (auto_indent, "auto-indent")
+STATE_HANDLER_BOOLEAN (show_line_numbers, "show-line-numbers")
+STATE_HANDLER_BOOLEAN (show_right_margin, "show-right-margin")
+STATE_HANDLER_BOOLEAN (highlight_current_line, "highlight-current-line")
+STATE_HANDLER_BOOLEAN (use_spaces, "insert-spaces-instead-of-tabs")
+STATE_HANDLER_BOOLEAN (smart_backspace, "smart-backspace")
+STATE_HANDLER_INT (tab_width, "tab-width")
+
+static void
+save_file_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ IdeBufferManager *buffer_manager = (IdeBufferManager *)object;
+ g_autoptr(GbEditorView) self = user_data;
+ GError *error = NULL;
+
+ if (!ide_buffer_manager_save_file_finish (buffer_manager, result, &error))
+ {
+ /* info bar */
+ g_warning ("%s", error->message);
+ g_clear_error (&error);
+ }
+
+ gb_widget_fade_hide (GTK_WIDGET (self->progress_bar));
+}
+
+static void
+gb_editor_view_actions_save (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbEditorView *self = user_data;
+ IdeContext *context;
+ IdeBufferManager *buffer_manager;
+ IdeFile *file;
+ IdeProgress *progress = NULL;
+
+ g_assert (GB_IS_EDITOR_VIEW (self));
+
+ file = ide_buffer_get_file (IDE_BUFFER (self->document));
+ context = ide_buffer_get_context (IDE_BUFFER (self->document));
+ buffer_manager = ide_context_get_buffer_manager (context);
+
+#if 0
+ if (!file || is_temporary (file))
+ {
+ /* todo: dialog */
+ }
+#endif
+
+ ide_buffer_manager_save_file_async (buffer_manager,
+ IDE_BUFFER (self->document),
+ file,
+ &progress,
+ NULL,
+ save_file_cb,
+ g_object_ref (self));
+ g_object_bind_property (progress, "fraction", self->progress_bar, "fraction",
+ G_BINDING_SYNC_CREATE);
+ gtk_widget_show (GTK_WIDGET (self->progress_bar));
+ g_clear_object (&progress);
+}
+
+static GActionEntry GbEditorViewActions[] = {
+ { "auto-indent", NULL, NULL, "false", gb_editor_view_actions_auto_indent },
+ { "language", NULL, "s", "''", gb_editor_view_actions_language },
+ { "highlight-current-line", NULL, NULL, "false", gb_editor_view_actions_highlight_current_line },
+ { "save", gb_editor_view_actions_save },
+ { "show-line-numbers", NULL, NULL, "false", gb_editor_view_actions_show_line_numbers },
+ { "show-right-margin", NULL, NULL, "false", gb_editor_view_actions_show_right_margin },
+ { "smart-backspace", NULL, NULL, "false", gb_editor_view_actions_smart_backspace },
+ { "tab-width", NULL, "i", "8", gb_editor_view_actions_tab_width },
+ { "use-spaces", NULL, "b", "false", gb_editor_view_actions_use_spaces },
+};
+
+void
+gb_editor_view_actions_init (GbEditorView *self)
+{
+ g_autoptr(GSimpleActionGroup) group = NULL;
+
+ group = g_simple_action_group_new ();
+ g_action_map_add_action_entries (G_ACTION_MAP (group), GbEditorViewActions,
+ G_N_ELEMENTS (GbEditorViewActions), self);
+ gtk_widget_insert_action_group (GTK_WIDGET (self), "editor-view", G_ACTION_GROUP (group));
+ gtk_widget_insert_action_group (GTK_WIDGET (self->tweak_widget), "editor-view",
+ G_ACTION_GROUP (group));
+
+#define WATCH_PROPERTY(name) \
+ G_STMT_START { \
+ g_signal_connect (self->frame1->source_view, \
+ "notify::"name, \
+ G_CALLBACK (gb_editor_view_actions_source_view_notify), \
+ group); \
+ g_object_notify (G_OBJECT (self->frame1->source_view), name); \
+ } G_STMT_END
+
+ WATCH_PROPERTY ("auto-indent");
+ WATCH_PROPERTY ("highlight-current-line");
+ WATCH_PROPERTY ("insert-spaces-instead-of-tabs");
+ WATCH_PROPERTY ("show-line-numbers");
+ WATCH_PROPERTY ("show-right-margin");
+ WATCH_PROPERTY ("smart-backspace");
+ WATCH_PROPERTY ("tab-width");
+
+#undef WATCH_PROPERTY
+}
diff --git a/src/auto-indent/c-parse-helper.h b/src/editor/gb-editor-view-actions.h
similarity index 57%
copy from src/auto-indent/c-parse-helper.h
copy to src/editor/gb-editor-view-actions.h
index 418f518..f623ab2 100644
--- a/src/auto-indent/c-parse-helper.h
+++ b/src/editor/gb-editor-view-actions.h
@@ -1,6 +1,6 @@
-/* c-parse-helper.h
+/* gb-editor-view-actions.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,26 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef C_PARSE_HELPER_H
-#define C_PARSE_HELPER_H
+#ifndef GB_EDITOR_VIEW_ACTIONS_H
+#define GB_EDITOR_VIEW_ACTIONS_H
-#include <glib.h>
+#include "gb-editor-view.h"
G_BEGIN_DECLS
-typedef struct
-{
- gchar *type;
- gchar *name;
- guint ellipsis : 1;
- guint n_star : 4;
-} Parameter;
-
-gboolean parameter_validate (Parameter *param);
-void parameter_free (Parameter *p);
-Parameter *parameter_copy (const Parameter *src);
-GSList *parse_parameters (const gchar *text);
+void gb_editor_view_actions_init (GbEditorView *self);
G_END_DECLS
-#endif /* C_PARSE_HELPER_H */
+#endif /* GB_EDITOR_VIEW_ACTIONS_H */
diff --git a/src/auto-indent/c-parse-helper.h b/src/editor/gb-editor-view-private.h
similarity index 51%
copy from src/auto-indent/c-parse-helper.h
copy to src/editor/gb-editor-view-private.h
index 418f518..280df02 100644
--- a/src/auto-indent/c-parse-helper.h
+++ b/src/editor/gb-editor-view-private.h
@@ -1,6 +1,6 @@
-/* c-parse-helper.h
+/* gb-editor-view-private.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,26 +16,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef C_PARSE_HELPER_H
-#define C_PARSE_HELPER_H
+#ifndef GB_EDITOR_VIEW_PRIVATE_H
+#define GB_EDITOR_VIEW_PRIVATE_H
-#include <glib.h>
+#include "gb-editor-document.h"
+#include "gb-editor-frame.h"
+#include "gb-editor-tweak-widget.h"
+#include "gb-view.h"
G_BEGIN_DECLS
-typedef struct
+struct _GbEditorView
{
- gchar *type;
- gchar *name;
- guint ellipsis : 1;
- guint n_star : 4;
-} Parameter;
+ GbView parent_instance;
-gboolean parameter_validate (Parameter *param);
-void parameter_free (Parameter *p);
-Parameter *parameter_copy (const Parameter *src);
-GSList *parse_parameters (const gchar *text);
+ GbEditorDocument *document;
+ GSettings *settings;
+
+ GbEditorFrame *frame1;
+ GbEditorFrame *frame2;
+ GtkPaned *paned;
+ GtkProgressBar *progress_bar;
+ GtkMenuButton *tweak_button;
+ GbEditorTweakWidget *tweak_widget;
+};
G_END_DECLS
-#endif /* C_PARSE_HELPER_H */
+#endif /* GB_EDITOR_VIEW_PRIVATE_H */
diff --git a/src/editor/gb-editor-view.c b/src/editor/gb-editor-view.c
index 7576d44..99358a3 100644
--- a/src/editor/gb-editor-view.c
+++ b/src/editor/gb-editor-view.c
@@ -1,6 +1,6 @@
/* gb-editor-view.c
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,951 +16,113 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "editor-view"
-
#include <glib/gi18n.h>
-#include "gb-animation.h"
-#include "gb-editor-frame.h"
#include "gb-editor-frame-private.h"
-#include "gb-editor-tweak-widget.h"
#include "gb-editor-view.h"
-#include "gb-glib.h"
-#include "gb-html-document.h"
-#include "gb-log.h"
-#include "gb-string.h"
+#include "gb-editor-view-actions.h"
+#include "gb-editor-view-private.h"
#include "gb-widget.h"
-struct _GbEditorViewPrivate
-{
- /* References owned by view */
- GbEditorDocument *document;
-
- /* Weak references */
- GbAnimation *progress_anim;
-
- /* References owned by GtkWidget template */
- GtkPaned *paned;
- GtkToggleButton *split_button;
- GbEditorFrame *frame;
- GtkProgressBar *progress_bar;
- GtkLabel *error_label;
- GtkButton *error_close_button;
- GtkRevealer *error_revealer;
- GtkLabel *modified_label;
- GtkButton *modified_reload_button;
- GtkButton *modified_cancel_button;
- GtkRevealer *modified_revealer;
- GtkMenuButton *tweak_button;
- GtkMenuButton *tweak_widget;
-
- guint8 tab_width;
- guint auto_indent : 1;
- guint highlight_current_line : 1;
- guint show_line_numbers : 1;
- guint show_right_margin : 1;
- guint use_spaces : 1;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (GbEditorView, gb_editor_view, GB_TYPE_DOCUMENT_VIEW)
+G_DEFINE_TYPE (GbEditorView, gb_editor_view, GB_TYPE_VIEW)
enum {
PROP_0,
- PROP_AUTO_INDENT,
PROP_DOCUMENT,
- PROP_HIGHLIGHT_CURRENT_LINE,
- PROP_SHOW_LINE_NUMBERS,
- PROP_SHOW_RIGHT_MARGIN,
- PROP_SPLIT_ENABLED,
- PROP_TAB_WIDTH,
- PROP_USE_SPACES,
LAST_PROP
};
static GParamSpec *gParamSpecs [LAST_PROP];
-static void gb_editor_view_toggle_split (GbEditorView *view);
-
-GtkWidget *
-gb_editor_view_new (GbEditorDocument *document)
-{
- return g_object_new (GB_TYPE_EDITOR_VIEW,
- "document", document,
- NULL);
-}
-
-static void
-gb_editor_view_action_set_state (GbEditorView *view,
- const gchar *action_name,
- GVariant *state)
-{
- GActionGroup *group;
- GAction *action;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
- g_return_if_fail (action_name);
- g_return_if_fail (state);
-
- group = gtk_widget_get_action_group (GTK_WIDGET (view), "editor-view");
- action = g_action_map_lookup_action (G_ACTION_MAP (group), action_name);
- g_simple_action_set_state (G_SIMPLE_ACTION (action), state);
-}
-
-static void
-apply_state_language (GSimpleAction *action,
- GVariant *param,
- gpointer user_data)
-{
- GbEditorView *view = user_data;
- GtkSourceLanguage *l = NULL;
- const gchar *lang_id;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- lang_id = g_variant_get_string (param, NULL);
-
- if (!gb_str_empty0 (lang_id))
- {
- GtkSourceLanguageManager *m;
-
- m = gtk_source_language_manager_get_default ();
- l = gtk_source_language_manager_get_language (m, lang_id);
- }
-
- gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (view->priv->document), l);
-}
-
-gboolean
-gb_editor_view_get_auto_indent (GbEditorView *view)
-{
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), FALSE);
-
- return view->priv->auto_indent;
-}
-
-void
-gb_editor_view_set_auto_indent (GbEditorView *view,
- gboolean auto_indent)
-{
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- view->priv->auto_indent = !!auto_indent;
- gb_editor_view_action_set_state (view, "auto-indent",
- g_variant_new_boolean (auto_indent));
- g_object_notify_by_pspec (G_OBJECT (view), gParamSpecs [PROP_AUTO_INDENT]);
-}
-
-gboolean
-gb_editor_view_get_highlight_current_line (GbEditorView *view)
-{
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), FALSE);
-
- return view->priv->highlight_current_line;
-}
-
-void
-gb_editor_view_set_highlight_current_line (GbEditorView *view,
- gboolean highlight_current_line)
-{
- GVariant *variant;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- view->priv->highlight_current_line = !!highlight_current_line;
- variant = g_variant_new_boolean (highlight_current_line);
- gb_editor_view_action_set_state (view, "highlight-current-line", variant);
- g_object_notify_by_pspec (G_OBJECT (view),
- gParamSpecs [PROP_HIGHLIGHT_CURRENT_LINE]);
-}
-
-gboolean
-gb_editor_view_get_show_right_margin (GbEditorView *view)
-{
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), FALSE);
-
- return view->priv->show_right_margin;
-}
-
-void
-gb_editor_view_set_show_right_margin (GbEditorView *view,
- gboolean show_right_margin)
-{
- GVariant *variant;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- view->priv->show_right_margin = !!show_right_margin;
- variant = g_variant_new_boolean (show_right_margin);
- gb_editor_view_action_set_state (view, "show-right-margin", variant);
- g_object_notify_by_pspec (G_OBJECT (view),
- gParamSpecs [PROP_SHOW_RIGHT_MARGIN]);
-}
-
-gboolean
-gb_editor_view_get_show_line_numbers (GbEditorView *view)
-{
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), FALSE);
-
- return view->priv->show_line_numbers;
-}
-
-void
-gb_editor_view_set_show_line_numbers (GbEditorView *view,
- gboolean show_line_numbers)
-{
- GVariant *variant;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- view->priv->show_line_numbers = !!show_line_numbers;
- variant = g_variant_new_boolean (show_line_numbers);
- gb_editor_view_action_set_state (view, "show-line-numbers", variant);
- g_object_notify_by_pspec (G_OBJECT (view),
- gParamSpecs [PROP_SHOW_LINE_NUMBERS]);
-}
-
-guint
-gb_editor_view_get_tab_width (GbEditorView *view)
-{
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), 0);
-
- return view->priv->tab_width;
-}
-
-void
-gb_editor_view_set_tab_width (GbEditorView *view,
- guint tab_width)
-{
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
- g_return_if_fail (tab_width >= 1);
- g_return_if_fail (tab_width <= 32);
-
- if (tab_width != view->priv->tab_width)
- {
- view->priv->tab_width = tab_width;
- gb_editor_view_action_set_state (view, "tab-width",
- g_variant_new_int32 (tab_width));
- g_object_notify_by_pspec (G_OBJECT (view),
- gParamSpecs [PROP_TAB_WIDTH]);
- }
-}
-
-gboolean
-gb_editor_view_get_use_spaces (GbEditorView *view)
-{
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), FALSE);
-
- return view->priv->use_spaces;
-}
-
-void
-gb_editor_view_set_use_spaces (GbEditorView *view,
- gboolean use_spaces)
-{
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- view->priv->use_spaces = !!use_spaces;
- gb_editor_view_action_set_state (view, "use-spaces",
- g_variant_new_boolean (use_spaces));
- g_object_notify_by_pspec (G_OBJECT (view), gParamSpecs [PROP_USE_SPACES]);
-}
-
-static void
-gb_editor_view_notify_language (GbEditorView *view,
- GParamSpec *pspec,
- GbEditorDocument *document)
-{
- GtkSourceLanguage *language;
- const gchar *lang_id = "";
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- g_object_notify (G_OBJECT (view), "can-preview");
-
- language = gtk_source_buffer_get_language (GTK_SOURCE_BUFFER (document));
- if (language)
- lang_id = gtk_source_language_get_id (language);
-
- gb_editor_view_action_set_state (view, "language",
- g_variant_new_string (lang_id));
-}
-
-static void
-gb_editor_view_notify_progress (GbEditorView *view,
- GParamSpec *pspec,
- GbEditorDocument *document)
-{
- GbEditorViewPrivate *priv;
- gdouble progress;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- priv = view->priv;
-
- progress = gb_editor_document_get_progress (document);
-
- if (!gtk_widget_get_visible (GTK_WIDGET (priv->progress_bar)))
- {
- gtk_progress_bar_set_fraction (priv->progress_bar, 0.0);
- gtk_widget_set_opacity (GTK_WIDGET (priv->progress_bar), 1.0);
- gtk_widget_show (GTK_WIDGET (priv->progress_bar));
- }
-
- if (priv->progress_anim)
- gb_animation_stop (priv->progress_anim);
-
- gb_clear_weak_pointer (&priv->progress_anim);
-
- priv->progress_anim = gb_object_animate (priv->progress_bar,
- GB_ANIMATION_LINEAR,
- 250,
- NULL,
- "fraction", progress,
- NULL);
- gb_set_weak_pointer (priv->progress_anim, &priv->progress_anim);
-
- if (progress == 1.0)
- gb_widget_fade_hide (GTK_WIDGET (priv->progress_bar));
-}
-
-static gboolean
-gb_editor_view_get_can_preview (GbDocumentView *view)
-{
- GbEditorViewPrivate *priv;
- GtkSourceLanguage *language;
- GtkSourceBuffer *buffer;
- const gchar *lang_id;
-
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), FALSE);
-
- priv = GB_EDITOR_VIEW (view)->priv;
-
- buffer = GTK_SOURCE_BUFFER (priv->document);
- language = gtk_source_buffer_get_language (buffer);
- if (!language)
- return FALSE;
-
- lang_id = gtk_source_language_get_id (language);
- if (!lang_id)
- return FALSE;
-
- return (g_str_equal (lang_id, "html") ||
- g_str_equal (lang_id, "markdown"));
-}
-
-/**
- * gb_editor_view_create_preview:
- * @view: A #GbEditorView.
- *
- * Creates a new document that can be previewed by calling
- * gb_document_create_view() on the document.
- *
- * Returns: (transfer full): A #GbDocument.
- */
static GbDocument *
-gb_editor_view_create_preview (GbDocumentView *view)
+gb_editor_view_get_document (GbView *view)
{
GbEditorView *self = (GbEditorView *)view;
- GbDocument *document;
- GbHtmlDocumentTransform transform = NULL;
- GtkSourceBuffer *buffer;
- GtkSourceLanguage *language;
-
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (self), NULL);
- buffer = GTK_SOURCE_BUFFER (self->priv->document);
- language = gtk_source_buffer_get_language (buffer);
-
- if (language)
- {
- const gchar *lang_id;
+ g_assert (GB_IS_EDITOR_VIEW (self));
- lang_id = gtk_source_language_get_id (language);
-
- if (g_strcmp0 (lang_id, "markdown") == 0)
- transform = gb_html_markdown_transform;
- }
-
- document = g_object_new (GB_TYPE_HTML_DOCUMENT,
- "buffer", buffer,
- NULL);
-
- if (transform)
- gb_html_document_set_transform_func (GB_HTML_DOCUMENT (document),
- transform);
-
- return document;
-}
-
-GbEditorFrame *
-gb_editor_view_get_frame1 (GbEditorView *view)
-{
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), NULL);
-
- return view->priv->frame;
-}
-
-GbEditorFrame *
-gb_editor_view_get_frame2 (GbEditorView *view)
-{
- GtkWidget *child2;
-
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), NULL);
-
- child2 = gtk_paned_get_child2 (view->priv->paned);
- if (GB_IS_EDITOR_FRAME (child2))
- return GB_EDITOR_FRAME (child2);
-
- return NULL;
-}
-
-static void
-gb_editor_view_hide_revealer_child (GtkRevealer *revealer)
-{
- g_return_if_fail (GTK_IS_REVEALER (revealer));
-
- gtk_revealer_set_reveal_child (revealer, FALSE);
-}
-
-static void
-gb_editor_view_file_changed_on_volume (GbEditorView *view,
- GParamSpec *pspec,
- GbEditorDocument *document)
-{
- GtkSourceFile *source_file;
- GFile *location;
- gchar *path;
- gchar *str;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- source_file = gb_editor_document_get_file (document);
- location = gtk_source_file_get_location (source_file);
-
- if (!location)
- return;
-
- if (g_file_is_native (location))
- path = g_file_get_path (location);
- else
- path = g_file_get_uri (location);
-
- str = g_strdup_printf (_("The file “%s” was modified outside of Builder."),
- path);
-
- gtk_label_set_label (view->priv->modified_label, str);
- gtk_revealer_set_reveal_child (view->priv->modified_revealer, TRUE);
-
- g_free (path);
- g_free (str);
-}
-
-static void
-gb_editor_view_reload_document (GbEditorView *view,
- GtkButton *button)
-{
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- gb_editor_document_reload (view->priv->document);
- gtk_revealer_set_reveal_child (view->priv->modified_revealer, FALSE);
-}
-
-static void
-gb_editor_view_notify_error (GbEditorView *view,
- GParamSpec *pspec,
- GbEditorDocument *document)
-{
- const GError *error;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
- g_return_if_fail (pspec);
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- error = gb_editor_document_get_error (document);
-
- /* Ignore file not found errors */
- if (error &&
- (error->domain == G_IO_ERROR) &&
- (error->code == G_IO_ERROR_NOT_FOUND))
- error = NULL;
-
- if (!error)
- {
- if (gtk_revealer_get_reveal_child (view->priv->error_revealer))
- gtk_revealer_set_reveal_child (view->priv->error_revealer, FALSE);
- }
- else
- {
- gtk_label_set_label (view->priv->error_label, error->message);
- gtk_revealer_set_reveal_child (view->priv->error_revealer, TRUE);
- }
+ return GB_DOCUMENT (self->document);
}
static gboolean
-transform_language_to_string (GBinding *binding,
- const GValue *from_value,
- GValue *to_value,
- gpointer user_data)
+language_to_string (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
{
GtkSourceLanguage *language;
- const gchar *str = _("Plain Text");
language = g_value_get_object (from_value);
- if (language)
- str = gtk_source_language_get_name (language);
- g_value_set_string (to_value, str);
-
+ if (language != NULL)
+ g_value_set_string (to_value, gtk_source_language_get_name (language));
return TRUE;
}
static void
-gb_editor_view_connect (GbEditorView *view,
- GbEditorDocument *document)
-{
- GtkWidget *child2;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- gb_editor_frame_set_document (view->priv->frame, document);
-
- child2 = gtk_paned_get_child2 (view->priv->paned);
- if (GB_IS_EDITOR_FRAME (child2))
- gb_editor_frame_set_document (GB_EDITOR_FRAME (child2), document);
-
- g_signal_connect_object (document,
- "notify::language",
- G_CALLBACK (gb_editor_view_notify_language),
- view,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (document,
- "notify::progress",
- G_CALLBACK (gb_editor_view_notify_progress),
- view,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (view->priv->modified_cancel_button,
- "clicked",
- G_CALLBACK (gb_editor_view_hide_revealer_child),
- view->priv->modified_revealer,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (view->priv->modified_reload_button,
- "clicked",
- G_CALLBACK (gb_editor_view_reload_document),
- view,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (document,
- "notify::error",
- G_CALLBACK (gb_editor_view_notify_error),
- view,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (view->priv->error_close_button,
- "clicked",
- G_CALLBACK (gb_editor_view_hide_revealer_child),
- view->priv->error_revealer,
- G_CONNECT_SWAPPED);
-
- g_signal_connect_object (document,
- "notify::file-changed-on-volume",
- G_CALLBACK (gb_editor_view_file_changed_on_volume),
- view,
- G_CONNECT_SWAPPED);
-
- g_object_bind_property_full (document, "language",
- view->priv->tweak_button, "label",
- G_BINDING_SYNC_CREATE,
- transform_language_to_string,
- NULL, NULL, NULL);
-}
-
-static void
-gb_editor_view_disconnect (GbEditorView *view,
- GbEditorDocument *document)
-{
- GtkWidget *child2;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
- g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
-
- gb_editor_frame_set_document (view->priv->frame, NULL);
-
- child2 = gtk_paned_get_child2 (view->priv->paned);
- if (GB_IS_EDITOR_FRAME (child2))
- gb_editor_frame_set_document (GB_EDITOR_FRAME (child2), document);
-
- g_signal_handlers_disconnect_by_func (document,
- G_CALLBACK (gb_editor_view_notify_language),
- view);
- g_signal_handlers_disconnect_by_func (document,
- G_CALLBACK (gb_editor_view_notify_progress),
- view);
-}
-
-static GbDocument *
-gb_editor_view_get_document (GbDocumentView *view)
-{
- GbEditorViewPrivate *priv;
-
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), NULL);
-
- priv = GB_EDITOR_VIEW (view)->priv;
-
- return GB_DOCUMENT (priv->document);
-}
-
-static void
-gb_editor_view_set_document (GbEditorView *view,
+gb_editor_view_set_document (GbEditorView *self,
GbEditorDocument *document)
{
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
+ g_return_if_fail (GB_IS_EDITOR_VIEW (self));
g_return_if_fail (GB_IS_EDITOR_DOCUMENT (document));
- if (document != view->priv->document)
- {
- if (view->priv->document)
- {
- gb_editor_view_disconnect (view, document);
- g_clear_object (&view->priv->document);
- }
-
- if (document)
- {
- view->priv->document = g_object_ref (document);
- gb_editor_view_connect (view, document);
- }
-
- g_object_notify_by_pspec (G_OBJECT (view), gParamSpecs [PROP_DOCUMENT]);
- }
-}
-
-static void
-gb_editor_view_switch_pane (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbEditorView *view = user_data;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- if (!gtk_widget_has_focus (GTK_WIDGET (view->priv->frame->priv->source_view)))
- gtk_widget_grab_focus (GTK_WIDGET (view->priv->frame));
- else
+ if (g_set_object (&self->document, document))
{
- GtkWidget *child2;
+ if (self->frame1)
+ gb_editor_frame_set_document (self->frame1, document);
- child2 = gtk_paned_get_child2 (view->priv->paned);
- if (child2)
- gtk_widget_grab_focus (child2);
- }
+ if (self->frame2)
+ gb_editor_frame_set_document (self->frame2, document);
- EXIT;
-}
+ g_settings_bind (self->settings, "style-scheme-name",
+ document, "style-scheme-name",
+ G_SETTINGS_BIND_GET);
+ g_settings_bind (self->settings, "highlight-matching-brackets",
+ document, "highlight-matching-brackets",
+ G_SETTINGS_BIND_GET);
-static gboolean
-gb_editor_view_on_execute_command (GbEditorView *self,
- const gchar *command_text,
- GbSourceVim *vim)
-{
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (self), FALSE);
- g_return_val_if_fail (command_text, FALSE);
- g_return_val_if_fail (GB_IS_SOURCE_VIM (vim), FALSE);
+ g_object_bind_property_full (document, "language", self->tweak_button,
+ "label", G_BINDING_SYNC_CREATE,
+ language_to_string, NULL, NULL, NULL);
- if (g_str_equal (command_text, "w"))
- {
- gb_widget_activate_action (GTK_WIDGET (self), "stack", "save", NULL);
- return TRUE;
- }
- else if (g_str_equal (command_text, "wq"))
- {
- gb_widget_activate_action (GTK_WIDGET (self), "stack", "save", NULL);
- gb_widget_activate_action (GTK_WIDGET (self), "stack", "close", NULL);
- return TRUE;
- }
- else if (g_str_equal (command_text, "q"))
- {
- if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (self->priv->document)))
- {
- /* TODO: Plumb warning message */
- }
- else
- gb_widget_activate_action (GTK_WIDGET (self), "stack", "close", NULL);
- return TRUE;
- }
- else if (g_str_equal (command_text, "q!"))
- {
- /* TODO: don't prompt about saving */
- gb_widget_activate_action (GTK_WIDGET (self), "stack", "close", NULL);
- return TRUE;
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_DOCUMENT]);
}
-
- return FALSE;
}
-static gboolean
-gb_editor_view_on_vim_split (GbEditorView *self,
- GbSourceVimSplit split,
- GbSourceVim *vim)
+static GbView *
+gb_editor_view_create_split (GbView *view)
{
- GtkWidget *toplevel;
- GtkWidget *focus = NULL;
- gboolean ret = FALSE;
-
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (self), FALSE);
- g_return_val_if_fail (split, FALSE);
- g_return_val_if_fail (GB_IS_SOURCE_VIM (vim), FALSE);
-
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
-
- switch (split)
- {
- case GB_SOURCE_VIM_SPLIT_HORIZONTAL:
- focus = gtk_window_get_focus (GTK_WINDOW (toplevel));
- if (!gb_editor_view_get_split_enabled (self))
- {
- gb_editor_view_toggle_split (self);
- ret = TRUE;
- }
- break;
-
- case GB_SOURCE_VIM_SPLIT_VERTICAL:
- focus = gtk_window_get_focus (GTK_WINDOW (toplevel));
- gb_widget_activate_action (GTK_WIDGET (self),
- "stack", "split-document-right",
- NULL);
- ret = TRUE;
- break;
-
- case GB_SOURCE_VIM_SPLIT_CYCLE_NEXT:
- if (gb_editor_view_get_split_enabled (self) &&
- gtk_widget_has_focus (GTK_WIDGET (self->priv->frame->priv->source_view)))
- gb_editor_view_switch_pane (NULL, NULL, self);
- else
- gb_widget_activate_action (GTK_WIDGET (self), "stack", "focus-right",
- NULL);
- break;
-
- case GB_SOURCE_VIM_SPLIT_CYCLE_PREVIOUS:
- {
- GbEditorFrame *frame2;
-
- frame2 = gb_editor_view_get_frame2 (self);
-
- if (frame2 &&
- gtk_widget_has_focus (GTK_WIDGET (frame2->priv->source_view)))
- gb_editor_view_switch_pane (NULL, NULL, self);
- else
- gb_widget_activate_action (GTK_WIDGET (self), "stack", "focus-left",
- NULL);
- }
- break;
-
- case GB_SOURCE_VIM_SPLIT_CLOSE:
- if (gb_editor_view_get_split_enabled (self))
- {
- /*
- * TODO: copy state from frame2 to frame1 if frame2 was focused.
- */
- gb_editor_view_toggle_split (self);
- ret = TRUE;
- }
- else
- {
- gb_widget_activate_action (GTK_WIDGET (self), "stack", "close", NULL);
- ret = TRUE;
- }
- break;
+ GbEditorView *self = (GbEditorView *)view;
+ GbView *ret;
- default:
- break;
- }
+ g_assert (GB_IS_EDITOR_VIEW (self));
- if (focus)
- gtk_widget_grab_focus (focus);
+ ret = g_object_new (GB_TYPE_EDITOR_VIEW,
+ "document", self->document,
+ "visible", TRUE,
+ NULL);
return ret;
}
-static GbEditorFrame *
-gb_editor_view_create_frame (GbEditorView *view)
-{
- GbSourceVim *vim;
- GtkWidget *frame;
-
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), NULL);
-
- frame = g_object_new (GB_TYPE_EDITOR_FRAME,
- "document", view->priv->document,
- "visible", TRUE,
- NULL);
- vim = gb_source_view_get_vim (GB_EDITOR_FRAME (frame)->priv->source_view);
- g_signal_connect_object (vim,
- "execute-command",
- G_CALLBACK (gb_editor_view_on_execute_command),
- view,
- G_CONNECT_SWAPPED);
- g_signal_connect_object (vim,
- "split",
- G_CALLBACK (gb_editor_view_on_vim_split),
- view,
- G_CONNECT_SWAPPED);
-
- g_object_bind_property (GB_EDITOR_FRAME (frame), "search-direction",
- vim, "search-direction", G_BINDING_SYNC_CREATE);
- g_object_bind_property (GB_EDITOR_FRAME (frame)->priv->search_settings,
- "search-text", vim, "search-text",
- G_BINDING_SYNC_CREATE);
- g_object_bind_property (view, "auto-indent",
- GB_EDITOR_FRAME (frame)->priv->source_view,
- "auto-indent",
- G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
- g_object_bind_property (view, "highlight-current-line",
- GB_EDITOR_FRAME (frame)->priv->source_view,
- "highlight-current-line",
- G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
- g_object_bind_property (view, "show-line-numbers",
- GB_EDITOR_FRAME (frame)->priv->source_view,
- "show-line-numbers",
- G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
- g_object_bind_property (view, "show-right-margin",
- GB_EDITOR_FRAME (frame)->priv->source_view,
- "show-right-margin",
- G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
- g_object_bind_property (view, "tab-width",
- GB_EDITOR_FRAME (frame)->priv->source_view,
- "tab-width",
- G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
- g_object_bind_property (view, "use-spaces",
- GB_EDITOR_FRAME (frame)->priv->source_view,
- "insert-spaces-instead-of-tabs",
- G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
-
- return GB_EDITOR_FRAME (frame);
-}
-
-static void
-gb_editor_view_toggle_split (GbEditorView *view)
-{
- GbEditorViewPrivate *priv;
- GtkWidget *child2;
- gboolean active;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- priv = view->priv;
-
- if ((child2 = gtk_paned_get_child2 (priv->paned)))
- {
- gtk_widget_destroy (child2);
- gtk_widget_grab_focus (GTK_WIDGET (priv->frame));
- active = FALSE;
- }
- else
- {
- GbEditorFrame *frame;
-
- frame = gb_editor_view_create_frame (view);
- gtk_container_add_with_properties (GTK_CONTAINER (view->priv->paned),
- GTK_WIDGET (frame),
- "shrink", TRUE,
- "resize", TRUE,
- NULL);
- gtk_widget_grab_focus (GTK_WIDGET (frame));
- active = TRUE;
- }
-
- gb_editor_view_action_set_state (view, "toggle-split",
- g_variant_new_boolean (active));
-
- EXIT;
-}
-
-gboolean
-gb_editor_view_get_split_enabled (GbEditorView *view)
-{
- g_return_val_if_fail (GB_IS_EDITOR_VIEW (view), FALSE);
-
- return !!gb_editor_view_get_frame2 (view);
-}
-
-void
-gb_editor_view_set_split_enabled (GbEditorView *view,
- gboolean split_enabled)
-{
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
-
- if (split_enabled == gb_editor_view_get_split_enabled (view))
- return;
-
- gb_editor_view_toggle_split (view);
- g_object_notify_by_pspec (G_OBJECT (view),
- gParamSpecs [PROP_SPLIT_ENABLED]);
-}
-
static void
gb_editor_view_grab_focus (GtkWidget *widget)
{
- GbEditorView *view = (GbEditorView *)widget;
-
- ENTRY;
+ GbEditorView *self = (GbEditorView *)widget;
- g_return_if_fail (GB_IS_EDITOR_VIEW (view));
+ g_assert (GB_IS_EDITOR_VIEW (self));
- gtk_widget_grab_focus (GTK_WIDGET (view->priv->frame));
+ /* todo: track last focus frame */
- EXIT;
+ gtk_widget_grab_focus (GTK_WIDGET (self->frame1->source_view));
}
-#define STATE_HANDLER_BOOLEAN(name) \
- static void \
- apply_state_##name (GSimpleAction *action, \
- GVariant *param, \
- gpointer user_data) \
- { \
- GbEditorView *view = user_data; \
- gboolean value; \
- g_return_if_fail (GB_IS_EDITOR_VIEW (view)); \
- value = g_variant_get_boolean (param); \
- gb_editor_view_set_##name (view, value); \
- }
-
-#define STATE_HANDLER_INT(name) \
- static void \
- apply_state_##name (GSimpleAction *action, \
- GVariant *param, \
- gpointer user_data) \
- { \
- GbEditorView *view = user_data; \
- guint value; \
- g_return_if_fail (GB_IS_EDITOR_VIEW (view)); \
- value = g_variant_get_int32 (param); \
- gb_editor_view_set_##name (view, value); \
- }
-
-STATE_HANDLER_BOOLEAN (auto_indent)
-STATE_HANDLER_BOOLEAN (highlight_current_line)
-STATE_HANDLER_BOOLEAN (show_line_numbers)
-STATE_HANDLER_BOOLEAN (show_right_margin)
-STATE_HANDLER_BOOLEAN (split_enabled)
-STATE_HANDLER_INT (tab_width)
-STATE_HANDLER_BOOLEAN (use_spaces)
-
static void
gb_editor_view_finalize (GObject *object)
{
- GbEditorView *view = (GbEditorView *)object;
+ GbEditorView *self = (GbEditorView *)object;
- g_clear_object (&view->priv->document);
+ g_clear_object (&self->document);
+ g_clear_object (&self->settings);
G_OBJECT_CLASS (gb_editor_view_parent_class)->finalize (object);
}
@@ -975,37 +137,8 @@ gb_editor_view_get_property (GObject *object,
switch (prop_id)
{
- case PROP_AUTO_INDENT:
- g_value_set_boolean (value, gb_editor_view_get_auto_indent (self));
- break;
-
case PROP_DOCUMENT:
- g_value_set_object (value, self->priv->document);
- break;
-
- case PROP_HIGHLIGHT_CURRENT_LINE:
- g_value_set_boolean (value,
- gb_editor_view_get_highlight_current_line (self));
- break;
-
- case PROP_SHOW_LINE_NUMBERS:
- g_value_set_boolean (value, gb_editor_view_get_show_line_numbers (self));
- break;
-
- case PROP_SHOW_RIGHT_MARGIN:
- g_value_set_boolean (value, gb_editor_view_get_show_right_margin (self));
- break;
-
- case PROP_SPLIT_ENABLED:
- g_value_set_boolean (value, gb_editor_view_get_split_enabled (self));
- break;
-
- case PROP_TAB_WIDTH:
- g_value_set_uint (value, gb_editor_view_get_tab_width (self));
- break;
-
- case PROP_USE_SPACES:
- g_value_set_boolean (value, gb_editor_view_get_use_spaces (self));
+ g_value_set_object (value, gb_editor_view_get_document (GB_VIEW (self)));
break;
default:
@@ -1023,38 +156,10 @@ gb_editor_view_set_property (GObject *object,
switch (prop_id)
{
- case PROP_AUTO_INDENT:
- gb_editor_view_set_auto_indent (self, g_value_get_boolean (value));
- break;
-
case PROP_DOCUMENT:
gb_editor_view_set_document (self, g_value_get_object (value));
break;
- case PROP_HIGHLIGHT_CURRENT_LINE:
- gb_editor_view_set_highlight_current_line (self, g_value_get_boolean (value));
- break;
-
- case PROP_SHOW_LINE_NUMBERS:
- gb_editor_view_set_show_line_numbers (self, g_value_get_boolean (value));
- break;
-
- case PROP_SHOW_RIGHT_MARGIN:
- gb_editor_view_set_show_right_margin (self, g_value_get_boolean (value));
- break;
-
- case PROP_SPLIT_ENABLED:
- gb_editor_view_set_split_enabled (self, g_value_get_boolean (value));
- break;
-
- case PROP_TAB_WIDTH:
- gb_editor_view_set_tab_width (self, g_value_get_uint (value));
- break;
-
- case PROP_USE_SPACES:
- gb_editor_view_set_use_spaces (self, g_value_get_boolean (value));
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -1065,7 +170,7 @@ gb_editor_view_class_init (GbEditorViewClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GbDocumentViewClass *view_class = GB_DOCUMENT_VIEW_CLASS (klass);
+ GbViewClass *view_class = GB_VIEW_CLASS (klass);
object_class->finalize = gb_editor_view_finalize;
object_class->get_property = gb_editor_view_get_property;
@@ -1073,97 +178,24 @@ gb_editor_view_class_init (GbEditorViewClass *klass)
widget_class->grab_focus = gb_editor_view_grab_focus;
+ view_class->create_split = gb_editor_view_create_split;
view_class->get_document = gb_editor_view_get_document;
- view_class->get_can_preview = gb_editor_view_get_can_preview;
- view_class->create_preview = gb_editor_view_create_preview;
-
- gParamSpecs [PROP_AUTO_INDENT] =
- g_param_spec_boolean ("auto-indent",
- _("Auto Indent"),
- _("If we should use the auto-indentation engine."),
- FALSE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_AUTO_INDENT,
- gParamSpecs [PROP_AUTO_INDENT]);
gParamSpecs [PROP_DOCUMENT] =
g_param_spec_object ("document",
_("Document"),
- _("The document edited by the view."),
- GB_TYPE_DOCUMENT,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_DOCUMENT,
- gParamSpecs [PROP_DOCUMENT]);
-
- gParamSpecs [PROP_HIGHLIGHT_CURRENT_LINE] =
- g_param_spec_boolean ("highlight-current-line",
- _("Highlight Current Line"),
- _("If the current line should be highlighted."),
- FALSE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_HIGHLIGHT_CURRENT_LINE,
- gParamSpecs [PROP_HIGHLIGHT_CURRENT_LINE]);
-
- gParamSpecs [PROP_SHOW_LINE_NUMBERS] =
- g_param_spec_boolean ("show-line-numbers",
- _("Show Line Numbers"),
- _("If the line numbers should be shown."),
- FALSE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_SHOW_LINE_NUMBERS,
- gParamSpecs [PROP_SHOW_LINE_NUMBERS]);
-
- gParamSpecs [PROP_SHOW_RIGHT_MARGIN] =
- g_param_spec_boolean ("show-right-margin",
- _("Show Right Margin"),
- _("If we should show the right margin."),
- FALSE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_SHOW_RIGHT_MARGIN,
- gParamSpecs [PROP_SHOW_RIGHT_MARGIN]);
-
- gParamSpecs [PROP_SPLIT_ENABLED] =
- g_param_spec_boolean ("split-enabled",
- _("Split Enabled"),
- _("If the view split is enabled."),
- FALSE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_SPLIT_ENABLED,
- gParamSpecs [PROP_SPLIT_ENABLED]);
-
- gParamSpecs [PROP_TAB_WIDTH] =
- g_param_spec_uint ("tab-width",
- _("Tab Width"),
- _("The width a tab should be drawn as."),
- 1,
- 32,
- 8,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_TAB_WIDTH,
- gParamSpecs [PROP_TAB_WIDTH]);
-
- gParamSpecs [PROP_USE_SPACES] =
- g_param_spec_boolean ("use-spaces",
- _("Use Spaces"),
- _("If spaces should be used instead of tabs."),
- FALSE,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_USE_SPACES,
- gParamSpecs [PROP_USE_SPACES]);
+ _("The editor document."),
+ GB_TYPE_EDITOR_DOCUMENT,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_DOCUMENT, gParamSpecs [PROP_DOCUMENT]);
GB_WIDGET_CLASS_TEMPLATE (klass, "gb-editor-view.ui");
+
+ GB_WIDGET_CLASS_BIND (klass, GbEditorView, frame1);
GB_WIDGET_CLASS_BIND (klass, GbEditorView, paned);
GB_WIDGET_CLASS_BIND (klass, GbEditorView, progress_bar);
- GB_WIDGET_CLASS_BIND (klass, GbEditorView, split_button);
GB_WIDGET_CLASS_BIND (klass, GbEditorView, tweak_button);
GB_WIDGET_CLASS_BIND (klass, GbEditorView, tweak_widget);
- GB_WIDGET_CLASS_BIND (klass, GbEditorView, modified_revealer);
- GB_WIDGET_CLASS_BIND (klass, GbEditorView, modified_label);
- GB_WIDGET_CLASS_BIND (klass, GbEditorView, modified_cancel_button);
- GB_WIDGET_CLASS_BIND (klass, GbEditorView, modified_reload_button);
- GB_WIDGET_CLASS_BIND (klass, GbEditorView, error_label);
- GB_WIDGET_CLASS_BIND (klass, GbEditorView, error_revealer);
- GB_WIDGET_CLASS_BIND (klass, GbEditorView, error_close_button);
g_type_ensure (GB_TYPE_EDITOR_FRAME);
g_type_ensure (GB_TYPE_EDITOR_TWEAK_WIDGET);
@@ -1172,47 +204,9 @@ gb_editor_view_class_init (GbEditorViewClass *klass)
static void
gb_editor_view_init (GbEditorView *self)
{
- const GActionEntry entries[] = {
- { "auto-indent", NULL, NULL, "false", apply_state_auto_indent },
- { "highlight-current-line", NULL, NULL, "false",
- apply_state_highlight_current_line },
- { "language", NULL, "s", "''", apply_state_language },
- { "show-line-numbers", NULL, NULL, "false", apply_state_show_line_numbers },
- { "show-right-margin", NULL, NULL, "false", apply_state_show_right_margin },
- { "switch-pane", gb_editor_view_switch_pane },
- { "tab-width", NULL, "i", "8", apply_state_tab_width },
- { "toggle-split", NULL, NULL, "false", apply_state_split_enabled },
- { "use-spaces", NULL, "b", "false", apply_state_use_spaces },
- };
- GSimpleActionGroup *actions;
- GtkWidget *controls;
-
- self->priv = gb_editor_view_get_instance_private (self);
-
gtk_widget_init_template (GTK_WIDGET (self));
- actions = g_simple_action_group_new ();
-
- /*
- * Unfortunately, we need to manually attach the action group in
- * a few places due to the complexity of how they are handled.
- */
- g_action_map_add_action_entries (G_ACTION_MAP (actions), entries,
- G_N_ELEMENTS (entries), self);
- gtk_widget_insert_action_group (GTK_WIDGET (self), "editor-view",
- G_ACTION_GROUP (actions));
- controls = gb_document_view_get_controls (GB_DOCUMENT_VIEW (self));
- gtk_widget_insert_action_group (GTK_WIDGET (controls), "editor-view",
- G_ACTION_GROUP (actions));
- gtk_widget_insert_action_group (GTK_WIDGET (self->priv->tweak_widget),
- "editor-view", G_ACTION_GROUP (actions));
-
- g_clear_object (&actions);
+ self->settings = g_settings_new ("org.gnome.builder.editor");
- self->priv->frame = gb_editor_view_create_frame (self);
- gtk_container_add_with_properties (GTK_CONTAINER (self->priv->paned),
- GTK_WIDGET (self->priv->frame),
- "shrink", TRUE,
- "resize", TRUE,
- NULL);
+ gb_editor_view_actions_init (self);
}
diff --git a/src/editor/gb-editor-view.h b/src/editor/gb-editor-view.h
index 6d4b90f..e189414 100644
--- a/src/editor/gb-editor-view.h
+++ b/src/editor/gb-editor-view.h
@@ -1,6 +1,6 @@
/* gb-editor-view.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -19,52 +19,13 @@
#ifndef GB_EDITOR_VIEW_H
#define GB_EDITOR_VIEW_H
-#include <gtk/gtk.h>
-
-#include "gb-document-view.h"
-#include "gb-editor-document.h"
-#include "gb-editor-frame.h"
+#include "gb-view.h"
G_BEGIN_DECLS
-#define GB_TYPE_EDITOR_VIEW (gb_editor_view_get_type())
-#define GB_EDITOR_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_EDITOR_VIEW,
GbEditorView))
-#define GB_EDITOR_VIEW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_EDITOR_VIEW, GbEditorView
const))
-#define GB_EDITOR_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_EDITOR_VIEW,
GbEditorViewClass))
-#define GB_IS_EDITOR_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_EDITOR_VIEW))
-#define GB_IS_EDITOR_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_EDITOR_VIEW))
-#define GB_EDITOR_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_EDITOR_VIEW,
GbEditorViewClass))
-
-typedef struct _GbEditorView GbEditorView;
-typedef struct _GbEditorViewClass GbEditorViewClass;
-typedef struct _GbEditorViewPrivate GbEditorViewPrivate;
-
-struct _GbEditorView
-{
- GbDocumentView parent;
-
- /*< private >*/
- GbEditorViewPrivate *priv;
-};
-
-struct _GbEditorViewClass
-{
- GbDocumentViewClass parent;
-};
+#define GB_TYPE_EDITOR_VIEW (gb_editor_view_get_type())
-GType gb_editor_view_get_type (void);
-GtkWidget *gb_editor_view_new (GbEditorDocument *document);
-GbEditorFrame *gb_editor_view_get_frame1 (GbEditorView *view);
-GbEditorFrame *gb_editor_view_get_frame2 (GbEditorView *view);
-gboolean gb_editor_view_get_split_enabled (GbEditorView *view);
-void gb_editor_view_set_split_enabled (GbEditorView *view,
- gboolean split_enabled);
-gboolean gb_editor_view_get_use_spaces (GbEditorView *view);
-void gb_editor_view_set_use_spaces (GbEditorView *view,
- gboolean use_spaces);
-gboolean gb_editor_view_get_auto_indent (GbEditorView *view);
-void gb_editor_view_set_auto_indent (GbEditorView *view,
- gboolean auto_indent);
+G_DECLARE_FINAL_TYPE (GbEditorView, gb_editor_view, GB, EDITOR_VIEW, GbView)
G_END_DECLS
diff --git a/src/auto-indent/c-parse-helper.h b/src/editor/gb-editor-workspace-actions.c
similarity index 55%
copy from src/auto-indent/c-parse-helper.h
copy to src/editor/gb-editor-workspace-actions.c
index 418f518..82f688b 100644
--- a/src/auto-indent/c-parse-helper.h
+++ b/src/editor/gb-editor-workspace-actions.c
@@ -1,6 +1,6 @@
-/* c-parse-helper.h
+/* gb-editor-workspace-actions.c
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,26 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef C_PARSE_HELPER_H
-#define C_PARSE_HELPER_H
+#include "gb-editor-workspace-actions.h"
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-typedef struct
+void
+gb_editor_workspace_actions_init (GbEditorWorkspace *self)
{
- gchar *type;
- gchar *name;
- guint ellipsis : 1;
- guint n_star : 4;
-} Parameter;
-
-gboolean parameter_validate (Parameter *param);
-void parameter_free (Parameter *p);
-Parameter *parameter_copy (const Parameter *src);
-GSList *parse_parameters (const gchar *text);
-
-G_END_DECLS
-
-#endif /* C_PARSE_HELPER_H */
+}
diff --git a/src/auto-indent/c-parse-helper.h b/src/editor/gb-editor-workspace-actions.h
similarity index 57%
copy from src/auto-indent/c-parse-helper.h
copy to src/editor/gb-editor-workspace-actions.h
index 418f518..c8bde9e 100644
--- a/src/auto-indent/c-parse-helper.h
+++ b/src/editor/gb-editor-workspace-actions.h
@@ -1,6 +1,6 @@
-/* c-parse-helper.h
+/* gb-editor-workspace-actions.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,26 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef C_PARSE_HELPER_H
-#define C_PARSE_HELPER_H
+#ifndef GB_EDITOR_WORKSPACE_ACTIONS_H
+#define GB_EDITOR_WORKSPACE_ACTIONS_H
-#include <glib.h>
+#include "gb-editor-workspace.h"
G_BEGIN_DECLS
-typedef struct
-{
- gchar *type;
- gchar *name;
- guint ellipsis : 1;
- guint n_star : 4;
-} Parameter;
-
-gboolean parameter_validate (Parameter *param);
-void parameter_free (Parameter *p);
-Parameter *parameter_copy (const Parameter *src);
-GSList *parse_parameters (const gchar *text);
+void gb_editor_workspace_actions_init (GbEditorWorkspace *self);
G_END_DECLS
-#endif /* C_PARSE_HELPER_H */
+#endif /* GB_EDITOR_WORKSPACE_ACTIONS_H */
diff --git a/src/auto-indent/c-parse-helper.h b/src/editor/gb-editor-workspace-private.h
similarity index 57%
copy from src/auto-indent/c-parse-helper.h
copy to src/editor/gb-editor-workspace-private.h
index 418f518..093c5ff 100644
--- a/src/auto-indent/c-parse-helper.h
+++ b/src/editor/gb-editor-workspace-private.h
@@ -1,6 +1,6 @@
-/* c-parse-helper.h
+/* gb-editor-workspace-private.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,26 +16,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef C_PARSE_HELPER_H
-#define C_PARSE_HELPER_H
+#ifndef GB_EDITOR_WORKSPACE_PRIVATE_H
+#define GB_EDITOR_WORKSPACE_PRIVATE_H
-#include <glib.h>
+#include "gb-workspace.h"
+#include "gb-view-grid.h"
G_BEGIN_DECLS
-typedef struct
+struct _GbEditorWorkspace
{
- gchar *type;
- gchar *name;
- guint ellipsis : 1;
- guint n_star : 4;
-} Parameter;
+ GbWorkspace parent_instance;
-gboolean parameter_validate (Parameter *param);
-void parameter_free (Parameter *p);
-Parameter *parameter_copy (const Parameter *src);
-GSList *parse_parameters (const gchar *text);
+ GbViewGrid *view_grid;
+};
G_END_DECLS
-#endif /* C_PARSE_HELPER_H */
+#endif /* GB_EDITOR_WORKSPACE_PRIVATE_H */
diff --git a/src/editor/gb-editor-workspace.c b/src/editor/gb-editor-workspace.c
index fdaba25..0c82659 100644
--- a/src/editor/gb-editor-workspace.c
+++ b/src/editor/gb-editor-workspace.c
@@ -1,6 +1,6 @@
/* gb-editor-workspace.c
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,424 +16,101 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "editor-workspace"
+#define G_LOG_DOMAIN "gb-editor-workspace"
#include <glib/gi18n.h>
-#include <gtksourceview/gtksource.h>
+#include <ide.h>
-#include "gb-devhelp-document.h"
-#include "gb-devhelp-view.h"
-#include "gb-document-grid.h"
#include "gb-editor-document.h"
#include "gb-editor-workspace.h"
-#include "gb-log.h"
-#include "gb-project-tree-builder.h"
-#include "gb-tree.h"
+#include "gb-editor-workspace-actions.h"
+#include "gb-editor-workspace-private.h"
+#include "gb-view-grid.h"
#include "gb-widget.h"
-#include "gb-workbench.h"
-#include "gb-dnd.h"
-enum
-{
- TARGET_URI_LIST = 100
-};
-
-static const GtkTargetEntry drop_types [] = {
- { "text/uri-list", 0, TARGET_URI_LIST}
-};
-
-struct _GbEditorWorkspacePrivate
-{
- GHashTable *command_map;
- GtkPaned *paned;
- gchar *current_folder_uri;
-
- /* References not owned by this instance */
- GbDocumentGrid *document_grid;
- GbProjectTreeBuilder *project_tree_builder;
- GtkBox *sidebar;
- GbTree *tree;
- GtkSizeGroup *title_size_group;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (GbEditorWorkspace, gb_editor_workspace,
- GB_TYPE_WORKSPACE)
-
-void
-gb_editor_workspace_open (GbEditorWorkspace *workspace,
- GFile *file)
-{
- GbEditorWorkspacePrivate *priv;
- GbDocumentManager *manager;
- GbWorkbench *workbench;
- GbDocument *document;
-
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
-
- priv = workspace->priv;
-
- workbench = gb_widget_get_workbench (GTK_WIDGET (workspace));
- manager = gb_workbench_get_document_manager (workbench);
- document = gb_document_manager_find_with_file (manager, file);
-
- if (!document)
- {
- gboolean close_untitled = FALSE;
- GList *list;
-
- /*
- * If we have a single document open, and it is an untitled document,
- * we want to close it so that it appears that this new document opens
- * in its place.
- */
- list = gb_document_manager_get_documents (manager);
- if ((g_list_length (list) == 1) &&
- gb_document_is_untitled (list->data) &&
- !gb_document_get_modified (list->data))
- close_untitled = TRUE;
- g_list_free (list);
-
- /*
- * Now open the new document.
- */
- document = GB_DOCUMENT (gb_editor_document_new ());
- gb_editor_document_load_async (GB_EDITOR_DOCUMENT (document),
- file, NULL, NULL, NULL);
- gb_document_manager_add (manager, document);
- gb_document_grid_focus_document (priv->document_grid, document);
- g_object_unref (document);
-
- /*
- * Now close the existing views if necessary.
- */
- if (close_untitled)
- gb_document_grid_close_untitled (priv->document_grid);
- }
- else
- gb_document_grid_focus_document (priv->document_grid, document);
-}
-
-static void
-gb_editor_workspace_open_uri_list (GbEditorWorkspace *workspace,
- const gchar **uri_list)
-{
- GFile *file;
- guint i;
-
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
- g_return_if_fail (uri_list);
-
- for (i = 0; uri_list [i]; i++)
- {
- file = g_file_new_for_commandline_arg (uri_list [i]);
-
- if (file)
- {
- gb_editor_workspace_open (workspace, file);
- g_clear_object (&file);
- }
- else
- g_warning ("Received invalid URI target");
- }
-}
+G_DEFINE_TYPE (GbEditorWorkspace, gb_editor_workspace, GB_TYPE_WORKSPACE)
static void
-gb_editor_workspace_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint timestamp,
- gpointer data)
+gb_editor_workspace__load_buffer_cb (GbEditorWorkspace *self,
+ IdeBuffer *buffer,
+ IdeBufferManager *buffer_manager)
{
- GbEditorWorkspace *workspace = (GbEditorWorkspace *)widget;
- gchar **uri_list;
- gboolean handled = FALSE;
+ IDE_ENTRY;
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
+ g_assert (GB_IS_EDITOR_WORKSPACE (self));
+ g_assert (IDE_IS_BUFFER (buffer));
+ g_assert (GB_IS_EDITOR_DOCUMENT (buffer));
+ g_assert (IDE_IS_BUFFER_MANAGER (buffer_manager));
- switch (info)
- {
- case TARGET_URI_LIST:
- uri_list = gb_dnd_get_uri_list (selection_data);
-
- if (uri_list)
- {
- gb_editor_workspace_open_uri_list (workspace,
- (const gchar **)uri_list);
- g_strfreev (uri_list);
- }
+ IDE_TRACE_MSG ("Loading %s.", ide_buffer_get_title (buffer));
- handled = TRUE;
- break;
+ gb_view_grid_focus_document (self->view_grid, GB_DOCUMENT (buffer));
- default:
- break;
- }
-
- gtk_drag_finish (context, handled, FALSE, timestamp);
+ IDE_EXIT;
}
static void
-gb_editor_workspace_action_jump_to_doc (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
+gb_editor_workspace_context_changed (GtkWidget *workspace,
+ IdeContext *context)
{
- GbEditorWorkspacePrivate *priv;
- GbEditorWorkspace *workspace = user_data;
- GbDocumentManager *manager;
- GbWorkbench *workbench;
- const gchar *search_text;
- GbDocument *document;
- GbDocument *reffed = NULL;
-
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
-
- priv = workspace->priv;
+ GbEditorWorkspace *self = (GbEditorWorkspace *)workspace;
- search_text = g_variant_get_string (parameter, NULL);
- if (!search_text || !*search_text)
- return;
+ g_assert (GB_IS_EDITOR_WORKSPACE (self));
+ g_assert (!context || IDE_IS_CONTEXT (context));
- workbench = gb_widget_get_workbench (GTK_WIDGET (workspace));
- manager = gb_workbench_get_document_manager (workbench);
- document = gb_document_manager_find_with_type (manager,
- GB_TYPE_DEVHELP_DOCUMENT);
-
- if (!document)
+ if (context)
{
- document = GB_DOCUMENT (gb_devhelp_document_new ());
- gb_document_manager_add (manager, document);
- reffed = document;
- }
+ IdeBufferManager *bufmgr;
+ g_autoptr(GPtrArray) buffers = NULL;
+ gsize i;
- gb_devhelp_document_set_search (GB_DEVHELP_DOCUMENT (document), search_text);
- gb_document_grid_focus_document (priv->document_grid, document);
-
- g_clear_object (&reffed);
-}
-
-static void
-gb_editor_workspace_action_open_uri_list (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbEditorWorkspace *workspace = user_data;
- const gchar **uri_list;
+ bufmgr = ide_context_get_buffer_manager (context);
+ g_signal_connect_object (bufmgr,
+ "load-buffer",
+ G_CALLBACK (gb_editor_workspace__load_buffer_cb),
+ self,
+ G_CONNECT_SWAPPED);
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
+ buffers = ide_buffer_manager_get_buffers (bufmgr);
- uri_list = g_variant_get_strv (parameter, NULL);
- if(uri_list != NULL)
- {
- gb_editor_workspace_open_uri_list (workspace, uri_list);
- g_free (uri_list);
- }
-}
-
-void
-gb_editor_workspace_new_document (GbEditorWorkspace *workspace)
-{
- GbDocumentManager *manager;
- GbWorkbench *workbench;
- GbDocument *document;
-
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
-
- workbench = gb_widget_get_workbench (GTK_WIDGET (workspace));
- manager = gb_workbench_get_document_manager (workbench);
- document = GB_DOCUMENT (gb_editor_document_new ());
-
- gb_document_manager_add (manager, document);
- gb_document_grid_focus_document (workspace->priv->document_grid, document);
-
- g_clear_object (&document);
-}
-
-static void
-gb_editor_workspace_action_new_document (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbEditorWorkspace *workspace = user_data;
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
- gb_editor_workspace_new_document (workspace);
-}
-
-static void
-gb_editor_workspace_action_toggle_sidebar (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbEditorWorkspace *workspace = user_data;
- GtkWidget *sidebar;
-
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
-
- sidebar = GTK_WIDGET (workspace->priv->sidebar);
- gtk_widget_set_visible (sidebar, !gtk_widget_get_visible (sidebar));
-}
-
-static void
-gb_editor_workspace_action_open (GSimpleAction *action,
- GVariant *parameter,
- gpointer user_data)
-{
- GbEditorWorkspace *workspace = user_data;
- GbEditorWorkspacePrivate *priv = workspace->priv;
- GtkFileChooserDialog *dialog;
- GtkWidget *toplevel;
- GtkWidget *suggested;
- GtkResponseType response;
-
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
-
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (workspace));
-
- dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
- "action", GTK_FILE_CHOOSER_ACTION_OPEN,
- "local-only", FALSE,
- "select-multiple", TRUE,
- "show-hidden", FALSE,
- "transient-for", toplevel,
- "title", _("Open Document"),
- NULL);
-
- if (priv->current_folder_uri)
- gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog),
- priv->current_folder_uri);
-
- gtk_dialog_add_buttons (GTK_DIALOG (dialog),
- _("Cancel"), GTK_RESPONSE_CANCEL,
- _("Open"), GTK_RESPONSE_OK,
- NULL);
-
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-
- suggested = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog),
- GTK_RESPONSE_OK);
- gtk_style_context_add_class (gtk_widget_get_style_context (suggested),
- GTK_STYLE_CLASS_SUGGESTED_ACTION);
-
- response = gtk_dialog_run (GTK_DIALOG (dialog));
-
- if (response == GTK_RESPONSE_OK)
- {
- GSList *files;
- GSList *iter;
- gchar *file_uri;
- gchar *uri;
-
- file_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
- uri = g_path_get_dirname (file_uri);
- if (g_strcmp0 (priv->current_folder_uri, uri) != 0)
- {
- g_free (priv->current_folder_uri);
- priv->current_folder_uri = uri;
- uri = NULL;
- }
- g_free (uri);
- g_free (file_uri);
-
- files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (dialog));
-
- for (iter = files; iter; iter = iter->next)
+ for (i = 0; i < buffers->len; i++)
{
- gb_editor_workspace_open (workspace, G_FILE (iter->data));
- g_clear_object (&iter->data);
+ IdeBuffer *buffer = g_ptr_array_index (buffers, i);
+ gb_editor_workspace__load_buffer_cb (self, buffer, bufmgr);
}
-
- g_slist_free (files);
}
-
- gtk_widget_destroy (GTK_WIDGET (dialog));
}
static void
gb_editor_workspace_grab_focus (GtkWidget *widget)
{
- GbEditorWorkspace *workspace = (GbEditorWorkspace *)widget;
+ GbEditorWorkspace *self = (GbEditorWorkspace *)widget;
- ENTRY;
+ g_assert (GB_IS_EDITOR_WORKSPACE (self));
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
-
- gtk_widget_grab_focus (GTK_WIDGET (workspace->priv->document_grid));
-
- EXIT;
-}
-
-static void
-gb_editor_workspace_context_set (GbEditorWorkspace *workspace,
- GParamSpec *pspec,
- GbWorkbench *workbench)
-{
- GbEditorWorkspacePrivate *priv;
- GbTreeNode *root;
- IdeContext *context;
-
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- priv = workspace->priv;
-
- context = gb_workbench_get_context (workbench);
-
- root = gb_tree_get_root (priv->tree);
- gb_tree_node_set_item (root, G_OBJECT (context));
-
- gb_project_tree_builder_set_context (priv->project_tree_builder, context);
-}
-
-static void
-gb_editor_workspace_map (GtkWidget *widget)
-{
- GbEditorWorkspacePrivate *priv;
- GbEditorWorkspace *workspace = (GbEditorWorkspace *)widget;
- GbDocumentManager *document_manager;
- GbWorkbench *workbench;
-
- g_return_if_fail (GB_IS_EDITOR_WORKSPACE (workspace));
-
- priv = workspace->priv;
-
- GTK_WIDGET_CLASS (gb_editor_workspace_parent_class)->map (widget);
-
- workbench = gb_widget_get_workbench (GTK_WIDGET (workspace));
- document_manager = gb_workbench_get_document_manager (workbench);
- gb_document_grid_set_document_manager (priv->document_grid, document_manager);
-
- g_signal_connect_object (workbench,
- "notify::context",
- G_CALLBACK (gb_editor_workspace_context_set),
- widget,
- G_CONNECT_SWAPPED);
-
- gb_editor_workspace_context_set (workspace, NULL, workbench);
+ gtk_widget_grab_focus (GTK_WIDGET (self->view_grid));
}
static void
gb_editor_workspace_constructed (GObject *object)
{
- GbEditorWorkspacePrivate *priv = GB_EDITOR_WORKSPACE (object)->priv;
+ GbEditorWorkspace *self = (GbEditorWorkspace *)object;
+
+ IDE_ENTRY;
G_OBJECT_CLASS (gb_editor_workspace_parent_class)->constructed (object);
- priv->project_tree_builder = gb_project_tree_builder_new (NULL);
- gb_tree_add_builder (priv->tree, GB_TREE_BUILDER (priv->project_tree_builder));
- gb_tree_set_root (priv->tree, gb_tree_node_new ());
+ gb_editor_workspace_actions_init (self);
+
+ IDE_EXIT;
}
static void
gb_editor_workspace_finalize (GObject *object)
{
- GbEditorWorkspacePrivate *priv = GB_EDITOR_WORKSPACE (object)->priv;
-
- g_clear_pointer (&priv->command_map, g_hash_table_unref);
- g_clear_pointer (&priv->current_folder_uri, g_free);
-
+ IDE_ENTRY;
G_OBJECT_CLASS (gb_editor_workspace_parent_class)->finalize (object);
+ IDE_EXIT;
}
static void
@@ -446,58 +123,17 @@ gb_editor_workspace_class_init (GbEditorWorkspaceClass *klass)
object_class->finalize = gb_editor_workspace_finalize;
widget_class->grab_focus = gb_editor_workspace_grab_focus;
- widget_class->map = gb_editor_workspace_map;
GB_WIDGET_CLASS_TEMPLATE (klass, "gb-editor-workspace.ui");
- GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, document_grid);
- GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, paned);
- GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, sidebar);
- GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, title_size_group);
- GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, tree);
+ GB_WIDGET_CLASS_BIND (klass, GbEditorWorkspace, view_grid);
- g_type_ensure (GB_TYPE_DOCUMENT_GRID);
- g_type_ensure (GB_TYPE_TREE);
+ g_type_ensure (GB_TYPE_VIEW_GRID);
}
static void
-gb_editor_workspace_init (GbEditorWorkspace *workspace)
+gb_editor_workspace_init (GbEditorWorkspace *self)
{
- const GActionEntry entries[] = {
- { "toggle-sidebar", gb_editor_workspace_action_toggle_sidebar },
- { "open", gb_editor_workspace_action_open },
- { "new-document", gb_editor_workspace_action_new_document },
- { "jump-to-doc", gb_editor_workspace_action_jump_to_doc, "s" },
- { "open-uri-list", gb_editor_workspace_action_open_uri_list, "as" }
- };
- GSimpleActionGroup *actions;
-
- workspace->priv = gb_editor_workspace_get_instance_private (workspace);
-
- workspace->priv->command_map = g_hash_table_new (g_str_hash, g_str_equal);
- workspace->priv->current_folder_uri = NULL;
-
- gtk_widget_init_template (GTK_WIDGET (workspace));
-
- actions = g_simple_action_group_new ();
- g_action_map_add_action_entries (G_ACTION_MAP (actions),
- entries, G_N_ELEMENTS (entries),
- workspace);
- gtk_widget_insert_action_group (GTK_WIDGET (workspace), "workspace",
- G_ACTION_GROUP (actions));
- g_clear_object (&actions);
-
- /* Drag and drop support*/
- gtk_drag_dest_set (GTK_WIDGET (workspace),
- GTK_DEST_DEFAULT_MOTION |
- GTK_DEST_DEFAULT_HIGHLIGHT |
- GTK_DEST_DEFAULT_DROP,
- drop_types,
- G_N_ELEMENTS (drop_types),
- GDK_ACTION_COPY);
-
- g_signal_connect (workspace,
- "drag-data-received",
- G_CALLBACK(gb_editor_workspace_drag_data_received),
- NULL);
+ gtk_widget_init_template (GTK_WIDGET (self));
+ gb_widget_set_context_handler (self, gb_editor_workspace_context_changed);
}
diff --git a/src/editor/gb-editor-workspace.h b/src/editor/gb-editor-workspace.h
index eaff983..5783cdf 100644
--- a/src/editor/gb-editor-workspace.h
+++ b/src/editor/gb-editor-workspace.h
@@ -1,6 +1,6 @@
/* gb-editor-workspace.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
*
* 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
@@ -23,35 +23,9 @@
G_BEGIN_DECLS
-#define GB_TYPE_EDITOR_WORKSPACE (gb_editor_workspace_get_type())
-#define GB_EDITOR_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_EDITOR_WORKSPACE,
GbEditorWorkspace))
-#define GB_EDITOR_WORKSPACE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_EDITOR_WORKSPACE,
GbEditorWorkspace const))
-#define GB_EDITOR_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_EDITOR_WORKSPACE,
GbEditorWorkspaceClass))
-#define GB_IS_EDITOR_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_EDITOR_WORKSPACE))
-#define GB_IS_EDITOR_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_EDITOR_WORKSPACE))
-#define GB_EDITOR_WORKSPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_EDITOR_WORKSPACE,
GbEditorWorkspaceClass))
+#define GB_TYPE_EDITOR_WORKSPACE (gb_editor_workspace_get_type())
-typedef struct _GbEditorWorkspace GbEditorWorkspace;
-typedef struct _GbEditorWorkspaceClass GbEditorWorkspaceClass;
-typedef struct _GbEditorWorkspacePrivate GbEditorWorkspacePrivate;
-
-struct _GbEditorWorkspace
-{
- GbWorkspace parent;
-
- /*< private >*/
- GbEditorWorkspacePrivate *priv;
-};
-
-struct _GbEditorWorkspaceClass
-{
- GbWorkspaceClass parent_class;
-};
-
-GType gb_editor_workspace_get_type (void);
-void gb_editor_workspace_new_document (GbEditorWorkspace *workspace);
-void gb_editor_workspace_open (GbEditorWorkspace *workspace,
- GFile *file);
+G_DECLARE_FINAL_TYPE (GbEditorWorkspace, gb_editor_workspace, GB, EDITOR_WORKSPACE, GbWorkspace)
G_END_DECLS
diff --git a/src/editor/gb-source-formatter.c b/src/editor/gb-source-formatter.c
index 8e97933..9dab8b5 100644
--- a/src/editor/gb-source-formatter.c
+++ b/src/editor/gb-source-formatter.c
@@ -20,8 +20,8 @@
#define UNCRUSTIFY_CONFIG_DIRECTORY "/org/gnome/builder/editor/uncrustify/"
#include <glib/gi18n.h>
+#include <ide.h>
-#include "gb-log.h"
#include "gb-source-formatter.h"
struct _GbSourceFormatterPrivate
@@ -194,7 +194,7 @@ gb_source_formatter_extract_configs (void)
gchar *target_dir;
guint i;
- ENTRY;
+ IDE_ENTRY;
target_dir = g_build_filename (g_get_user_config_dir (),
"gnome-builder", "uncrustify",
@@ -213,7 +213,7 @@ gb_source_formatter_extract_configs (void)
{
g_warning ("%s", error->message);
g_clear_error (&error);
- GOTO (cleanup);
+ IDE_GOTO (cleanup);
}
for (i = 0; names [i]; i++)
@@ -255,7 +255,7 @@ cleanup:
g_strfreev (names);
g_free (target_dir);
- EXIT;
+ IDE_EXIT;
}
static void
diff --git a/src/gnome-builder.mk b/src/gnome-builder.mk
index 4039565..2d7f0aa 100644
--- a/src/gnome-builder.mk
+++ b/src/gnome-builder.mk
@@ -3,134 +3,58 @@ noinst_LTLIBRARIES += libgnome-builder.la
libgnome_builder_la_SOURCES = \
$(gnome_builder_built_sources) \
- src/animation/gb-animation.c \
- src/animation/gb-animation.h \
- src/animation/gb-frame-source.c \
- src/animation/gb-frame-source.h \
+ cut-n-paste/trie.c \
+ cut-n-paste/trie.h \
src/app/gb-application.c \
src/app/gb-application.h \
- src/auto-indent/c-parse-helper.c \
- src/auto-indent/c-parse-helper.h \
- src/auto-indent/gb-source-auto-indenter-c.c \
- src/auto-indent/gb-source-auto-indenter-c.h \
- src/auto-indent/gb-source-auto-indenter-python.c \
- src/auto-indent/gb-source-auto-indenter-python.h \
- src/auto-indent/gb-source-auto-indenter-xml.c \
- src/auto-indent/gb-source-auto-indenter-xml.h \
- src/auto-indent/gb-source-auto-indenter.c \
- src/auto-indent/gb-source-auto-indenter.h \
- src/code-assistant/gb-source-code-assistant-renderer.c \
- src/code-assistant/gb-source-code-assistant-renderer.h \
- src/code-assistant/gb-source-code-assistant.c \
- src/code-assistant/gb-source-code-assistant.h \
- src/commands/gb-command-bar-item.c \
- src/commands/gb-command-bar-item.h \
+ src/app/gb-application-actions.c \
+ src/app/gb-application-actions.h \
+ src/app/gb-application-private.h \
src/commands/gb-command-bar.c \
src/commands/gb-command-bar.h \
- src/commands/gb-command-gaction-provider.c \
- src/commands/gb-command-gaction-provider.h \
- src/commands/gb-command-gaction.c \
- src/commands/gb-command-gaction.h \
+ src/commands/gb-command-bar-item.c \
+ src/commands/gb-command-bar-item.h \
src/commands/gb-command-manager.c \
src/commands/gb-command-manager.h \
src/commands/gb-command-provider.c \
src/commands/gb-command-provider.h \
src/commands/gb-command-result.c \
src/commands/gb-command-result.h \
- src/commands/gb-command-vim-provider.c \
- src/commands/gb-command-vim-provider.h \
- src/commands/gb-command-vim.c \
- src/commands/gb-command-vim.h \
src/commands/gb-command.c \
src/commands/gb-command.h \
- src/credits/gb-credits-widget.c \
- src/credits/gb-credits-widget.h \
- src/devhelp/gb-devhelp-document.c \
- src/devhelp/gb-devhelp-document.h \
- src/devhelp/gb-devhelp-view.c \
- src/devhelp/gb-devhelp-view.h \
- src/dialogs/gb-close-confirmation-dialog.c \
- src/dialogs/gb-close-confirmation-dialog.h \
- src/documents/gb-document-grid.c \
- src/documents/gb-document-grid.h \
- src/documents/gb-document-manager.c \
- src/documents/gb-document-manager.h \
- src/documents/gb-document-menu-button.c \
- src/documents/gb-document-menu-button.h \
- src/documents/gb-document-private.h \
- src/documents/gb-document-split.c \
- src/documents/gb-document-split.h \
- src/documents/gb-document-stack.c \
- src/documents/gb-document-stack.h \
- src/documents/gb-document-view.c \
- src/documents/gb-document-view.h \
src/documents/gb-document.c \
src/documents/gb-document.h \
src/editor/gb-editor-document.c \
src/editor/gb-editor-document.h \
- src/editor/gb-editor-file-mark.c \
- src/editor/gb-editor-file-mark.h \
- src/editor/gb-editor-file-marks.c \
- src/editor/gb-editor-file-marks.h \
- src/editor/gb-editor-frame-private.h \
src/editor/gb-editor-frame.c \
src/editor/gb-editor-frame.h \
- src/editor/gb-editor-navigation-item.c \
- src/editor/gb-editor-navigation-item.h \
+ src/editor/gb-editor-frame-actions.c \
+ src/editor/gb-editor-frame-actions.h \
+ src/editor/gb-editor-frame-private.h \
src/editor/gb-editor-settings-widget.c \
src/editor/gb-editor-settings-widget.h \
src/editor/gb-editor-tweak-widget.c \
src/editor/gb-editor-tweak-widget.h \
src/editor/gb-editor-view.c \
src/editor/gb-editor-view.h \
+ src/editor/gb-editor-view-actions.c \
+ src/editor/gb-editor-view-actions.h \
+ src/editor/gb-editor-view-private.h \
+ src/editor/gb-editor-workspace-actions.c \
+ src/editor/gb-editor-workspace-actions.h \
+ src/editor/gb-editor-workspace-private.h \
src/editor/gb-editor-workspace.c \
src/editor/gb-editor-workspace.h \
- src/editor/gb-source-change-gutter-renderer.c \
- src/editor/gb-source-change-gutter-renderer.h \
- src/editor/gb-source-change-monitor.c \
- src/editor/gb-source-change-monitor.h \
- src/editor/gb-source-formatter.c \
- src/editor/gb-source-formatter.h \
- src/editor/gb-source-highlight-menu.c \
- src/editor/gb-source-highlight-menu.h \
- src/editor/gb-source-search-highlighter.c \
- src/editor/gb-source-search-highlighter.h \
- src/editor/gb-source-view.c \
- src/editor/gb-source-view.h \
- src/emacs/gb-source-emacs.c \
- src/emacs/gb-source-emacs.h \
- src/fuzzy/fuzzy.c \
- src/fuzzy/fuzzy.h \
- src/gca/gca-diagnostics.c \
- src/gca/gca-diagnostics.h \
- src/gca/gca-service.c \
- src/gca/gca-service.h \
- src/gca/gca-structs.c \
- src/gca/gca-structs.h \
src/gd/gd-tagged-entry.c \
src/gd/gd-tagged-entry.h \
src/gedit/gedit-close-button.c \
src/gedit/gedit-close-button.h \
src/gedit/gedit-menu-stack-switcher.c \
src/gedit/gedit-menu-stack-switcher.h \
- src/git/gb-git-search-provider.c \
- src/git/gb-git-search-provider.h \
- src/html/gb-html-completion-provider.c \
- src/html/gb-html-completion-provider.h \
- src/html/gb-html-document.c \
- src/html/gb-html-document.h \
- src/html/gb-html-view.c \
- src/html/gb-html-view.h \
src/keybindings/gb-keybindings.c \
src/keybindings/gb-keybindings.h \
- src/log/gb-log.c \
- src/log/gb-log.h \
src/nautilus/nautilus-floating-bar.c \
src/nautilus/nautilus-floating-bar.h \
- src/navigation/gb-navigation-item.c \
- src/navigation/gb-navigation-item.h \
- src/navigation/gb-navigation-list.c \
- src/navigation/gb-navigation-list.h \
src/preferences/gb-preferences-page-editor.c \
src/preferences/gb-preferences-page-editor.h \
src/preferences/gb-preferences-page-emacs.c \
@@ -149,56 +73,25 @@ libgnome_builder_la_SOURCES = \
src/scrolledwindow/gb-scrolled-window.h \
src/search/gb-search-box.c \
src/search/gb-search-box.h \
- src/search/gb-search-context.c \
- src/search/gb-search-context.h \
- src/search/gb-search-display.c \
- src/search/gb-search-display.h \
src/search/gb-search-display-group.c \
src/search/gb-search-display-group.h \
src/search/gb-search-display-row.c \
src/search/gb-search-display-row.h \
- src/search/gb-search-manager.c \
- src/search/gb-search-manager.h \
- src/search/gb-search-provider.c \
- src/search/gb-search-provider.h \
- src/search/gb-search-reducer.c \
- src/search/gb-search-reducer.h \
- src/search/gb-search-result.c \
- src/search/gb-search-result.h \
+ src/search/gb-search-display.c \
+ src/search/gb-search-display.h \
src/search/gb-search-types.h \
- src/snippets/gb-source-snippet-chunk.c \
- src/snippets/gb-source-snippet-chunk.h \
- src/snippets/gb-source-snippet-completion-item.c \
- src/snippets/gb-source-snippet-completion-item.h \
- src/snippets/gb-source-snippet-completion-provider.c \
- src/snippets/gb-source-snippet-completion-provider.h \
- src/snippets/gb-source-snippet-context.c \
- src/snippets/gb-source-snippet-context.h \
- src/snippets/gb-source-snippet-parser.c \
- src/snippets/gb-source-snippet-parser.h \
- src/snippets/gb-source-snippet-private.h \
- src/snippets/gb-source-snippet.c \
- src/snippets/gb-source-snippet.h \
- src/snippets/gb-source-snippets-manager.c \
- src/snippets/gb-source-snippets-manager.h \
- src/snippets/gb-source-snippets.c \
- src/snippets/gb-source-snippets.h \
src/support/gb-support.c \
src/support/gb-support.h \
- src/theatrics/gb-box-theatric.c \
- src/theatrics/gb-box-theatric.h \
src/tree/gb-tree-builder.c \
src/tree/gb-tree-builder.h \
src/tree/gb-tree-node.c \
src/tree/gb-tree-node.h \
- src/tree/gb-project-tree-builder.c \
- src/tree/gb-project-tree-builder.h \
src/tree/gb-tree.c \
src/tree/gb-tree.h \
- src/trie/trie.c \
- src/trie/trie.h \
src/util/gb-cairo.c \
src/util/gb-cairo.h \
+ src/util/gb-dnd.c \
+ src/util/gb-dnd.h \
src/util/gb-doc-seq.c \
src/util/gb-doc-seq.h \
src/util/gb-glib.h \
@@ -212,15 +105,63 @@ libgnome_builder_la_SOURCES = \
src/util/gb-string.h \
src/util/gb-widget.c \
src/util/gb-widget.h \
- src/util/gb-dnd.c \
- src/util/gb-dnd.h \
- src/vim/gb-source-vim.c \
- src/vim/gb-source-vim.h \
+ src/views/gb-view-grid.c \
+ src/views/gb-view-grid.h \
+ src/views/gb-view-stack-actions.c \
+ src/views/gb-view-stack-actions.h \
+ src/views/gb-view-stack-private.h \
+ src/views/gb-view-stack.c \
+ src/views/gb-view-stack.h \
+ src/views/gb-view.c \
+ src/views/gb-view.h \
+ src/workbench/gb-workbench-actions.c \
+ src/workbench/gb-workbench-actions.h \
+ src/workbench/gb-workbench-private.h \
src/workbench/gb-workbench-types.h \
src/workbench/gb-workbench.c \
src/workbench/gb-workbench.h \
src/workbench/gb-workspace.c \
- src/workbench/gb-workspace.h
+ src/workbench/gb-workspace.h \
+ $(NULL)
+
+disabled_files = \
+ src/commands/gb-command-gaction-provider.c \
+ src/commands/gb-command-gaction-provider.h \
+ src/commands/gb-command-gaction.c \
+ src/commands/gb-command-gaction.h \
+ src/commands/gb-command-vim-provider.c \
+ src/commands/gb-command-vim-provider.h \
+ src/commands/gb-command-vim.c \
+ src/commands/gb-command-vim.h \
+ src/devhelp/gb-devhelp-document.c \
+ src/devhelp/gb-devhelp-document.h \
+ src/devhelp/gb-devhelp-view.c \
+ src/devhelp/gb-devhelp-view.h \
+ src/documents/gb-document-grid.c \
+ src/documents/gb-document-grid.h \
+ src/documents/gb-document-private.h \
+ src/documents/gb-document-split.c \
+ src/documents/gb-document-split.h \
+ src/documents/gb-document-stack.c \
+ src/documents/gb-document-stack.h \
+ src/editor/gb-editor-frame-private.h \
+ src/editor/gb-editor-tweak-widget.c \
+ src/editor/gb-editor-tweak-widget.h \
+ src/editor/gb-editor-workspace.c \
+ src/editor/gb-editor-workspace.h \
+ src/editor/gb-source-formatter.c \
+ src/editor/gb-source-formatter.h \
+ src/editor/gb-source-highlight-menu.c \
+ src/editor/gb-source-highlight-menu.h \
+ src/html/gb-html-completion-provider.c \
+ src/html/gb-html-completion-provider.h \
+ src/html/gb-html-document.c \
+ src/html/gb-html-document.h \
+ src/html/gb-html-view.c \
+ src/html/gb-html-view.h \
+ src/tree/gb-project-tree-builder.c \
+ src/tree/gb-project-tree-builder.h \
+ $(NULL)
libgnome_builder_la_LIBADD = \
$(BUILDER_LIBS) \
@@ -234,39 +175,26 @@ libgnome_builder_la_CFLAGS = \
$(MAINTAINER_CFLAGS) \
-I$(top_builddir)/src/resources \
-I$(top_builddir)/src/util \
+ -I$(top_srcdir)/cut-n-paste \
-I$(top_srcdir)/libide \
- -I$(top_srcdir)/src/animation \
-I$(top_srcdir)/src/app \
- -I$(top_srcdir)/src/auto-indent \
-I$(top_srcdir)/src/commands \
- -I$(top_srcdir)/src/code-assistant \
- -I$(top_srcdir)/src/credits \
-I$(top_srcdir)/src/devhelp \
- -I$(top_srcdir)/src/dialogs \
-I$(top_srcdir)/src/documents \
-I$(top_srcdir)/src/editor \
- -I$(top_srcdir)/src/emacs \
- -I$(top_srcdir)/src/fuzzy \
- -I$(top_srcdir)/src/gca \
-I$(top_srcdir)/src/gd \
-I$(top_srcdir)/src/gedit \
- -I$(top_srcdir)/src/git \
-I$(top_srcdir)/src/html \
-I$(top_srcdir)/src/keybindings \
- -I$(top_srcdir)/src/log \
-I$(top_srcdir)/src/nautilus \
- -I$(top_srcdir)/src/navigation \
-I$(top_srcdir)/src/preferences \
-I$(top_srcdir)/src/resources \
-I$(top_srcdir)/src/scrolledwindow \
-I$(top_srcdir)/src/search \
- -I$(top_srcdir)/src/snippets \
-I$(top_srcdir)/src/support \
-I$(top_srcdir)/src/tree \
- -I$(top_srcdir)/src/trie \
- -I$(top_srcdir)/src/theatrics \
-I$(top_srcdir)/src/util \
- -I$(top_srcdir)/src/vim \
+ -I$(top_srcdir)/src/views \
-I$(top_srcdir)/src/workbench
if ENABLE_TRACING
diff --git a/src/html/gb-html-view.c b/src/html/gb-html-view.c
index 967f18a..7983b93 100644
--- a/src/html/gb-html-view.c
+++ b/src/html/gb-html-view.c
@@ -20,11 +20,11 @@
#include <glib/gi18n.h>
#include <gtksourceview/gtksourcefile.h>
+#include <ide.h>
#include <webkit2/webkit2.h>
#include "gb-editor-document.h"
#include "gb-html-view.h"
-#include "gb-log.h"
struct _GbHtmlViewPrivate
{
@@ -61,7 +61,7 @@ gb_html_view_changed (GbHtmlView *view,
gchar *content;
gchar *base_uri = NULL;
- ENTRY;
+ IDE_ENTRY;
g_return_if_fail (GB_IS_HTML_VIEW (view));
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
@@ -91,7 +91,7 @@ gb_html_view_changed (GbHtmlView *view,
g_free (content);
g_free (base_uri);
- EXIT;
+ IDE_EXIT;
}
static void
diff --git a/src/keybindings/gb-keybindings.c b/src/keybindings/gb-keybindings.c
index e202506..e2af70f 100644
--- a/src/keybindings/gb-keybindings.c
+++ b/src/keybindings/gb-keybindings.c
@@ -1,6 +1,6 @@
/* gb-keybindings.c
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,183 +16,231 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "keybindings"
+#define G_LOG_DOMAIN "gb-keybindings"
#include <glib/gi18n.h>
+#include <ide.h>
-#include "gb-log.h"
#include "gb-keybindings.h"
-struct _GbKeybindingsPrivate
+struct _GbKeybindings
{
- GHashTable *keybindings;
+ GObject parent_instance;
+
+ GtkApplication *application;
+ GtkCssProvider *css_provider;
+ gchar *mode;
+ guint constructed : 1;
+};
+
+enum
+{
+ PROP_0,
+ PROP_APPLICATION,
+ PROP_MODE,
+ LAST_PROP
};
-G_DEFINE_TYPE_WITH_PRIVATE (GbKeybindings, gb_keybindings, G_TYPE_OBJECT)
+G_DEFINE_TYPE (GbKeybindings, gb_keybindings, G_TYPE_OBJECT)
+
+static GParamSpec *gParamSpecs [LAST_PROP];
GbKeybindings *
-gb_keybindings_new (void)
+gb_keybindings_new (GtkApplication *application,
+ const gchar *mode)
{
- return g_object_new (GB_TYPE_KEYBINDINGS, NULL);
+ g_return_val_if_fail (GTK_IS_APPLICATION (application), NULL);
+
+ return g_object_new (GB_TYPE_KEYBINDINGS,
+ "application", application,
+ "mode", mode,
+ NULL);
}
static void
-gb_keybindings_load (GbKeybindings *keybindings,
- GKeyFile *key_file)
+gb_keybindings_reload (GbKeybindings *self)
{
- GbKeybindingsPrivate *priv;
- gchar **keys;
- gchar **groups;
- gchar *value;
- guint i;
- guint j;
+ const gchar *mode;
+ g_autofree gchar *path = NULL;
+ g_autoptr(GBytes) bytes = NULL;
+ g_autoptr(GError) error = NULL;
- g_assert (GB_IS_KEYBINDINGS (keybindings));
- g_assert (key_file);
+ IDE_ENTRY;
- priv = keybindings->priv;
+ g_assert (GB_IS_KEYBINDINGS (self));
- groups = g_key_file_get_groups (key_file, NULL);
+ mode = self->mode ? self->mode : "default";
+ IDE_TRACE_MSG ("Loading %s keybindings", mode);
+ path = g_strdup_printf ("/org/gnome/builder/keybindings/%s.css", mode);
+ bytes = g_resources_lookup_data (path, G_RESOURCE_LOOKUP_FLAGS_NONE, &error);
- for (i = 0; groups[i]; i++)
- {
- keys = g_key_file_get_keys (key_file, groups[i], NULL, NULL);
- if (!keys)
- continue;
+ if (error == NULL)
+ gtk_css_provider_load_from_data (self->css_provider,
+ g_bytes_get_data (bytes, NULL),
+ g_bytes_get_size (bytes),
+ &error);
- for (j = 0; keys[j]; j++)
- {
- value = g_key_file_get_string (key_file, groups[i], keys[j], NULL);
- if (!value || !*value)
- continue;
+ if (error)
+ g_warning ("%s", error->message);
- g_hash_table_replace (priv->keybindings,
- g_strdup_printf ("%s.%s", groups[i], keys[j]),
- value);
- }
+ IDE_EXIT;
+}
- g_strfreev (keys);
- }
+const gchar *
+gb_keybindings_get_mode (GbKeybindings *self)
+{
+ g_return_val_if_fail (GB_IS_KEYBINDINGS (self), NULL);
- g_strfreev (groups);
+ return self->mode;
}
-gboolean
-gb_keybindings_load_bytes (GbKeybindings *keybindings,
- GBytes *bytes,
- GError **error)
+void
+gb_keybindings_set_mode (GbKeybindings *self,
+ const gchar *mode)
{
- gconstpointer data;
- GKeyFile *key_file;
- gsize len = 0;
- gboolean ret = FALSE;
-
- ENTRY;
+ g_return_if_fail (GB_IS_KEYBINDINGS (self));
- g_return_val_if_fail (GB_IS_KEYBINDINGS (keybindings), FALSE);
- g_return_val_if_fail (bytes, FALSE);
+ if (mode != self->mode)
+ {
+ g_free (self->mode);
+ self->mode = g_strdup (mode);
+ if (self->constructed)
+ gb_keybindings_reload (self);
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_MODE]);
+ }
+}
- key_file = g_key_file_new ();
- data = g_bytes_get_data (bytes, &len);
- if (!g_key_file_load_from_data (key_file, data, len,
- G_KEY_FILE_NONE, error))
- GOTO (cleanup);
+GtkApplication *
+gb_keybindings_get_application (GbKeybindings *self)
+{
+ g_return_val_if_fail (GB_IS_KEYBINDINGS (self), NULL);
- gb_keybindings_load (keybindings, key_file);
+ return self->application;
+}
- ret = TRUE;
+static void
+gb_keybindings_set_application (GbKeybindings *self,
+ GtkApplication *application)
+{
+ g_assert (GB_IS_KEYBINDINGS (self));
+ g_assert (!application || GTK_IS_APPLICATION (application));
-cleanup:
- g_key_file_free (key_file);
+ if (application != self->application)
+ {
+ if (self->application)
+ {
+ /* remove keybindings */
+ g_clear_object (&self->application);
+ }
- RETURN (ret);
+ if (application)
+ {
+ /* connect keybindings */
+ self->application = g_object_ref (application);
+ }
+ }
}
-gboolean
-gb_keybindings_load_path (GbKeybindings *keybindings,
- const gchar *path,
- GError **error)
+static void
+gb_keybindings_parsing_error (GtkCssProvider *css_provider,
+ GtkCssSection *section,
+ GError *error,
+ gpointer user_data)
{
- GKeyFile *key_file;
- gboolean ret = FALSE;
+ g_autofree gchar *filename = NULL;
+ GFile *file;
+ guint start_line;
+ guint end_line;
+
+ file = gtk_css_section_get_file (section);
+ filename = g_file_get_uri (file);
+ start_line = gtk_css_section_get_start_line (section);
+ end_line = gtk_css_section_get_end_line (section);
+
+ g_warning ("CSS parsing error in %s between lines %u and %u", filename, start_line, end_line);
+}
- ENTRY;
+static void
+gb_keybindings_constructed (GObject *object)
+{
+ GbKeybindings *self = (GbKeybindings *)object;
+ GdkScreen *screen;
- g_return_val_if_fail (GB_IS_KEYBINDINGS (keybindings), FALSE);
- g_return_val_if_fail (path, FALSE);
+ IDE_ENTRY;
- key_file = g_key_file_new ();
+ G_OBJECT_CLASS (gb_keybindings_parent_class)->constructed (object);
- if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, error))
- GOTO (cleanup);
+ screen = gdk_screen_get_default ();
+ gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (self->css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- gb_keybindings_load (keybindings, key_file);
+ self->constructed = TRUE;
-cleanup:
- g_key_file_free (key_file);
+ gb_keybindings_reload (self);
- RETURN (ret);
+ IDE_EXIT;
}
-void
-gb_keybindings_register (GbKeybindings *keybindings,
- GtkApplication *application)
+static void
+gb_keybindings_finalize (GObject *object)
{
- GbKeybindingsPrivate *priv;
- GHashTableIter iter;
- const gchar *action_name;
- const gchar *accelerator;
- gchar *accel_list[2] = { NULL };
+ GbKeybindings *self = (GbKeybindings *)object;
- g_return_if_fail (GB_IS_KEYBINDINGS (keybindings));
- g_return_if_fail (GTK_IS_APPLICATION (application));
+ IDE_ENTRY;
- priv = keybindings->priv;
+ g_clear_object (&self->application);
+ g_clear_object (&self->css_provider);
+ g_clear_pointer (&self->mode, g_free);
- g_hash_table_iter_init (&iter, priv->keybindings);
+ G_OBJECT_CLASS (gb_keybindings_parent_class)->finalize (object);
- while (g_hash_table_iter_next (&iter,
- (gpointer *) &action_name,
- (gpointer *) &accelerator))
- {
- accel_list[0] = (gchar *) accelerator;
- gtk_application_set_accels_for_action (application,
- action_name,
- (const gchar* const*)accel_list);
- }
+ IDE_EXIT;
}
-void
-gb_keybindings_unregister (GbKeybindings *keybindings,
- GtkApplication *application)
+static void
+gb_keybindings_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- GHashTableIter iter;
- const gchar *action_name;
- const gchar *accelerator;
- gchar *accels[] = { NULL };
+ GbKeybindings *self = GB_KEYBINDINGS (object);
- g_return_if_fail (GB_IS_KEYBINDINGS (keybindings));
- g_return_if_fail (GTK_IS_APPLICATION (application));
+ switch (prop_id)
+ {
+ case PROP_APPLICATION:
+ g_value_set_object (value, gb_keybindings_get_application (self));
+ break;
- g_hash_table_iter_init (&iter, keybindings->priv->keybindings);
+ case PROP_MODE:
+ g_value_set_string (value, gb_keybindings_get_mode (self));
+ break;
- while (g_hash_table_iter_next (&iter,
- (gpointer *)&action_name,
- (gpointer *)&accelerator))
- gtk_application_set_accels_for_action (application, action_name,
- (const gchar * const *)accels);
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
-gb_keybindings_finalize (GObject *object)
+gb_keybindings_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GbKeybindingsPrivate *priv;
+ GbKeybindings *self = GB_KEYBINDINGS (object);
- priv = GB_KEYBINDINGS (object)->priv;
+ switch (prop_id)
+ {
+ case PROP_APPLICATION:
+ gb_keybindings_set_application (self, g_value_get_object (value));
+ break;
- g_clear_pointer (&priv->keybindings, g_hash_table_unref);
+ case PROP_MODE:
+ gb_keybindings_set_mode (self, g_value_get_string (value));
+ break;
- G_OBJECT_CLASS (gb_keybindings_parent_class)->finalize (object);
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
@@ -200,16 +248,35 @@ gb_keybindings_class_init (GbKeybindingsClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->constructed = gb_keybindings_constructed;
object_class->finalize = gb_keybindings_finalize;
+ object_class->get_property = gb_keybindings_get_property;
+ object_class->set_property = gb_keybindings_set_property;
+
+ gParamSpecs [PROP_APPLICATION] =
+ g_param_spec_object ("application",
+ _("Application"),
+ _("The application to register keybindings for."),
+ GTK_TYPE_APPLICATION,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_APPLICATION, gParamSpecs [PROP_APPLICATION]);
+
+ gParamSpecs [PROP_MODE] =
+ g_param_spec_string ("mode",
+ _("Mode"),
+ _("The name of the keybindings mode."),
+ NULL,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_MODE, gParamSpecs [PROP_MODE]);
}
static void
-gb_keybindings_init (GbKeybindings *keybindings)
+gb_keybindings_init (GbKeybindings *self)
{
- keybindings->priv = gb_keybindings_get_instance_private (keybindings);
+ self->css_provider = gtk_css_provider_new ();
- keybindings->priv->keybindings = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- g_free);
+ g_signal_connect (self->css_provider,
+ "parsing-error",
+ G_CALLBACK (gb_keybindings_parsing_error),
+ NULL);
}
diff --git a/src/keybindings/gb-keybindings.h b/src/keybindings/gb-keybindings.h
index 7d449ce..4053bae 100644
--- a/src/keybindings/gb-keybindings.h
+++ b/src/keybindings/gb-keybindings.h
@@ -1,6 +1,6 @@
/* gb-keybindings.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
*
* 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
@@ -23,43 +23,16 @@
G_BEGIN_DECLS
-#define GB_TYPE_KEYBINDINGS (gb_keybindings_get_type())
-#define GB_KEYBINDINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_KEYBINDINGS,
GbKeybindings))
-#define GB_KEYBINDINGS_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_KEYBINDINGS,
GbKeybindings const))
-#define GB_KEYBINDINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_KEYBINDINGS,
GbKeybindingsClass))
-#define GB_IS_KEYBINDINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_KEYBINDINGS))
-#define GB_IS_KEYBINDINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_KEYBINDINGS))
-#define GB_KEYBINDINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_KEYBINDINGS,
GbKeybindingsClass))
+#define GB_TYPE_KEYBINDINGS (gb_keybindings_get_type())
-typedef struct _GbKeybindings GbKeybindings;
-typedef struct _GbKeybindingsClass GbKeybindingsClass;
-typedef struct _GbKeybindingsPrivate GbKeybindingsPrivate;
+G_DECLARE_FINAL_TYPE (GbKeybindings, gb_keybindings, GB, KEYBINDINGS, GObject)
-struct _GbKeybindings
-{
- GObject parent;
-
- /*< private >*/
- GbKeybindingsPrivate *priv;
-};
-
-struct _GbKeybindingsClass
-{
- GObjectClass parent_class;
-};
-
-GType gb_keybindings_get_type (void);
-GbKeybindings *gb_keybindings_new (void);
-gboolean gb_keybindings_load_bytes (GbKeybindings *keybindings,
- GBytes *bytes,
- GError **error);
-gboolean gb_keybindings_load_path (GbKeybindings *keybindings,
- const gchar *path,
- GError **error);
-void gb_keybindings_register (GbKeybindings *keybindings,
- GtkApplication *application);
-void gb_keybindings_unregister (GbKeybindings *keybindings,
- GtkApplication *application);
+GbKeybindings *gb_keybindings_new (GtkApplication *application,
+ const gchar *mode);
+GtkApplication *gb_keybindings_get_application (GbKeybindings *self);
+const gchar *gb_keybindings_get_mode (GbKeybindings *self);
+void gb_keybindings_set_mode (GbKeybindings *self,
+ const gchar *name);
G_END_DECLS
diff --git a/src/main.c b/src/main.c
index b38e3a5..faf03c3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -29,7 +29,6 @@
#include <locale.h>
#include "gb-application.h"
-#include "gb-log.h"
int
main (int argc,
@@ -49,7 +48,7 @@ main (int argc,
ide_set_program_name ("gnome-builder");
- gb_log_init (TRUE, NULL);
+ ide_log_init (TRUE, NULL);
g_message ("Initializing with Gtk+ version %d.%d.%d.",
gtk_get_major_version (),
@@ -64,7 +63,7 @@ main (int argc,
ret = g_application_run (app, argc, argv);
g_clear_object (&app);
- gb_log_shutdown ();
+ ide_log_shutdown ();
return ret;
}
diff --git a/src/preferences/gb-preferences-page-editor.c b/src/preferences/gb-preferences-page-editor.c
index 6b11f06..21203b1 100644
--- a/src/preferences/gb-preferences-page-editor.c
+++ b/src/preferences/gb-preferences-page-editor.c
@@ -35,6 +35,7 @@ struct _GbPreferencesPageEditorPrivate
GtkSwitch *show_line_numbers_switch;
GtkSwitch *highlight_current_line_switch;
GtkSwitch *highlight_matching_brackets_switch;
+ GtkSwitch *smart_backspace_switch;
GtkSwitch *smart_home_end_switch;
GtkSwitch *show_grid_lines_switch;
GtkFontButton *font_button;
@@ -47,6 +48,7 @@ struct _GbPreferencesPageEditorPrivate
GtkWidget *show_line_numbers_container;
GtkWidget *highlight_current_line_container;
GtkWidget *highlight_matching_brackets_container;
+ GtkWidget *smart_backspace_container;
GtkWidget *smart_home_end_container;
GtkWidget *show_grid_lines_container;
};
@@ -92,7 +94,7 @@ gb_preferences_page_editor_constructed (GObject *object)
g_settings_bind (priv->settings, "restore-insert-mark",
priv->restore_insert_mark_switch, "active",
G_SETTINGS_BIND_DEFAULT);
- g_settings_bind (priv->settings, "show-diff",
+ g_settings_bind (priv->settings, "show-line-changes",
priv->show_diff_switch, "active",
G_SETTINGS_BIND_DEFAULT);
g_settings_bind (priv->settings, "word-completion",
@@ -110,6 +112,9 @@ gb_preferences_page_editor_constructed (GObject *object)
g_settings_bind (priv->settings, "smart-home-end",
priv->smart_home_end_switch, "active",
G_SETTINGS_BIND_DEFAULT);
+ g_settings_bind (priv->settings, "smart-backspace",
+ priv->smart_backspace_switch, "active",
+ G_SETTINGS_BIND_DEFAULT);
g_settings_bind (priv->settings, "show-grid-lines",
priv->show_grid_lines_switch, "active",
G_SETTINGS_BIND_DEFAULT);
@@ -154,25 +159,27 @@ gb_preferences_page_editor_class_init (GbPreferencesPageEditorClass *klass)
GB_WIDGET_CLASS_TEMPLATE (widget_class, "gb-preferences-page-editor.ui");
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, font_button);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, restore_insert_mark_switch);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, show_diff_switch);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, style_scheme_button);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, word_completion_switch);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, show_line_numbers_switch);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, highlight_current_line_switch);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, highlight_matching_brackets_switch);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, smart_home_end_switch);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, show_grid_lines_switch);
-
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, restore_insert_mark_container);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, word_completion_container);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, show_diff_container);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, show_line_numbers_container);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, highlight_current_line_container);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, highlight_matching_brackets_container);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, smart_home_end_container);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesPageEditor, show_grid_lines_container);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, font_button);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, restore_insert_mark_switch);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, show_diff_switch);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, style_scheme_button);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, word_completion_switch);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, show_line_numbers_switch);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, highlight_current_line_switch);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, highlight_matching_brackets_switch);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, smart_home_end_switch);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, smart_backspace_switch);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, show_grid_lines_switch);
+
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, restore_insert_mark_container);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, word_completion_container);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, show_diff_container);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, show_line_numbers_container);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, highlight_current_line_container);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor,
highlight_matching_brackets_container);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, smart_home_end_container);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, smart_backspace_container);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesPageEditor, show_grid_lines_container);
}
static void
@@ -223,8 +230,14 @@ gb_preferences_page_editor_init (GbPreferencesPageEditor *self)
self->priv->smart_home_end_container,
self->priv->smart_home_end_switch,
NULL);
+ /* To translators: This is a list of keywords for the preferences page */
gb_preferences_page_set_keywords_for_widget (GB_PREFERENCES_PAGE (self),
+ _("smart back backspace indent align"),
+ self->priv->smart_backspace_container,
+ self->priv->smart_backspace_switch,
+ NULL);
/* To translators: This is a list of keywords for the preferences page */
+ gb_preferences_page_set_keywords_for_widget (GB_PREFERENCES_PAGE (self),
_("show grid lines"),
self->priv->show_grid_lines_container,
self->priv->show_grid_lines_switch,
diff --git a/src/preferences/gb-preferences-page-emacs.c b/src/preferences/gb-preferences-page-emacs.c
index bc16f1e..e10e39d 100644
--- a/src/preferences/gb-preferences-page-emacs.c
+++ b/src/preferences/gb-preferences-page-emacs.c
@@ -41,6 +41,8 @@ gb_preferences_page_emacs_constructed (GObject *object)
{
GbPreferencesPageEmacsPrivate *priv;
GbPreferencesPageEmacs *emacs = (GbPreferencesPageEmacs *)object;
+ GSimpleActionGroup *group;
+ GAction *action;
g_return_if_fail (GB_IS_PREFERENCES_PAGE_EMACS (emacs));
@@ -48,9 +50,12 @@ gb_preferences_page_emacs_constructed (GObject *object)
priv->editor_settings = g_settings_new ("org.gnome.builder.editor");
- g_settings_bind (priv->editor_settings, "emacs-mode",
- priv->emacs_mode_switch, "active",
- G_SETTINGS_BIND_DEFAULT);
+ group = g_simple_action_group_new ();
+ action = g_settings_create_action (priv->editor_settings, "keybindings");
+ g_action_map_add_action (G_ACTION_MAP (group), action);
+ g_clear_object (&action);
+ gtk_widget_insert_action_group (GTK_WIDGET (emacs), "settings", G_ACTION_GROUP (group));
+ g_clear_object (&group);
}
static void
diff --git a/src/preferences/gb-preferences-page-vim.c b/src/preferences/gb-preferences-page-vim.c
index c9ca6f3..fddbead 100644
--- a/src/preferences/gb-preferences-page-vim.c
+++ b/src/preferences/gb-preferences-page-vim.c
@@ -44,6 +44,8 @@ gb_preferences_page_vim_constructed (GObject *object)
{
GbPreferencesPageVimPrivate *priv;
GbPreferencesPageVim *vim = (GbPreferencesPageVim *)object;
+ GSimpleActionGroup *group;
+ GAction *action;
g_return_if_fail (GB_IS_PREFERENCES_PAGE_VIM (vim));
@@ -52,12 +54,18 @@ gb_preferences_page_vim_constructed (GObject *object)
priv->editor_settings = g_settings_new ("org.gnome.builder.editor");
priv->vim_settings = g_settings_new ("org.gnome.builder.editor.vim");
- g_settings_bind (priv->vim_settings, "scroll-off",
- priv->scroll_off_spin, "value",
- G_SETTINGS_BIND_DEFAULT);
- g_settings_bind (priv->editor_settings, "vim-mode",
- priv->vim_mode_switch, "active",
- G_SETTINGS_BIND_DEFAULT);
+ group = g_simple_action_group_new ();
+
+ action = g_settings_create_action (priv->editor_settings, "keybindings");
+ g_action_map_add_action (G_ACTION_MAP (group), action);
+ g_clear_object (&action);
+
+ action = g_settings_create_action (priv->vim_settings, "scroll-off");
+ g_action_map_add_action (G_ACTION_MAP (group), action);
+ g_clear_object (&action);
+
+ gtk_widget_insert_action_group (GTK_WIDGET (vim), "settings", G_ACTION_GROUP (group));
+ g_clear_object (&group);
}
static void
diff --git a/src/preferences/gb-preferences-page.c b/src/preferences/gb-preferences-page.c
index c661327..d6de247 100644
--- a/src/preferences/gb-preferences-page.c
+++ b/src/preferences/gb-preferences-page.c
@@ -19,9 +19,9 @@
#define G_LOG_DOMAIN "prefs-page"
#include <glib/gi18n.h>
+#include <ide.h>
#include "gb-preferences-page.h"
-#include "gb-log.h"
#include "gb-string.h"
struct _GbPreferencesPagePrivate
diff --git a/src/preferences/gb-preferences-window.c b/src/preferences/gb-preferences-window.c
index 98f417b..a79e58b 100644
--- a/src/preferences/gb-preferences-window.c
+++ b/src/preferences/gb-preferences-window.c
@@ -329,10 +329,10 @@ gb_preferences_window_class_init (GbPreferencesWindowClass *klass)
GB_WIDGET_CLASS_TEMPLATE (widget_class, "gb-preferences-window.ui");
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesWindow, right_header_bar);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesWindow, search_bar);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesWindow, search_entry);
- GB_WIDGET_CLASS_BIND (widget_class, GbPreferencesWindow, stack);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesWindow, right_header_bar);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesWindow, search_bar);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesWindow, search_entry);
+ GB_WIDGET_CLASS_BIND_PRIVATE (widget_class, GbPreferencesWindow, stack);
g_type_ensure (GB_TYPE_PREFERENCES_PAGE_GIT);
g_type_ensure (GB_TYPE_PREFERENCES_PAGE_EDITOR);
diff --git a/src/resources/css/builder.Adwaita.css b/src/resources/css/builder.Adwaita.css
index 6e29d3a..98bc405 100644
--- a/src/resources/css/builder.Adwaita.css
+++ b/src/resources/css/builder.Adwaita.css
@@ -138,15 +138,6 @@ GtkEntry.gb-command-bar-entry {
/*
- * Styling of main window header bar.
- */
-GbWorkbench GtkHeaderBar {
- border-bottom: none;
- box-shadow: none;
-}
-
-
-/*
* Tab header styling.
*/
GtkMenuButton.tab-header-first .button,
@@ -219,3 +210,7 @@ GbSearchDisplayGroup GtkListBox .list-row {
GbDocumentStack .button {
transition: none;
}
+
+GbViewStack GtkBox.header.notebook {
+ border-bottom: 1px solid @borders;
+}
diff --git a/src/resources/gnome-builder.gresource.xml b/src/resources/gnome-builder.gresource.xml
index 9cc5a62..31fc406 100644
--- a/src/resources/gnome-builder.gresource.xml
+++ b/src/resources/gnome-builder.gresource.xml
@@ -14,23 +14,21 @@
<file>js/marked.js</file>
<file>js/markdown-view.js</file>
- <file>keybindings/default.ini</file>
- <file>keybindings/emacs.ini</file>
- <file>keybindings/vim.ini</file>
+ <file alias="keybindings/default.css">../../data/keybindings/default.css</file>
+ <file alias="keybindings/emacs.css">../../data/keybindings/emacs.css</file>
+ <file alias="keybindings/vim.css">../../data/keybindings/vim.css</file>
- <file>language/defaults.ini</file>
+ <file alias="ui/gb-command-bar.ui">../../data/ui/gb-command-bar.ui</file>
+ <file alias="ui/gb-editor-frame.ui">../../data/ui/gb-editor-frame.ui</file>
+ <file alias="ui/gb-editor-settings-widget.ui">../../data/ui/gb-editor-settings-widget.ui</file>
+ <file alias="ui/gb-editor-tweak-widget.ui">../../data/ui/gb-editor-tweak-widget.ui</file>
+ <file alias="ui/gb-editor-view.ui">../../data/ui/gb-editor-view.ui</file>
+ <file alias="ui/gb-editor-workspace.ui">../../data/ui/gb-editor-workspace.ui</file>
+ <file alias="ui/gb-view-stack.ui">../../data/ui/gb-view-stack.ui</file>
+ <file alias="ui/gb-workbench.ui">../../data/ui/gb-workbench.ui</file>
- <file>ui/gb-command-bar.ui</file>
<file>ui/gb-command-bar-item.ui</file>
- <file>ui/gb-credits-widget.ui</file>
<file>ui/gb-devhelp-view.ui</file>
- <file>ui/gb-document-stack.ui</file>
- <file>ui/gb-document-menu-button.ui</file>
- <file>ui/gb-editor-settings-widget.ui</file>
- <file>ui/gb-editor-frame.ui</file>
- <file>ui/gb-editor-tweak-widget.ui</file>
- <file>ui/gb-editor-view.ui</file>
- <file>ui/gb-editor-workspace.ui</file>
<file>ui/gb-html-view.ui</file>
<file>ui/gb-preferences-window.ui</file>
<file>ui/gb-preferences-page-editor.ui</file>
@@ -41,6 +39,5 @@
<file>ui/gb-search-box.ui</file>
<file>ui/gb-search-display-group.ui</file>
<file>ui/gb-search-display-row.ui</file>
- <file>ui/gb-workbench.ui</file>
</gresource>
</gresources>
diff --git a/src/resources/gtk/menus.ui b/src/resources/gtk/menus.ui
index 66e8975..ea326ce 100644
--- a/src/resources/gtk/menus.ui
+++ b/src/resources/gtk/menus.ui
@@ -18,12 +18,8 @@
<section>
<attribute name="id">help-section</attribute>
<item>
- <attribute name="label" translatable="yes">_Help</attribute>
- <attribute name="action">app.help</attribute>
- </item>
- <item>
<attribute name="label" translatable="yes">_About</attribute>
- <attribute name="action">win.about</attribute>
+ <attribute name="action">app.about</attribute>
</item>
<item>
<attribute name="label" translatable="yes">_Quit</attribute>
diff --git a/src/resources/ui/gb-preferences-page-editor.ui b/src/resources/ui/gb-preferences-page-editor.ui
index 32ce0d3..0614f9a 100644
--- a/src/resources/ui/gb-preferences-page-editor.ui
+++ b/src/resources/ui/gb-preferences-page-editor.ui
@@ -92,7 +92,7 @@
</packing>
</child>
<child>
- <object class="GtkSwitch" id="show_grid_lines_switch">
+ <object class="GtkSwitch" id="smart_backspace_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
@@ -103,6 +103,17 @@
</packing>
</child>
<child>
+ <object class="GtkSwitch" id="show_grid_lines_switch">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="valign">center</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">9</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkBox" id="restore_insert_mark_container">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -411,6 +422,50 @@
</packing>
</child>
<child>
+ <object class="GtkBox" id="smart_backspace_container">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes"><b>Smart Backspace</b></property>
+ <property name="use_markup">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Backspace will remove extra spaces to keep you
aligned with your indentation size.</property>
+ <property name="xalign">0</property>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">8</property>
+ </packing>
+ </child>
+ <child>
<object class="GtkBox" id="show_grid_lines_container">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -451,7 +506,7 @@
</object>
<packing>
<property name="left_attach">1</property>
- <property name="top_attach">8</property>
+ <property name="top_attach">9</property>
</packing>
</child>
</object>
diff --git a/src/resources/ui/gb-preferences-page-emacs.ui b/src/resources/ui/gb-preferences-page-emacs.ui
index 90cb6a7..34d68ee 100644
--- a/src/resources/ui/gb-preferences-page-emacs.ui
+++ b/src/resources/ui/gb-preferences-page-emacs.ui
@@ -16,6 +16,8 @@
<property name="column_spacing">12</property>
<child>
<object class="GtkSwitch" id="emacs_mode_switch">
+ <property name="action-name">settings.keybindings</property>
+ <property name="action-target">'emacs'</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
diff --git a/src/resources/ui/gb-preferences-page-vim.ui b/src/resources/ui/gb-preferences-page-vim.ui
index b3560a9..569107b 100644
--- a/src/resources/ui/gb-preferences-page-vim.ui
+++ b/src/resources/ui/gb-preferences-page-vim.ui
@@ -16,6 +16,8 @@
<property name="column_spacing">12</property>
<child>
<object class="GtkSwitch" id="vim_mode_switch">
+ <property name="action-name">settings.keybindings</property>
+ <property name="action-target">'vim'</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="valign">center</property>
diff --git a/src/search/gb-search-box.c b/src/search/gb-search-box.c
index f5f2c1a..af2ab33 100644
--- a/src/search/gb-search-box.c
+++ b/src/search/gb-search-box.c
@@ -16,17 +16,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "search-box"
+#define G_LOG_DOMAIN "ide-search-box"
#include <glib/gi18n.h>
#include "gb-glib.h"
#include "gb-scrolled-window.h"
#include "gb-search-box.h"
-#include "gb-search-context.h"
#include "gb-search-display.h"
-#include "gb-search-manager.h"
-#include "gb-search-result.h"
#include "gb-string.h"
#include "gb-widget.h"
#include "gb-workbench.h"
@@ -34,16 +31,15 @@
#define SHORT_DELAY_TIMEOUT_MSEC 30
#define LONG_DELAY_TIMEOUT_MSEC 30
-struct _GbSearchBoxPrivate
+struct _GbSearchBox
{
- /* References owned by instance */
- GbSearchManager *search_manager;
+ GtkBox parent_instance;
/* Weak references */
GbWorkbench *workbench;
gulong set_focus_handler;
- /* References owned by template */
+ /* Template references */
GtkMenuButton *button;
GbSearchDisplay *display;
GtkSearchEntry *entry;
@@ -52,15 +48,7 @@ struct _GbSearchBoxPrivate
guint delay_timeout;
};
-G_DEFINE_TYPE_WITH_PRIVATE (GbSearchBox, gb_search_box, GTK_TYPE_BOX)
-
-enum {
- PROP_0,
- PROP_SEARCH_MANAGER,
- LAST_PROP
-};
-
-static GParamSpec *gParamSpecs [LAST_PROP];
+G_DEFINE_TYPE (GbSearchBox, gb_search_box, GTK_TYPE_BOX)
GtkWidget *
gb_search_box_new (void)
@@ -68,58 +56,54 @@ gb_search_box_new (void)
return g_object_new (GB_TYPE_SEARCH_BOX, NULL);
}
-GbSearchManager *
-gb_search_box_get_search_manager (GbSearchBox *box)
+IdeSearchEngine *
+gb_search_box_get_search_engine (GbSearchBox *self)
{
- g_return_val_if_fail (GB_IS_SEARCH_BOX (box), NULL);
+ IdeContext *context;
+ IdeSearchEngine *search_engine;
- return box->priv->search_manager;
-}
+ g_return_val_if_fail (GB_IS_SEARCH_BOX (self), NULL);
-void
-gb_search_box_set_search_manager (GbSearchBox *box,
- GbSearchManager *search_manager)
-{
- g_return_if_fail (GB_IS_SEARCH_BOX (box));
- g_return_if_fail (!search_manager || GB_IS_SEARCH_MANAGER (search_manager));
+ if (self->workbench == NULL)
+ return NULL;
- if (box->priv->search_manager != search_manager)
- {
- g_clear_object (&box->priv->search_manager);
+ context = gb_workbench_get_context (self->workbench);
+ if (context == NULL)
+ return NULL;
- if (search_manager)
- box->priv->search_manager = g_object_ref (search_manager);
+ search_engine = ide_context_get_search_engine (context);
- g_object_notify_by_pspec (G_OBJECT (box),
- gParamSpecs [PROP_SEARCH_MANAGER]);
- }
+ return search_engine;
}
static gboolean
gb_search_box_delay_cb (gpointer user_data)
{
- GbSearchBox *box = user_data;
- GbSearchContext *context;
+ GbSearchBox *self = user_data;
+ IdeSearchEngine *search_engine;
+ IdeSearchContext *context;
const gchar *search_text;
- g_return_val_if_fail (GB_IS_SEARCH_BOX (box), G_SOURCE_REMOVE);
+ g_return_val_if_fail (GB_IS_SEARCH_BOX (self), G_SOURCE_REMOVE);
- box->priv->delay_timeout = 0;
+ self->delay_timeout = 0;
- context = gb_search_display_get_context (box->priv->display);
+ context = gb_search_display_get_context (self->display);
if (context)
- gb_search_context_cancel (context);
+ ide_search_context_cancel (context);
- if (!box->priv->search_manager)
+ search_engine = gb_search_box_get_search_engine (self);
+ if (!search_engine)
return G_SOURCE_REMOVE;
- search_text = gtk_entry_get_text (GTK_ENTRY (box->priv->entry));
+ search_text = gtk_entry_get_text (GTK_ENTRY (self->entry));
if (!search_text)
return G_SOURCE_REMOVE;
- context = gb_search_manager_search (box->priv->search_manager, NULL, search_text); /* TODO: Remove search
text */
- gb_search_display_set_context (box->priv->display, context);
- gb_search_context_execute (context, search_text);
+ /* TODO: Remove search text */
+ context = ide_search_engine_search (search_engine, NULL, search_text);
+ gb_search_display_set_context (self->display, context);
+ ide_search_context_execute (context, search_text, 5);
g_object_unref (context);
return G_SOURCE_REMOVE;
@@ -135,36 +119,36 @@ gb_search_box_popover_closed (GbSearchBox *box,
}
static gboolean
-gb_search_box_entry_focus_in (GbSearchBox *box,
+gb_search_box_entry_focus_in (GbSearchBox *self,
GdkEventFocus *focus,
GtkWidget *entry)
{
const gchar *text;
- g_return_val_if_fail (GB_IS_SEARCH_BOX (box), FALSE);
+ g_return_val_if_fail (GB_IS_SEARCH_BOX (self), FALSE);
g_return_val_if_fail (focus, FALSE);
g_return_val_if_fail (GTK_IS_SEARCH_ENTRY (entry), FALSE);
- text = gtk_entry_get_text (GTK_ENTRY (box->priv->entry));
+ text = gtk_entry_get_text (GTK_ENTRY (self->entry));
if (!gb_str_empty0 (text))
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (box->priv->button), TRUE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->button), TRUE);
return GDK_EVENT_PROPAGATE;
}
static void
-gb_search_box_entry_activate (GbSearchBox *box,
+gb_search_box_entry_activate (GbSearchBox *self,
GtkSearchEntry *entry)
{
- g_return_if_fail (GB_IS_SEARCH_BOX (box));
+ g_return_if_fail (GB_IS_SEARCH_BOX (self));
g_return_if_fail (GTK_IS_SEARCH_ENTRY (entry));
- gb_search_display_activate (box->priv->display);
+ gb_search_display_activate (self->display);
}
static void
-gb_search_box_entry_changed (GbSearchBox *box,
+gb_search_box_entry_changed (GbSearchBox *self,
GtkSearchEntry *entry)
{
GtkToggleButton *button;
@@ -172,17 +156,17 @@ gb_search_box_entry_changed (GbSearchBox *box,
gboolean active;
guint delay_msec = SHORT_DELAY_TIMEOUT_MSEC;
- g_return_if_fail (GB_IS_SEARCH_BOX (box));
+ g_return_if_fail (GB_IS_SEARCH_BOX (self));
g_return_if_fail (GTK_IS_SEARCH_ENTRY (entry));
- button = GTK_TOGGLE_BUTTON (box->priv->button);
+ button = GTK_TOGGLE_BUTTON (self->button);
text = gtk_entry_get_text (GTK_ENTRY (entry));
active = !gb_str_empty0 (text);
if (gtk_toggle_button_get_active (button) != active)
gtk_toggle_button_set_active (button, active);
- if (!box->priv->delay_timeout)
+ if (!self->delay_timeout)
{
const gchar *search_text;
@@ -191,19 +175,19 @@ gb_search_box_entry_changed (GbSearchBox *box,
{
if (strlen (search_text) < 3)
delay_msec = LONG_DELAY_TIMEOUT_MSEC;
- box->priv->delay_timeout = g_timeout_add (delay_msec,
- gb_search_box_delay_cb,
- box);
+ self->delay_timeout = g_timeout_add (delay_msec,
+ gb_search_box_delay_cb,
+ self);
}
}
}
static gboolean
-gb_search_box_entry_key_press_event (GbSearchBox *box,
+gb_search_box_entry_key_press_event (GbSearchBox *self,
GdkEventKey *key,
GtkSearchEntry *entry)
{
- g_return_val_if_fail (GB_IS_SEARCH_BOX (box), GDK_EVENT_PROPAGATE);
+ g_return_val_if_fail (GB_IS_SEARCH_BOX (self), GDK_EVENT_PROPAGATE);
g_return_val_if_fail (key, GDK_EVENT_PROPAGATE);
g_return_val_if_fail (GTK_IS_SEARCH_ENTRY (entry), GDK_EVENT_PROPAGATE);
@@ -213,7 +197,7 @@ gb_search_box_entry_key_press_event (GbSearchBox *box,
{
GtkWidget *toplevel;
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (box->priv->button),
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->button),
FALSE);
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (entry));
@@ -227,7 +211,7 @@ gb_search_box_entry_key_press_event (GbSearchBox *box,
case GDK_KEY_KP_Tab:
case GDK_KEY_Down:
case GDK_KEY_KP_Down:
- gtk_widget_grab_focus (GTK_WIDGET (box->priv->display));
+ gtk_widget_grab_focus (GTK_WIDGET (self->display));
return GDK_EVENT_STOP;
default:
@@ -238,71 +222,71 @@ gb_search_box_entry_key_press_event (GbSearchBox *box,
}
static void
-gb_search_box_display_result_activated (GbSearchBox *box,
- GbSearchResult *result,
+gb_search_box_display_result_activated (GbSearchBox *self,
+ IdeSearchResult *result,
GbSearchDisplay *display)
{
- g_return_if_fail (GB_IS_SEARCH_BOX (box));
- g_return_if_fail (GB_IS_SEARCH_RESULT (result));
+ g_return_if_fail (GB_IS_SEARCH_BOX (self));
+ g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (box->priv->button), FALSE);
- gtk_entry_set_text (GTK_ENTRY (box->priv->entry), "");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->button), FALSE);
+ gtk_entry_set_text (GTK_ENTRY (self->entry), "");
}
static void
-gb_search_box_button_toggled (GbSearchBox *box,
+gb_search_box_button_toggled (GbSearchBox *self,
GtkToggleButton *button)
{
- g_return_if_fail (GB_IS_SEARCH_BOX (box));
+ g_return_if_fail (GB_IS_SEARCH_BOX (self));
g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
if (gtk_toggle_button_get_active (button))
{
- if (!gtk_widget_has_focus (GTK_WIDGET (box->priv->entry)))
- gtk_widget_grab_focus (GTK_WIDGET (box->priv->entry));
+ if (!gtk_widget_has_focus (GTK_WIDGET (self->entry)))
+ gtk_widget_grab_focus (GTK_WIDGET (self->entry));
}
else
{
- gtk_widget_hide (GTK_WIDGET (box->priv->popover));
+ gtk_widget_hide (GTK_WIDGET (self->popover));
}
}
static void
gb_search_box_grab_focus (GtkWidget *widget)
{
- GbSearchBox *box = (GbSearchBox *)widget;
+ GbSearchBox *self = (GbSearchBox *)widget;
- g_return_if_fail (GB_IS_SEARCH_BOX (box));
+ g_return_if_fail (GB_IS_SEARCH_BOX (self));
- gtk_widget_grab_focus (GTK_WIDGET (box->priv->entry));
+ gtk_widget_grab_focus (GTK_WIDGET (self->entry));
}
static void
-gb_search_box_workbench_set_focus (GbSearchBox *box,
+gb_search_box_workbench_set_focus (GbSearchBox *self,
GtkWidget *focus,
GbWorkbench *workbench)
{
- g_return_if_fail (GB_IS_SEARCH_BOX (box));
+ g_return_if_fail (GB_IS_SEARCH_BOX (self));
g_return_if_fail (!focus || GTK_IS_WIDGET (focus));
g_return_if_fail (GB_IS_WORKBENCH (workbench));
if (!focus ||
- (!gtk_widget_is_ancestor (focus, GTK_WIDGET (box)) &&
- !gtk_widget_is_ancestor (focus, GTK_WIDGET (box->priv->popover))))
+ (!gtk_widget_is_ancestor (focus, GTK_WIDGET (self)) &&
+ !gtk_widget_is_ancestor (focus, GTK_WIDGET (self->popover))))
{
- gtk_entry_set_text (GTK_ENTRY (box->priv->entry), "");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (box->priv->button), FALSE);
+ gtk_entry_set_text (GTK_ENTRY (self->entry), "");
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->button), FALSE);
}
}
static void
gb_search_box_map (GtkWidget *widget)
{
- GbSearchBox *box = (GbSearchBox *)widget;
+ GbSearchBox *self = (GbSearchBox *)widget;
GtkWidget *toplevel;
- g_return_if_fail (GB_IS_SEARCH_BOX (box));
+ g_return_if_fail (GB_IS_SEARCH_BOX (self));
GTK_WIDGET_CLASS (gb_search_box_parent_class)->map (widget);
@@ -310,12 +294,12 @@ gb_search_box_map (GtkWidget *widget)
if (GB_IS_WORKBENCH (toplevel))
{
- gb_set_weak_pointer (toplevel, &box->priv->workbench);
- box->priv->set_focus_handler =
+ gb_set_weak_pointer (toplevel, &self->workbench);
+ self->set_focus_handler =
g_signal_connect_object (toplevel,
"set-focus",
G_CALLBACK (gb_search_box_workbench_set_focus),
- box,
+ self,
G_CONNECT_SWAPPED | G_CONNECT_AFTER);
}
}
@@ -323,16 +307,14 @@ gb_search_box_map (GtkWidget *widget)
static void
gb_search_box_unmap (GtkWidget *widget)
{
- GbSearchBox *box = (GbSearchBox *)widget;
+ GbSearchBox *self = (GbSearchBox *)widget;
- g_return_if_fail (GB_IS_SEARCH_BOX (box));
+ g_return_if_fail (GB_IS_SEARCH_BOX (self));
- if (box->priv->workbench)
+ if (self->workbench)
{
- g_signal_handler_disconnect (box->priv->workbench,
- box->priv->set_focus_handler);
- box->priv->set_focus_handler = 0;
- gb_clear_weak_pointer (&box->priv->workbench);
+ ide_clear_signal_handler (self->workbench, &self->set_focus_handler);
+ ide_clear_weak_pointer (&self->workbench);
}
GTK_WIDGET_CLASS (gb_search_box_parent_class)->unmap (widget);
@@ -341,48 +323,45 @@ gb_search_box_unmap (GtkWidget *widget)
static void
gb_search_box_constructed (GObject *object)
{
- GbSearchBoxPrivate *priv;
GbSearchBox *self = (GbSearchBox *)object;
g_return_if_fail (GB_IS_SEARCH_BOX (self));
- priv = self->priv;
-
G_OBJECT_CLASS (gb_search_box_parent_class)->constructed (object);
- gtk_popover_set_relative_to (priv->popover, GTK_WIDGET (priv->entry));
+ gtk_popover_set_relative_to (self->popover, GTK_WIDGET (self->entry));
- g_signal_connect_object (priv->popover,
+ g_signal_connect_object (self->popover,
"closed",
G_CALLBACK (gb_search_box_popover_closed),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->entry,
+ g_signal_connect_object (self->entry,
"focus-in-event",
G_CALLBACK (gb_search_box_entry_focus_in),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->entry,
+ g_signal_connect_object (self->entry,
"activate",
G_CALLBACK (gb_search_box_entry_activate),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->entry,
+ g_signal_connect_object (self->entry,
"changed",
G_CALLBACK (gb_search_box_entry_changed),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->entry,
+ g_signal_connect_object (self->entry,
"key-press-event",
G_CALLBACK (gb_search_box_entry_key_press_event),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->display,
+ g_signal_connect_object (self->display,
"result-activated",
G_CALLBACK (gb_search_box_display_result_activated),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (priv->button,
+ g_signal_connect_object (self->button,
"toggled",
G_CALLBACK (gb_search_box_button_toggled),
self,
@@ -392,58 +371,18 @@ gb_search_box_constructed (GObject *object)
static void
gb_search_box_finalize (GObject *object)
{
- GbSearchBoxPrivate *priv = GB_SEARCH_BOX (object)->priv;
+ GbSearchBox *self = (GbSearchBox *)object;
- if (priv->delay_timeout)
+ if (self->delay_timeout)
{
- g_source_remove (priv->delay_timeout);
- priv->delay_timeout = 0;
+ g_source_remove (self->delay_timeout);
+ self->delay_timeout = 0;
}
- g_clear_object (&priv->search_manager);
-
G_OBJECT_CLASS (gb_search_box_parent_class)->finalize (object);
}
static void
-gb_search_box_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GbSearchBox *self = GB_SEARCH_BOX (object);
-
- switch (prop_id)
- {
- case PROP_SEARCH_MANAGER:
- g_value_set_object (value, gb_search_box_get_search_manager (self));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-gb_search_box_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GbSearchBox *self = GB_SEARCH_BOX (object);
-
- switch (prop_id)
- {
- case PROP_SEARCH_MANAGER:
- gb_search_box_set_search_manager (self, g_value_get_object (value));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
gb_search_box_class_init (GbSearchBoxClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -451,22 +390,11 @@ gb_search_box_class_init (GbSearchBoxClass *klass)
object_class->constructed = gb_search_box_constructed;
object_class->finalize = gb_search_box_finalize;
- object_class->get_property = gb_search_box_get_property;
- object_class->set_property = gb_search_box_set_property;
widget_class->grab_focus = gb_search_box_grab_focus;
widget_class->map = gb_search_box_map;
widget_class->unmap = gb_search_box_unmap;
- gParamSpecs [PROP_SEARCH_MANAGER] =
- g_param_spec_object ("search-manager",
- _("Search Manager"),
- _("The search manager for the search box."),
- GB_TYPE_SEARCH_MANAGER,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_SEARCH_MANAGER,
- gParamSpecs [PROP_SEARCH_MANAGER]);
-
GB_WIDGET_CLASS_TEMPLATE (klass, "gb-search-box.ui");
GB_WIDGET_CLASS_BIND (klass, GbSearchBox, button);
GB_WIDGET_CLASS_BIND (klass, GbSearchBox, display);
@@ -480,8 +408,6 @@ gb_search_box_class_init (GbSearchBoxClass *klass)
static void
gb_search_box_init (GbSearchBox *self)
{
- self->priv = gb_search_box_get_instance_private (self);
-
gtk_widget_init_template (GTK_WIDGET (self));
/*
@@ -494,5 +420,5 @@ gb_search_box_init (GbSearchBox *self)
*
* https://bugzilla.gnome.org/show_bug.cgi?id=741529
*/
- g_object_ref (self->priv->popover);
+ g_object_ref (self->popover);
}
diff --git a/src/search/gb-search-box.h b/src/search/gb-search-box.h
index 6f3e32e..84623ac 100644
--- a/src/search/gb-search-box.h
+++ b/src/search/gb-search-box.h
@@ -20,41 +20,18 @@
#define GB_SEARCH_BOX_H
#include <gtk/gtk.h>
-
-#include "gb-search-manager.h"
+#include <ide.h>
G_BEGIN_DECLS
-#define GB_TYPE_SEARCH_BOX (gb_search_box_get_type())
-#define GB_SEARCH_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_BOX, GbSearchBox))
-#define GB_SEARCH_BOX_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_BOX, GbSearchBox
const))
-#define GB_SEARCH_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_SEARCH_BOX,
GbSearchBoxClass))
-#define GB_IS_SEARCH_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_SEARCH_BOX))
-#define GB_IS_SEARCH_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_SEARCH_BOX))
-#define GB_SEARCH_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_SEARCH_BOX,
GbSearchBoxClass))
-
-typedef struct _GbSearchBox GbSearchBox;
-typedef struct _GbSearchBoxClass GbSearchBoxClass;
-typedef struct _GbSearchBoxPrivate GbSearchBoxPrivate;
-
-struct _GbSearchBox
-{
- GtkBox parent;
-
- /*< private >*/
- GbSearchBoxPrivate *priv;
-};
+#define GB_TYPE_SEARCH_BOX (gb_search_box_get_type())
-struct _GbSearchBoxClass
-{
- GtkBoxClass parent;
-};
+G_DECLARE_FINAL_TYPE (GbSearchBox, gb_search_box, GB, SEARCH_BOX, GtkBox)
-GType gb_search_box_get_type (void);
GtkWidget *gb_search_box_new (void);
-GbSearchManager *gb_search_box_get_search_manager (GbSearchBox *box);
-void gb_search_box_set_search_manager (GbSearchBox *box,
- GbSearchManager *search_manager);
+IdeSearchEngine *gb_search_box_get_search_engine (GbSearchBox *box);
+void gb_search_box_set_search_engine (GbSearchBox *box,
+ IdeSearchEngine *search_engine);
G_END_DECLS
diff --git a/src/search/gb-search-display-group.c b/src/search/gb-search-display-group.c
index c5180fb..2b9f460 100644
--- a/src/search/gb-search-display-group.c
+++ b/src/search/gb-search-display-group.c
@@ -20,27 +20,25 @@
#include "gb-search-display-group.h"
#include "gb-search-display-row.h"
-#include "gb-search-provider.h"
-#include "gb-search-result.h"
#include "gb-widget.h"
-struct _GbSearchDisplayGroupPrivate
+struct _GbSearchDisplayGroup
{
+ GtkBox parent_instance;
+
/* References owned by instance */
- GbSearchProvider *provider;
+ IdeSearchProvider *provider;
/* References owned by template */
- GtkLabel *more_label;
- GtkListBoxRow *more_row;
- GtkLabel *label;
- GtkListBox *rows;
+ GtkLabel *more_label;
+ GtkListBoxRow *more_row;
+ GtkLabel *label;
+ GtkListBox *rows;
- guint64 count;
+ guint64 count;
};
-G_DEFINE_TYPE_WITH_PRIVATE (GbSearchDisplayGroup,
- gb_search_display_group,
- GTK_TYPE_BOX)
+G_DEFINE_TYPE (GbSearchDisplayGroup, gb_search_display_group, GTK_TYPE_BOX)
enum {
PROP_0,
@@ -60,14 +58,14 @@ static GQuark gQuarkRow;
static GParamSpec *gParamSpecs [LAST_PROP];
static guint gSignals [LAST_SIGNAL];
-GbSearchResult *
-gb_search_display_group_get_first (GbSearchDisplayGroup *group)
+IdeSearchResult *
+gb_search_display_group_get_first (GbSearchDisplayGroup *self)
{
GtkListBoxRow *row;
- g_return_val_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group), NULL);
+ g_return_val_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self), NULL);
- row = gtk_list_box_get_row_at_y (group->priv->rows, 1);
+ row = gtk_list_box_get_row_at_y (self->rows, 1);
if (row)
{
@@ -81,49 +79,49 @@ gb_search_display_group_get_first (GbSearchDisplayGroup *group)
return NULL;
}
-GbSearchProvider *
-gb_search_display_group_get_provider (GbSearchDisplayGroup *group)
+IdeSearchProvider *
+gb_search_display_group_get_provider (GbSearchDisplayGroup *self)
{
- g_return_val_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group), NULL);
+ g_return_val_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self), NULL);
- return group->priv->provider;
+ return self->provider;
}
static void
-gb_search_display_group_set_provider (GbSearchDisplayGroup *group,
- GbSearchProvider *provider)
+gb_search_display_group_set_provider (GbSearchDisplayGroup *self,
+ IdeSearchProvider *provider)
{
const gchar *verb;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
- g_return_if_fail (!provider || GB_IS_SEARCH_PROVIDER (provider));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
+ g_return_if_fail (!provider || IDE_IS_SEARCH_PROVIDER (provider));
if (provider)
{
- group->priv->provider = g_object_ref (provider);
- verb = gb_search_provider_get_verb (provider);
- gtk_label_set_label (group->priv->label, verb);
+ self->provider = g_object_ref (provider);
+ verb = ide_search_provider_get_verb (provider);
+ gtk_label_set_label (self->label, verb);
}
}
static void
-gb_search_display_group_set_size_group (GbSearchDisplayGroup *group,
+gb_search_display_group_set_size_group (GbSearchDisplayGroup *self,
GtkSizeGroup *size_group)
{
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
g_return_if_fail (!size_group || GTK_IS_SIZE_GROUP (size_group));
if (size_group)
- gtk_size_group_add_widget (size_group, GTK_WIDGET (group->priv->label));
+ gtk_size_group_add_widget (size_group, GTK_WIDGET (self->label));
}
GtkWidget *
-gb_search_display_group_create_row (GbSearchResult *result)
+gb_search_display_group_create_row (IdeSearchResult *result)
{
GtkListBoxRow *row;
GbSearchDisplayRow *disp_row;
- g_return_val_if_fail (GB_IS_SEARCH_RESULT (result), NULL);
+ g_return_val_if_fail (IDE_IS_SEARCH_RESULT (result), NULL);
row = g_object_new (GTK_TYPE_LIST_BOX_ROW,
"visible", TRUE,
@@ -140,53 +138,53 @@ gb_search_display_group_create_row (GbSearchResult *result)
}
void
-gb_search_display_group_remove_result (GbSearchDisplayGroup *group,
- GbSearchResult *result)
+gb_search_display_group_remove_result (GbSearchDisplayGroup *self,
+ IdeSearchResult *result)
{
GtkWidget *row;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
- g_return_if_fail (GB_IS_SEARCH_RESULT (result));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
+ g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
row = g_object_get_qdata (G_OBJECT (result), gQuarkRow);
if (row)
- gtk_container_remove (GTK_CONTAINER (group->priv->rows), row);
+ gtk_container_remove (GTK_CONTAINER (self->rows), row);
}
void
-gb_search_display_group_add_result (GbSearchDisplayGroup *group,
- GbSearchResult *result)
+gb_search_display_group_add_result (GbSearchDisplayGroup *self,
+ IdeSearchResult *result)
{
GtkWidget *row;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
- g_return_if_fail (GB_IS_SEARCH_RESULT (result));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
+ g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
row = gb_search_display_group_create_row (result);
- gtk_container_add (GTK_CONTAINER (group->priv->rows), row);
+ gtk_container_add (GTK_CONTAINER (self->rows), row);
- gtk_list_box_invalidate_sort (group->priv->rows);
+ gtk_list_box_invalidate_sort (self->rows);
- group->priv->count++;
+ self->count++;
}
void
-gb_search_display_group_set_count (GbSearchDisplayGroup *group,
+gb_search_display_group_set_count (GbSearchDisplayGroup *self,
guint64 count)
{
GtkWidget *parent;
gchar *markup;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
markup = g_strdup_printf (_("%"G_GUINT64_FORMAT" more"), count);
- gtk_label_set_label (group->priv->more_label, markup);
+ gtk_label_set_label (self->more_label, markup);
g_free (markup);
- parent = GTK_WIDGET (group->priv->more_row);
+ parent = GTK_WIDGET (self->more_row);
- if ((count - group->priv->count) > 0)
+ if ((count - self->count) > 0)
gtk_widget_show (parent);
else
gtk_widget_hide (parent);
@@ -200,8 +198,8 @@ compare_cb (GtkListBoxRow *row1,
GtkListBoxRow *more_row = user_data;
GtkWidget *child1;
GtkWidget *child2;
- GbSearchResult *result1;
- GbSearchResult *result2;
+ IdeSearchResult *result1;
+ IdeSearchResult *result2;
gfloat score1;
gfloat score2;
@@ -216,8 +214,8 @@ compare_cb (GtkListBoxRow *row1,
result1 = gb_search_display_row_get_result (GB_SEARCH_DISPLAY_ROW (child1));
result2 = gb_search_display_row_get_result (GB_SEARCH_DISPLAY_ROW (child2));
- score1 = gb_search_result_get_score (result1);
- score2 = gb_search_result_get_score (result2);
+ score1 = ide_search_result_get_score (result1);
+ score2 = ide_search_result_get_score (result2);
if (score1 < score2)
return 1;
@@ -228,21 +226,21 @@ compare_cb (GtkListBoxRow *row1,
}
void
-gb_search_display_group_unselect (GbSearchDisplayGroup *group)
+gb_search_display_group_unselect (GbSearchDisplayGroup *self)
{
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
- gtk_list_box_unselect_all (group->priv->rows);
+ gtk_list_box_unselect_all (self->rows);
}
static void
-gb_search_display_group_row_activated (GbSearchDisplayGroup *group,
+gb_search_display_group_row_activated (GbSearchDisplayGroup *self,
GtkListBoxRow *row,
GtkListBox *list_box)
{
GtkWidget *child;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
g_return_if_fail (!row || GTK_IS_LIST_BOX_ROW (row));
g_return_if_fail (GTK_IS_LIST_BOX (list_box));
@@ -250,22 +248,22 @@ gb_search_display_group_row_activated (GbSearchDisplayGroup *group,
if (GB_IS_SEARCH_DISPLAY_ROW (child))
{
- GbSearchResult *result;
+ IdeSearchResult *result;
result = gb_search_display_row_get_result (GB_SEARCH_DISPLAY_ROW (child));
if (result)
- g_signal_emit (group, gSignals [RESULT_ACTIVATED], 0, result);
+ g_signal_emit (self, gSignals [RESULT_ACTIVATED], 0, result);
}
}
static void
-gb_search_display_group_row_selected (GbSearchDisplayGroup *group,
+gb_search_display_group_row_selected (GbSearchDisplayGroup *self,
GtkListBoxRow *row,
GtkListBox *list_box)
{
GtkWidget *child;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
g_return_if_fail (!row || GTK_IS_LIST_BOX_ROW (row));
g_return_if_fail (GTK_IS_LIST_BOX (list_box));
@@ -275,46 +273,46 @@ gb_search_display_group_row_selected (GbSearchDisplayGroup *group,
if (GB_IS_SEARCH_DISPLAY_ROW (child))
{
- GbSearchResult *result;
+ IdeSearchResult *result;
result = gb_search_display_row_get_result (GB_SEARCH_DISPLAY_ROW (child));
if (result)
- g_signal_emit (group, gSignals [RESULT_SELECTED], 0, result);
+ g_signal_emit (self, gSignals [RESULT_SELECTED], 0, result);
}
}
}
void
-gb_search_display_group_focus_first (GbSearchDisplayGroup *group)
+gb_search_display_group_focus_first (GbSearchDisplayGroup *self)
{
GtkListBoxRow *row;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
- row = gtk_list_box_get_row_at_y (group->priv->rows, 1);
+ row = gtk_list_box_get_row_at_y (self->rows, 1);
if (row)
{
- gtk_list_box_unselect_all (group->priv->rows);
- gtk_widget_child_focus (GTK_WIDGET (group->priv->rows), GTK_DIR_DOWN);
+ gtk_list_box_unselect_all (self->rows);
+ gtk_widget_child_focus (GTK_WIDGET (self->rows), GTK_DIR_DOWN);
}
}
void
-gb_search_display_group_focus_last (GbSearchDisplayGroup *group)
+gb_search_display_group_focus_last (GbSearchDisplayGroup *self)
{
GtkAllocation alloc;
GtkListBoxRow *row;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self));
- gtk_widget_get_allocation (GTK_WIDGET (group->priv->rows), &alloc);
- row = gtk_list_box_get_row_at_y (group->priv->rows, alloc.height - 2);
+ gtk_widget_get_allocation (GTK_WIDGET (self->rows), &alloc);
+ row = gtk_list_box_get_row_at_y (self->rows, alloc.height - 2);
if (row)
{
- gtk_list_box_unselect_all (group->priv->rows);
- gtk_widget_child_focus (GTK_WIDGET (group->priv->rows), GTK_DIR_UP);
+ gtk_list_box_unselect_all (self->rows);
+ gtk_widget_child_focus (GTK_WIDGET (self->rows), GTK_DIR_UP);
}
}
@@ -338,16 +336,16 @@ gb_search_display_group_header_cb (GtkListBoxRow *row,
}
static gboolean
-gb_search_display_group_keynav_failed (GbSearchDisplayGroup *group,
+gb_search_display_group_keynav_failed (GbSearchDisplayGroup *self,
GtkDirectionType dir,
GtkListBox *list_box)
{
gboolean ret = FALSE;
- g_return_val_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group), FALSE);
+ g_return_val_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (self), FALSE);
g_return_val_if_fail (GTK_IS_LIST_BOX (list_box), FALSE);
- g_signal_emit_by_name (group, "keynav-failed", dir, &ret);
+ g_signal_emit_by_name (self, "keynav-failed", dir, &ret);
return ret;
}
@@ -355,9 +353,9 @@ gb_search_display_group_keynav_failed (GbSearchDisplayGroup *group,
static void
gb_search_display_group_finalize (GObject *object)
{
- GbSearchDisplayGroupPrivate *priv = GB_SEARCH_DISPLAY_GROUP (object)->priv;
+ GbSearchDisplayGroup *self = (GbSearchDisplayGroup *)object;
- g_clear_object (&priv->provider);
+ g_clear_object (&self->provider);
G_OBJECT_CLASS (gb_search_display_group_parent_class)->finalize (object);
}
@@ -418,10 +416,8 @@ gb_search_display_group_class_init (GbSearchDisplayGroupClass *klass)
g_param_spec_object ("provider",
_("Provider"),
_("The search provider"),
- GB_TYPE_SEARCH_PROVIDER,
- (G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
+ IDE_TYPE_SEARCH_PROVIDER,
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_PROVIDER,
gParamSpecs [PROP_PROVIDER]);
@@ -430,9 +426,7 @@ gb_search_display_group_class_init (GbSearchDisplayGroupClass *klass)
_("Size Group"),
_("The size group for the label."),
GTK_TYPE_SIZE_GROUP,
- (G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
+ (G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_SIZE_GROUP,
gParamSpecs [PROP_SIZE_GROUP]);
@@ -443,10 +437,10 @@ gb_search_display_group_class_init (GbSearchDisplayGroupClass *klass)
0,
NULL,
NULL,
- g_cclosure_marshal_generic,
+ g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
- GB_TYPE_SEARCH_RESULT);
+ IDE_TYPE_SEARCH_RESULT);
gSignals [RESULT_SELECTED] =
g_signal_new ("result-selected",
@@ -455,10 +449,10 @@ gb_search_display_group_class_init (GbSearchDisplayGroupClass *klass)
0,
NULL,
NULL,
- g_cclosure_marshal_generic,
+ g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
- GB_TYPE_SEARCH_RESULT);
+ IDE_TYPE_SEARCH_RESULT);
GB_WIDGET_CLASS_TEMPLATE (widget_class, "gb-search-display-group.ui");
GB_WIDGET_CLASS_BIND (widget_class, GbSearchDisplayGroup, more_label);
@@ -472,29 +466,24 @@ gb_search_display_group_class_init (GbSearchDisplayGroupClass *klass)
static void
gb_search_display_group_init (GbSearchDisplayGroup *self)
{
- self->priv = gb_search_display_group_get_instance_private (self);
-
gtk_widget_init_template (GTK_WIDGET (self));
- gtk_list_box_set_sort_func (self->priv->rows, compare_cb,
- self->priv->more_row, NULL);
-
- g_signal_connect_object (self->priv->rows,
+ g_signal_connect_object (self->rows,
"keynav-failed",
G_CALLBACK (gb_search_display_group_keynav_failed),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (self->priv->rows,
+ g_signal_connect_object (self->rows,
"row-activated",
G_CALLBACK (gb_search_display_group_row_activated),
self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (self->priv->rows,
+ g_signal_connect_object (self->rows,
"row-selected",
G_CALLBACK (gb_search_display_group_row_selected),
self,
G_CONNECT_SWAPPED);
- gtk_list_box_set_header_func (self->priv->rows,
- gb_search_display_group_header_cb,
- NULL, NULL);
+
+ gtk_list_box_set_sort_func (self->rows, compare_cb, self->more_row, NULL);
+ gtk_list_box_set_header_func (self->rows, gb_search_display_group_header_cb, NULL, NULL);
}
diff --git a/src/search/gb-search-display-group.h b/src/search/gb-search-display-group.h
index dbbcb27..a6e4b86 100644
--- a/src/search/gb-search-display-group.h
+++ b/src/search/gb-search-display-group.h
@@ -20,43 +20,26 @@
#define GB_SEARCH_DISPLAY_GROUP_H
#include <gtk/gtk.h>
-
-#include "gb-search-types.h"
+#include <ide.h>
G_BEGIN_DECLS
-#define GB_SEARCH_DISPLAY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_SEARCH_DISPLAY_GROUP, GbSearchDisplayGroup))
-#define GB_SEARCH_DISPLAY_GROUP_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_SEARCH_DISPLAY_GROUP, GbSearchDisplayGroup const))
-#define GB_SEARCH_DISPLAY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GB_TYPE_SEARCH_DISPLAY_GROUP, GbSearchDisplayGroupClass))
-#define GB_IS_SEARCH_DISPLAY_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GB_TYPE_SEARCH_DISPLAY_GROUP))
-#define GB_IS_SEARCH_DISPLAY_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GB_TYPE_SEARCH_DISPLAY_GROUP))
-#define GB_SEARCH_DISPLAY_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GB_TYPE_SEARCH_DISPLAY_GROUP, GbSearchDisplayGroupClass))
-
-struct _GbSearchDisplayGroup
-{
- GtkBox parent;
-
- /*< private >*/
- GbSearchDisplayGroupPrivate *priv;
-};
-
-struct _GbSearchDisplayGroupClass
-{
- GtkBoxClass parent;
-};
-
-void gb_search_display_group_clear (GbSearchDisplayGroup *group);
-GbSearchProvider *gb_search_display_group_get_provider (GbSearchDisplayGroup *group);
-void gb_search_display_group_add_result (GbSearchDisplayGroup *group,
- GbSearchResult *result);
-void gb_search_display_group_remove_result (GbSearchDisplayGroup *group,
- GbSearchResult *result);
-void gb_search_display_group_set_count (GbSearchDisplayGroup *group,
- guint64 count);
-void gb_search_display_group_unselect (GbSearchDisplayGroup *group);
-void gb_search_display_group_focus_first (GbSearchDisplayGroup *group);
-void gb_search_display_group_focus_last (GbSearchDisplayGroup *group);
-GbSearchResult *gb_search_display_group_get_first (GbSearchDisplayGroup *group);
+#define GB_TYPE_SEARCH_DISPLAY_GROUP (gb_search_display_group_get_type())
+
+G_DECLARE_FINAL_TYPE (GbSearchDisplayGroup, gb_search_display_group, GB, SEARCH_DISPLAY_GROUP, GtkBox)
+
+void gb_search_display_group_clear (GbSearchDisplayGroup *group);
+IdeSearchProvider *gb_search_display_group_get_provider (GbSearchDisplayGroup *group);
+void gb_search_display_group_add_result (GbSearchDisplayGroup *group,
+ IdeSearchResult *result);
+void gb_search_display_group_remove_result (GbSearchDisplayGroup *group,
+ IdeSearchResult *result);
+void gb_search_display_group_set_count (GbSearchDisplayGroup *group,
+ guint64 count);
+void gb_search_display_group_unselect (GbSearchDisplayGroup *group);
+void gb_search_display_group_focus_first (GbSearchDisplayGroup *group);
+void gb_search_display_group_focus_last (GbSearchDisplayGroup *group);
+IdeSearchResult *gb_search_display_group_get_first (GbSearchDisplayGroup *group);
G_END_DECLS
diff --git a/src/search/gb-search-display-row.c b/src/search/gb-search-display-row.c
index f7fc31a..55a85f8 100644
--- a/src/search/gb-search-display-row.c
+++ b/src/search/gb-search-display-row.c
@@ -19,21 +19,21 @@
#include <glib/gi18n.h>
#include "gb-search-display-row.h"
-#include "gb-search-result.h"
#include "gb-widget.h"
-struct _GbSearchDisplayRowPrivate
+struct _GbSearchDisplayRow
{
- GbSearchResult *result;
+ GtkBox parent_instance;
+
+ IdeSearchResult *result;
/* References owned by template */
- GtkLabel *title;
- GtkLabel *subtitle;
- GtkProgressBar *progress;
+ GtkLabel *title;
+ GtkLabel *subtitle;
+ GtkProgressBar *progress;
};
-G_DEFINE_TYPE_WITH_PRIVATE (GbSearchDisplayRow, gb_search_display_row,
- GTK_TYPE_BOX)
+G_DEFINE_TYPE (GbSearchDisplayRow, gb_search_display_row, GTK_TYPE_BOX)
enum {
PROP_0,
@@ -45,50 +45,50 @@ static GParamSpec *gParamSpecs [LAST_PROP];
static void
gb_search_display_row_connect (GbSearchDisplayRow *row,
- GbSearchResult *result)
+ IdeSearchResult *result)
{
const gchar *title;
const gchar *subtitle;
gfloat fraction;
g_return_if_fail (GB_IS_SEARCH_DISPLAY_ROW (row));
- g_return_if_fail (GB_IS_SEARCH_RESULT (result));
+ g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
- title = gb_search_result_get_title (result);
- gtk_label_set_markup (row->priv->title, title);
+ title = ide_search_result_get_title (result);
+ gtk_label_set_markup (row->title, title);
- subtitle = gb_search_result_get_subtitle (result);
+ subtitle = ide_search_result_get_subtitle (result);
if (subtitle)
- gtk_label_set_markup (row->priv->subtitle, subtitle);
- gtk_widget_set_visible (GTK_WIDGET (row->priv->subtitle), !!subtitle);
+ gtk_label_set_markup (row->subtitle, subtitle);
+ gtk_widget_set_visible (GTK_WIDGET (row->subtitle), !!subtitle);
- fraction = gb_search_result_get_score (result);
- gtk_progress_bar_set_fraction (row->priv->progress, fraction);
- gtk_widget_set_visible (GTK_WIDGET (row->priv->progress), (fraction > 0.0));
+ fraction = ide_search_result_get_score (result);
+ gtk_progress_bar_set_fraction (row->progress, fraction);
+ gtk_widget_set_visible (GTK_WIDGET (row->progress), (fraction > 0.0));
}
-GbSearchResult *
+IdeSearchResult *
gb_search_display_row_get_result (GbSearchDisplayRow *row)
{
g_return_val_if_fail (GB_IS_SEARCH_DISPLAY_ROW (row), NULL);
- return row->priv->result;
+ return row->result;
}
void
gb_search_display_row_set_result (GbSearchDisplayRow *row,
- GbSearchResult *result)
+ IdeSearchResult *result)
{
g_return_if_fail (GB_IS_SEARCH_DISPLAY_ROW (row));
- g_return_if_fail (GB_IS_SEARCH_RESULT (result));
+ g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
- if (result != row->priv->result)
+ if (result != row->result)
{
- g_clear_object (&row->priv->result);
+ g_clear_object (&row->result);
if (result)
{
- row->priv->result = g_object_ref (result);
+ row->result = g_object_ref (result);
gb_search_display_row_connect (row, result);
}
@@ -99,9 +99,9 @@ gb_search_display_row_set_result (GbSearchDisplayRow *row,
static void
gb_search_display_row_finalize (GObject *object)
{
- GbSearchDisplayRowPrivate *priv = GB_SEARCH_DISPLAY_ROW (object)->priv;
+ GbSearchDisplayRow *self = (GbSearchDisplayRow *)object;
- g_clear_object (&priv->result);
+ g_clear_object (&self->result);
G_OBJECT_CLASS (gb_search_display_row_parent_class)->finalize (object);
}
@@ -158,11 +158,9 @@ gb_search_display_row_class_init (GbSearchDisplayRowClass *klass)
g_param_spec_object ("result",
_("Result"),
_("Result"),
- GB_TYPE_SEARCH_RESULT,
- (G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_RESULT,
- gParamSpecs [PROP_RESULT]);
+ IDE_TYPE_SEARCH_RESULT,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_RESULT, gParamSpecs [PROP_RESULT]);
GB_WIDGET_CLASS_TEMPLATE (widget_class, "gb-search-display-row.ui");
GB_WIDGET_CLASS_BIND (widget_class, GbSearchDisplayRow, progress);
@@ -173,7 +171,5 @@ gb_search_display_row_class_init (GbSearchDisplayRowClass *klass)
static void
gb_search_display_row_init (GbSearchDisplayRow *self)
{
- self->priv = gb_search_display_row_get_instance_private (self);
-
gtk_widget_init_template (GTK_WIDGET (self));
}
diff --git a/src/search/gb-search-display-row.h b/src/search/gb-search-display-row.h
index 807a6c1..649a8a2 100644
--- a/src/search/gb-search-display-row.h
+++ b/src/search/gb-search-display-row.h
@@ -20,34 +20,17 @@
#define GB_SEARCH_DISPLAY_ROW_H
#include <gtk/gtk.h>
-
-#include "gb-search-types.h"
+#include <ide.h>
G_BEGIN_DECLS
-#define GB_SEARCH_DISPLAY_ROW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_SEARCH_DISPLAY_ROW, GbSearchDisplayRow))
-#define GB_SEARCH_DISPLAY_ROW_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GB_TYPE_SEARCH_DISPLAY_ROW, GbSearchDisplayRow const))
-#define GB_SEARCH_DISPLAY_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GB_TYPE_SEARCH_DISPLAY_ROW, GbSearchDisplayRowClass))
-#define GB_IS_SEARCH_DISPLAY_ROW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GB_TYPE_SEARCH_DISPLAY_ROW))
-#define GB_IS_SEARCH_DISPLAY_ROW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GB_TYPE_SEARCH_DISPLAY_ROW))
-#define GB_SEARCH_DISPLAY_ROW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GB_TYPE_SEARCH_DISPLAY_ROW, GbSearchDisplayRowClass))
-
-struct _GbSearchDisplayRow
-{
- GtkBox parent;
-
- /*< private >*/
- GbSearchDisplayRowPrivate *priv;
-};
-
-struct _GbSearchDisplayRowClass
-{
- GtkBoxClass parent;
-};
-
-GbSearchResult *gb_search_display_row_get_result (GbSearchDisplayRow *row);
-void gb_search_display_row_set_result (GbSearchDisplayRow *row,
- GbSearchResult *result);
+#define GB_TYPE_SEARCH_DISPLAY_ROW (gb_search_display_row_get_type())
+
+G_DECLARE_FINAL_TYPE (GbSearchDisplayRow, gb_search_display_row, GB, SEARCH_DISPLAY_ROW, GtkBox)
+
+IdeSearchResult *gb_search_display_row_get_result (GbSearchDisplayRow *row);
+void gb_search_display_row_set_result (GbSearchDisplayRow *row,
+ IdeSearchResult *result);
G_END_DECLS
diff --git a/src/search/gb-search-display.c b/src/search/gb-search-display.c
index da092c9..8561588 100644
--- a/src/search/gb-search-display.c
+++ b/src/search/gb-search-display.c
@@ -16,28 +16,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#define G_LOG_DOMAIN "gb-search-display"
+
#include <glib/gi18n.h>
+#include <ide.h>
#include "gb-search-display.h"
#include "gb-search-display-group.h"
-#include "gb-search-provider.h"
-#include "gb-search-result.h"
-struct _GbSearchDisplayPrivate
+struct _GbSearchDisplay
{
- GbSearchContext *context;
- GArray *providers;
+ GtkBox parent_instance;
+
+ IdeSearchContext *context;
+ GPtrArray *providers;
GtkSizeGroup *size_group;
GbSearchDisplayGroup *last_group;
};
typedef struct
{
- GbSearchProvider *provider;
+ IdeSearchProvider *provider;
GbSearchDisplayGroup *group;
} ProviderEntry;
-G_DEFINE_TYPE_WITH_PRIVATE (GbSearchDisplay, gb_search_display, GTK_TYPE_BOX)
+G_DEFINE_TYPE (GbSearchDisplay, gb_search_display, GTK_TYPE_BOX)
enum {
PROP_0,
@@ -58,20 +61,28 @@ provider_entry_destroy (gpointer data)
{
ProviderEntry *entry = data;
+ IDE_ENTRY;
+
+ IDE_TRACE_MSG ("releasing %p", data);
+
+ ide_clear_weak_pointer (&entry->group);
g_clear_object (&entry->provider);
+ g_free (entry);
+
+ IDE_EXIT;
}
static gint
provider_entry_sort (gconstpointer ptra,
gconstpointer ptrb)
{
- const ProviderEntry *entrya = ptra;
- const ProviderEntry *entryb = ptrb;
+ ProviderEntry **entrya = (ProviderEntry **)ptra;
+ ProviderEntry **entryb = (ProviderEntry **)ptrb;
gint a;
gint b;
- a = gb_search_provider_get_priority ((GB_SEARCH_PROVIDER (entrya->provider)));
- b = gb_search_provider_get_priority ((GB_SEARCH_PROVIDER (entryb->provider)));
+ a = ide_search_provider_get_priority ((IDE_SEARCH_PROVIDER ((*entrya)->provider)));
+ b = ide_search_provider_get_priority ((IDE_SEARCH_PROVIDER ((*entryb)->provider)));
return a - b;
}
@@ -83,50 +94,54 @@ gb_search_display_new (void)
}
static void
-gb_search_display_real_result_activated (GbSearchDisplay *display,
- GbSearchResult *result)
+gb_search_display_real_result_activated (GbSearchDisplay *self,
+ IdeSearchResult *result)
{
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (GB_IS_SEARCH_RESULT (result));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
- gb_search_result_activate (result);
+#if 1
+ g_warning ("ACTICATE SEARCH RESULT");
+#else
+ ide_search_result_activate (result);
+#endif
}
static void
-gb_search_display_result_activated (GbSearchDisplay *display,
- GbSearchResult *result,
+gb_search_display_result_activated (GbSearchDisplay *self,
+ IdeSearchResult *result,
GbSearchDisplayGroup *group)
{
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (!result || GB_IS_SEARCH_RESULT (result));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (!result || IDE_IS_SEARCH_RESULT (result));
g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
- g_signal_emit (display, gSignals [RESULT_ACTIVATED], 0, result);
+ g_signal_emit (self, gSignals [RESULT_ACTIVATED], 0, result);
}
static void
-gb_search_display_result_selected (GbSearchDisplay *display,
- GbSearchResult *result,
+gb_search_display_result_selected (GbSearchDisplay *self,
+ IdeSearchResult *result,
GbSearchDisplayGroup *group)
{
guint i;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (!result || GB_IS_SEARCH_RESULT (result));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (!result || IDE_IS_SEARCH_RESULT (result));
g_return_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group));
- for (i = 0; i < display->priv->providers->len; i++)
+ for (i = 0; i < self->providers->len; i++)
{
ProviderEntry *ptr;
- ptr = &g_array_index (display->priv->providers, ProviderEntry, i);
- if (ptr->group != group)
+ ptr = g_ptr_array_index (self->providers, i);
+ if ((ptr->group != NULL) && (ptr->group != group))
gb_search_display_group_unselect (ptr->group);
}
}
static gboolean
-gb_search_display_keynav_failed (GbSearchDisplay *display,
+gb_search_display_keynav_failed (GbSearchDisplay *self,
GtkDirectionType dir,
GbSearchDisplayGroup *group)
{
@@ -134,18 +149,18 @@ gb_search_display_keynav_failed (GbSearchDisplay *display,
GList *iter;
gint position = -1;
- g_return_val_if_fail (GB_IS_SEARCH_DISPLAY (display), FALSE);
+ g_return_val_if_fail (GB_IS_SEARCH_DISPLAY (self), FALSE);
g_return_val_if_fail (GB_IS_SEARCH_DISPLAY_GROUP (group), FALSE);
- gtk_container_child_get (GTK_CONTAINER (display), GTK_WIDGET (group),
+ gtk_container_child_get (GTK_CONTAINER (self), GTK_WIDGET (group),
"position", &position,
NULL);
if (dir == GTK_DIR_DOWN)
{
- list = gtk_container_get_children (GTK_CONTAINER (display));
+ list = gtk_container_get_children (GTK_CONTAINER (self));
iter = g_list_nth (list, position + 1);
- if (iter && (iter->data != display->priv->last_group))
+ if (iter && (iter->data != self->last_group))
{
gb_search_display_group_unselect (group);
gb_search_display_group_focus_first (iter->data);
@@ -154,7 +169,7 @@ gb_search_display_keynav_failed (GbSearchDisplay *display,
}
else if (dir == GTK_DIR_UP && position > 0)
{
- list = gtk_container_get_children (GTK_CONTAINER (display));
+ list = gtk_container_get_children (GTK_CONTAINER (self));
iter = g_list_nth (list, position - 1);
if (iter)
{
@@ -170,20 +185,18 @@ gb_search_display_keynav_failed (GbSearchDisplay *display,
void
gb_search_display_activate (GbSearchDisplay *self)
{
- GbSearchDisplayPrivate *priv;
- GbSearchResult *result = NULL;
+ IdeSearchResult *result = NULL;
guint i;
g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
- priv = self->priv;
-
- for (i = 0; !result && i < priv->providers->len; i++)
+ for (i = 0; !result && i < self->providers->len; i++)
{
ProviderEntry *ptr;
- ptr = &g_array_index (self->priv->providers, ProviderEntry, i);
- result = gb_search_display_group_get_first (ptr->group);
+ ptr = g_ptr_array_index (self->providers, i);
+ if (ptr->group != NULL)
+ result = gb_search_display_group_get_first (ptr->group);
}
if (result)
@@ -191,24 +204,24 @@ gb_search_display_activate (GbSearchDisplay *self)
}
static void
-gb_search_display_add_provider (GbSearchDisplay *display,
- GbSearchProvider *provider)
+gb_search_display_add_provider (GbSearchDisplay *self,
+ IdeSearchProvider *provider)
{
- ProviderEntry entry = { 0 };
+ ProviderEntry *entry;
guint i;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
/*
* Make sure we don't add an item twice. Probably can assert here, but
* warning will do for now.
*/
- for (i = 0; i < display->priv->providers->len; i++)
+ for (i = 0; i < self->providers->len; i++)
{
ProviderEntry *ptr;
- ptr = &g_array_index (display->priv->providers, ProviderEntry, i);
+ ptr = g_ptr_array_index (self->providers, i);
if (ptr->provider == provider)
{
@@ -221,44 +234,46 @@ gb_search_display_add_provider (GbSearchDisplay *display,
* Add the entry to our array and sort the array to determine our target
* widget packing position.
*/
- entry.provider = g_object_ref (provider);
- entry.group = g_object_new (GB_TYPE_SEARCH_DISPLAY_GROUP,
- "size-group", display->priv->size_group,
- "provider", provider,
- "visible", FALSE,
- NULL);
- g_signal_connect_object (entry.group,
+ entry = g_new0 (ProviderEntry, 1);
+ entry->provider = g_object_ref (provider);
+ entry->group = g_object_new (GB_TYPE_SEARCH_DISPLAY_GROUP,
+ "size-group", self->size_group,
+ "provider", provider,
+ "visible", FALSE,
+ NULL);
+ g_object_add_weak_pointer (G_OBJECT (entry->group), (gpointer *)&entry->group);
+ g_signal_connect_object (entry->group,
"result-activated",
G_CALLBACK (gb_search_display_result_activated),
- display,
+ self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (entry.group,
+ g_signal_connect_object (entry->group,
"result-selected",
G_CALLBACK (gb_search_display_result_selected),
- display,
+ self,
G_CONNECT_SWAPPED);
- g_signal_connect_object (entry.group,
+ g_signal_connect_object (entry->group,
"keynav-failed",
G_CALLBACK (gb_search_display_keynav_failed),
- display,
+ self,
G_CONNECT_SWAPPED);
- g_array_append_val (display->priv->providers, entry);
- g_array_sort (display->priv->providers, provider_entry_sort);
+ g_ptr_array_add (self->providers, entry);
+ g_ptr_array_sort (self->providers, provider_entry_sort);
/*
* Find the location of the entry and use the index to pack the display
* group widget.
*/
- for (i = 0; i < display->priv->providers->len; i++)
+ for (i = 0; i < self->providers->len; i++)
{
ProviderEntry *ptr;
- ptr = &g_array_index (display->priv->providers, ProviderEntry, i);
+ ptr = g_ptr_array_index (self->providers, i);
if (ptr->provider == provider)
{
- gtk_container_add_with_properties (GTK_CONTAINER (display),
- GTK_WIDGET (entry.group),
+ gtk_container_add_with_properties (GTK_CONTAINER (self),
+ GTK_WIDGET (entry->group),
"position", i,
NULL);
break;
@@ -267,25 +282,27 @@ gb_search_display_add_provider (GbSearchDisplay *display,
}
static void
-gb_search_display_remove_provider (GbSearchDisplay *display,
- GbSearchProvider *provider)
+gb_search_display_remove_provider (GbSearchDisplay *self,
+ IdeSearchProvider *provider)
{
guint i;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
- for (i = 0; i < display->priv->providers->len; i++)
+ for (i = 0; i < self->providers->len; i++)
{
ProviderEntry *ptr;
- ptr = &g_array_index (display->priv->providers, ProviderEntry, i);
+ ptr = g_ptr_array_index (self->providers, i);
if (ptr->provider == provider)
{
- gtk_container_remove (GTK_CONTAINER (display),
- GTK_WIDGET (ptr->group));
- g_array_remove_index (display->priv->providers, i);
+ GbSearchDisplayGroup *group = ptr->group;
+
+ if (group)
+ gtk_container_remove (GTK_CONTAINER (self), GTK_WIDGET (group));
+ g_ptr_array_remove_index (self->providers, i);
return;
}
}
@@ -294,173 +311,174 @@ gb_search_display_remove_provider (GbSearchDisplay *display,
}
static void
-gb_search_display_result_added (GbSearchDisplay *display,
- GbSearchProvider *provider,
- GbSearchResult *result,
- GbSearchContext *context)
+gb_search_display_result_added (GbSearchDisplay *self,
+ IdeSearchProvider *provider,
+ IdeSearchResult *result,
+ IdeSearchContext *context)
{
guint i;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
- g_return_if_fail (GB_IS_SEARCH_RESULT (result));
- g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+ g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
+ g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
- for (i = 0; i < display->priv->providers->len; i++)
+ for (i = 0; i < self->providers->len; i++)
{
ProviderEntry *ptr;
- ptr = &g_array_index (display->priv->providers, ProviderEntry, i);
+ ptr = g_ptr_array_index (self->providers, i);
if (ptr->provider == provider)
{
- gb_search_display_group_add_result (ptr->group, result);
- gtk_widget_show (GTK_WIDGET (ptr->group));
+ if (ptr->group != NULL)
+ {
+ gb_search_display_group_add_result (ptr->group, result);
+ gtk_widget_show (GTK_WIDGET (ptr->group));
+ }
break;
}
}
}
static void
-gb_search_display_result_removed (GbSearchDisplay *display,
- GbSearchProvider *provider,
- GbSearchResult *result,
- GbSearchContext *context)
+gb_search_display_result_removed (GbSearchDisplay *self,
+ IdeSearchProvider *provider,
+ IdeSearchResult *result,
+ IdeSearchContext *context)
{
guint i;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
- g_return_if_fail (GB_IS_SEARCH_RESULT (result));
- g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+ g_return_if_fail (IDE_IS_SEARCH_RESULT (result));
+ g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
- for (i = 0; i < display->priv->providers->len; i++)
+ for (i = 0; i < self->providers->len; i++)
{
ProviderEntry *ptr;
- ptr = &g_array_index (display->priv->providers, ProviderEntry, i);
+ ptr = g_ptr_array_index (self->providers, i);
if (ptr->provider == provider)
{
- gb_search_display_group_remove_result (ptr->group, result);
+ if (ptr->group != NULL)
+ gb_search_display_group_remove_result (ptr->group, result);
break;
}
}
}
static void
-gb_search_display_count_set (GbSearchDisplay *display,
- GbSearchProvider *provider,
- guint64 count,
- GbSearchContext *context)
+gb_search_display_count_set (GbSearchDisplay *self,
+ IdeSearchProvider *provider,
+ guint64 count,
+ IdeSearchContext *context)
{
guint i;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (GB_IS_SEARCH_PROVIDER (provider));
- g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (IDE_IS_SEARCH_PROVIDER (provider));
+ g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
- for (i = 0; i < display->priv->providers->len; i++)
+ for (i = 0; i < self->providers->len; i++)
{
ProviderEntry *ptr;
- ptr = &g_array_index (display->priv->providers, ProviderEntry, i);
+ ptr = g_ptr_array_index (self->providers, i);
if (ptr->provider == provider)
{
- gb_search_display_group_set_count (ptr->group, count);
+ if (ptr->group != NULL)
+ gb_search_display_group_set_count (ptr->group, count);
break;
}
}
}
static void
-gb_search_display_connect_context (GbSearchDisplay *display,
- GbSearchContext *context)
+gb_search_display_connect_context (GbSearchDisplay *self,
+ IdeSearchContext *context)
{
const GList *providers;
const GList *iter;
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
- providers = gb_search_context_get_providers (context);
+ providers = ide_search_context_get_providers (context);
for (iter = providers; iter; iter = iter->next)
- gb_search_display_add_provider (display, iter->data);
+ gb_search_display_add_provider (self, iter->data);
g_signal_connect_object (context,
"result-added",
G_CALLBACK (gb_search_display_result_added),
- display,
+ self,
G_CONNECT_SWAPPED);
g_signal_connect_object (context,
"result-removed",
G_CALLBACK (gb_search_display_result_removed),
- display,
+ self,
G_CONNECT_SWAPPED);
g_signal_connect_object (context,
"count-set",
G_CALLBACK (gb_search_display_count_set),
- display,
+ self,
G_CONNECT_SWAPPED);
}
static void
-gb_search_display_disconnect_context (GbSearchDisplay *display,
- GbSearchContext *context)
+gb_search_display_disconnect_context (GbSearchDisplay *self,
+ IdeSearchContext *context)
{
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (GB_IS_SEARCH_CONTEXT (context));
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (IDE_IS_SEARCH_CONTEXT (context));
- while (display->priv->providers->len)
+ g_signal_handlers_disconnect_by_func (context,
+ G_CALLBACK (gb_search_display_result_added),
+ self);
+
+ while (self->providers->len)
{
ProviderEntry *ptr;
- ptr = &g_array_index (display->priv->providers, ProviderEntry,
- display->priv->providers->len - 1);
- gb_search_display_remove_provider (display, ptr->provider);
+ ptr = g_ptr_array_index (self->providers,
+ self->providers->len - 1);
+ gb_search_display_remove_provider (self, ptr->provider);
}
-
- g_signal_handlers_disconnect_by_func (context,
- G_CALLBACK (gb_search_display_result_added),
- display);
}
-GbSearchContext *
-gb_search_display_get_context (GbSearchDisplay *display)
+IdeSearchContext *
+gb_search_display_get_context (GbSearchDisplay *self)
{
- g_return_val_if_fail (GB_IS_SEARCH_DISPLAY (display), NULL);
+ g_return_val_if_fail (GB_IS_SEARCH_DISPLAY (self), NULL);
- return display->priv->context;
+ return self->context;
}
void
-gb_search_display_set_context (GbSearchDisplay *display,
- GbSearchContext *context)
+gb_search_display_set_context (GbSearchDisplay *self,
+ IdeSearchContext *context)
{
- GbSearchDisplayPrivate *priv;
-
- g_return_if_fail (GB_IS_SEARCH_DISPLAY (display));
- g_return_if_fail (!context || GB_IS_SEARCH_CONTEXT (context));
-
- priv = display->priv;
+ g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
+ g_return_if_fail (!context || IDE_IS_SEARCH_CONTEXT (context));
- if (priv->context != context)
+ if (self->context != context)
{
- if (priv->context)
+ if (self->context)
{
- gb_search_display_disconnect_context (display, priv->context);
- g_clear_object (&display->priv->context);
+ gb_search_display_disconnect_context (self, self->context);
+ g_clear_object (&self->context);
}
if (context)
{
- priv->context = g_object_ref (context);
- gb_search_display_connect_context (display, priv->context);
+ self->context = g_object_ref (context);
+ gb_search_display_connect_context (self, self->context);
}
- g_object_notify_by_pspec (G_OBJECT (display), gParamSpecs [PROP_CONTEXT]);
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_CONTEXT]);
}
}
@@ -471,11 +489,11 @@ gb_search_display_grab_focus (GtkWidget *widget)
g_return_if_fail (GB_IS_SEARCH_DISPLAY (self));
- if (self->priv->providers->len)
+ if (self->providers->len)
{
ProviderEntry *ptr;
- ptr = &g_array_index (self->priv->providers, ProviderEntry, 0);
+ ptr = g_ptr_array_index (self->providers, 0);
gtk_widget_child_focus (GTK_WIDGET (ptr->group), GTK_DIR_DOWN);
}
}
@@ -483,11 +501,11 @@ gb_search_display_grab_focus (GtkWidget *widget)
static void
gb_search_display_dispose (GObject *object)
{
- GbSearchDisplayPrivate *priv = GB_SEARCH_DISPLAY (object)->priv;
+ GbSearchDisplay *self = (GbSearchDisplay *)object;
- g_clear_pointer (&priv->providers, g_array_unref);
- g_clear_object (&priv->context);
- g_clear_object (&priv->size_group);
+ g_clear_pointer (&self->providers, g_ptr_array_unref);
+ g_clear_object (&self->context);
+ g_clear_object (&self->size_group);
G_OBJECT_CLASS (gb_search_display_parent_class)->dispose (object);
}
@@ -542,50 +560,41 @@ gb_search_display_class_init (GbSearchDisplayClass *klass)
object_class->get_property = gb_search_display_get_property;
object_class->set_property = gb_search_display_set_property;
- klass->result_activated = gb_search_display_real_result_activated;
-
gParamSpecs [PROP_CONTEXT] =
g_param_spec_object ("context",
_("Context"),
_("The active search context."),
- GB_TYPE_SEARCH_CONTEXT,
- (G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_CONTEXT,
- gParamSpecs [PROP_CONTEXT]);
+ IDE_TYPE_SEARCH_CONTEXT,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_CONTEXT, gParamSpecs [PROP_CONTEXT]);
gSignals [RESULT_ACTIVATED] =
- g_signal_new ("result-activated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GbSearchDisplayClass, result_activated),
- NULL,
- NULL,
- g_cclosure_marshal_generic,
- G_TYPE_NONE,
- 1,
- GB_TYPE_SEARCH_RESULT);
+ g_signal_new_class_handler ("result-activated",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_CALLBACK (gb_search_display_real_result_activated),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ IDE_TYPE_SEARCH_RESULT);
}
static void
gb_search_display_init (GbSearchDisplay *self)
{
- self->priv = gb_search_display_get_instance_private (self);
-
- self->priv->providers = g_array_new (FALSE, FALSE, sizeof (ProviderEntry));
- g_array_set_clear_func (self->priv->providers,
- (GDestroyNotify)provider_entry_destroy);
+ self->providers = g_ptr_array_new_with_free_func (provider_entry_destroy);
- self->priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ self->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
gtk_orientable_set_orientation (GTK_ORIENTABLE (self),
GTK_ORIENTATION_VERTICAL);
- self->priv->last_group = g_object_new (GB_TYPE_SEARCH_DISPLAY_GROUP,
- "size-group", self->priv->size_group,
+ self->last_group = g_object_new (GB_TYPE_SEARCH_DISPLAY_GROUP,
+ "size-group", self->size_group,
"visible", TRUE,
"vexpand", TRUE,
NULL);
gtk_container_add (GTK_CONTAINER (self),
- GTK_WIDGET (self->priv->last_group));
+ GTK_WIDGET (self->last_group));
}
diff --git a/src/search/gb-search-display.h b/src/search/gb-search-display.h
index 7958c21..66cdc89 100644
--- a/src/search/gb-search-display.h
+++ b/src/search/gb-search-display.h
@@ -20,39 +20,18 @@
#define GB_SEARCH_DISPLAY_H
#include <gtk/gtk.h>
-
-#include "gb-search-types.h"
+#include <ide.h>
G_BEGIN_DECLS
-#define GB_SEARCH_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_DISPLAY,
GbSearchDisplay))
-#define GB_SEARCH_DISPLAY_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_SEARCH_DISPLAY,
GbSearchDisplay const))
-#define GB_SEARCH_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_SEARCH_DISPLAY,
GbSearchDisplayClass))
-#define GB_IS_SEARCH_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_SEARCH_DISPLAY))
-#define GB_IS_SEARCH_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_SEARCH_DISPLAY))
-#define GB_SEARCH_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_SEARCH_DISPLAY,
GbSearchDisplayClass))
-
-struct _GbSearchDisplay
-{
- GtkBox parent;
-
- /*< private >*/
- GbSearchDisplayPrivate *priv;
-};
-
-struct _GbSearchDisplayClass
-{
- GtkBoxClass parent;
-
- void (*result_activated) (GbSearchDisplay *display,
- GbSearchResult *result);
-};
-
-GtkWidget *gb_search_display_new (void);
-void gb_search_display_activate (GbSearchDisplay *display);
-GbSearchContext *gb_search_display_get_context (GbSearchDisplay *display);
-void gb_search_display_set_context (GbSearchDisplay *display,
- GbSearchContext *context);
+#define GB_TYPE_SEARCH_DISPLAY (gb_search_display_get_type())
+
+G_DECLARE_FINAL_TYPE (GbSearchDisplay, gb_search_display, GB, SEARCH_DISPLAY, GtkBin)
+
+void gb_search_display_activate (GbSearchDisplay *display);
+IdeSearchContext *gb_search_display_get_context (GbSearchDisplay *display);
+void gb_search_display_set_context (GbSearchDisplay *display,
+ IdeSearchContext *context);
G_END_DECLS
diff --git a/src/tree/gb-tree.c b/src/tree/gb-tree.c
index b808d81..037424d 100644
--- a/src/tree/gb-tree.c
+++ b/src/tree/gb-tree.c
@@ -19,8 +19,8 @@
#define G_LOG_DOMAIN "tree"
#include <glib/gi18n.h>
+#include <ide.h>
-#include "gb-log.h"
#include "gb-tree.h"
#include "gb-tree-node.h"
@@ -98,14 +98,14 @@ gb_tree_unselect (GbTree *tree)
{
GtkTreeSelection *selection;
- ENTRY;
+ IDE_ENTRY;
g_return_if_fail (GB_IS_TREE (tree));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
gtk_tree_selection_unselect_all (selection);
- EXIT;
+ IDE_EXIT;
}
/**
@@ -123,7 +123,7 @@ gb_tree_select (GbTree *tree,
GbTreePrivate *priv;
GtkTreePath *path;
- ENTRY;
+ IDE_ENTRY;
g_return_if_fail (GB_IS_TREE (tree));
g_return_if_fail (GB_IS_TREE_NODE (node));
@@ -143,7 +143,7 @@ gb_tree_select (GbTree *tree,
gtk_tree_selection_select_path (selection, path);
gtk_tree_path_free (path);
- EXIT;
+ IDE_EXIT;
}
static void
@@ -188,7 +188,7 @@ gb_tree_popup (GbTree *tree,
gboolean at_least_one_visible = FALSE;
guint i;
- ENTRY;
+ IDE_ENTRY;
g_return_if_fail (GB_IS_TREE (tree));
g_return_if_fail (GB_IS_TREE_NODE (node));
@@ -221,7 +221,7 @@ gb_tree_popup (GbTree *tree,
button->button,
button->time);
- EXIT;
+ IDE_EXIT;
}
/**
@@ -242,7 +242,7 @@ gb_tree_selection_changed (GbTree *tree,
GbTreeNode *unselection;
gint i;
- ENTRY;
+ IDE_ENTRY;
g_return_if_fail (GB_IS_TREE (tree));
g_return_if_fail (GTK_IS_TREE_SELECTION (selection));
@@ -273,7 +273,7 @@ gb_tree_selection_changed (GbTree *tree,
}
}
- EXIT;
+ IDE_EXIT;
}
/**
@@ -416,7 +416,7 @@ gb_tree_add_builder_foreach_cb (GtkTreeModel *model,
GbTreeNode *node = NULL;
GbTreeBuilder *builder = (GbTreeBuilder *) user_data;
- ENTRY;
+ IDE_ENTRY;
g_return_val_if_fail (GTK_IS_TREE_MODEL (model), FALSE);
g_return_val_if_fail (path != NULL, FALSE);
@@ -426,7 +426,7 @@ gb_tree_add_builder_foreach_cb (GtkTreeModel *model,
gb_tree_builder_build_node (builder, node);
g_clear_object (&node);
- RETURN (FALSE);
+ IDE_RETURN (FALSE);
}
/**
@@ -442,7 +442,7 @@ gb_tree_add_builder (GbTree *tree,
{
GbTreePrivate *priv;
- ENTRY;
+ IDE_ENTRY;
g_return_if_fail (GB_IS_TREE (tree));
g_return_if_fail (GB_IS_TREE_BUILDER (builder));
@@ -460,7 +460,7 @@ gb_tree_add_builder (GbTree *tree,
if (GB_TREE_BUILDER_GET_CLASS (builder)->added)
GB_TREE_BUILDER_GET_CLASS (builder)->added (builder, GTK_WIDGET (tree));
- EXIT;
+ IDE_EXIT;
}
/**
@@ -474,7 +474,7 @@ void
gb_tree_remove_builder (GbTree *tree,
GbTreeBuilder *builder)
{
- ENTRY;
+ IDE_ENTRY;
g_return_if_fail (GB_IS_TREE (tree));
g_return_if_fail (GB_IS_TREE_BUILDER (builder));
@@ -484,7 +484,7 @@ gb_tree_remove_builder (GbTree *tree,
g_ptr_array_remove (tree->priv->builders, builder);
- EXIT;
+ IDE_EXIT;
}
/**
@@ -520,7 +520,7 @@ gb_tree_set_root (GbTree *tree,
GbTreeBuilder *builder;
gint i;
- ENTRY;
+ IDE_ENTRY;
g_return_if_fail (GB_IS_TREE (tree));
@@ -540,7 +540,7 @@ gb_tree_set_root (GbTree *tree,
}
}
- EXIT;
+ IDE_EXIT;
}
void
diff --git a/src/util/gb-widget.c b/src/util/gb-widget.c
index e244678..4f73d84 100644
--- a/src/util/gb-widget.c
+++ b/src/util/gb-widget.c
@@ -16,9 +16,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <ide.h>
#include <math.h>
-#include "gb-animation.h"
#include "gb-cairo.h"
#include "gb-rgba.h"
#include "gb-widget.h"
@@ -176,14 +176,14 @@ gb_widget_fade_hide (GtkWidget *widget)
if (gtk_widget_get_visible (widget))
{
frame_clock = gtk_widget_get_frame_clock (widget);
- gb_object_animate_full (widget,
- GB_ANIMATION_LINEAR,
- 1000,
- frame_clock,
- hide_callback,
- g_object_ref (widget),
- "opacity", 0.0,
- NULL);
+ ide_object_animate_full (widget,
+ IDE_ANIMATION_LINEAR,
+ 1000,
+ frame_clock,
+ hide_callback,
+ g_object_ref (widget),
+ "opacity", 0.0,
+ NULL);
}
}
@@ -199,14 +199,14 @@ gb_widget_fade_show (GtkWidget *widget)
frame_clock = gtk_widget_get_frame_clock (widget);
gtk_widget_set_opacity (widget, 0.0);
gtk_widget_show (widget);
- gb_object_animate_full (widget,
- GB_ANIMATION_LINEAR,
- 500,
- frame_clock,
- NULL,
- NULL,
- "opacity", 1.0,
- NULL);
+ ide_object_animate_full (widget,
+ IDE_ANIMATION_LINEAR,
+ 500,
+ frame_clock,
+ NULL,
+ NULL,
+ "opacity", 1.0,
+ NULL);
}
}
@@ -274,74 +274,64 @@ gb_widget_get_context (GtkWidget *widget)
}
static void
-gb_widget_bind_context_notify (GtkWidget *widget,
- GParamSpec *pspec,
- gpointer user_data)
+gb_widget_notify_context (GtkWidget *toplevel,
+ GParamSpec *pspec,
+ GtkWidget *widget)
{
- GbWorkbench *workbench = (GbWorkbench *)widget;
- GtkWidget *child = user_data;
- IdeContext *context;
+ GbWidgetContextHandler handler;
+ IdeContext *context = NULL;
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (GTK_IS_WIDGET (child));
+ handler = g_object_get_data (G_OBJECT (widget), "GB_CONTEXT_HANDLER");
+ if (!handler)
+ return;
- context = gb_workbench_get_context (workbench);
- g_object_set (child, "context", context, NULL);
+ g_object_get (toplevel, "context", &context, NULL);
+ handler (widget, context);
+ g_clear_object (&context);
}
static void
-gb_widget_bind_context_hierarchy_changed (GtkWidget *widget,
- GtkWidget *previous_toplevel,
- gpointer user_data)
+gb_widget_hierarchy_changed (GtkWidget *widget,
+ GtkWidget *previous_toplevel,
+ gpointer user_data)
{
- GbWorkbench *workbench;
+ GtkWidget *toplevel;
- g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_assert (GTK_IS_WIDGET (widget));
- if (GB_IS_WORKBENCH (previous_toplevel))
+ if (GTK_IS_WINDOW (previous_toplevel))
g_signal_handlers_disconnect_by_func (previous_toplevel,
- G_CALLBACK (gb_widget_bind_context_notify),
+ G_CALLBACK (gb_widget_notify_context),
widget);
- workbench = gb_widget_get_workbench (widget);
+ toplevel = gtk_widget_get_toplevel (widget);
- if (workbench)
+ if (GTK_IS_WINDOW (toplevel))
{
- IdeContext *context;
-
- g_signal_connect_object (workbench,
+ g_signal_connect_object (toplevel,
"notify::context",
- G_CALLBACK (gb_widget_bind_context_notify),
+ G_CALLBACK (gb_widget_notify_context),
widget,
0);
- context = gb_workbench_get_context (workbench);
- g_object_set (widget, "context", context, NULL);
+ gb_widget_notify_context (toplevel, NULL, widget);
}
}
void
-gb_widget_bind_context (GtkWidget *widget)
+gb_widget_set_context_handler (gpointer widget,
+ GbWidgetContextHandler handler)
{
- GParamSpec *pspec;
- IdeContext *context;
+ GtkWidget *toplevel;
g_return_if_fail (GTK_IS_WIDGET (widget));
- pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (widget), "context");
-
- if (!pspec || (pspec->value_type != IDE_TYPE_CONTEXT))
- {
- g_warning ("%s() requires a widget with a context property named "
- "\"context\".", G_STRFUNC);
- return;
- }
+ g_object_set_data (G_OBJECT (widget), "GB_CONTEXT_HANDLER", handler);
g_signal_connect (widget,
"hierarchy-changed",
- G_CALLBACK (gb_widget_bind_context_hierarchy_changed),
+ G_CALLBACK (gb_widget_hierarchy_changed),
NULL);
- context = gb_widget_get_context (widget);
- if (context)
- g_object_set (widget, "context", context, NULL);
+ if ((toplevel = gtk_widget_get_toplevel (widget)))
+ gb_widget_hierarchy_changed (widget, NULL, NULL);
}
diff --git a/src/util/gb-widget.h b/src/util/gb-widget.h
index 1257882..b3aa907 100644
--- a/src/util/gb-widget.h
+++ b/src/util/gb-widget.h
@@ -30,25 +30,30 @@ G_BEGIN_DECLS
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS (klass), \
"/org/gnome/builder/ui/"name)
#define GB_WIDGET_CLASS_BIND(klass, TN, field) \
- gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), \
- TN, field)
-
-void gb_widget_bind_context (GtkWidget *widget);
-IdeContext *gb_widget_get_context (GtkWidget *widget);
-void gb_widget_add_style_class (gpointer widget,
- const gchar *class_name);
-cairo_surface_t *gb_widget_snapshot (GtkWidget *widget,
- gint width,
- gint height,
- gdouble alpha,
- gboolean draw_border);
-GbWorkbench *gb_widget_get_workbench (GtkWidget *widget);
-void gb_widget_fade_hide (GtkWidget *widget);
-void gb_widget_fade_show (GtkWidget *widget);
-void gb_widget_activate_action (GtkWidget *widget,
- const gchar *prefix,
- const gchar *action_name,
- GVariant *parameter);
+ gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS (klass), TN, field)
+#define GB_WIDGET_CLASS_BIND_PRIVATE(klass, TN, field) \
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), TN, field)
+
+typedef void (*GbWidgetContextHandler) (GtkWidget *widget,
+ IdeContext *context);
+
+IdeContext *gb_widget_get_context (GtkWidget *widget);
+void gb_widget_add_style_class (gpointer widget,
+ const gchar *class_name);
+cairo_surface_t *gb_widget_snapshot (GtkWidget *widget,
+ gint width,
+ gint height,
+ gdouble alpha,
+ gboolean draw_border);
+GbWorkbench *gb_widget_get_workbench (GtkWidget *widget);
+void gb_widget_fade_hide (GtkWidget *widget);
+void gb_widget_fade_show (GtkWidget *widget);
+void gb_widget_activate_action (GtkWidget *widget,
+ const gchar *prefix,
+ const gchar *action_name,
+ GVariant *parameter);
+void gb_widget_set_context_handler (gpointer widget,
+ GbWidgetContextHandler handler);
G_END_DECLS
diff --git a/src/views/gb-view-grid.c b/src/views/gb-view-grid.c
new file mode 100644
index 0000000..5c9e09b
--- /dev/null
+++ b/src/views/gb-view-grid.c
@@ -0,0 +1,631 @@
+/* gb-view-grid.c
+ *
+ * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ *
+ * 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 3 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 "gb-view-grid"
+
+#include <glib/gi18n.h>
+
+#include "gb-view.h"
+#include "gb-view-grid.h"
+#include "gb-widget.h"
+
+struct _GbViewGrid
+{
+ GtkBin parent_instance;
+ GbViewStack *last_focus;
+};
+
+G_DEFINE_TYPE (GbViewGrid, gb_view_grid, GTK_TYPE_BIN)
+
+static void gb_view_grid_reposition (GbViewGrid *self);
+
+GtkWidget *
+gb_view_grid_new (void)
+{
+ return g_object_new (GB_TYPE_VIEW_GRID, NULL);
+}
+
+static void
+gb_view_grid_remove_stack (GbViewGrid *self,
+ GbViewStack *stack)
+{
+ GtkWidget *new_focus;
+ GList *stacks;
+ GList *iter;
+
+ g_return_if_fail (GB_IS_VIEW_GRID (self));
+ g_return_if_fail (GB_IS_VIEW_STACK (stack));
+
+ stacks = gb_view_grid_get_stacks (self);
+
+ /* refuse to remove the stack if there is only one */
+ if (g_list_length (stacks) == 1)
+ return;
+
+ new_focus = gb_view_grid_get_stack_before (self, stack);
+ if (!new_focus)
+ new_focus = gb_view_grid_get_stack_after (self, stack);
+
+ for (iter = stacks; iter; iter = iter->next)
+ {
+ GbViewStack *item = GB_VIEW_STACK (iter->data);
+
+ if (item == stack)
+ {
+ if (!iter->prev)
+ {
+ GtkWidget *paned;
+ GtkWidget *child2;
+
+ /*
+ * This is the first stack in the grid. All we need to do to get
+ * to a consistent state is to take the child2 paned and replace
+ * our toplevel paned with it.
+ */
+ paned = gtk_bin_get_child (GTK_BIN (self));
+ child2 = gtk_paned_get_child2 (GTK_PANED (paned));
+ g_object_ref (child2);
+ gtk_container_remove (GTK_CONTAINER (paned), child2);
+ gtk_container_remove (GTK_CONTAINER (self), paned);
+ gtk_container_add (GTK_CONTAINER (self), child2);
+ g_object_unref (child2);
+ }
+ else if (!iter->next)
+ {
+ GtkWidget *paned;
+ GtkWidget *grandparent;
+
+ /*
+ * This is the last stack in the grid. All we need to do to get
+ * to a consistent state is remove our parent paned from the
+ * grandparent.
+ */
+ paned = gtk_widget_get_parent (GTK_WIDGET (stack));
+ grandparent = gtk_widget_get_parent (paned);
+ gtk_container_remove (GTK_CONTAINER (grandparent), paned);
+ }
+ else if (iter->next && iter->prev)
+ {
+ GtkWidget *grandparent;
+ GtkWidget *paned;
+ GtkWidget *child2;
+
+ /*
+ * This stack is somewhere in the middle. All we need to do to
+ * get into a consistent state is take our parent paneds child2
+ * and put it in our parent's location.
+ */
+ paned = gtk_widget_get_parent (GTK_WIDGET (stack));
+ grandparent = gtk_widget_get_parent (paned);
+ child2 = gtk_paned_get_child2 (GTK_PANED (paned));
+ g_object_ref (child2);
+ gtk_container_remove (GTK_CONTAINER (paned), child2);
+ gtk_container_remove (GTK_CONTAINER (grandparent), paned);
+ gtk_container_add (GTK_CONTAINER (grandparent), child2);
+ g_object_unref (child2);
+ }
+ else
+ g_assert_not_reached ();
+
+ gb_view_grid_reposition (self);
+
+ break;
+ }
+ }
+
+ if (new_focus)
+ gtk_widget_grab_focus (new_focus);
+
+ g_list_free (stacks);
+}
+
+static GtkWidget *
+gb_view_grid_get_first_stack (GbViewGrid *self)
+{
+ GtkWidget *child;
+
+ g_return_val_if_fail (GB_IS_VIEW_GRID (self), NULL);
+
+ child = gtk_bin_get_child (GTK_BIN (self));
+
+ if (GTK_IS_PANED (child))
+ {
+ child = gtk_paned_get_child1 (GTK_PANED (child));
+ if (GB_IS_VIEW_STACK (child))
+ return child;
+ }
+
+ return NULL;
+}
+
+static GtkWidget *
+gb_view_grid_get_last_stack (GbViewGrid *self)
+{
+ GtkWidget *child;
+ GtkWidget *child2;
+
+ g_return_val_if_fail (GB_IS_VIEW_GRID (self), NULL);
+
+ child = gtk_bin_get_child (GTK_BIN (self));
+
+ while (GTK_IS_PANED (child) &&
+ (child2 = gtk_paned_get_child2 (GTK_PANED (child))))
+ child = child2;
+
+ child = gtk_paned_get_child1 (GTK_PANED (child));
+
+ if (GB_IS_VIEW_STACK (child))
+ return child;
+
+ return NULL;
+}
+
+static void
+gb_view_grid_focus_neighbor (GbViewGrid *self,
+ GtkDirectionType dir,
+ GbViewStack *stack)
+{
+ GtkWidget *neighbor;
+
+ g_return_if_fail (GB_IS_VIEW_GRID (self));
+ g_return_if_fail (GB_IS_VIEW_STACK (stack));
+
+ switch ((int)dir)
+ {
+ case GTK_DIR_LEFT:
+ neighbor = gb_view_grid_get_stack_before (self, stack);
+ if (!neighbor)
+ neighbor = gb_view_grid_get_last_stack (self);
+ break;
+
+ case GTK_DIR_RIGHT:
+ neighbor = gb_view_grid_get_stack_after (self, stack);
+ if (!neighbor)
+ neighbor = gb_view_grid_get_first_stack (self);
+ break;
+
+ default:
+ neighbor = NULL;
+ break;
+ }
+
+ if (neighbor != NULL)
+ gtk_widget_grab_focus (neighbor);
+}
+
+static void
+gb_view_grid_stack_empty (GbViewGrid *self,
+ GbViewStack *stack)
+{
+ GList *stacks;
+
+ g_return_if_fail (GB_IS_VIEW_GRID (self));
+ g_return_if_fail (GB_IS_VIEW_STACK (stack));
+
+ stacks = gb_view_grid_get_stacks (self);
+
+ g_assert (stacks != NULL);
+
+ if (g_list_length (stacks) == 1)
+ goto cleanup;
+
+ gb_view_grid_focus_neighbor (self, GTK_DIR_LEFT, stack);
+ gb_view_grid_remove_stack (self, stack);
+
+cleanup:
+ g_list_free (stacks);
+}
+
+static GtkPaned *
+gb_view_grid_create_paned (GbViewGrid *self)
+{
+ return g_object_new (GTK_TYPE_PANED,
+ "orientation", GTK_ORIENTATION_HORIZONTAL,
+ "visible", TRUE,
+ NULL);
+}
+
+static GbViewStack *
+gb_view_grid_create_stack (GbViewGrid *self)
+{
+ GbViewStack *stack;
+
+ g_assert (GB_IS_VIEW_GRID (self));
+
+ stack = g_object_new (GB_TYPE_VIEW_STACK,
+ "visible", TRUE,
+ NULL);
+
+ g_signal_connect_object (stack,
+ "empty",
+ G_CALLBACK (gb_view_grid_stack_empty),
+ self,
+ G_CONNECT_SWAPPED);
+
+ return stack;
+}
+
+static void
+gb_view_grid_reposition (GbViewGrid *self)
+{
+ GtkAllocation alloc;
+ GtkWidget *paned;
+ GtkWidget *stack;
+ guint count = 0;
+ guint position;
+
+ g_return_if_fail (GB_IS_VIEW_GRID (self));
+
+ gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
+
+ paned = gtk_bin_get_child (GTK_BIN (self));
+
+ if (!GTK_IS_PANED (paned))
+ return;
+
+ stack = gtk_paned_get_child1 (GTK_PANED (paned));
+ g_assert (GB_IS_VIEW_STACK (stack));
+
+ do
+ {
+ count++;
+ stack = gb_view_grid_get_stack_after (self, GB_VIEW_STACK (stack));
+ g_assert (!stack || GB_IS_VIEW_STACK (stack));
+ }
+ while (stack);
+
+ position = alloc.width / count;
+
+ stack = gtk_paned_get_child1 (GTK_PANED (paned));
+ g_assert (GB_IS_VIEW_STACK (stack));
+ do
+ {
+ paned = gtk_widget_get_parent (stack);
+ gtk_paned_set_position (GTK_PANED (paned), position);
+ stack = gb_view_grid_get_stack_after (self, GB_VIEW_STACK (stack));
+ g_assert (!stack|| GB_IS_VIEW_STACK (stack));
+ }
+ while (stack);
+}
+
+/**
+ * gb_view_grid_get_stacks:
+ *
+ * Fetches all of the stacks in the grid. The resulting #GList should be
+ * freed with g_list_free().
+ *
+ * Returns: (transfer container) (element-type GbViewStack*): A #GList.
+ */
+GList *
+gb_view_grid_get_stacks (GbViewGrid *self)
+{
+ GtkWidget *paned;
+ GList *list = NULL;
+
+ g_return_val_if_fail (GB_IS_VIEW_GRID (self), NULL);
+
+ paned = gtk_bin_get_child (GTK_BIN (self));
+
+ while (paned)
+ {
+ GtkWidget *stack;
+
+ stack = gtk_paned_get_child1 (GTK_PANED (paned));
+
+ if (GB_IS_VIEW_STACK (stack))
+ list = g_list_append (list, stack);
+
+ paned = gtk_paned_get_child2 (GTK_PANED (paned));
+ }
+
+#ifndef IDE_DISABLE_TRACE
+ {
+ GList *iter;
+
+ for (iter = list; iter; iter = iter->next)
+ g_assert (GB_IS_VIEW_STACK (iter->data));
+ }
+#endif
+
+ return list;
+}
+
+GtkWidget *
+gb_view_grid_add_stack_before (GbViewGrid *self,
+ GbViewStack *stack)
+{
+ GbViewStack *new_stack;
+ GtkWidget *parent;
+ GtkWidget *grandparent;
+ GtkPaned *new_paned;
+
+ g_return_val_if_fail (GB_IS_VIEW_GRID (self), NULL);
+
+ new_paned = gb_view_grid_create_paned (self);
+ new_stack = gb_view_grid_create_stack (self);
+ gtk_container_add (GTK_CONTAINER (new_paned), GTK_WIDGET (new_stack));
+
+ parent = gtk_widget_get_parent (GTK_WIDGET (stack));
+ grandparent = gtk_widget_get_parent (GTK_WIDGET (parent));
+
+ if (GTK_IS_PANED (grandparent))
+ {
+ g_object_ref (parent);
+ gtk_container_remove (GTK_CONTAINER (grandparent), GTK_WIDGET (parent));
+ gtk_container_add_with_properties (GTK_CONTAINER (grandparent),
+ GTK_WIDGET (new_paned),
+ "shrink", FALSE,
+ "resize", TRUE,
+ NULL);
+ gtk_container_add_with_properties (GTK_CONTAINER (new_paned),
+ GTK_WIDGET (parent),
+ "shrink", FALSE,
+ "resize", TRUE,
+ NULL);
+ g_object_unref (parent);
+ }
+ else if (GB_IS_VIEW_GRID (grandparent))
+ {
+ g_object_ref (parent);
+ gtk_container_remove (GTK_CONTAINER (grandparent), GTK_WIDGET (parent));
+ gtk_container_add (GTK_CONTAINER (grandparent), GTK_WIDGET (new_paned));
+ gtk_container_add_with_properties (GTK_CONTAINER (new_paned), parent,
+ "shrink", FALSE,
+ "resize", TRUE,
+ NULL);
+ g_object_unref (parent);
+ }
+ else
+ g_assert_not_reached ();
+
+ gb_view_grid_reposition (self);
+
+ return GTK_WIDGET (new_stack);
+}
+
+GtkWidget *
+gb_view_grid_add_stack_after (GbViewGrid *self,
+ GbViewStack *stack)
+{
+ GbViewStack *new_stack;
+ GtkWidget *parent;
+ GtkPaned *new_paned;
+
+ g_return_val_if_fail (GB_IS_VIEW_GRID (self), NULL);
+
+ new_paned = gb_view_grid_create_paned (self);
+ new_stack = gb_view_grid_create_stack (self);
+ gtk_container_add (GTK_CONTAINER (new_paned), GTK_WIDGET (new_stack));
+
+ parent = gtk_widget_get_parent (GTK_WIDGET (stack));
+
+ if (GTK_IS_PANED (parent))
+ {
+ GtkWidget *child2;
+
+ child2 = gtk_paned_get_child2 (GTK_PANED (parent));
+
+ if (child2)
+ {
+ g_object_ref (child2);
+ gtk_container_remove (GTK_CONTAINER (parent), child2);
+ }
+
+ gtk_container_add_with_properties (GTK_CONTAINER (parent),
+ GTK_WIDGET (new_paned),
+ "shrink", FALSE,
+ "resize", TRUE,
+ NULL);
+
+ if (child2)
+ {
+ gtk_container_add_with_properties (GTK_CONTAINER (new_paned), child2,
+ "shrink", FALSE,
+ "resize", TRUE,
+ NULL);
+ g_object_unref (child2);
+ }
+ }
+ else
+ g_assert_not_reached ();
+
+ gb_view_grid_reposition (self);
+
+ return GTK_WIDGET (new_stack);
+}
+
+GtkWidget *
+gb_view_grid_get_stack_before (GbViewGrid *self,
+ GbViewStack *stack)
+{
+ GtkWidget *parent;
+
+ g_return_val_if_fail (GB_IS_VIEW_GRID (self), NULL);
+ g_return_val_if_fail (GB_IS_VIEW_STACK (stack), NULL);
+
+ parent = gtk_widget_get_parent (GTK_WIDGET (stack));
+
+ if (GTK_IS_PANED (parent))
+ {
+ parent = gtk_widget_get_parent (parent);
+ if (GTK_IS_PANED (parent))
+ return gtk_paned_get_child1 (GTK_PANED (parent));
+ }
+
+ return NULL;
+}
+
+GtkWidget *
+gb_view_grid_get_stack_after (GbViewGrid *self,
+ GbViewStack *stack)
+{
+ GtkWidget *parent;
+
+ g_return_val_if_fail (GB_IS_VIEW_GRID (self), NULL);
+ g_return_val_if_fail (GB_IS_VIEW_STACK (stack), NULL);
+
+ parent = gtk_widget_get_parent (GTK_WIDGET (stack));
+
+ if (GTK_IS_PANED (parent))
+ {
+ GtkWidget *child2;
+
+ child2 = gtk_paned_get_child2 (GTK_PANED (parent));
+ if (GTK_IS_PANED (child2))
+ return gtk_paned_get_child1 (GTK_PANED (child2));
+ }
+
+ return NULL;
+}
+
+void
+gb_view_grid_focus_document (GbViewGrid *self,
+ GbDocument *document)
+{
+ GList *stacks;
+ GList *iter;
+
+ g_return_if_fail (GB_IS_VIEW_GRID (self));
+ g_return_if_fail (GB_IS_DOCUMENT (document));
+
+ stacks = gb_view_grid_get_stacks (self);
+
+ for (iter = stacks; iter; iter = iter->next)
+ {
+ GbViewStack *stack = iter->data;
+ GtkWidget *view;
+
+ view = gb_view_stack_find_with_document (stack, document);
+
+ if (view)
+ {
+ gb_view_stack_focus_document (stack, document);
+ goto cleanup;
+ }
+ }
+
+ g_assert (stacks);
+
+ if (self->last_focus)
+ gb_view_stack_focus_document (self->last_focus, document);
+ else
+ gb_view_stack_focus_document (stacks->data, document);
+
+cleanup:
+ g_list_free (stacks);
+}
+
+static void
+gb_view_grid_grab_focus (GtkWidget *widget)
+{
+ GbViewGrid *self = (GbViewGrid *)widget;
+ GList *stacks;
+
+ g_return_if_fail (GB_IS_VIEW_GRID (self));
+
+ if (self->last_focus)
+ {
+ gtk_widget_grab_focus (GTK_WIDGET (self->last_focus));
+ return;
+ }
+
+ stacks = gb_view_grid_get_stacks (self);
+ if (stacks)
+ gtk_widget_grab_focus (stacks->data);
+ g_list_free (stacks);
+}
+
+static void
+gb_view_grid_toplevel_set_focus (GtkWidget *toplevel,
+ GtkWidget *focus,
+ GbViewGrid *self)
+{
+ g_return_if_fail (GB_IS_VIEW_GRID (self));
+
+ if (focus && gtk_widget_is_ancestor (focus, GTK_WIDGET (self)))
+ {
+ GtkWidget *parent = focus;
+
+ while (parent && !GB_IS_VIEW_STACK (parent))
+ parent = gtk_widget_get_parent (parent);
+
+ if (GB_IS_VIEW_STACK (parent))
+ ide_set_weak_pointer (&self->last_focus, GB_VIEW_STACK (parent));
+ }
+}
+
+static void
+gb_view_grid_hierarchy_changed (GtkWidget *widget,
+ GtkWidget *previous_toplevel)
+{
+ GbViewGrid *self = (GbViewGrid *)widget;
+ GtkWidget *toplevel;
+
+ g_return_if_fail (GB_IS_VIEW_GRID (self));
+
+ if (GTK_IS_WINDOW (previous_toplevel))
+ g_signal_handlers_disconnect_by_func (previous_toplevel,
+ G_CALLBACK (gb_view_grid_toplevel_set_focus),
+ self);
+
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ g_signal_connect (toplevel,
+ "set-focus",
+ G_CALLBACK (gb_view_grid_toplevel_set_focus),
+ self);
+}
+
+static void
+gb_view_grid_finalize (GObject *object)
+{
+ GbViewGrid *self = (GbViewGrid *)object;
+
+ ide_clear_weak_pointer (&self->last_focus);
+
+ G_OBJECT_CLASS (gb_view_grid_parent_class)->finalize (object);
+}
+
+static void
+gb_view_grid_class_init (GbViewGridClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->finalize = gb_view_grid_finalize;
+
+ widget_class->grab_focus = gb_view_grid_grab_focus;
+ widget_class->hierarchy_changed = gb_view_grid_hierarchy_changed;
+}
+
+static void
+gb_view_grid_init (GbViewGrid *self)
+{
+ GbViewStack *stack;
+ GtkPaned *paned;
+
+ paned = gb_view_grid_create_paned (self);
+ stack = gb_view_grid_create_stack (self);
+
+ gtk_container_add_with_properties (GTK_CONTAINER (paned), GTK_WIDGET (stack),
+ "shrink", FALSE,
+ "resize", TRUE,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (paned));
+}
diff --git a/src/views/gb-view-grid.h b/src/views/gb-view-grid.h
new file mode 100644
index 0000000..acf915c
--- /dev/null
+++ b/src/views/gb-view-grid.h
@@ -0,0 +1,48 @@
+/* gb-document-grid.h
+ *
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
+ *
+ * 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 3 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 GB_DOCUMENT_GRID_H
+#define GB_DOCUMENT_GRID_H
+
+#include <gtk/gtk.h>
+
+#include "gb-document.h"
+#include "gb-view-stack.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_VIEW_GRID (gb_view_grid_get_type())
+
+G_DECLARE_FINAL_TYPE (GbViewGrid, gb_view_grid, GB, VIEW_GRID, GtkBin)
+
+GtkWidget *gb_view_grid_new (void);
+GtkWidget *gb_view_grid_add_stack_after (GbViewGrid *grid,
+ GbViewStack *stack);
+GtkWidget *gb_view_grid_add_stack_before (GbViewGrid *grid,
+ GbViewStack *stack);
+GtkWidget *gb_view_grid_get_stack_after (GbViewGrid *grid,
+ GbViewStack *stack);
+GtkWidget *gb_view_grid_get_stack_before (GbViewGrid *grid,
+ GbViewStack *stack);
+GList *gb_view_grid_get_stacks (GbViewGrid *grid);
+void gb_view_grid_focus_document (GbViewGrid *grid,
+ GbDocument *document);
+
+G_END_DECLS
+
+#endif /* GB_DOCUMENT_GRID_H */
diff --git a/src/views/gb-view-stack-actions.c b/src/views/gb-view-stack-actions.c
new file mode 100644
index 0000000..6426426
--- /dev/null
+++ b/src/views/gb-view-stack-actions.c
@@ -0,0 +1,125 @@
+/* gb-view-stack-actions.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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 General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gb-view-stack.h"
+#include "gb-view-stack-actions.h"
+#include "gb-view-stack-private.h"
+
+static void
+gb_view_stack_actions_close (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbViewStack *self = user_data;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+}
+
+static void
+gb_view_stack_actions_move_left (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbViewStack *self = user_data;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+}
+
+static void
+gb_view_stack_actions_move_right (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbViewStack *self = user_data;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+}
+
+static void
+gb_view_stack_actions_save (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbViewStack *self = user_data;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+}
+
+static void
+gb_view_stack_actions_save_as (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbViewStack *self = user_data;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+}
+
+static void
+gb_view_stack_actions_split_down (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbViewStack *self = user_data;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+}
+
+static void
+gb_view_stack_actions_split_left (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbViewStack *self = user_data;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+}
+
+static void
+gb_view_stack_actions_split_right (GSimpleAction *action,
+ GVariant *param,
+ gpointer user_data)
+{
+ GbViewStack *self = user_data;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+}
+
+static const GActionEntry gGbViewStackActions[] = {
+ { "close", gb_view_stack_actions_close },
+ { "move-left", gb_view_stack_actions_move_left },
+ { "move-right", gb_view_stack_actions_move_right },
+ { "save", gb_view_stack_actions_save },
+ { "save-as", gb_view_stack_actions_save_as },
+ { "split-down", gb_view_stack_actions_split_down },
+ { "split-left", gb_view_stack_actions_split_left },
+ { "split-right", gb_view_stack_actions_split_right },
+};
+
+void
+gb_view_stack_actions_init (GbViewStack *self)
+{
+ GSimpleActionGroup *actions;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+
+ actions = g_simple_action_group_new ();
+ g_action_map_add_action_entries (G_ACTION_MAP (actions), gGbViewStackActions,
+ G_N_ELEMENTS (gGbViewStackActions), self);
+ gtk_widget_insert_action_group (GTK_WIDGET (self), "view", G_ACTION_GROUP (actions));
+}
diff --git a/src/views/gb-view-stack-actions.h b/src/views/gb-view-stack-actions.h
new file mode 100644
index 0000000..8b51a80
--- /dev/null
+++ b/src/views/gb-view-stack-actions.h
@@ -0,0 +1,30 @@
+/* gb-view-stack-actions.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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 General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_VIEW_STACK_ACTIONS_H
+#define GB_VIEW_STACK_ACTIONS_H
+
+#include "gb-view-stack.h"
+
+G_BEGIN_DECLS
+
+void gb_view_stack_actions_init (GbViewStack *self);
+
+G_END_DECLS
+
+#endif /* GB_VIEW_STACK_ACTIONS_H */
diff --git a/src/views/gb-view-stack-private.h b/src/views/gb-view-stack-private.h
new file mode 100644
index 0000000..c837eb2
--- /dev/null
+++ b/src/views/gb-view-stack-private.h
@@ -0,0 +1,49 @@
+/* gb-view-stack-private.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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 General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_VIEW_STACK_PRIVATE_H
+#define GB_VIEW_STACK_PRIVATE_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+struct _GbViewStack
+{
+ GtkBin parent_instance;
+
+ GList *focus_history;
+
+ /* Weak references */
+ GtkWidget *active_view;
+ GBinding *title_binding;
+
+ /* Template references */
+ GtkStack *controls_stack;
+ GtkButton *go_backward;
+ GtkButton *go_forward;
+ GtkPopover *popover;
+ GtkStack *stack;
+ GtkLabel *title_label;
+
+ guint focused : 1;
+};
+
+G_END_DECLS
+
+#endif /* GB_VIEW_STACK_PRIVATE_H */
diff --git a/src/views/gb-view-stack.c b/src/views/gb-view-stack.c
new file mode 100644
index 0000000..e78cc25
--- /dev/null
+++ b/src/views/gb-view-stack.c
@@ -0,0 +1,409 @@
+/* gb-view-stack.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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 General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+#include <ide.h>
+
+#include "gb-view.h"
+#include "gb-view-stack.h"
+#include "gb-view-stack-actions.h"
+#include "gb-view-stack-private.h"
+#include "gb-widget.h"
+
+G_DEFINE_TYPE (GbViewStack, gb_view_stack, GTK_TYPE_BIN)
+
+enum {
+ PROP_0,
+ PROP_ACTIVE_VIEW,
+ LAST_PROP
+};
+
+enum {
+ EMPTY,
+ LAST_SIGNAL
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+static guint gSignals [LAST_SIGNAL];
+
+static void
+gb_view_stack_add (GtkContainer *container,
+ GtkWidget *child)
+{
+ GbViewStack *self = (GbViewStack *)container;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+
+ if (GB_IS_VIEW (child))
+ {
+ GtkWidget *controls;
+
+ self->focus_history = g_list_prepend (self->focus_history, child);
+ controls = gb_view_get_controls (GB_VIEW (child));
+ if (controls)
+ gtk_container_add (GTK_CONTAINER (self->controls_stack), controls);
+ gtk_container_add (GTK_CONTAINER (self->stack), child);
+ gtk_stack_set_visible_child (self->stack, child);
+ }
+ else
+ {
+ GTK_CONTAINER_CLASS (gb_view_stack_parent_class)->add (container, child);
+ }
+}
+
+static void
+gb_view_stack_remove (GtkContainer *container,
+ GtkWidget *child)
+{
+ GbViewStack *self = (GbViewStack *)container;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+
+ if (GB_IS_VIEW (child))
+ {
+ self->focus_history = g_list_remove (self->focus_history, child);
+ gtk_container_remove (GTK_CONTAINER (self->stack), child);
+ if (self->focus_history)
+ gtk_stack_set_visible_child (self->stack, self->focus_history->data);
+ else
+ g_signal_emit (self, gSignals [EMPTY], 0);
+ }
+ else
+ {
+ GTK_CONTAINER_CLASS (gb_view_stack_parent_class)->remove (container, child);
+ }
+}
+
+static void
+gb_view_stack__notify_visible_child (GbViewStack *self,
+ GParamSpec *pspec,
+ GtkStack *stack)
+{
+ GtkWidget *visible_child;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+ g_assert (GTK_IS_STACK (stack));
+
+ visible_child = gtk_stack_get_visible_child (stack);
+
+ gb_view_stack_set_active_view (self, visible_child);
+}
+
+static void
+gb_view_stack__set_focus (GbViewStack *self,
+ GtkWidget *focus_widget,
+ GtkWindow *toplevel)
+{
+ g_assert (GB_IS_VIEW_STACK (self));
+ g_assert (!focus_widget || GTK_IS_WIDGET (focus_widget));
+ g_assert (!toplevel || GTK_IS_WIDGET (toplevel));
+
+ self->focused = focus_widget && gtk_widget_is_ancestor (GTK_WIDGET (self), focus_widget);
+}
+
+static void
+gb_view_stack_hierarchy_changed (GtkWidget *widget,
+ GtkWidget *previous_toplevel)
+{
+ GbViewStack *self = (GbViewStack *)widget;
+ GtkWidget *toplevel;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+ g_assert (!previous_toplevel || GTK_IS_WIDGET (previous_toplevel));
+
+ if (GTK_IS_WINDOW (previous_toplevel))
+ g_signal_handlers_disconnect_by_func (previous_toplevel,
+ G_CALLBACK (gb_view_stack__set_focus),
+ self);
+
+ toplevel = gtk_widget_get_toplevel (widget);
+ if (GTK_IS_WINDOW (toplevel))
+ g_signal_connect_object (toplevel,
+ "set-focus",
+ G_CALLBACK (gb_view_stack__set_focus),
+ self,
+ G_CONNECT_SWAPPED);
+}
+
+static gboolean
+gb_view_stack_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GbViewStack *self = (GbViewStack *)widget;
+ GtkStyleContext *style_context;
+ gboolean ret;
+
+ g_assert (GB_IS_VIEW_STACK (self));
+ g_assert (cr);
+
+ style_context = gtk_widget_get_style_context (widget);
+ gtk_style_context_save (style_context);
+ if (self->focused)
+ gtk_style_context_add_class (style_context, "focused");
+ ret = GTK_WIDGET_CLASS (gb_view_stack_parent_class)->draw (widget, cr);
+ gtk_style_context_restore (style_context);
+
+ return ret;
+}
+
+static void
+gb_view_stack_constructed (GObject *object)
+{
+ GbViewStack *self = (GbViewStack *)object;
+
+ G_OBJECT_CLASS (gb_view_stack_parent_class)->constructed (object);
+
+ gb_view_stack_actions_init (self);
+}
+
+static void
+gb_view_stack_finalize (GObject *object)
+{
+ GbViewStack *self = (GbViewStack *)object;
+
+ g_clear_pointer (&self->focus_history, g_list_free);
+ ide_clear_weak_pointer (&self->title_binding);
+ ide_clear_weak_pointer (&self->active_view);
+
+ G_OBJECT_CLASS (gb_view_stack_parent_class)->finalize (object);
+}
+
+static void
+gb_view_stack_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbViewStack *self = GB_VIEW_STACK (object);
+
+ switch (prop_id)
+ {
+ case PROP_ACTIVE_VIEW:
+ g_value_set_object (value, gb_view_stack_get_active_view (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gb_view_stack_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GbViewStack *self = GB_VIEW_STACK (object);
+
+ switch (prop_id)
+ {
+ case PROP_ACTIVE_VIEW:
+ gb_view_stack_set_active_view (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gb_view_stack_class_init (GbViewStackClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
+
+ object_class->constructed = gb_view_stack_constructed;
+ object_class->finalize = gb_view_stack_finalize;
+ object_class->get_property = gb_view_stack_get_property;
+ object_class->set_property = gb_view_stack_set_property;
+
+ widget_class->draw = gb_view_stack_draw;
+ widget_class->hierarchy_changed = gb_view_stack_hierarchy_changed;
+
+ container_class->add = gb_view_stack_add;
+ container_class->remove = gb_view_stack_remove;
+
+ gParamSpecs [PROP_ACTIVE_VIEW] =
+ g_param_spec_object ("active-view",
+ _("Active View"),
+ _("The active view."),
+ GB_TYPE_VIEW,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_ACTIVE_VIEW, gParamSpecs [PROP_ACTIVE_VIEW]);
+
+ gSignals [EMPTY] = g_signal_new ("empty",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ GB_WIDGET_CLASS_TEMPLATE (klass, "gb-view-stack.ui");
+ GB_WIDGET_CLASS_BIND (klass, GbViewStack, controls_stack);
+ GB_WIDGET_CLASS_BIND (klass, GbViewStack, go_backward);
+ GB_WIDGET_CLASS_BIND (klass, GbViewStack, go_forward);
+ GB_WIDGET_CLASS_BIND (klass, GbViewStack, popover);
+ GB_WIDGET_CLASS_BIND (klass, GbViewStack, stack);
+ GB_WIDGET_CLASS_BIND (klass, GbViewStack, title_label);
+}
+
+static void
+gb_view_stack_init (GbViewStack *self)
+{
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ g_signal_connect_object (self->stack,
+ "notify::visible-child",
+ G_CALLBACK (gb_view_stack__notify_visible_child),
+ self,
+ G_CONNECT_SWAPPED);
+}
+
+GtkWidget *
+gb_view_stack_new (void)
+{
+ return g_object_new (GB_TYPE_VIEW_STACK, NULL);
+}
+
+GtkWidget *
+gb_view_stack_get_active_view (GbViewStack *self)
+{
+ g_return_val_if_fail (GB_IS_VIEW_STACK (self), NULL);
+
+ return self->active_view;
+}
+
+void
+gb_view_stack_set_active_view (GbViewStack *self,
+ GtkWidget *active_view)
+{
+ g_return_if_fail (GB_IS_VIEW_STACK (self));
+ g_return_if_fail (!active_view || GB_IS_VIEW (active_view));
+
+ if (self->active_view != active_view)
+ {
+ if (self->active_view)
+ {
+ self->focus_history = g_list_remove (self->focus_history, self->active_view);
+ if (self->title_binding)
+ g_binding_unbind (self->title_binding);
+ ide_clear_weak_pointer (&self->title_binding);
+ gtk_label_set_label (self->title_label, NULL);
+ ide_clear_weak_pointer (&self->active_view);
+ gtk_widget_hide (GTK_WIDGET (self->controls_stack));
+ }
+
+ if (active_view)
+ {
+ GtkWidget *controls;
+ GBinding *binding;
+
+ self->focus_history = g_list_prepend (self->focus_history, active_view);
+ if (active_view != gtk_stack_get_visible_child (self->stack))
+ gtk_stack_set_visible_child (self->stack, active_view);
+ binding = g_object_bind_property (active_view, "title",
+ self->title_label, "label",
+ G_BINDING_SYNC_CREATE);
+ ide_set_weak_pointer (&self->title_binding, binding);
+ ide_set_weak_pointer (&self->active_view, active_view);
+ controls = gb_view_get_controls (GB_VIEW (active_view));
+ if (controls)
+ {
+ gtk_stack_set_visible_child (self->controls_stack, controls);
+ gtk_widget_show (GTK_WIDGET (self->controls_stack));
+ }
+ }
+
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_ACTIVE_VIEW]);
+ }
+}
+
+GtkWidget *
+gb_view_stack_find_with_document (GbViewStack *self,
+ GbDocument *document)
+{
+ GtkWidget *ret = NULL;
+ GList *iter;
+ GList *children;
+
+ g_return_val_if_fail (GB_IS_VIEW_STACK (self), NULL);
+ g_return_val_if_fail (GB_IS_DOCUMENT (document), NULL);
+
+ children = gtk_container_get_children (GTK_CONTAINER (self->stack));
+
+ for (iter = children; iter; iter = iter->next)
+ {
+ GbView *view = iter->data;
+ GbDocument *item;
+
+ g_assert (GB_IS_VIEW (view));
+
+ item = gb_view_get_document (view);
+
+ if (item == document)
+ {
+ ret = GTK_WIDGET (view);
+ break;
+ }
+ }
+
+ g_list_free (children);
+
+ return ret;
+}
+
+void
+gb_view_stack_focus_document (GbViewStack *self,
+ GbDocument *document)
+{
+ GtkWidget *view;
+
+ g_return_if_fail (GB_IS_VIEW_STACK (self));
+ g_return_if_fail (GB_IS_DOCUMENT (document));
+
+ view = gb_view_stack_find_with_document (self, document);
+
+ if (view != NULL && GB_IS_VIEW (view))
+ {
+ gb_view_stack_set_active_view (self, view);
+ return;
+ }
+
+ view = gb_document_create_view (document);
+
+ if (view == NULL)
+ {
+ g_warning ("Document %s failed to create a view",
+ gb_document_get_title (document));
+ return;
+ }
+
+ if (!GB_IS_VIEW (view))
+ {
+ g_warning ("Document %s did not create a GbView instance.",
+ gb_document_get_title (document));
+ return;
+ }
+
+ gb_view_stack_add (GTK_CONTAINER (self), view);
+ gb_view_stack_set_active_view (self, view);
+ gtk_widget_grab_focus (view);
+}
diff --git a/src/views/gb-view-stack.h b/src/views/gb-view-stack.h
new file mode 100644
index 0000000..07e0ea9
--- /dev/null
+++ b/src/views/gb-view-stack.h
@@ -0,0 +1,43 @@
+/* gb-view-stack.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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 General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_VIEW_STACK_H
+#define GB_VIEW_STACK_H
+
+#include <gtk/gtk.h>
+
+#include "gb-document.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_VIEW_STACK (gb_view_stack_get_type())
+
+G_DECLARE_FINAL_TYPE (GbViewStack, gb_view_stack, GB, VIEW_STACK, GtkBin)
+
+GtkWidget *gb_view_stack_new (void);
+GtkWidget *gb_view_stack_get_active_view (GbViewStack *self);
+void gb_view_stack_set_active_view (GbViewStack *self,
+ GtkWidget *active_view);
+GtkWidget *gb_view_stack_find_with_document (GbViewStack *self,
+ GbDocument *document);
+void gb_view_stack_focus_document (GbViewStack *self,
+ GbDocument *document);
+
+G_END_DECLS
+
+#endif /* GB_VIEW_STACK_H */
diff --git a/src/views/gb-view.c b/src/views/gb-view.c
new file mode 100644
index 0000000..963e184
--- /dev/null
+++ b/src/views/gb-view.c
@@ -0,0 +1,240 @@
+/* gb-view.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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 General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+
+#include "gb-view.h"
+
+typedef struct
+{
+ GtkBox *controls;
+} GbViewPrivate;
+
+static void buildable_iface_init (GtkBuildableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GbView, gb_view, GTK_TYPE_BOX,
+ G_ADD_PRIVATE (GbView)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, buildable_iface_init))
+
+enum {
+ PROP_0,
+ PROP_CAN_SPLIT,
+ PROP_DOCUMENT,
+ PROP_TITLE,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+/**
+ * gb_view_get_can_split:
+ * @self: A #GbView.
+ *
+ * Checks if @self can create a split view. If so, %TRUE is returned. Otherwise, %FALSE.
+ *
+ * Returns: %TRUE if @self can create a split.
+ */
+gboolean
+gb_view_get_can_split (GbView *self)
+{
+ g_return_val_if_fail (GB_IS_VIEW (self), FALSE);
+
+ if (GB_VIEW_GET_CLASS (self)->get_can_split)
+ return GB_VIEW_GET_CLASS (self)->get_can_split (self);
+
+ return FALSE;
+}
+
+/**
+ * gb_view_create_split:
+ * @self: A #GbView.
+ *
+ * Creates a new view similar to @self that can be displayed in a split.
+ * If the view does not support splits, %NULL will be returned.
+ *
+ * Returns: (transfer full): A #GbView.
+ */
+GbView *
+gb_view_create_split (GbView *self)
+{
+ g_return_val_if_fail (GB_IS_VIEW (self), NULL);
+
+ if (GB_VIEW_GET_CLASS (self)->create_split)
+ return GB_VIEW_GET_CLASS (self)->create_split (self);
+
+ return NULL;
+}
+
+/**
+ * gb_view_get_controls:
+ * @self: A #GbView.
+ *
+ * Gets the controls for the view.
+ *
+ * Returns: (transfer none) (nullable): A #GtkWidget.
+ */
+GtkWidget *
+gb_view_get_controls (GbView *self)
+{
+ GbViewPrivate *priv = gb_view_get_instance_private (self);
+
+ g_return_val_if_fail (GB_IS_VIEW (self), NULL);
+
+ return GTK_WIDGET (priv->controls);
+}
+
+/**
+ * gb_view_get_document:
+ * @self: A #GbView.
+ *
+ * Gets the document for the view.
+ *
+ * Returns: (transfer none): A #GbDocument.
+ */
+GbDocument *
+gb_view_get_document (GbView *self)
+{
+ g_return_val_if_fail (GB_IS_VIEW (self), NULL);
+
+ if (GB_VIEW_GET_CLASS (self)->get_document)
+ return GB_VIEW_GET_CLASS (self)->get_document (self);
+
+ return NULL;
+}
+
+const gchar *
+gb_view_get_title (GbView *self)
+{
+ GbDocument *document;
+
+ if (GB_VIEW_GET_CLASS (self)->get_title)
+ return GB_VIEW_GET_CLASS (self)->get_title (self);
+
+ document = gb_view_get_document (self);
+
+ return gb_document_get_title (document);
+}
+
+static void
+gb_view_destroy (GtkWidget *widget)
+{
+ GbView *self = (GbView *)widget;
+ GbViewPrivate *priv = gb_view_get_instance_private (self);
+
+ g_clear_object (&priv->controls);
+
+ GTK_WIDGET_CLASS (gb_view_parent_class)->destroy (widget);
+}
+
+static void
+gb_view_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GbView *self = GB_VIEW (object);
+
+ switch (prop_id)
+ {
+ case PROP_CAN_SPLIT:
+ g_value_set_boolean (value, gb_view_get_can_split (self));
+ break;
+
+ case PROP_DOCUMENT:
+ g_value_set_object (value, gb_view_get_document (self));
+ break;
+
+ case PROP_TITLE:
+ g_value_set_string (value, gb_view_get_title (self));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+
+static void
+gb_view_class_init (GbViewClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = gb_view_get_property;
+
+ widget_class->destroy = gb_view_destroy;
+
+ gParamSpecs [PROP_CAN_SPLIT] =
+ g_param_spec_boolean ("can-split",
+ _("Can Split"),
+ _("If the view can be split."),
+ FALSE,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_CAN_SPLIT, gParamSpecs [PROP_CAN_SPLIT]);
+
+ gParamSpecs [PROP_DOCUMENT] =
+ g_param_spec_object ("document",
+ _("Document"),
+ _("The underlying document."),
+ GB_TYPE_DOCUMENT,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_DOCUMENT, gParamSpecs [PROP_DOCUMENT]);
+
+ gParamSpecs [PROP_TITLE] =
+ g_param_spec_string ("title",
+ _("Title"),
+ _("The view title."),
+ NULL,
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_TITLE, gParamSpecs [PROP_TITLE]);
+}
+
+static void
+gb_view_init (GbView *self)
+{
+ GbViewPrivate *priv = gb_view_get_instance_private (self);
+ GtkBox *controls;
+
+ controls = g_object_new (GTK_TYPE_BOX,
+ "orientation", GTK_ORIENTATION_HORIZONTAL,
+ "visible", TRUE,
+ NULL);
+ priv->controls = g_object_ref_sink (controls);
+}
+
+static GObject *
+gb_view_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname)
+{
+ GbView *self = (GbView *)buildable;
+ GbViewPrivate *priv = gb_view_get_instance_private (self);
+
+ g_assert (GB_IS_VIEW (self));
+
+ if (g_strcmp0 (childname, "controls") == 0)
+ return G_OBJECT (priv->controls);
+
+ return NULL;
+}
+
+static void
+buildable_iface_init (GtkBuildableIface *iface)
+{
+ iface->get_internal_child = gb_view_get_internal_child;
+}
diff --git a/src/views/gb-view.h b/src/views/gb-view.h
new file mode 100644
index 0000000..86b9019
--- /dev/null
+++ b/src/views/gb-view.h
@@ -0,0 +1,50 @@
+/* gb-view.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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 General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GB_VIEW_H
+#define GB_VIEW_H
+
+#include <gtk/gtk.h>
+
+#include "gb-document.h"
+
+G_BEGIN_DECLS
+
+#define GB_TYPE_VIEW (gb_view_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (GbView, gb_view, GB, VIEW, GtkBox)
+
+struct _GbViewClass
+{
+ GtkBinClass parent;
+
+ gboolean (*get_can_split) (GbView *self);
+ GbDocument *(*get_document) (GbView *self);
+ const gchar *(*get_title) (GbView *self);
+ GbView *(*create_split) (GbView *self);
+};
+
+GbView *gb_view_create_split (GbView *self);
+gboolean gb_view_get_can_split (GbView *self);
+GbDocument *gb_view_get_document (GbView *self);
+const gchar *gb_view_get_title (GbView *self);
+GtkWidget *gb_view_get_controls (GbView *self);
+
+G_END_DECLS
+
+#endif /* GB_VIEW_H */
diff --git a/src/workbench/gb-workbench-actions.c b/src/workbench/gb-workbench-actions.c
new file mode 100644
index 0000000..7f54a69
--- /dev/null
+++ b/src/workbench/gb-workbench-actions.c
@@ -0,0 +1,81 @@
+/* gb-workbench-actions.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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 3 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 "gb-workbench-actions"
+
+#include "gb-workbench.h"
+#include "gb-workbench-actions.h"
+#include "gb-workbench-private.h"
+
+static void
+gb_workbench_actions_build (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+}
+
+static void
+gb_workbench_actions_global_search (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GbWorkbench *self = user_data;
+
+ g_assert (GB_IS_WORKBENCH (self));
+
+ gtk_widget_grab_focus (GTK_WIDGET (self->search_box));
+}
+
+static void
+gb_workbench_actions_save_all (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+}
+
+static void
+gb_workbench_actions_show_command_bar (GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ GbWorkbench *self = user_data;
+
+ g_assert (GB_IS_WORKBENCH (self));
+
+ gb_command_bar_show (self->command_bar);
+}
+
+static const GActionEntry GbWorkbenchActions[] = {
+ { "build", gb_workbench_actions_build },
+ { "global-search", gb_workbench_actions_global_search },
+ { "save-all", gb_workbench_actions_save_all },
+ { "show-command-bar", gb_workbench_actions_show_command_bar },
+};
+
+void
+gb_workbench_actions_init (GbWorkbench *self)
+{
+ GSimpleActionGroup *actions;
+
+ g_assert (GB_IS_WORKBENCH (self));
+
+ actions = g_simple_action_group_new ();
+ g_action_map_add_action_entries (G_ACTION_MAP (actions), GbWorkbenchActions,
+ G_N_ELEMENTS (GbWorkbenchActions), self);
+ gtk_widget_insert_action_group (GTK_WIDGET (self), "workbench", G_ACTION_GROUP (actions));
+}
diff --git a/src/auto-indent/c-parse-helper.h b/src/workbench/gb-workbench-actions.h
similarity index 57%
rename from src/auto-indent/c-parse-helper.h
rename to src/workbench/gb-workbench-actions.h
index 418f518..316a70e 100644
--- a/src/auto-indent/c-parse-helper.h
+++ b/src/workbench/gb-workbench-actions.h
@@ -1,6 +1,6 @@
-/* c-parse-helper.h
+/* gb-workbench-actions.h
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,26 +16,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef C_PARSE_HELPER_H
-#define C_PARSE_HELPER_H
+#ifndef GB_WORKBENCH_ACTIONS_H
+#define GB_WORKBENCH_ACTIONS_H
-#include <glib.h>
+#include "gb-workbench-types.h"
G_BEGIN_DECLS
-typedef struct
-{
- gchar *type;
- gchar *name;
- guint ellipsis : 1;
- guint n_star : 4;
-} Parameter;
-
-gboolean parameter_validate (Parameter *param);
-void parameter_free (Parameter *p);
-Parameter *parameter_copy (const Parameter *src);
-GSList *parse_parameters (const gchar *text);
+void gb_workbench_actions_init (GbWorkbench *workbench);
G_END_DECLS
-#endif /* C_PARSE_HELPER_H */
+#endif /* GB_WORKBENCH_ACTIONS_H */
diff --git a/src/workbench/gb-workbench-private.h b/src/workbench/gb-workbench-private.h
new file mode 100644
index 0000000..0114375
--- /dev/null
+++ b/src/workbench/gb-workbench-private.h
@@ -0,0 +1,60 @@
+/* gb-workbench-private.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * 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 3 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 GB_WORKBENCH_PRIVATE_H
+#define GB_WORKBENCH_PRIVATE_H
+
+#include <gtk/gtk.h>
+#include <ide.h>
+
+#include "gb-command-bar.h"
+#include "gb-command-manager.h"
+#include "gb-editor-workspace.h"
+#include "gb-search-box.h"
+#include "gb-workbench-types.h"
+#include "gedit-menu-stack-switcher.h"
+
+G_BEGIN_DECLS
+
+struct _GbWorkbench
+{
+ GtkApplicationWindow parent_instance;
+
+ /* Owned reference */
+ GbCommandManager *command_manager;
+ IdeContext *context;
+ GCancellable *unload_cancellable;
+
+ /* Weak reference */
+ GbWorkspace *active_workspace;
+
+ /* Template references */
+ GbCommandBar *command_bar;
+ GbEditorWorkspace *editor_workspace;
+ GeditMenuStackSwitcher *gear_menu_button;
+ GbSearchBox *search_box;
+ GtkStack *stack;
+
+ guint disposing;
+ guint building : 1;
+ guint unloading : 1;
+};
+
+G_END_DECLS
+
+#endif /* GB_WORKBENCH_PRIVATE_H */
diff --git a/src/workbench/gb-workbench-types.h b/src/workbench/gb-workbench-types.h
index 0fbe0a5..9c5f6b3 100644
--- a/src/workbench/gb-workbench-types.h
+++ b/src/workbench/gb-workbench-types.h
@@ -23,13 +23,8 @@
G_BEGIN_DECLS
-typedef struct _GbWorkbench GbWorkbench;
-typedef struct _GbWorkbenchClass GbWorkbenchClass;
-typedef struct _GbWorkbenchPrivate GbWorkbenchPrivate;
-
-typedef struct _GbWorkspace GbWorkspace;
-typedef struct _GbWorkspaceClass GbWorkspaceClass;
-typedef struct _GbWorkspacePrivate GbWorkspacePrivate;
+typedef struct _GbWorkbench GbWorkbench;
+typedef struct _GbWorkspace GbWorkspace;
G_END_DECLS
diff --git a/src/workbench/gb-workbench.c b/src/workbench/gb-workbench.c
index 58d352c..414c273 100644
--- a/src/workbench/gb-workbench.c
+++ b/src/workbench/gb-workbench.c
@@ -1,6 +1,6 @@
/* gb-workbench.c
*
- * Copyright (C) 2014 Christian Hergert <christian hergert me>
+ * Copyright (C) 2014-2015 Christian Hergert <christian hergert me>
*
* 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
@@ -16,808 +16,129 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#define G_LOG_DOMAIN "workbench"
+#define G_LOG_DOMAIN "gb-workbench"
#include <glib/gi18n.h>
-#include <libgit2-glib/ggit.h>
-
-#include "gb-command-bar.h"
-#include "gb-command-gaction-provider.h"
-#include "gb-command-manager.h"
-#include "gb-command-vim-provider.h"
-#include "gb-close-confirmation-dialog.h"
-#include "gb-credits-widget.h"
-#include "gb-document-manager.h"
-#include "gb-editor-workspace.h"
-#include "gb-git-search-provider.h"
-#include "gb-glib.h"
-#include "gb-log.h"
-#include "gb-search-box.h"
-#include "gb-search-manager.h"
+#include <ide.h>
+
#include "gb-widget.h"
+#include "gb-workbench-actions.h"
+#include "gb-workbench-private.h"
#include "gb-workbench.h"
-#include "gedit-menu-stack-switcher.h"
-
-struct _GbWorkbenchPrivate
-{
- GbCommandManager *command_manager;
- GbDocumentManager *document_manager;
- GbNavigationList *navigation_list;
- GbSearchManager *search_manager;
- IdeContext *context;
-
- guint search_timeout;
- guint disposing;
- guint building : 1;
-
- GbWorkspace *active_workspace;
- GbCommandBar *command_bar;
- GbCreditsWidget *credits;
- GbWorkspace *editor;
- GeditMenuStackSwitcher *gear_menu_button;
- GtkHeaderBar *header_bar;
- GtkButton *run_button;
- GbSearchBox *search_box;
- GtkStack *stack;
-};
+#include "gb-workspace.h"
-typedef struct
-{
- GCancellable *cancellable;
- gint outstanding;
-} SavedState;
+G_DEFINE_TYPE (GbWorkbench, gb_workbench, GTK_TYPE_APPLICATION_WINDOW)
enum {
PROP_0,
+ PROP_ACTIVE_WORKSPACE,
PROP_COMMAND_MANAGER,
PROP_CONTEXT,
- PROP_NAVIGATION_LIST,
LAST_PROP
};
-enum {
- WORKSPACE_CHANGED,
- LAST_SIGNAL
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (GbWorkbench, gb_workbench,
- GTK_TYPE_APPLICATION_WINDOW)
-
static GParamSpec *gParamSpecs [LAST_PROP];
-static guint gSignals [LAST_SIGNAL];
-
-IdeContext *
-gb_workbench_get_context (GbWorkbench *workbench)
-{
- g_return_val_if_fail (GB_IS_WORKBENCH (workbench), NULL);
-
- return workbench->priv->context;
-}
-
-void
-gb_workbench_set_context (GbWorkbench *workbench,
- IdeContext *context)
-{
- GbWorkbenchPrivate *priv;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (!context || IDE_IS_CONTEXT (context));
-
- priv = workbench->priv;
-
- if (g_set_object (&priv->context, context))
- g_object_notify_by_pspec (G_OBJECT (workbench), gParamSpecs [PROP_CONTEXT]);
-}
-
-/**
- * gb_workbench_get_command_manager:
- *
- * Retrieves the command manager for the workspace.
- *
- * Returns: (transfer none) (type GbCommandManager*): A #GbCommandManager.
- */
-GbCommandManager *
-gb_workbench_get_command_manager (GbWorkbench *workbench)
-{
- g_return_val_if_fail (GB_IS_WORKBENCH (workbench), NULL);
-
- return workbench->priv->command_manager;
-}
-
-/**
- * gb_workbench_get_document_manager:
- * @workbench: A #GbWorkbench
- *
- * Retrieves the document manager for the workbench.
- *
- * Returns: (transfer none): A #GbDocumentManager.
- */
-GbDocumentManager *
-gb_workbench_get_document_manager (GbWorkbench *workbench)
-{
- g_return_val_if_fail (GB_IS_WORKBENCH (workbench), NULL);
-
- return workbench->priv->document_manager;
-}
-
-/**
- * gb_workbench_get_navigation_list:
- *
- * Fetches the navigation list for the workbench. This can be used to move
- * between edit points between workspaces.
- *
- * Returns: (transfer none): A #GbNavigationlist.
- */
-GbNavigationList *
-gb_workbench_get_navigation_list (GbWorkbench *workbench)
-{
- g_return_val_if_fail (GB_IS_WORKBENCH (workbench), NULL);
-
- return workbench->priv->navigation_list;
-}
-
-static gboolean
-gb_workbench_key_press_event (GtkWidget *widget,
- GdkEventKey *event)
-{
- GbWorkbench *self = (GbWorkbench *)widget;
-
- g_return_val_if_fail (GB_IS_WORKBENCH (self), FALSE);
- g_return_val_if_fail (event, FALSE);
-
- switch (event->keyval)
- {
- case GDK_KEY_KP_Enter:
- case GDK_KEY_Return:
- case GDK_KEY_Escape:
- case GDK_KEY_space:
- if (gb_credits_widget_is_rolling (self->priv->credits))
- {
- gb_credits_widget_stop (self->priv->credits);
- return GDK_EVENT_STOP;
- }
- break;
-
- default:
- break;
- }
-
- return GTK_WIDGET_CLASS (gb_workbench_parent_class)->key_press_event (widget, event);
-}
static void
-load_repository_func (GTask *task,
- gpointer source_object,
- gpointer task_data,
- GCancellable *cancellable)
+gb_workbench_set_context (GbWorkbench *self,
+ IdeContext *context)
{
- GbSearchProvider *provider;
- GgitRepository *repository;
- GError *error = NULL;
- GFile *file = task_data;
-
- g_return_if_fail (G_IS_TASK (task));
- g_return_if_fail (GB_IS_WORKBENCH (source_object));
- g_return_if_fail (G_IS_FILE (file));
-
- repository = ggit_repository_open (file, &error);
-
- if (!repository)
- {
- g_task_return_error (task, error);
- return;
- }
+ g_return_if_fail (GB_IS_WORKBENCH (self));
+ g_return_if_fail (IDE_IS_CONTEXT (context));
- provider = g_object_new (GB_TYPE_GIT_SEARCH_PROVIDER,
- "workbench", source_object,
- "repository", repository,
- NULL);
- g_task_return_pointer (task, provider, g_object_unref);
- g_clear_object (&repository);
+ if (g_set_object (&self->context, context))
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_CONTEXT]);
}
static void
-repository_loaded (GObject *object,
- GAsyncResult *result,
- gpointer unused)
+gb_workbench__unload_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- GbWorkbench *workbench = (GbWorkbench *)object;
- GbSearchProvider *provider;
+ IdeContext *context = (IdeContext *)object;
+ g_autoptr(GbWorkbench) self = user_data;
GError *error = NULL;
- GTask *task = (GTask *)result;
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (G_IS_TASK (task));
-
- provider = g_task_propagate_pointer (task, &error);
-
- if (!provider)
+ if (!ide_context_unload_finish (context, result, &error))
{
- g_printerr ("%s\n", error->message);
+ g_warning ("%s", error->message);
g_clear_error (&error);
}
- else
- {
- gb_search_manager_add_provider (workbench->priv->search_manager,
- provider);
- g_clear_object (&provider);
- }
-}
-
-GbSearchManager *
-gb_workbench_get_search_manager (GbWorkbench *workbench)
-{
- GbWorkbenchPrivate *priv;
-
- g_return_val_if_fail (GB_IS_WORKBENCH (workbench), NULL);
-
- priv = workbench->priv;
-
- if (!priv->search_manager)
- {
- GFile *file;
- GTask *task;
-
- priv->search_manager = gb_search_manager_new ();
-
- /* TODO: Keep repository in sync with loaded project */
- file = g_file_new_for_path (".");
- task = g_task_new (workbench, NULL, repository_loaded, NULL);
- g_task_set_task_data (task, g_object_ref (file), g_object_unref);
- g_task_run_in_thread (task, load_repository_func);
- g_clear_object (&task);
- g_clear_object (&file);
- }
-
- return priv->search_manager;
-}
-
-/**
- * gb_workbench_get_active_workspace:
- *
- * Retrieves the active workspace.
- *
- * Returns: (transfer none): A #GbWorkbench.
- */
-GbWorkspace *
-gb_workbench_get_active_workspace (GbWorkbench *workbench)
-{
- GtkWidget *child;
-
- g_return_val_if_fail (GB_IS_WORKBENCH (workbench), NULL);
-
- child = gtk_stack_get_visible_child (workbench->priv->stack);
-
- return GB_WORKSPACE (child);
-}
-
-/**
- * gb_workbench_get_workspace:
- * @type: A #GType descending from #GbWorkspace
- *
- * Retrieves the workspace of type @type.
- *
- * Returns: (transfer none) (nullable): A #GbWorkspace or %NULL.
- */
-GbWorkspace *
-gb_workbench_get_workspace (GbWorkbench *workbench,
- GType type)
-{
- g_return_val_if_fail (GB_IS_WORKBENCH (workbench), NULL);
- g_return_val_if_fail (g_type_is_a (type, GB_TYPE_WORKSPACE), NULL);
-
- if (type == GB_TYPE_EDITOR_WORKSPACE)
- return GB_WORKSPACE (workbench->priv->editor);
-
- return NULL;
-}
-
-static void
-gb_workbench_roll_credits (GbWorkbench *workbench)
-{
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- gb_credits_widget_start (workbench->priv->credits);
-}
-
-static void
-gb_workbench_workspace_changed (GbWorkbench *workbench,
- GbWorkspace *workspace)
-{
- GbWorkbenchPrivate *priv;
-
- ENTRY;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (GB_IS_WORKSPACE (workspace));
-
- priv = workbench->priv;
-
- gb_clear_weak_pointer (&priv->active_workspace);
-
- if (workspace)
- {
- gb_set_weak_pointer (workspace, &priv->active_workspace);
- gtk_widget_grab_focus (GTK_WIDGET (workspace));
- }
-
- EXIT;
-}
-
-static void
-gb_workbench_stack_child_changed (GbWorkbench *workbench,
- GParamSpec *pspec,
- GtkStack *stack)
-{
- GtkWidget *child;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (GTK_IS_STACK (stack));
-
- child = gtk_stack_get_visible_child (stack);
- g_assert (!child || GB_IS_WORKSPACE (child));
-
- if (GB_IS_WORKSPACE (child))
- {
- GActionGroup *action_group;
-
- /*
- * Some actions need to be propagated from the workspace to the
- * toplevel. This way the header bar can activate them.
- */
- action_group = gtk_widget_get_action_group (child, "workspace");
- gtk_widget_insert_action_group (GTK_WIDGET (workbench),
- "workspace", action_group);
- }
-
- if (child)
- g_signal_emit (workbench, gSignals[WORKSPACE_CHANGED], 0, child);
-}
-
-static void
-gb_workbench_realize (GtkWidget *widget)
-{
- GbWorkbench *workbench = (GbWorkbench *)widget;
-
- if (GTK_WIDGET_CLASS (gb_workbench_parent_class)->realize)
- GTK_WIDGET_CLASS (gb_workbench_parent_class)->realize (widget);
-
- gtk_widget_grab_focus (GTK_WIDGET (workbench->priv->editor));
-}
-
-static void
-gb_workbench_action_go_forward (GSimpleAction *action,
- GVariant *variant,
- gpointer user_data)
-{
- GbWorkbench *workbench = user_data;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- if (gb_navigation_list_get_can_go_forward (workbench->priv->navigation_list))
- gb_navigation_list_go_forward (workbench->priv->navigation_list);
-}
-
-static void
-gb_workbench_action_go_backward (GSimpleAction *action,
- GVariant *variant,
- gpointer user_data)
-{
- GbWorkbench *workbench = user_data;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- if (gb_navigation_list_get_can_go_backward (workbench->priv->navigation_list))
- gb_navigation_list_go_backward (workbench->priv->navigation_list);
-}
-
-static void
-gb_workbench_action_toggle_command_bar (GSimpleAction *action,
- GVariant *parameters,
- gpointer user_data)
-{
- GbWorkbench *workbench = user_data;
- gboolean show = TRUE;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- show = g_variant_get_boolean (parameters);
-
- if (show)
- gb_command_bar_show (workbench->priv->command_bar);
- else
- gb_command_bar_hide (workbench->priv->command_bar);
-}
-
-static void
-gb_workbench_action_show_command_bar (GSimpleAction *action,
- GVariant *parameters,
- gpointer user_data)
-{
- GVariant *b;
-
- g_return_if_fail (GB_IS_WORKBENCH (user_data));
-
- b = g_variant_new_boolean (TRUE);
- gb_workbench_action_toggle_command_bar (NULL, b, user_data);
- g_variant_unref (b);
-}
-
-static void
-build_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- IdeBuilder *builder = (IdeBuilder *)object;
- g_autoptr(GbWorkbench) workbench = user_data;
- g_autoptr(IdeBuildResult) build_result = NULL;
- g_autoptr(GError) error = NULL;
-
- g_return_if_fail (IDE_IS_BUILDER (builder));
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- workbench->priv->building = FALSE;
-
- g_print ("Build finished.\n");
-
- build_result = ide_builder_build_finish (builder, result, &error);
-
- if (!build_result)
- {
- /*
- * TODO: Focus build output pane?
- */
- }
-}
-
-static void
-gb_workbench_action_build (GSimpleAction *action,
- GVariant *parameters,
- gpointer user_data)
-{
- GbWorkbenchPrivate *priv;
- GbWorkbench *workbench = user_data;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- priv = workbench->priv;
-
- if (priv->building)
- {
- /*
- * TODO: Can we have multiple parallel builds? Seems okay as long as they
- * are for different devices.
- */
- g_message (_("Already building.\n"));
- return;
- }
-
- if (priv->context)
- {
- IdeDeviceManager *device_manager;
- IdeBuildSystem *build_system;
- g_autoptr(IdeDevice) device = NULL;
- GPtrArray *devices;
- guint i;
-
- /*
- * TODO: Add combo to select the target device we are working with.
- */
-
- device_manager = ide_context_get_device_manager (priv->context);
- build_system = ide_context_get_build_system (priv->context);
-
- devices = ide_device_manager_get_devices (device_manager);
- for (i = 0; i < devices->len; i++)
- {
- IdeDevice *item = g_ptr_array_index (devices, i);
-
- if (IDE_IS_LOCAL_DEVICE (item))
- {
- device = g_object_ref (item);
- break;
- }
- }
- g_ptr_array_unref (devices);
-
- if (device)
- {
- g_autoptr(IdeBuilder) builder = NULL;
- g_autoptr(GError) error = NULL;
- g_autoptr(GKeyFile) config = NULL;
-
- /*
- * TODO: This should come from the current workspace configuration
- * for the build. We probably need to persist this between
- * runs as well.
- */
- config = g_key_file_new ();
-
- builder = ide_build_system_get_builder (build_system,
- config,
- device,
- &error);
-
- if (!builder)
- {
- g_warning ("%s\n", error->message);
- return;
- }
-
- /*
- * TODO: We should attach to the results progress signal so that we
- * can proxy that to the build status in the workbench.
- */
- priv->building = TRUE;
- ide_builder_build_async (builder,
- NULL,
- NULL,
- build_cb,
- g_object_ref (workbench));
- }
- }
-}
-static void
-gb_workbench_action_global_search (GSimpleAction *action,
- GVariant *parameters,
- gpointer user_data)
-{
- GbWorkbench *workbench = user_data;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- gtk_widget_grab_focus (GTK_WIDGET (workbench->priv->search_box));
-}
-
-static void
-gb_workbench_action_roll_credits (GSimpleAction *action,
- GVariant *parameters,
- gpointer user_data)
-{
- GbWorkbench *workbench = user_data;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
-
- gb_workbench_roll_credits (workbench);
+ self->unloading = FALSE;
+ g_clear_object (&self->context);
+ gtk_window_close (GTK_WINDOW (self));
}
-static void
-gb_workbench_action_save_all (GSimpleAction *action,
- GVariant *parameters,
- gpointer user_data)
+static gboolean
+gb_workbench_delete_event (GtkWidget *widget,
+ GdkEventAny *event)
{
- GbWorkbench *workbench = user_data;
- GList *list;
- GList *iter;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
+ GbWorkbench *self = (GbWorkbench *)widget;
- list = gb_document_manager_get_documents (workbench->priv->document_manager);
+ g_assert (GB_IS_WORKBENCH (self));
- for (iter = list; iter; iter = iter->next)
+ if (self->unloading)
{
- GbDocument *document = GB_DOCUMENT (iter->data);
-
- /* This will not save files which do not have location set */
- if (gb_document_get_modified (document))
- gb_document_save_async (document, GTK_WIDGET (workbench),
- NULL, NULL, NULL);
+ /* Second attempt to kill things, cancel clean shutdown */
+ g_cancellable_cancel (self->unload_cancellable);
+ return TRUE;
}
- g_list_free (list);
-}
-
-static void
-gb_workbench_navigation_changed (GbWorkbench *workbench,
- GParamSpec *pspec,
- GbNavigationList *list)
-{
- GbWorkbenchPrivate *priv;
- GbNavigationItem *item;
- GbWorkspace *workspace;
-
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (GB_IS_NAVIGATION_LIST (list));
-
- priv = workbench->priv;
-
- item = gb_navigation_list_get_current_item (list);
-
- if (item)
+ if (self->context != NULL)
{
- workspace = gb_navigation_item_get_workspace (item);
- if (workspace)
- gtk_stack_set_visible_child (priv->stack, GTK_WIDGET (workspace));
- gb_navigation_item_activate (item);
+ g_assert (!self->unload_cancellable);
+
+ self->unloading = TRUE;
+ self->unload_cancellable = g_cancellable_new ();
+ ide_context_unload_async (self->context,
+ self->unload_cancellable,
+ gb_workbench__unload_cb,
+ g_object_ref (self));
+ return TRUE;
}
-}
-
-static void
-gb_workbench_save_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- SavedState *state = user_data;
-
- GbDocument *document = (GbDocument *)object;
-
- gb_document_save_finish (document, result, NULL);
-
- state->outstanding--;
-}
-
-static void
-gb_workbench_save_as_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- SavedState *state = user_data;
-
- GbDocument *document = (GbDocument *)object;
-
- gb_document_save_as_finish (document, result, NULL);
-
- state->outstanding--;
-}
-
-static void
-gb_workbench_begin_save (GbWorkbench *workbench,
- GbDocument *document,
- SavedState *state)
-{
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (GB_IS_DOCUMENT (document));
- g_return_if_fail (state);
- state->outstanding++;
-
- gb_document_save_async (document,
- GTK_WIDGET (workbench),
- state->cancellable,
- gb_workbench_save_cb,
- state);
-}
-
-static void
-gb_workbench_begin_save_as (GbWorkbench *workbench,
- GbDocument *document,
- SavedState *state)
-{
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (GB_IS_DOCUMENT (document));
- g_return_if_fail (state);
-
- state->outstanding++;
-
- gb_document_save_as_async (document,
- GTK_WIDGET (workbench),
- state->cancellable,
- gb_workbench_save_as_cb,
- state);
-}
-
-static void
-gb_workbench_wait_for_saved (GbWorkbench *workbench,
- GtkDialog *dialog,
- SavedState *state)
-{
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (GTK_IS_DIALOG (dialog));
- g_return_if_fail (state);
-
- gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE);
- while (state->outstanding)
- gtk_main_iteration_do (TRUE);
- gtk_widget_set_sensitive (GTK_WIDGET (dialog), TRUE);
+ return FALSE;
}
static gboolean
-gb_workbench_confirm_close (GbWorkbench *workbench)
+gb_workbench_draw (GtkWidget *widget,
+ cairo_t *cr)
{
- GbDocumentManager *document_manager;
- gboolean ret = FALSE;
- GList *unsaved = NULL;
-
- g_return_val_if_fail (GB_IS_WORKBENCH (workbench), FALSE);
-
- document_manager = gb_workbench_get_document_manager (workbench);
- unsaved = gb_document_manager_get_unsaved_documents (document_manager);
+ GbWorkbench *self = (GbWorkbench *)widget;
+ GtkStyleContext *style_context;
+ gboolean ret;
- if (unsaved)
- {
- GbCloseConfirmationDialog *close;
- SavedState state = { 0 };
- GtkWidget *dialog;
- GList *selected;
- GList *iter;
- gint response_id;
-
- dialog = gb_close_confirmation_dialog_new (GTK_WINDOW (workbench),
- unsaved);
- close = GB_CLOSE_CONFIRMATION_DIALOG (dialog);
- response_id = gtk_dialog_run (GTK_DIALOG (dialog));
- selected = gb_close_confirmation_dialog_get_selected_documents (close);
-
- switch (response_id)
- {
- case GTK_RESPONSE_YES:
- state.cancellable = g_cancellable_new ();
-
- for (iter = selected; iter; iter = iter->next)
- {
- GbDocument *document = GB_DOCUMENT (iter->data);
-
- if (gb_document_is_untitled (document))
- gb_workbench_begin_save_as (workbench, document, &state);
- else
- gb_workbench_begin_save (workbench, document, &state);
- }
-
- gb_workbench_wait_for_saved (workbench, GTK_DIALOG (dialog), &state);
- g_clear_object (&state.cancellable);
- break;
-
- case GTK_RESPONSE_NO:
- break;
-
- case GTK_RESPONSE_DELETE_EVENT:
- case GTK_RESPONSE_CANCEL:
- ret = TRUE;
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- g_list_free (selected);
- gtk_widget_hide (dialog);
- gtk_widget_destroy (dialog);
- }
+ g_assert (GB_IS_WORKBENCH (self));
- g_list_free (unsaved);
+ style_context = gtk_widget_get_style_context (widget);
+ gtk_style_context_save (style_context);
+ if (self->building)
+ gtk_style_context_add_class (style_context, "building");
+ ret = GTK_WIDGET_CLASS (gb_workbench_parent_class)->draw (widget, cr);
+ gtk_style_context_restore (style_context);
return ret;
}
-static gboolean
-gb_workbench_delete_event (GtkWidget *widget,
- GdkEventAny *event)
-{
- GbWorkbench *workbench = (GbWorkbench *)widget;
-
- g_return_val_if_fail (GB_IS_WORKBENCH (workbench), FALSE);
-
- if (!gb_workbench_confirm_close (workbench))
- {
- if (GTK_WIDGET_CLASS (gb_workbench_parent_class)->delete_event)
- return GTK_WIDGET_CLASS (gb_workbench_parent_class)->delete_event (widget, event);
- return FALSE;
- }
-
- return TRUE;
-}
-
static void
-gb_workbench_add_command_provider (GbWorkbench *workbench,
- GType type)
+gb_workbench_realize (GtkWidget *widget)
{
- GbCommandProvider *provider;
+ GbWorkbench *self = (GbWorkbench *)widget;
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
- g_return_if_fail (g_type_is_a (type, GB_TYPE_COMMAND_PROVIDER));
+ if (GTK_WIDGET_CLASS (gb_workbench_parent_class)->realize)
+ GTK_WIDGET_CLASS (gb_workbench_parent_class)->realize (widget);
- provider = g_object_new (type, "workbench", workbench, NULL);
- gb_command_manager_add_provider (workbench->priv->command_manager, provider);
+ gtk_widget_grab_focus (GTK_WIDGET (self->editor_workspace));
}
static void
gb_workbench_set_focus (GtkWindow *window,
GtkWidget *widget)
{
- GbWorkbench *workbench = (GbWorkbench *)window;
+ GbWorkbench *self = (GbWorkbench *)window;
- g_return_if_fail (GB_IS_WORKBENCH (workbench));
+ g_return_if_fail (GB_IS_WORKBENCH (self));
/*
* The goal here is to focus the current workspace if we are trying to
@@ -826,7 +147,7 @@ gb_workbench_set_focus (GtkWindow *window,
GTK_WINDOW_CLASS (gb_workbench_parent_class)->set_focus (window, widget);
- if (!widget && !workbench->priv->disposing)
+ if (!widget && !self->disposing)
{
GbWorkspace *workspace;
@@ -837,131 +158,69 @@ gb_workbench_set_focus (GtkWindow *window,
* for reentrancy later, but if that happens, we are probably doing
* something else wrong.
*/
- workspace = gb_workbench_get_active_workspace (workbench);
+ workspace = gb_workbench_get_active_workspace (self);
if (workspace)
gtk_widget_grab_focus (GTK_WIDGET (workspace));
}
}
static void
-on_context_new_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- g_autoptr(GbWorkbench) self = user_data;
- g_autoptr(IdeContext) context = NULL;
- g_autoptr(GError) error = NULL;
-
- context = ide_context_new_finish (result, &error);
-
- if (!context)
- g_warning ("%s\n", error->message);
- else
- gb_workbench_set_context (self, context);
-}
-
-static void
gb_workbench_constructed (GObject *object)
{
- static const GActionEntry actions[] = {
- { "build", gb_workbench_action_build },
- { "global-search", gb_workbench_action_global_search },
- { "go-backward", gb_workbench_action_go_backward },
- { "go-forward", gb_workbench_action_go_forward },
- { "show-command-bar", gb_workbench_action_show_command_bar },
- { "toggle-command-bar", gb_workbench_action_toggle_command_bar, "b" },
- { "save-all", gb_workbench_action_save_all },
- { "about", gb_workbench_action_roll_credits },
- };
- GbWorkbenchPrivate *priv;
- GbWorkbench *workbench = (GbWorkbench *)object;
- GbSearchManager *search_manager;
+ GbWorkbench *self = (GbWorkbench *)object;
GtkApplication *app;
- GAction *action;
GMenu *menu;
- g_assert (GB_IS_WORKBENCH (workbench));
-
- ENTRY;
-
- priv = workbench->priv;
+ IDE_ENTRY;
G_OBJECT_CLASS (gb_workbench_parent_class)->constructed (object);
+ gb_workbench_actions_init (self);
+
app = GTK_APPLICATION (g_application_get_default ());
menu = gtk_application_get_menu_by_id (app, "gear-menu");
- gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (priv->gear_menu_button),
- G_MENU_MODEL (menu));
-
- g_signal_connect_object (priv->stack,
- "notify::visible-child",
- G_CALLBACK (gb_workbench_stack_child_changed),
- workbench,
- (G_CONNECT_SWAPPED | G_CONNECT_AFTER));
+ gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (self->gear_menu_button), G_MENU_MODEL (menu));
- g_action_map_add_action_entries (G_ACTION_MAP (workbench), actions,
- G_N_ELEMENTS (actions), workbench);
+ if (self->active_workspace)
+ gtk_widget_grab_focus (GTK_WIDGET (self->active_workspace));
+ else
+ gtk_widget_grab_focus (GTK_WIDGET (self->editor_workspace));
- g_signal_connect_object (priv->navigation_list,
- "notify::current-item",
- G_CALLBACK (gb_workbench_navigation_changed),
- workbench,
- G_CONNECT_SWAPPED);
+ IDE_EXIT;
+}
- action = g_action_map_lookup_action (G_ACTION_MAP (workbench), "go-backward");
- g_object_bind_property (priv->navigation_list, "can-go-backward",
- action, "enabled", G_BINDING_SYNC_CREATE);
+static void
+gb_workbench_dispose (GObject *object)
+{
+ GbWorkbench *self = (GbWorkbench *)object;
- action = g_action_map_lookup_action (G_ACTION_MAP (workbench), "go-forward");
- g_object_bind_property (priv->navigation_list, "can-go-forward",
- action, "enabled", G_BINDING_SYNC_CREATE);
+ IDE_ENTRY;
- search_manager = gb_workbench_get_search_manager (workbench);
- gb_search_box_set_search_manager (workbench->priv->search_box,
- search_manager);
+ self->disposing++;
- gb_workbench_stack_child_changed (workbench, NULL, priv->stack);
+ g_clear_object (&self->command_manager);
+ g_clear_object (&self->unload_cancellable);
- /*
- * TODO: Dummy code until we have real project loading.
- */
- {
- g_autoptr(GFile) project_dir = g_file_new_for_path (".");
+ G_OBJECT_CLASS (gb_workbench_parent_class)->dispose (object);
- ide_context_new_async (project_dir,
- NULL,
- on_context_new_cb,
- g_object_ref (workbench));
- }
+ self->disposing--;
- EXIT;
+ IDE_EXIT;
}
static void
-gb_workbench_dispose (GObject *object)
+gb_workbench_finalize (GObject *object)
{
- GbWorkbenchPrivate *priv = GB_WORKBENCH (object)->priv;
-
- ENTRY;
-
- priv->disposing++;
-
- if (priv->search_timeout)
- {
- g_source_remove (priv->search_timeout);
- priv->search_timeout = 0;
- }
+ GbWorkbench *self = (GbWorkbench *)object;
- g_clear_object (&priv->command_manager);
- g_clear_object (&priv->document_manager);
- g_clear_object (&priv->navigation_list);
- g_clear_object (&priv->search_manager);
+ IDE_ENTRY;
- G_OBJECT_CLASS (gb_workbench_parent_class)->dispose (object);
+ ide_clear_weak_pointer (&self->active_workspace);
+ g_clear_object (&self->context);
- priv->disposing--;
+ G_OBJECT_CLASS (gb_workbench_parent_class)->finalize (object);
- EXIT;
+ IDE_EXIT;
}
static void
@@ -974,6 +233,10 @@ gb_workbench_get_property (GObject *object,
switch (prop_id)
{
+ case PROP_ACTIVE_WORKSPACE:
+ g_value_set_object (value, gb_workbench_get_active_workspace (self));
+ break;
+
case PROP_COMMAND_MANAGER:
g_value_set_object (value, gb_workbench_get_command_manager (self));
break;
@@ -982,10 +245,6 @@ gb_workbench_get_property (GObject *object,
g_value_set_object (value, gb_workbench_get_context (self));
break;
- case PROP_NAVIGATION_LIST:
- g_value_set_object (value, gb_workbench_get_navigation_list (self));
- break;
-
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -1001,6 +260,10 @@ gb_workbench_set_property (GObject *object,
switch (prop_id)
{
+ case PROP_ACTIVE_WORKSPACE:
+ gb_workbench_set_active_workspace (self, g_value_get_object (value));
+ break;
+
case PROP_CONTEXT:
gb_workbench_set_context (self, g_value_get_object (value));
break;
@@ -1019,88 +282,153 @@ gb_workbench_class_init (GbWorkbenchClass *klass)
object_class->constructed = gb_workbench_constructed;
object_class->dispose = gb_workbench_dispose;
+ object_class->finalize = gb_workbench_finalize;
object_class->get_property = gb_workbench_get_property;
object_class->set_property = gb_workbench_set_property;
+ widget_class->draw = gb_workbench_draw;
widget_class->realize = gb_workbench_realize;
widget_class->delete_event = gb_workbench_delete_event;
- widget_class->key_press_event = gb_workbench_key_press_event;
window_class->set_focus = gb_workbench_set_focus;
- klass->workspace_changed = gb_workbench_workspace_changed;
+ gParamSpecs [PROP_ACTIVE_WORKSPACE] =
+ g_param_spec_object ("active-workspace",
+ _("Active Workspace"),
+ _("The active workspace"),
+ GB_TYPE_WORKSPACE,
+ (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_ACTIVE_WORKSPACE,
+ gParamSpecs [PROP_ACTIVE_WORKSPACE]);
gParamSpecs [PROP_COMMAND_MANAGER] =
g_param_spec_object ("command-manager",
_("Command Manager"),
- _("The command manager for the workspace."),
+ _("The command manager for the workbench"),
GB_TYPE_COMMAND_MANAGER,
- (G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
+ (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_COMMAND_MANAGER,
gParamSpecs [PROP_COMMAND_MANAGER]);
+ /**
+ * GbWorkbench:context:
+ *
+ * The "context" property is the #IdeContext that shall be worked upon in
+ * the #GbWorkbench. This must be set during workbench creation. Use
+ * another window or dialog to choose the project information before
+ * creating a workbench window.
+ */
gParamSpecs [PROP_CONTEXT] =
g_param_spec_object ("context",
_("Context"),
- _("The IDE context for the workbench."),
+ _("The IdeContext for the workbench."),
IDE_TYPE_CONTEXT,
- (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_CONTEXT,
- gParamSpecs [PROP_CONTEXT]);
-
- gParamSpecs [PROP_NAVIGATION_LIST] =
- g_param_spec_object ("navigation-list",
- _("Navigation List"),
- _("The navigation list for the workbench."),
- GB_TYPE_NAVIGATION_LIST,
- (G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_NAVIGATION_LIST,
- gParamSpecs [PROP_NAVIGATION_LIST]);
-
- gSignals [WORKSPACE_CHANGED] =
- g_signal_new ("workspace-changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GbWorkbenchClass, workspace_changed),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- GB_TYPE_WORKSPACE);
+ (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, PROP_CONTEXT, gParamSpecs [PROP_CONTEXT]);
GB_WIDGET_CLASS_TEMPLATE (klass, "gb-workbench.ui");
GB_WIDGET_CLASS_BIND (klass, GbWorkbench, command_bar);
- GB_WIDGET_CLASS_BIND (klass, GbWorkbench, credits);
- GB_WIDGET_CLASS_BIND (klass, GbWorkbench, editor);
+ GB_WIDGET_CLASS_BIND (klass, GbWorkbench, editor_workspace);
GB_WIDGET_CLASS_BIND (klass, GbWorkbench, gear_menu_button);
- GB_WIDGET_CLASS_BIND (klass, GbWorkbench, header_bar);
- GB_WIDGET_CLASS_BIND (klass, GbWorkbench, run_button);
GB_WIDGET_CLASS_BIND (klass, GbWorkbench, search_box);
GB_WIDGET_CLASS_BIND (klass, GbWorkbench, stack);
g_type_ensure (GB_TYPE_COMMAND_BAR);
- g_type_ensure (GB_TYPE_CREDITS_WIDGET);
g_type_ensure (GB_TYPE_EDITOR_WORKSPACE);
g_type_ensure (GB_TYPE_SEARCH_BOX);
g_type_ensure (GEDIT_TYPE_MENU_STACK_SWITCHER);
}
static void
-gb_workbench_init (GbWorkbench *workbench)
+gb_workbench_init (GbWorkbench *self)
+{
+ IDE_ENTRY;
+
+ gtk_widget_init_template (GTK_WIDGET (self));
+
+ self->command_manager = gb_command_manager_new ();
+
+ IDE_EXIT;
+}
+
+/**
+ * gb_workbench_get_context:
+ * @self: A #GbWorkbench.
+ *
+ * Gets the #IdeContext for the workbench.
+ *
+ * Returns: (transfer none): An #IdeContext.
+ */
+IdeContext *
+gb_workbench_get_context (GbWorkbench *self)
{
- workbench->priv = gb_workbench_get_instance_private (workbench);
+ g_return_val_if_fail (GB_IS_WORKBENCH (self), NULL);
- workbench->priv->document_manager = gb_document_manager_new ();
- workbench->priv->command_manager = gb_command_manager_new ();
- workbench->priv->navigation_list = gb_navigation_list_new (workbench);
+ return self->context;
+}
+
+/**
+ * gb_workbench_get_active_workspace:
+ * @self: A #GbWorkbench.
+ *
+ * Gets the currently selected workspace.
+ *
+ * Returns: (transfer none): An #GbWorkspace.
+ */
+GbWorkspace *
+gb_workbench_get_active_workspace (GbWorkbench *self)
+{
+ g_return_val_if_fail (GB_IS_WORKBENCH (self), NULL);
+
+ return self->active_workspace;
+}
- gtk_widget_init_template (GTK_WIDGET (workbench));
+void
+gb_workbench_set_active_workspace (GbWorkbench *self,
+ GbWorkspace *workspace)
+{
+ g_return_if_fail (GB_IS_WORKBENCH (self));
+ g_return_if_fail (GB_IS_WORKSPACE (workspace));
+
+ if (ide_set_weak_pointer (&self->active_workspace, workspace))
+ gtk_stack_set_visible_child (self->stack, GTK_WIDGET (workspace));
+}
+
+void
+gb_workbench_open (GbWorkbench *self,
+ GFile *file)
+{
+ g_autoptr(IdeFile) idefile = NULL;
+ IdeBufferManager *buffer_manager;
+ IdeProject *project;
+
+ g_return_if_fail (GB_IS_WORKBENCH (self));
+ g_return_if_fail (self->unloading == FALSE);
+ g_return_if_fail (self->context);
+
+ /*
+ * TODO: We probably want to dispatch this based on the type. But for now,
+ * we will just try to open it with the buffer manager.
+ */
+
+ buffer_manager = ide_context_get_buffer_manager (self->context);
+ project = ide_context_get_project (self->context);
+ idefile = ide_project_get_project_file (project, file);
+ ide_buffer_manager_load_file_async (buffer_manager, idefile, FALSE, NULL, NULL, NULL, NULL);
+}
+
+/**
+ * gb_workbench_get_command_manager:
+ * @self: A #GbWorkbench.
+ *
+ * Gets the command manager for the workbench. This may be moved into libide.
+ *
+ * Returns: (transfer none): A #GbCommandManager.
+ */
+GbCommandManager *
+gb_workbench_get_command_manager (GbWorkbench *self)
+{
+ g_return_val_if_fail (GB_IS_WORKBENCH (self), NULL);
- gb_workbench_add_command_provider (workbench,
- GB_TYPE_COMMAND_GACTION_PROVIDER);
- gb_workbench_add_command_provider (workbench,
- GB_TYPE_COMMAND_VIM_PROVIDER);
+ return self->command_manager;
}
diff --git a/src/workbench/gb-workbench.h b/src/workbench/gb-workbench.h
index 08fbea5..54ea1bf 100644
--- a/src/workbench/gb-workbench.h
+++ b/src/workbench/gb-workbench.h
@@ -23,46 +23,21 @@
#include <ide.h>
#include "gb-command-manager.h"
-#include "gb-document-manager.h"
-#include "gb-navigation-list.h"
#include "gb-workbench-types.h"
G_BEGIN_DECLS
-#define GB_TYPE_WORKBENCH (gb_workbench_get_type())
-#define GB_WORKBENCH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_WORKBENCH, GbWorkbench))
-#define GB_WORKBENCH_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_WORKBENCH, GbWorkbench
const))
-#define GB_WORKBENCH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_WORKBENCH,
GbWorkbenchClass))
-#define GB_IS_WORKBENCH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_WORKBENCH))
-#define GB_IS_WORKBENCH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_WORKBENCH))
-#define GB_WORKBENCH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_WORKBENCH,
GbWorkbenchClass))
+#define GB_TYPE_WORKBENCH (gb_workbench_get_type())
-G_DEFINE_AUTOPTR_CLEANUP_FUNC (GbWorkbench, g_object_unref)
+G_DECLARE_FINAL_TYPE (GbWorkbench, gb_workbench, GB, WORKBENCH, GtkApplicationWindow)
-struct _GbWorkbench
-{
- GtkApplicationWindow parent;
-
- /*< private >*/
- GbWorkbenchPrivate *priv;
-};
-
-struct _GbWorkbenchClass
-{
- GtkApplicationWindowClass parent_class;
-
- void (*workspace_changed) (GbWorkbench *workbench,
- GbWorkspace *workspace);
-};
-
-GType gb_workbench_get_type (void);
-IdeContext *gb_workbench_get_context (GbWorkbench *workbench);
-GbNavigationList *gb_workbench_get_navigation_list (GbWorkbench *workbench);
-GbDocumentManager *gb_workbench_get_document_manager (GbWorkbench *workbench);
-GbWorkspace *gb_workbench_get_active_workspace (GbWorkbench *workbench);
-GbWorkspace *gb_workbench_get_workspace (GbWorkbench *workbench,
- GType type);
-GbCommandManager *gb_workbench_get_command_manager (GbWorkbench *workbench);
+IdeContext *gb_workbench_get_context (GbWorkbench *self);
+GbWorkspace *gb_workbench_get_active_workspace (GbWorkbench *self);
+void gb_workbench_set_active_workspace (GbWorkbench *self,
+ GbWorkspace *workspace);
+void gb_workbench_open (GbWorkbench *self,
+ GFile *file);
+GbCommandManager *gb_workbench_get_command_manager (GbWorkbench *self);
G_END_DECLS
diff --git a/src/workbench/gb-workspace.c b/src/workbench/gb-workspace.c
index aa4c70b..64351e5 100644
--- a/src/workbench/gb-workspace.c
+++ b/src/workbench/gb-workspace.c
@@ -20,11 +20,11 @@
#include "gb-workspace.h"
-struct _GbWorkspacePrivate
+typedef struct
{
gchar *icon_name;
gchar *title;
-};
+} GbWorkspacePrivate;
enum {
PROP_0,
@@ -38,51 +38,62 @@ G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GbWorkspace, gb_workspace, GTK_TYPE_BIN)
static GParamSpec *gParamSpecs[LAST_PROP];
const gchar *
-gb_workspace_get_icon_name (GbWorkspace *workspace)
+gb_workspace_get_icon_name (GbWorkspace *self)
{
- g_return_val_if_fail (GB_IS_WORKSPACE (workspace), NULL);
+ GbWorkspacePrivate *priv = gb_workspace_get_instance_private (self);
+
+ g_return_val_if_fail (GB_IS_WORKSPACE (self), NULL);
- return workspace->priv->icon_name;
+ return priv->icon_name;
}
void
-gb_workspace_set_icon_name (GbWorkspace *workspace,
+gb_workspace_set_icon_name (GbWorkspace *self,
const gchar *icon_name)
{
- g_return_if_fail (GB_IS_WORKSPACE (workspace));
+ GbWorkspacePrivate *priv = gb_workspace_get_instance_private (self);
+
+ g_return_if_fail (GB_IS_WORKSPACE (self));
- g_free (workspace->priv->icon_name);
- workspace->priv->icon_name = g_strdup (icon_name);
- g_object_notify_by_pspec (G_OBJECT (workspace),
- gParamSpecs[PROP_ICON_NAME]);
+ if (priv->icon_name != icon_name)
+ {
+ g_free (priv->icon_name);
+ priv->icon_name = g_strdup (icon_name);
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs[PROP_ICON_NAME]);
+ }
}
const gchar *
-gb_workspace_get_title (GbWorkspace *workspace)
+gb_workspace_get_title (GbWorkspace *self)
{
- g_return_val_if_fail (GB_IS_WORKSPACE (workspace), NULL);
+ GbWorkspacePrivate *priv = gb_workspace_get_instance_private (self);
- return workspace->priv->title;
+ g_return_val_if_fail (GB_IS_WORKSPACE (self), NULL);
+
+ return priv->title;
}
void
-gb_workspace_set_title (GbWorkspace *workspace,
+gb_workspace_set_title (GbWorkspace *self,
const gchar *title)
{
- g_return_if_fail (GB_IS_WORKSPACE (workspace));
+ GbWorkspacePrivate *priv = gb_workspace_get_instance_private (self);
+
+ g_return_if_fail (GB_IS_WORKSPACE (self));
- g_free (workspace->priv->title);
- workspace->priv->title = g_strdup (title);
- g_object_notify_by_pspec (G_OBJECT (workspace),
- gParamSpecs[PROP_TITLE]);
+ if (priv->title != title)
+ {
+ g_free (priv->title);
+ priv->title = g_strdup (title);
+ g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_TITLE]);
+ }
}
static void
gb_workspace_finalize (GObject *object)
{
- GbWorkspacePrivate *priv;
-
- priv = GB_WORKSPACE (object)->priv;
+ GbWorkspace *self = (GbWorkspace *)object;
+ GbWorkspacePrivate *priv = gb_workspace_get_instance_private (self);
g_clear_pointer (&priv->icon_name, g_free);
g_clear_pointer (&priv->title, g_free);
@@ -96,16 +107,16 @@ gb_workspace_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
- GbWorkspace *workspace = GB_WORKSPACE (object);
+ GbWorkspace *self = GB_WORKSPACE (object);
switch (prop_id)
{
case PROP_ICON_NAME:
- g_value_set_string (value, gb_workspace_get_icon_name (workspace));
+ g_value_set_string (value, gb_workspace_get_icon_name (self));
break;
case PROP_TITLE:
- g_value_set_string (value, gb_workspace_get_title (workspace));
+ g_value_set_string (value, gb_workspace_get_title (self));
break;
default:
@@ -119,16 +130,16 @@ gb_workspace_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- GbWorkspace *workspace = GB_WORKSPACE (object);
+ GbWorkspace *self = GB_WORKSPACE (object);
switch (prop_id)
{
case PROP_ICON_NAME:
- gb_workspace_set_icon_name (workspace, g_value_get_string (value));
+ gb_workspace_set_icon_name (self, g_value_get_string (value));
break;
case PROP_TITLE:
- gb_workspace_set_title (workspace, g_value_get_string (value));
+ gb_workspace_set_title (self, g_value_get_string (value));
break;
default:
@@ -153,8 +164,7 @@ gb_workspace_class_init (GbWorkspaceClass *klass)
NULL,
(G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_TITLE,
- gParamSpecs[PROP_TITLE]);
+ g_object_class_install_property (object_class, PROP_TITLE, gParamSpecs[PROP_TITLE]);
gParamSpecs[PROP_ICON_NAME] =
g_param_spec_string ("icon-name",
@@ -163,12 +173,10 @@ gb_workspace_class_init (GbWorkspaceClass *klass)
NULL,
(G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
- g_object_class_install_property (object_class, PROP_ICON_NAME,
- gParamSpecs[PROP_ICON_NAME]);
+ g_object_class_install_property (object_class, PROP_ICON_NAME, gParamSpecs[PROP_ICON_NAME]);
}
static void
gb_workspace_init (GbWorkspace *workspace)
{
- workspace->priv = gb_workspace_get_instance_private (workspace);
}
diff --git a/src/workbench/gb-workspace.h b/src/workbench/gb-workspace.h
index 46346f3..cffbbed 100644
--- a/src/workbench/gb-workspace.h
+++ b/src/workbench/gb-workspace.h
@@ -25,33 +25,20 @@
G_BEGIN_DECLS
-#define GB_TYPE_WORKSPACE (gb_workspace_get_type())
-#define GB_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_WORKSPACE, GbWorkspace))
-#define GB_WORKSPACE_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GB_TYPE_WORKSPACE, GbWorkspace
const))
-#define GB_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GB_TYPE_WORKSPACE,
GbWorkspaceClass))
-#define GB_IS_WORKSPACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GB_TYPE_WORKSPACE))
-#define GB_IS_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GB_TYPE_WORKSPACE))
-#define GB_WORKSPACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GB_TYPE_WORKSPACE,
GbWorkspaceClass))
-
-struct _GbWorkspace
-{
- GtkBin parent;
+#define GB_TYPE_WORKSPACE (gb_workspace_get_type())
- /*< private >*/
- GbWorkspacePrivate *priv;
-};
+G_DECLARE_DERIVABLE_TYPE (GbWorkspace, gb_workspace, GB, WORKSPACE, GtkBin)
struct _GbWorkspaceClass
{
GtkBinClass parent_class;
};
-GType gb_workspace_get_type (void);
-const gchar *gb_workspace_get_icon_name (GbWorkspace *workspace);
-void gb_workspace_set_icon_name (GbWorkspace *workspace,
+const gchar *gb_workspace_get_icon_name (GbWorkspace *self);
+void gb_workspace_set_icon_name (GbWorkspace *self,
const gchar *icon_name);
-const gchar *gb_workspace_get_title (GbWorkspace *workspace);
-void gb_workspace_set_title (GbWorkspace *workspace,
+const gchar *gb_workspace_get_title (GbWorkspace *self);
+void gb_workspace_set_title (GbWorkspace *self,
const gchar *title);
G_END_DECLS
diff --git a/tests/tests.mk b/tests/tests.mk
index a23dce7..0962d15 100644
--- a/tests/tests.mk
+++ b/tests/tests.mk
@@ -1,15 +1,8 @@
noinst_PROGRAMS += test-c-parse-helper
TESTS += test-c-parse-helper
-test_c_parse_helper_SOURCES = tests/test-c-parse-helper.c
-test_c_parse_helper_CFLAGS = $(libgnome_builder_la_CFLAGS)
-test_c_parse_helper_LDADD = libgnome-builder.la
-
-
-noinst_PROGRAMS += test-navigation-list
-TESTS += test-navigation-list
-test_navigation_list_SOURCES = tests/test-navigation-list.c
-test_navigation_list_CFLAGS = $(libgnome_builder_la_CFLAGS)
-test_navigation_list_LDADD = libgnome-builder.la
+test_c_parse_helper_SOURCES = tests/test-c-parse-helper.c libide/c/c-parse-helper.c
+test_c_parse_helper_CFLAGS = $(libide_1_0_la_CFLAGS) -I$(top_srcdir)/libide/c/
+test_c_parse_helper_LDADD = $(LIBIDE_LIBS)
noinst_PROGRAMS += test-ide-context
diff --git a/tools/ide-search.c b/tools/ide-search.c
index ae4e939..f9fb53c 100644
--- a/tools/ide-search.c
+++ b/tools/ide-search.c
@@ -95,7 +95,7 @@ context_cb (GObject *object,
G_CALLBACK (on_completed_cb),
g_object_ref (context));
- ide_search_context_execute (search_context, gSearchTerms);
+ ide_search_context_execute (search_context, gSearchTerms, 0);
}
gint
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]